3b0d24c18cd3f878fdd0880b07bc4448fcea3209
[core.git] / inc / classes / main / controller / class_BaseController.php
1 <?php
2 /**
3  * A generic controller class. You should extend this base class if you want to
4  * write your own controller. You get the advantage that you can use the pre and
5  * post filters.
6  *
7  * @author              Roland Haeder <webmaster@shipsimu.org>
8  * @version             0.0.0
9  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
10  * @license             GNU GPL 3.0 or any newer version
11  * @link                http://www.shipsimu.org
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 class BaseController extends BaseFrameworkSystem implements Registerable {
27         // Exception constants
28         const EXCEPTION_FILTER_CHAIN_INVALID = 0xf10;
29
30         // Names of controller's own filter chains
31         const FILTER_CHAIN_PRE_COMMAND  = 'controller_pre_command';
32         const FILTER_CHAIN_POST_COMMAND = 'controller_post_command';
33
34         /**
35          * Generic filter chains
36          */
37         private $filterChains = array();
38
39         /**
40          * Protected constructor
41          *
42          * @param       $className      Name of the class
43          * @return      void
44          */
45         protected function __construct ($className) {
46                 // Call parent constructor
47                 parent::__construct($className);
48
49                 // Initialize both filter chains
50                 $this->initFilterChain(self::FILTER_CHAIN_PRE_COMMAND);
51                 $this->initFilterChain(self::FILTER_CHAIN_POST_COMMAND);
52
53                 // Add this controller to the registry
54                 Registry::getRegistry()->addInstance('controller', $this);
55         }
56
57         /**
58          * Executes a command with pre and post filters
59          *
60          * @param       $requestInstance        A Requestable class
61          * @param       $responseInstance       A Responseable class
62          * @return      void
63          */
64         public function executeGenericPrePostCommand (Requestable $requestInstance, Responseable $responseInstance) {
65                 // Get the command instance from the resolver by sending a request instance to the resolver
66                 $commandInstance = $this->getResolverInstance()->resolveCommandByRequest($requestInstance);
67
68                 // Add more filters by the command
69                 $commandInstance->addExtraFilters($this, $requestInstance);
70
71                 // Run the pre filters
72                 $this->executePreFilters($requestInstance, $responseInstance);
73
74                 // This request was valid! :-D
75                 $requestInstance->requestIsValid();
76
77                 // Execute the command
78                 $commandInstance->execute($requestInstance, $responseInstance);
79
80                 // Run the post filters
81                 $this->executePostFilters($requestInstance, $responseInstance);
82
83                 // Flush the response out
84                 $responseInstance->flushBuffer();
85         }
86
87         /**
88          * Private method to initialize a given filter chain
89          *
90          * @param       $filterChain    Name of the filter chain
91          * @return      void
92          */
93         protected function initFilterChain ($filterChain) {
94                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONTROLLER: ' . $filterChain . ' init: START');
95                 $this->filterChains[$filterChain] = ObjectFactory::createObjectByConfiguredName('filter_chain_class');
96                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONTROLLER: ' . $filterChain . ' init: FINISHED');
97         }
98
99         /**
100          * Adds a filter to a given filter chain
101          *
102          * @param       $filterChain    Chain of the filter
103          * @param       $filterInstance         An instance of a filter
104          * @return      void
105          * @throws      InvalidFilterChainException     If the filter chain is invalid
106          */
107         protected function addFilter ($filterChain, Filterable $filterInstance) {
108                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONTROLLER: ' . $filterChain . ',' . $filterInstance->__toString(). ' add: START');
109
110                 // Test if the filter is there
111                 if (!isset($this->filterChains[$filterChain])) {
112                         // Throw an exception here
113                         throw new InvalidFilterChainException(array($this, $filterChain), self::EXCEPTION_FILTER_CHAIN_INVALID);
114                 } // END - if
115
116                 // Add the filter
117                 $this->filterChains[$filterChain]->addFilter($filterInstance);
118                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONTROLLER: ' . $filterChain . ',' . $filterInstance->__toString(). ' add: FINISH');
119         }
120
121         /**
122          * Adds a filter to the pre filter chain
123          *
124          * @param       $filterInstance         An instance of a filter
125          * @return      void
126          */
127         public function addPreFilter (Filterable $filterInstance) {
128                 // Add the pre filter
129                 $this->addFilter(self::FILTER_CHAIN_PRE_COMMAND, $filterInstance);
130         }
131
132         /**
133          * Adds a filter to the post filter chain
134          *
135          * @param       $filterInstance         An instance of a filter
136          * @return      void
137          */
138         public function addPostFilter (Filterable $filterInstance) {
139                 // Add the post filter
140                 $this->addFilter(self::FILTER_CHAIN_POST_COMMAND, $filterInstance);
141         }
142
143         /**
144          * Add a shutdown filter
145          *
146          * @param       $filterInstance         A Filterable class
147          * @return      void
148          */
149         public function addShutdownFilter (Filterable $filterInstance) {
150                 $this->addFilter('shutdown', $filterInstance);
151         }
152
153         /**
154          * Executes given filter chain chain
155          *
156          * @param       $filterChain            Chain of the filter to execute
157          * @param       $requestInstance        An instance of a request class
158          * @param       $responseInstance       An instance of a response class
159          * @return      void
160          * @throws      InvalidFilterChainException     If the filter chain is invalid
161          */
162         protected function executeFilters ($filterChain, Requestable $requestInstance, Responseable $responseInstance) {
163                 // Test if the filter is there
164                 if (!isset($this->filterChains[$filterChain])) {
165                         // Throw an exception here
166                         throw new InvalidFilterChainException(array($this, $filterChain), self::EXCEPTION_FILTER_CHAIN_INVALID);
167                 } // END - if
168
169                 // Run all filters
170                 $this->filterChains[$filterChain]->processFilters($requestInstance, $responseInstance);
171         }
172
173         /**
174          * Executes all pre filters
175          *
176          * @param       $requestInstance        An instance of a request class
177          * @param       $responseInstance       An instance of a response class
178          * @return      void
179          */
180         protected function executePreFilters (Requestable $requestInstance, Responseable $responseInstance) {
181                 // Execute all pre filters
182                 $this->executeFilters(self::FILTER_CHAIN_PRE_COMMAND, $requestInstance, $responseInstance);
183         }
184
185         /**
186          * Executes all post filters
187          *
188          * @param       $requestInstance        An instance of a request class
189          * @param       $responseInstance       An instance of a response class
190          * @return      void
191          */
192         protected function executePostFilters (Requestable $requestInstance, Responseable $responseInstance) {
193                 // Execute all post filters
194                 $this->executeFilters(self::FILTER_CHAIN_POST_COMMAND, $requestInstance, $responseInstance);
195         }
196
197         /**
198          * Executes all shutdown filters
199          *
200          * @param       $requestInstance        A Requestable class
201          * @param       $responseInstance       A Responseable class
202          * @return      void
203          */
204         public function executeShutdownFilters (Requestable $requestInstance, Responseable $responseInstance) {
205                 $this->executeFilters('shutdown', $requestInstance, $responseInstance);
206         }
207 }
208
209 // [EOF]
210 ?>