]> git.mxchange.org Git - core.git/blob - framework/main/classes/resolver/controller/class_BaseControllerResolver.php
Continued:
[core.git] / framework / main / classes / resolver / controller / class_BaseControllerResolver.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Resolver\Controller;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Controller\Controller;
8 use Org\Mxchange\CoreFramework\Controller\DefaultControllerException;
9 use Org\Mxchange\CoreFramework\Controller\InvalidControllerException;
10 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
11 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
12 use Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper;
13 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
14 use Org\Mxchange\CoreFramework\Resolver\BaseResolver;
15 use Org\Mxchange\CoreFramework\Resolver\Controller\ControllerResolver;
16 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
17
18 // Import SPL stuff
19 use \InvalidArgumentException;
20
21 /**
22  * A generic controller resolver class
23  *
24  * @author              Roland Haeder <webmaster@shipsimu.org>
25  * @version             0.0.0
26  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
27  * @license             GNU GPL 3.0 or any newer version
28  * @link                http://www.shipsimu.org
29  *
30  * This program is free software: you can redistribute it and/or modify
31  * it under the terms of the GNU General Public License as published by
32  * the Free Software Foundation, either version 3 of the License, or
33  * (at your option) any later version.
34  *
35  * This program is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  * GNU General Public License for more details.
39  *
40  * You should have received a copy of the GNU General Public License
41  * along with this program. If not, see <http://www.gnu.org/licenses/>.
42  */
43 abstract class BaseControllerResolver extends BaseResolver {
44         /**
45          * Controller name
46          */
47         private $controllerName = '';
48
49         /**
50          * Protected constructor
51          *
52          * @param       $className      Name of the real class
53          * @return      void
54          */
55         protected function __construct (string $className) {
56                 // Call parent constructor
57                 parent::__construct($className);
58         }
59
60         /**
61          * Setter for controller name
62          *
63          * @param       $controllerName Last validated controller name
64          * @return      void
65          */
66         protected final function setControllerName (string $controllerName) {
67                 $this->controllerName = $controllerName;
68         }
69
70         /**
71          * Getter for controller name
72          *
73          * @return      $controllerName Last validated controller name
74          */
75         protected final function getControllerName () {
76                 return $this->controllerName;
77         }
78
79         /**
80          * "Loads" a given controller and instances it if not yet cached. If the
81          * controller was not found one of the default controllers will be used
82          * depending on whether news shall be displayed.
83          *
84          * @param       $controllerName                 A controller name we shall look for
85          * @return      $controllerInstance             A loaded controller instance
86          * @throws      InvalidControllerException      Thrown if even the requested
87          *                                                                              controller class is missing (bad!)
88          */
89         protected function loadController (string $controllerName) {
90                 // Cache default controller
91                 $defaultController = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('default_' . strtolower($this->getClassPrefix()) . '_controller');
92
93                 // Create full class name
94                 $className = sprintf(
95                         '%s\%sDefaultNewsController',
96                         $this->getNamespace(),
97                         $this->getCapitalizedClassPrefix()
98                 );
99
100                 // Default controller
101                 $this->setClassName($className);
102
103                 // Generate the class name
104                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BEFORE: controller=' . $controllerName);
105                 if ($controllerName != $defaultController) {
106                         // Create controller class name
107                         $className = sprintf(
108                                 '%s\%s%sController',
109                                 $this->getNamespace(),
110                                 $this->getCapitalizedClassPrefix(),
111                                 StringUtils::convertToClassName($controllerName)
112                         );
113
114                         // ... and set it
115                         $this->setClassName($className);
116                 } else {
117                         // No news at main controller or non-news controller
118                         $this->setClassName($className);
119                 }
120
121                 // Is this class loaded?
122                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('AFTER: controller=' . $this->getClassName());
123                 if (!class_exists($this->getClassName())) {
124                         // Throw an exception here
125                         throw new InvalidControllerException(array($this, $controllerName), self::EXCEPTION_INVALID_CONTROLLER);
126                 }
127
128                 // Try to read a config entry for our resolver including controller name... ;-)
129                 $resolverConfigEntry = sprintf('%s_cmd_%s_resolver_class', strtolower($this->getClassPrefix()), strtolower($controllerName));
130
131                 // Get the config, this will throw an exception if there is no special controller resolver
132                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CONTROLLER-RESOLVER: resolverConfigEntry=%s', $resolverConfigEntry));
133                 $resolverClass = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($resolverConfigEntry);
134
135                 // Initiate the resolver and controller
136                 $resolverInstance = ObjectFactory::createObjectByConfiguredName(
137                         $resolverConfigEntry,
138                         array(
139                                 $controllerName,
140                                 ApplicationHelper::getSelfInstance()
141                         )
142                 );
143
144                 // Get controller instance
145                 $controllerInstance = ObjectFactory::createObjectByName(
146                         $this->getClassName(),
147                         array($resolverInstance)
148                 );
149
150                 // Return the result
151                 return $controllerInstance;
152         }
153
154         /**
155          * Checks whether the given controller is valid
156          *
157          * @param       $namespace                      Namespace to look in, no trailing backslash
158          * @param       $controllerName         The default controller we shall execute
159          * @return      $isValid                        Whether the given controller is valid
160          * @throws      InvalidArgumentException                Thrown if given controller is not set
161          * @throws      DefaultControllerException      Thrown if default controller was not found
162          */
163         protected function isControllerValid (string $namespace, string $controllerName) {
164                 // Is a action set?
165                 if (empty($namespace)) {
166                         // Then thrown an exception here
167                         throw new InvalidArgumentException('Parameter "namespace" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
168                 } elseif (empty($controllerName)) {
169                         // Then thrown an exception here
170                         throw new InvalidArgumentException('Parameter "controllerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
171                 }
172
173                 // By default nothing shall be valid
174                 $isValid = false;
175
176                 // Create class name
177                 $className = sprintf(
178                         '%s\%s%sController',
179                         $namespace,
180                         $this->getCapitalizedClassPrefix(),
181                         StringUtils::convertToClassName($controllerName)
182                 );
183
184                 // Application's default news controller
185                 $appDefaultControllerName = sprintf(
186                         '%s\%sDefaultNewsController',
187                         $namespace,
188                         $this->getCapitalizedClassPrefix()
189                 );
190
191                 // Framework's default news controller
192                 $defaultControllerName = sprintf(
193                         'Org\Mxchange\CoreFramework\Controller\News\%sDefaultNewsController',
194                         $this->getCapitalizedClassPrefix()
195                 );
196
197                 // Now, let us create the full name of the controller class
198                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('className=%s', $className));
199                 $this->setClassName($className);
200
201                 // Try it hard to get an controller
202                 while ($isValid === false) {
203                         // Is this class already loaded?
204                         if (class_exists($this->getClassName())) {
205                                 // This class does exist. :-)
206                                 $isValid = true;
207                         } elseif ($this->getClassName() != $appDefaultControllerName) {
208                                 // Set application's default controller
209                                 $this->setClassName($appDefaultControllerName);
210                         } elseif ($this->getClassName() != $defaultControllerName) {
211                                 // Set framework's default controller
212                                 $this->setClassName($defaultControllerName);
213                         } else {
214                                 // All is tried, give it up here
215                                 throw new DefaultControllerException($this, self::EXCEPTION_DEFAULT_CONTROLLER_GONE);
216                         }
217                 }
218
219                 // Return the result
220                 return $isValid;
221         }
222
223         /**
224          * Resolves the default controller of the given controller
225          *
226          * @return      $controllerInstance             A controller instance for the default
227          *                                                                      controller
228          * @throws      InvalidControllerInstanceException      Thrown if $controllerInstance
229          *                                                                                              is invalid
230          */
231         public function resolveController () {
232                 // Init variables
233                 $controllerName = $this->getControllerName();
234
235                 // Get the controller
236                 $controllerInstance = $this->loadController($controllerName);
237
238                 // And validate it
239                 if ((!is_object($controllerInstance)) || (!$controllerInstance instanceof Controller)) {
240                         // This controller has an invalid instance!
241                         throw new InvalidControllerInstanceException(array($this, $controllerName), self::EXCEPTION_INVALID_CONTROLLER);
242                 }
243
244                 // Set last controller
245                 $this->setResolvedInstance($controllerInstance);
246
247                 // Return the maybe resolved instance
248                 return $controllerInstance;
249         }
250
251 }