Controller.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\presentation;
12 
24 
25 /**
26  * Controller is the base class of all controllers.
27  *
28  * Error Handling:
29  * - throw an Exception or use response action _failure_ to signal fatal errors
30  * (calls wcmf::application::controller::FailureController)
31  * - add an ApplicationError to the response to signal non fatal errors
32  *
33  * The following default request/response parameters are defined:
34  *
35  * | Parameter | Description
36  * |-------------------------|-------------------------
37  * | _in_ / _out_ `action` | The action to be executed
38  * | _in_ / _out_ `context` | The context of the action
39  * | _in_ `language` | The language of the requested data (optional)
40  * | _out_ `controller` | The name of the executed controller
41  * | _out_ `success` | Boolean whether the action completed successfully or not (depends on existence of error messages)
42  * | _out_ `errorMessage` | An error message which is displayed to the user
43  * | _out_ `errorCode` | An error code, describing the type of error
44  * | _out_ `errorData` | Some error codes require to transmit further information to the client
45  *
46  * @author ingo herwig <ingo@wemove.com>
47  */
48 class Controller {
49 
50  private $_request = null;
51  private $_response = null;
52 
53  private $_logger = null;
54  private $_session = null;
55  private $_persistenceFacade = null;
56  private $_permissionManager = null;
57  private $_actionMapper = null;
58  private $_localization = null;
59  private $_message = null;
60  private $_configuration = null;
61 
62  /**
63  * Constructor
64  * @param $session
65  * @param $persistenceFacade
66  * @param $permissionManager
67  * @param $actionMapper
68  * @param $localization
69  * @param $message
70  * @param $configuration
71  */
72  public function __construct(Session $session,
73  PersistenceFacade $persistenceFacade,
74  PermissionManager $permissionManager,
75  ActionMapper $actionMapper,
76  Localization $localization,
78  Configuration $configuration) {
79  $this->_logger = LogManager::getLogger(get_class($this));
80  $this->_session = $session;
81  $this->_persistenceFacade = $persistenceFacade;
82  $this->_permissionManager = $permissionManager;
83  $this->_actionMapper = $actionMapper;
84  $this->_localization = $localization;
85  $this->_message = $message;
86  $this->_configuration = $configuration;
87  }
88 
89  /**
90  * Initialize the Controller with request/response data. Which data is required is defined by the Controller.
91  * The base class method just stores the parameters in a member variable. Specialized Controllers may overide
92  * this behaviour for further initialization.
93  * @attention It lies in its responsibility to fail or do some default action if some data is missing.
94  * @param $request A reference to the Request sent to the Controller. The sender attribute of the Request is the
95  * last controller's name, the context is the current context and the action is the requested one.
96  * All data sent from the last controller are accessible using the Request::getValue method. The request is
97  * supposed to be read-only. It will not be used any more after beeing passed to the controller.
98  * @param $response A reference to the Response that will be modified by the Controller. The initial values for
99  * context and action are the same as in the request parameter and are meant to be modified according to the
100  * performed action. The sender attribute of the response is set to the current controller. Initially there
101  * are no data stored in the response.
102  */
103  public function initialize(Request $request, Response $response) {
104  // set sender on response
105  $response->setSender(get_class($this));
106 
107  $this->_request = $request;
108  $this->_response = $response;
109  }
110 
111  /**
112  * Check if the data given by initialize() meet the requirements of the Controller.
113  * Subclasses will override this method to validate against their special requirements.
114  * @return Boolean whether the data are ok or not.
115  */
116  protected function validate() {
117  return true;
118  }
119 
120  /**
121  * Execute the Controller resulting in its action processed. The actual
122  * processing is delegated to the given method, which must be implemented
123  * by concrete Controller subclasses.
124  * @param $method The name of the method to execute (optional, defaults to 'doExecute' if not given)
125  */
126  public function execute($method=null) {
127  $method = $method == null ? 'doExecute' : $method;
128  $isDebugEnabled = $this->_logger->isDebugEnabled();
129  if ($isDebugEnabled) {
130  $this->_logger->debug('Executing: '.get_class($this).'::'.$method);
131  $this->_logger->debug('Request: '.$this->_request);
132  }
133 
134  // validate controller data
135  $validationFailed = false;
136  if (!$this->validate()) {
137  $validationFailed = true;
138  }
139 
140  // execute controller logic
141  if (!$validationFailed) {
142  if (method_exists($this, $method)) {
143  call_user_func(array($this, $method));
144  }
145  else {
146  throw new IllegalArgumentException("The method '".$method."' is not defined in class ".get_class($this));
147  }
148  }
149 
150  // prepare the response
151  $this->assignResponseDefaults();
152  if ($isDebugEnabled) {
153  $this->_logger->debug('Response: '.$this->_response);
154  }
155 
156  // log errors
157  $errors = $this->_response->getErrors();
158  for ($i=0,$count=sizeof($errors); $i<$count; $i++) {
159  $this->_logger->error($errors[$i]->__toString());
160  }
161  }
162 
163  /**
164  * Delegate the current request to another action. The context is the same as
165  * the current context and the source controller will be set to this.
166  * The request and response format will be NullFormat
167  * which means that all request values should be passed in the application internal
168  * format and all response values will have that format.
169  * @param $action The name of the action to execute
170  * @return Response instance
171  */
172  protected function executeSubAction($action) {
173  $curRequest = $this->getRequest();
174  $subRequest = ObjectFactory::getInstance('request');
175  $subRequest->setSender(get_class($this));
176  $subRequest->setContext($curRequest->getContext());
177  $subRequest->setAction($action);
178  $subRequest->setHeaders($curRequest->getHeaders());
179  $subRequest->setValues($curRequest->getValues());
180  $subRequest->setFormat('null');
181  $subRequest->setResponseFormat('null');
182  $response = $this->_actionMapper->processAction($subRequest);
183  return $response;
184  }
185 
186  /**
187  * Get the Request instance.
188  * @return Request
189  */
190  public function getRequest() {
191  return $this->_request;
192  }
193 
194  /**
195  * Get the Response instance.
196  * @return Response
197  */
198  public function getResponse() {
199  return $this->_response;
200  }
201 
202  /**
203  * Get the Logger instance.
204  * @return Logger
205  */
206  protected function getLogger() {
207  return $this->_logger;
208  }
209 
210  /**
211  * Get the Session instance.
212  * @return Session
213  */
214  protected function getSession() {
215  return $this->_session;
216  }
217 
218  /**
219  * Get the PersistenceFacade instance.
220  * @return PersistenceFacade
221  */
222  protected function getPersistenceFacade() {
223  return $this->_persistenceFacade;
224  }
225 
226  /**
227  * Get the PermissionManager instance.
228  * @return PermissionManager
229  */
230  protected function getPermissionManager() {
231  return $this->_permissionManager;
232  }
233 
234  /**
235  * Get the ActionMapper instance.
236  * @return ActionMapper
237  */
238  protected function getActionMapper() {
239  return $this->_actionMapper;
240  }
241 
242  /**
243  * Get the Localization instance.
244  * @return Localization
245  */
246  protected function getLocalization() {
247  return $this->_localization;
248  }
249 
250  /**
251  * Get the Message instance.
252  * @return Message
253  */
254  protected function getMessage() {
255  return $this->_message;
256  }
257 
258  /**
259  * Get the Configuration instance.
260  * @return Configuration
261  */
262  protected function getConfiguration() {
263  return $this->_configuration;
264  }
265 
266  /**
267  * Assign default variables to the response. This method is called after Controller execution.
268  * This method may be used by derived controller classes for convenient response setup.
269  */
270  protected function assignResponseDefaults() {
271  // return the first error
272  $errors = $this->_response->getErrors();
273  if (sizeof($errors) > 0) {
274  $error = $errors[0];
275  $this->_response->setValue('errorCode', $error->getCode());
276  $this->_response->setValue('errorMessage', $error->getMessage());
277  $this->_response->setValue('errorData', $error->getData());
278  $this->_response->setStatus(Response::STATUS_400);
279  }
280  // set the success flag
281  if (sizeof($errors) > 0) {
282  $this->_response->setValue('success', false);
283  }
284  else {
285  $this->_response->setValue('success', true);
286  }
287 
288  // set wCMF specific values
289  $this->_response->setValue('controller', get_class($this));
290  $this->_response->setValue('context', $this->_response->getContext());
291  $this->_response->setValue('action', $this->_response->getAction());
292  }
293 
294  /**
295  * Check if the current request is localized. This is true,
296  * if it has a language parameter that is not equal to Localization::getDefaultLanguage().
297  * Throws an exception if a language is given which is not supported
298  * @return Boolean whether the request is localized or not
299  */
300  protected function isLocalizedRequest() {
301  if ($this->_request->hasValue('language')) {
302  $language = $this->_request->getValue('language');
303  if ($language != $this->_localization->getDefaultLanguage()) {
304  return true;
305  }
306  }
307  return false;
308  }
309 
310  /**
311  * Checks the language request parameter and adds an response error,
312  * if it is not contained in the Localization::getSupportedLanguages() list.
313  * @return Boolean
314  */
315  protected function checkLanguageParameter() {
316  if ($this->_request->hasValue('language')) {
317  $language = $this->_request->getValue('language');
318  if (!in_array($language, array_keys($this->_localization->getSupportedLanguages()))) {
319  $this->_response->addError(ApplicationError::get('PARAMETER_INVALID',
320  array('invalidParameters' => array('language'))));
321  return false;
322  }
323  }
324  return true;
325  }
326 }
327 ?>
Response holds the response values that are used as output from Controller instances.
Definition: Response.php:20
getRequest()
Get the Request instance.
Definition: Controller.php:190
Localization defines the interface for storing localized entity instances and retrieving them back...
getMessage()
Get the Message instance.
Definition: Controller.php:254
Controller is the base class of all controllers.
Definition: Controller.php:48
assignResponseDefaults()
Assign default variables to the response.
Definition: Controller.php:270
IllegalArgumentException signals an exception in method arguments.
setSender($sender)
Set the name of the sending Controller.
Presentation related interfaces and classes.
Definition: namespaces.php:59
getPermissionManager()
Get the PermissionManager instance.
Definition: Controller.php:230
isLocalizedRequest()
Check if the current request is localized.
Definition: Controller.php:300
static getLogger($name)
Get the logger with the given name.
Definition: LogManager.php:35
getLocalization()
Get the Localization instance.
Definition: Controller.php:246
static getInstance($name, $dynamicConfiguration=array())
Message is used to get localized messages to be used in the user interface.
Definition: Message.php:23
checkLanguageParameter()
Checks the language request parameter and adds an response error, if it is not contained in the Local...
Definition: Controller.php:315
Session is the interface for session implementations and defines access to session variables...
Definition: Session.php:21
getConfiguration()
Get the Configuration instance.
Definition: Controller.php:262
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:20
validate()
Check if the data given by initialize() meet the requirements of the Controller.
Definition: Controller.php:116
$message
Predefined errors.
executeSubAction($action)
Delegate the current request to another action.
Definition: Controller.php:172
PermissionManager implementations are used to handle all authorization requests.
Implementations of Configuration give access to the application configuration.
ActionMapper implementations are responsible for instantiating and executing Controllers based on the...
static get($code, $data=null)
Factory method for retrieving a predefind error instance.
execute($method=null)
Execute the Controller resulting in its action processed.
Definition: Controller.php:126
__construct(Session $session, PersistenceFacade $persistenceFacade, PermissionManager $permissionManager, ActionMapper $actionMapper, Localization $localization, Message $message, Configuration $configuration)
Constructor.
Definition: Controller.php:72
initialize(Request $request, Response $response)
Initialize the Controller with request/response data.
Definition: Controller.php:103
PersistenceFacade defines the interface for PersistenceFacade implementations.
getLogger()
Get the Logger instance.
Definition: Controller.php:206
getActionMapper()
Get the ActionMapper instance.
Definition: Controller.php:238
getResponse()
Get the Response instance.
Definition: Controller.php:198
getSession()
Get the Session instance.
Definition: Controller.php:214
getPersistenceFacade()
Get the PersistenceFacade instance.
Definition: Controller.php:222