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