[TASK] Replace inject methods with @inject
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Web / RequestBuilder.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Web;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Extbase Team (http://forge.typo3.org/projects/typo3v4-mvc)
8 * Extbase is a backport of TYPO3 Flow. All credits go to the TYPO3 Flow team.
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script 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 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30 /**
31 * Builds a web request.
32 */
33 class RequestBuilder implements \TYPO3\CMS\Core\SingletonInterface {
34
35 /**
36 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
37 * @inject
38 */
39 protected $objectManager;
40
41 /**
42 * This is the vendor name of the extension
43 *
44 * @var string
45 */
46 protected $vendorName;
47
48 /**
49 * This is a unique key for a plugin (not the extension key!)
50 *
51 * @var string
52 */
53 protected $pluginName = 'plugin';
54
55 /**
56 * The name of the extension (in UpperCamelCase)
57 *
58 * @var string
59 */
60 protected $extensionName;
61
62 /**
63 * The default controller name
64 *
65 * @var string
66 */
67 protected $defaultControllerName;
68
69 /**
70 * The default format of the response object
71 *
72 * @var string
73 */
74 protected $defaultFormat = 'html';
75
76 /**
77 * The allowed actions of the controller. This actions can be called via $_GET and $_POST.
78 *
79 * @var array
80 */
81 protected $allowedControllerActions = array();
82
83 /**
84 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
85 * @inject
86 */
87 protected $configurationManager;
88
89 /**
90 * @var \TYPO3\CMS\Extbase\Service\ExtensionService
91 * @inject
92 */
93 protected $extensionService;
94
95 /**
96 * @var \TYPO3\CMS\Extbase\Service\EnvironmentService
97 * @inject
98 */
99 protected $environmentService;
100
101 /**
102 * @throws \TYPO3\CMS\Extbase\Mvc\Exception
103 * @return void
104 */
105 protected function loadDefaultValues() {
106 $configuration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
107 if (empty($configuration['extensionName'])) {
108 throw new \TYPO3\CMS\Extbase\Mvc\Exception('"extensionName" is not properly configured. Request can\'t be dispatched!', 1289843275);
109 }
110 if (empty($configuration['pluginName'])) {
111 throw new \TYPO3\CMS\Extbase\Mvc\Exception('"pluginName" is not properly configured. Request can\'t be dispatched!', 1289843277);
112 }
113 if (!empty($configuration['vendorName'])) {
114 $this->vendorName = $configuration['vendorName'];
115 } else {
116 $this->vendorName = NULL;
117 }
118 $this->extensionName = $configuration['extensionName'];
119 $this->pluginName = $configuration['pluginName'];
120 $this->defaultControllerName = current(array_keys($configuration['controllerConfiguration']));
121 $this->allowedControllerActions = array();
122 foreach ($configuration['controllerConfiguration'] as $controllerName => $controllerActions) {
123 $this->allowedControllerActions[$controllerName] = $controllerActions['actions'];
124 }
125 if (!empty($configuration['format'])) {
126 $this->defaultFormat = $configuration['format'];
127 }
128 }
129
130 /**
131 * Builds a web request object from the raw HTTP information and the configuration
132 *
133 * @return \TYPO3\CMS\Extbase\Mvc\Web\Request The web request as an object
134 */
135 public function build() {
136 $this->loadDefaultValues();
137 $pluginNamespace = $this->extensionService->getPluginNamespace($this->extensionName, $this->pluginName);
138 $parameters = \TYPO3\CMS\Core\Utility\GeneralUtility::_GPmerged($pluginNamespace);
139 $files = $this->untangleFilesArray($_FILES);
140 if (isset($files[$pluginNamespace]) && is_array($files[$pluginNamespace])) {
141 $parameters = \TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule($parameters, $files[$pluginNamespace]);
142 }
143 $controllerName = $this->resolveControllerName($parameters);
144 $actionName = $this->resolveActionName($controllerName, $parameters);
145 /** @var $request \TYPO3\CMS\Extbase\Mvc\Web\Request */
146 $request = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request');
147 if ($this->vendorName !== NULL) {
148 $request->setControllerVendorName($this->vendorName);
149 }
150 $request->setPluginName($this->pluginName);
151 $request->setControllerExtensionName($this->extensionName);
152 $request->setControllerName($controllerName);
153 $request->setControllerActionName($actionName);
154 $request->setRequestUri(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'));
155 $request->setBaseUri(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL'));
156 $request->setMethod($this->environmentService->getServerRequestMethod());
157 if (is_string($parameters['format']) && strlen($parameters['format'])) {
158 $request->setFormat(filter_var($parameters['format'], FILTER_SANITIZE_STRING));
159 } else {
160 $request->setFormat($this->defaultFormat);
161 }
162 foreach ($parameters as $argumentName => $argumentValue) {
163 $request->setArgument($argumentName, $argumentValue);
164 }
165 return $request;
166 }
167
168 /**
169 * Returns the current ControllerName extracted from given $parameters.
170 * If no controller is specified, the defaultControllerName will be returned.
171 * If that's not available, an exception is thrown.
172 *
173 * @param array $parameters
174 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
175 * @throws \TYPO3\CMS\Extbase\Mvc\Exception if the controller could not be resolved
176 * @throws \TYPO3\CMS\Core\Error\Http\PageNotFoundException
177 * @return string
178 */
179 protected function resolveControllerName(array $parameters) {
180 if (!isset($parameters['controller']) || strlen($parameters['controller']) === 0) {
181 if (strlen($this->defaultControllerName) === 0) {
182 throw new \TYPO3\CMS\Extbase\Mvc\Exception('The default controller for extension "' . $this->extensionName . '" and plugin "' . $this->pluginName . '" can not be determined. Please check for TYPO3\\CMS\\Extbase\\Utility\\ExtensionUtility::configurePlugin() in your ext_localconf.php.', 1316104317);
183 }
184 return $this->defaultControllerName;
185 }
186 $allowedControllerNames = array_keys($this->allowedControllerActions);
187 if (!in_array($parameters['controller'], $allowedControllerNames)) {
188 $configuration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
189 if (isset($configuration['mvc']['throwPageNotFoundExceptionIfActionCantBeResolved']) && (boolean) $configuration['mvc']['throwPageNotFoundExceptionIfActionCantBeResolved']) {
190 throw new \TYPO3\CMS\Core\Error\Http\PageNotFoundException('The requested resource was not found', 1313857897);
191 } elseif (isset($configuration['mvc']['callDefaultActionIfActionCantBeResolved']) && (boolean) $configuration['mvc']['callDefaultActionIfActionCantBeResolved']) {
192 return $this->defaultControllerName;
193 }
194 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller "' . $parameters['controller'] . '" is not allowed by this plugin. Please check for TYPO3\\CMS\\Extbase\\Utility\\ExtensionUtility::configurePlugin() in your ext_localconf.php.', 1313855173);
195 }
196 return filter_var($parameters['controller'], FILTER_SANITIZE_STRING);
197 }
198
199 /**
200 * Returns the current actionName extracted from given $parameters.
201 * If no action is specified, the defaultActionName will be returned.
202 * If that's not available or the specified action is not defined in the current plugin, an exception is thrown.
203 *
204 * @param string $controllerName
205 * @param array $parameters
206 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException
207 * @throws \TYPO3\CMS\Extbase\Mvc\Exception
208 * @throws \TYPO3\CMS\Core\Error\Http\PageNotFoundException
209 * @return string
210 */
211 protected function resolveActionName($controllerName, array $parameters) {
212 $defaultActionName = is_array($this->allowedControllerActions[$controllerName]) ? current($this->allowedControllerActions[$controllerName]) : '';
213 if (!isset($parameters['action']) || strlen($parameters['action']) === 0) {
214 if (strlen($defaultActionName) === 0) {
215 throw new \TYPO3\CMS\Extbase\Mvc\Exception('The default action can not be determined for controller "' . $controllerName . '". Please check TYPO3\\CMS\\Extbase\\Utility\\ExtensionUtility::configurePlugin() in your ext_localconf.php.', 1295479651);
216 }
217 return $defaultActionName;
218 }
219 $actionName = $parameters['action'];
220 $allowedActionNames = $this->allowedControllerActions[$controllerName];
221 if (!in_array($actionName, $allowedActionNames)) {
222 $configuration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
223 if (isset($configuration['mvc']['throwPageNotFoundExceptionIfActionCantBeResolved']) && (boolean) $configuration['mvc']['throwPageNotFoundExceptionIfActionCantBeResolved']) {
224 throw new \TYPO3\CMS\Core\Error\Http\PageNotFoundException('The requested resource was not found', 1313857897);
225 } elseif (isset($configuration['mvc']['callDefaultActionIfActionCantBeResolved']) && (boolean) $configuration['mvc']['callDefaultActionIfActionCantBeResolved']) {
226 return $defaultActionName;
227 }
228 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException('The action "' . $actionName . '" (controller "' . $controllerName . '") is not allowed by this plugin. Please check TYPO3\\CMS\\Extbase\\Utility\\ExtensionUtility::configurePlugin() in your ext_localconf.php.', 1313855175);
229 }
230 return filter_var($actionName, FILTER_SANITIZE_STRING);
231 }
232
233 /**
234 * Transforms the convoluted _FILES superglobal into a manageable form.
235 *
236 * @param array $convolutedFiles The _FILES superglobal
237 * @return array Untangled files
238 * @see TYPO3\FLOW3\Utility\Environment
239 */
240 protected function untangleFilesArray(array $convolutedFiles) {
241 $untangledFiles = array();
242 $fieldPaths = array();
243 foreach ($convolutedFiles as $firstLevelFieldName => $fieldInformation) {
244 if (!is_array($fieldInformation['error'])) {
245 $fieldPaths[] = array($firstLevelFieldName);
246 } else {
247 $newFieldPaths = $this->calculateFieldPaths($fieldInformation['error'], $firstLevelFieldName);
248 array_walk($newFieldPaths, function (&$value, $key) {
249 $value = explode('/', $value);
250 });
251 $fieldPaths = array_merge($fieldPaths, $newFieldPaths);
252 }
253 }
254 foreach ($fieldPaths as $fieldPath) {
255 if (count($fieldPath) === 1) {
256 $fileInformation = $convolutedFiles[$fieldPath[0]];
257 } else {
258 $fileInformation = array();
259 foreach ($convolutedFiles[$fieldPath[0]] as $key => $subStructure) {
260 $fileInformation[$key] = \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($subStructure, array_slice($fieldPath, 1));
261 }
262 }
263 $untangledFiles = \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($untangledFiles, $fieldPath, $fileInformation);
264 }
265 return $untangledFiles;
266 }
267
268 /**
269 * Returns an array of all possibles "field paths" for the given array.
270 *
271 * @param array $structure The array to walk through
272 * @param string $firstLevelFieldName
273 * @return array An array of paths (as strings) in the format "key1/key2/key3" ...
274 */
275 protected function calculateFieldPaths(array $structure, $firstLevelFieldName = NULL) {
276 $fieldPaths = array();
277 if (is_array($structure)) {
278 foreach ($structure as $key => $subStructure) {
279 $fieldPath = ($firstLevelFieldName !== NULL ? $firstLevelFieldName . '/' : '') . $key;
280 if (is_array($subStructure)) {
281 foreach ($this->calculateFieldPaths($subStructure) as $subFieldPath) {
282 $fieldPaths[] = $fieldPath . '/' . $subFieldPath;
283 }
284 } else {
285 $fieldPaths[] = $fieldPath;
286 }
287 }
288 }
289 return $fieldPaths;
290 }
291 }
292
293 ?>