ExtBase:
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Controller / ActionController.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * A multi action controller
27 *
28 * @package TYPO3
29 * @subpackage extbase
30 * @version $ID:$
31 */
32 // SK: fill initializeArguments() so it parses the arguments for a given view. We need to discuss how this parsing can be
33 // SK: done effectively.
34 class Tx_ExtBase_Controller_ActionController extends Tx_ExtBase_Controller_AbstractController {
35
36 /**
37 * @var boolean If initializeView() should be called on an action invocation.
38 */
39 protected $initializeView = TRUE;
40
41 /**
42 * @var Tx_ExtBase_View_AbstractView By default a view with the same name as the current action is provided. Contains NULL if none was found.
43 */
44 protected $view = NULL;
45
46 /**
47 * By default a matching view will be resolved. If this property is set, automatic resolving is disabled and the specified object is used instead.
48 * @var string
49 */
50 // SK: rename to defaultViewObjectName. Should only be used if no custom view could be found.
51 // SK: How do we implement this with TYPO3 v4? How can we check if a class exists?
52 // SK: Changing the logic here makes it possible to write specific views for a given action, and use the default view for all other actions.
53 protected $viewObjectName = NULL;
54
55 /**
56 * Pattern after which the view object name is built
57 *
58 * @var string
59 */
60 // SK: Decision: Do we support "format"?
61 protected $viewObjectNamePattern = 'Tx_@extension_View_@controller@action';
62
63 /**
64 * Name of the action method
65 * @var string
66 */
67 protected $actionMethodName = 'indexAction';
68
69 /**
70 * Handles a request. The result output is returned by altering the given response.
71 *
72 * @param Tx_ExtBase_Request $request The request object
73 * @param Tx_ExtBase_Response $response The response, modified by this handler
74 * @return void
75 */
76 public function processRequest(Tx_ExtBase_Request $request, Tx_ExtBase_Response $response) {
77 $this->request = $request;
78 $this->request->setDispatched(TRUE);
79 $this->response = $response;
80
81 $this->actionMethodName = $this->resolveActionMethodName();
82 $this->initializeArguments();
83 $this->mapRequestArgumentsToLocalArguments();
84 if ($this->initializeView) $this->initializeView();
85 $this->initializeAction();
86 $this->callActionMethod();
87 }
88
89 /**
90 * Determines the action method and assures that the method exists.
91 *
92 * @return string The action method name
93 * @throws Tx_ExtBase_Exception_NoSuchAction if the action specified in the request object does not exist (and if there's no default action either).
94 */
95 protected function resolveActionMethodName() {
96 $actionMethodName = $this->request->getControllerActionName() . 'Action';
97 if (!method_exists($this, $actionMethodName)) throw new Tx_ExtBase_Exception_NoSuchAction('An action "' . $actionMethodName . '" does not exist in controller "' . get_class($this) . '".', 1186669086);
98 return $actionMethodName;
99 }
100
101 /**
102 * Returns TRUE if the given action (a name of an action like 'show'; without
103 * trailing 'Action') should be cached, otherwise it returns FALSE.
104 *
105 * @param string $actionName
106 * @return void
107 * @author Jochen Rau <jochen.rau@typoplanet.de>
108 */
109 public function isCachableAction($actionName) {
110 return !in_array($actionName, $this->nonCachableActions);
111 }
112
113 /**
114 * Calls the specified action method and passes the arguments.
115 * If the action returns a string, it is appended to the content in the
116 * response object.
117 *
118 * @param string $actionMethodName Name of the action method
119 * @return void
120 */
121 protected function callActionMethod() {
122 $actionResult = call_user_func_array(array($this, $this->actionMethodName), array());
123 if ($actionResult === NULL && $this->view instanceof Tx_ExtBase_View_ViewInterface) {
124 $this->response->appendContent($this->view->render());
125 } elseif (is_string($actionResult) && strlen($actionResult) > 0) {
126 $this->response->appendContent($actionResult);
127 }
128 }
129
130 /**
131 * Prepares a view for the current action and stores it in $this->view.
132 * By default, this method tries to locate a view with a name matching
133 * the current action.
134 *
135 * @return void
136 */
137 protected function initializeView() {
138 $viewObjectName = ($this->viewObjectName === NULL) ? $this->resolveViewObjectName() : $this->viewObjectName;
139 if (!class_exists($viewObjectName)) $viewObjectName = 'Tx_ExtBase_View_EmptyView';
140
141 $this->view = t3lib_div::makeInstance($viewObjectName);
142 $this->view->setRequest($this->request);
143 }
144
145 /**
146 * Determines the fully qualified view object name.
147 *
148 * @return string The fully qualified view object name
149 */
150 protected function resolveViewObjectName() {
151 $possibleViewName = $this->viewObjectNamePattern;
152 $extensionName = $this->request->getExtensionName();
153 $possibleViewName = str_replace('@extension', $extensionName, $possibleViewName);
154 $possibleViewName = str_replace('@controller', $this->request->getControllerName(), $possibleViewName);
155 $possibleViewName = str_replace('@action', ucfirst($this->request->getControllerActionName()), $possibleViewName);
156 return $possibleViewName;
157 }
158
159 /**
160 * Initializes the controller before invoking an action method.
161 *
162 * Override this method to solve tasks which all actions have in
163 * common.
164 *
165 * @return void
166 */
167 protected function initializeAction() {
168 }
169
170 /**
171 * The default action of this controller.
172 *
173 * This method should always be overridden by the concrete action
174 * controller implementation.
175 *
176 * @return void
177 */
178 protected function indexAction() {
179 return 'No index action has been implemented yet for this controller.';
180 }
181 }
182 ?>