[+FEATURE] Extbase (MVC): made layoutRootPath and partialRootPath configurable. Now...
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / MVC / Web / Routing / UriBuilder.php
1 <?php
2 /* *
3 * This script is part of the TYPO3 project - inspiring people to share! *
4 * *
5 * TYPO3 is free software; you can redistribute it and/or modify it under *
6 * the terms of the GNU General Public License version 2 as published by *
7 * the Free Software Foundation. *
8 * *
9 * This script is distributed in the hope that it will be useful, but *
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
11 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
12 * Public License for more details. *
13 * */
14
15 /**
16 * An URI Builder
17 *
18 * @package Extbase
19 * @subpackage MVC\Web\Routing
20 * @version $Id$
21 */
22 class Tx_Extbase_MVC_Web_Routing_UriBuilder {
23
24 /**
25 * An instance of tslib_cObj
26 *
27 * @var tslib_cObj
28 */
29 protected $contentObject;
30
31 /**
32 * @var Tx_Extbase_MVC_Web_Request
33 */
34 protected $request;
35
36 /**
37 * @var array
38 */
39 protected $arguments = array();
40
41 /**
42 * @var string
43 */
44 protected $section = '';
45
46 /**
47 * @var boolean
48 */
49 protected $createAbsoluteUri = FALSE;
50
51 /**
52 * @var boolean
53 */
54 protected $addQueryString = FALSE;
55
56 /**
57 * @var array
58 */
59 protected $argumentsToBeExcludedFromQueryString = array();
60
61 /**
62 * @var boolean
63 */
64 protected $linkAccessRestrictedPages = FALSE;
65
66 /**
67 * @var integer
68 */
69 protected $targetPageUid = NULL;
70
71 /**
72 * @var integer
73 */
74 protected $targetPageType = 0;
75
76 /**
77 * @var boolean
78 */
79 protected $noCache = FALSE;
80
81 /**
82 * @var boolean
83 */
84 protected $useCacheHash = TRUE;
85
86 /**
87 * @var string
88 */
89 protected $format = '';
90
91 /**
92 * Constructs this URI Helper
93 *
94 * @param tslib_cObj $contentObject
95 */
96 public function __construct(tslib_cObj $contentObject = NULL) {
97 $this->contentObject = $contentObject !== NULL ? $contentObject : t3lib_div::makeInstance('tslib_cObj');
98 }
99
100 /**
101 * Sets the current request
102 *
103 * @param Tx_Extbase_MVC_Web_Request $request
104 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
105 */
106 public function setRequest(Tx_Extbase_MVC_Web_Request $request) {
107 $this->request = $request;
108 return $this;
109 }
110
111 /**
112 * @return Tx_Extbase_MVC_Web_Request
113 */
114 public function getRequest() {
115 return $this->request;
116 }
117
118 /**
119 * Additional query parameters.
120 * If you want to "prefix" arguments, you can pass in multidimensional arrays:
121 * array('prefix1' => array('foo' => 'bar')) gets "&prefix1[foo]=bar"
122 *
123 * @param array $arguments
124 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
125 * @api
126 */
127 public function setArguments(array $arguments) {
128 $this->arguments = $arguments;
129 return $this;
130 }
131
132 /**
133 * @return array
134 * @api
135 */
136 public function getArguments() {
137 return $this->arguments;
138 }
139
140 /**
141 * If specified, adds a given HTML anchor to the URI (#...)
142 *
143 * @param string $section
144 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
145 * @api
146 */
147 public function setSection($section) {
148 $this->section = $section;
149 return $this;
150 }
151
152 /**
153 * @return string
154 * @api
155 */
156 public function getSection() {
157 return $this->section;
158 }
159
160 /**
161 * Specifies the format of the target (e.g. "html" or "xml")
162 *
163 * @param string $section
164 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
165 * @api
166 */
167 public function setFormat($format) {
168 $this->format = $format;
169 return $this;
170 }
171
172 /**
173 * @return string
174 * @api
175 */
176 public function getFormat() {
177 return $this->format;
178 }
179
180 /**
181 * If set, the URI is prepended with the current base URI. Defaults to FALSE.
182 *
183 * @param boolean $createAbsoluteUri
184 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
185 * @api
186 */
187 public function setCreateAbsoluteUri($createAbsoluteUri) {
188 $this->createAbsoluteUri = $createAbsoluteUri;
189 return $this;
190 }
191
192 /**
193 * @return boolean
194 * @api
195 */
196 public function getCreateAbsoluteUri() {
197 return $this->createAbsoluteUri;
198 }
199
200 /**
201 * If set, the current query parameters will be merged with $this->arguments. Defaults to FALSE.
202 *
203 * @param boolean $addQueryString
204 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
205 * @api
206 * @see TSref/typolink.addQueryString
207 */
208 public function setAddQueryString($addQueryString) {
209 $this->addQueryString = (boolean)$addQueryString;
210 return $this;
211 }
212
213 /**
214 * @return boolean
215 * @api
216 */
217 public function getAddQueryString() {
218 return $this->addQueryString;
219 }
220
221 /**
222 * A list of arguments to be excluded from the query parameters
223 * Only active if addQueryString is set
224 *
225 * @param array $argumentsToBeExcludedFromQueryString
226 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
227 * @api
228 * @see TSref/typolink.addQueryString.exclude
229 * @see setAddQueryString()
230 */
231 public function setArgumentsToBeExcludedFromQueryString(array $argumentsToBeExcludedFromQueryString) {
232 $this->argumentsToBeExcludedFromQueryString = $argumentsToBeExcludedFromQueryString;
233 return $this;
234 }
235
236 /**
237 * @return array
238 * @api
239 */
240 public function getArgumentsToBeExcludedFromQueryString() {
241 return $this->argumentsToBeExcludedFromQueryString;
242 }
243
244 /**
245 * If set, URIs for pages without access permissions will be created
246 *
247 * @param boolean $linkAccessRestrictedPages
248 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
249 * @api
250 */
251 public function setLinkAccessRestrictedPages($linkAccessRestrictedPages) {
252 $this->linkAccessRestrictedPages = (boolean)$linkAccessRestrictedPages;
253 return $this;
254 }
255
256 /**
257 * @return boolean
258 * @api
259 */
260 public function getLinkAccessRestrictedPages() {
261 return $this->linkAccessRestrictedPages;
262 }
263
264 /**
265 * Uid of the target page
266 *
267 * @param integer $pageUid
268 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
269 * @api
270 */
271 public function setTargetPageUid($targetPageUid) {
272 $this->targetPageUid = $targetPageUid;
273 return $this;
274 }
275
276 /**
277 * returns $this->targetPageUid.
278 *
279 * @return integer
280 * @api
281 */
282 public function getTargetPageUid() {
283 return $this->targetPageUid;
284 }
285
286 /**
287 * Sets the page type of the target URI. Defaults to 0
288 *
289 * @param integer $pageType
290 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
291 * @api
292 */
293 public function setTargetPageType($targetPageType) {
294 $this->targetPageType = (integer)$targetPageType;
295 return $this;
296 }
297
298 /**
299 * @return integer
300 * @api
301 */
302 public function getTargetPageType() {
303 return $this->targetPageType;
304 }
305
306 /**
307 * by default FALSE; if TRUE, &no_cache=1 will be appended to the URI
308 * This overrules the useCacheHash setting
309 *
310 * @param boolean $noCache
311 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
312 * @api
313 */
314 public function setNoCache($noCache) {
315 $this->noCache = (boolean)$noCache;
316 return $this;
317 }
318
319 /**
320 * @return boolean
321 * @api
322 */
323 public function getNoCache() {
324 return $this->noCache;
325 }
326
327 /**
328 * by default TRUE; if FALSE, no cHash parameter will be appended to the URI
329 * If noCache is set, this setting will be ignored.
330 *
331 * @param boolean $useCacheHash
332 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
333 * @api
334 */
335 public function setUseCacheHash($useCacheHash) {
336 $this->useCacheHash = (boolean)$useCacheHash;
337 return $this;
338 }
339
340 /**
341 * @return boolean
342 * @api
343 */
344 public function getUseCacheHash() {
345 return $this->useCacheHash;
346 }
347
348 /**
349 * Resets all UriBuilder options to their default value
350 *
351 * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
352 * @api
353 */
354 public function reset() {
355 $this->arguments = array();
356 $this->section = '';
357 $this->format = '';
358 $this->createAbsoluteUri = FALSE;
359 $this->addQueryString = FALSE;
360 $this->argumentsToBeExcludedFromQueryString = array();
361 $this->linkAccessRestrictedPages = FALSE;
362 $this->targetPageUid = NULL;
363 $this->targetPageType = 0;
364 $this->noCache = FALSE;
365 $this->useCacheHash = TRUE;
366
367 return $this;
368 }
369
370 /**
371 * Creates an URI used for linking to an Extbase action.
372 * Works in Frondend and Backend mode of TYPO3.
373 *
374 * @param string $actionName Name of the action to be called
375 * @param array $controllerArguments Additional query parameters. Will be "namespaced" and merged with $this->arguments.
376 * @param string $controllerName Name of the target controller. If not set, current ControllerName is used.
377 * @param string $extensionName Name of the target extension, without underscores. If not set, current ExtensionName is used.
378 * @param string $pluginName Name of the target plugin. If not set, current PluginName is used.
379 * @return string the rendered URI
380 * @api
381 * @see build()
382 */
383 public function uriFor($actionName = NULL, $controllerArguments = array(), $controllerName = NULL, $extensionName = NULL, $pluginName = NULL) {
384 if ($actionName !== NULL) {
385 $controllerArguments['action'] = $actionName;
386 }
387 if ($controllerName !== NULL) {
388 $controllerArguments['controller'] = $controllerName;
389 } else {
390 $controllerArguments['controller'] = $this->request->getControllerName();
391 }
392 if ($extensionName === NULL) {
393 $extensionName = $this->request->getControllerExtensionName();
394 }
395 if ($pluginName === NULL) {
396 $pluginName = $this->request->getPluginName();
397 }
398 if ($this->format !== '') {
399 $controllerArguments['format'] = $this->format;
400 }
401 $argumentPrefix = strtolower('tx_' . $extensionName . '_' . $pluginName);
402 $prefixedControllerArguments = array($argumentPrefix => $controllerArguments);
403 $this->arguments = t3lib_div::array_merge_recursive_overrule($this->arguments, $prefixedControllerArguments);
404
405 return $this->build();
406 }
407
408 /**
409 * Builds the URI
410 * Depending on the current context this calls buildBackendUri() or buildFrontendUri()
411 *
412 * @return string The URI
413 * @api
414 * @see buildBackendUri()
415 * @see buildFrontendUri()
416 */
417 public function build() {
418 if (TYPO3_MODE === 'BE') {
419 return $this->buildBackendUri();
420 } else {
421 return $this->buildFrontendUri();
422 }
423 }
424
425 /**
426 * Builds the URI, backend flavour
427 * The resulting URI is relative and starts with "mod.php".
428 * The settings pageUid, pageType, noCache, useCacheHash & linkAccessRestrictedPages
429 * will be ignored in the backend.
430 *
431 * @return string The URI
432 */
433 public function buildBackendUri() {
434 if ($this->addQueryString === TRUE) {
435 $arguments = t3lib_div::_GET();
436 foreach($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
437 unset($arguments[$argumentToBeExcluded]);
438 }
439 } else {
440 $arguments = array(
441 'M' => t3lib_div::_GET('M'),
442 'id' => t3lib_div::_GET('id')
443 );
444 }
445 $arguments = t3lib_div::array_merge_recursive_overrule($arguments, $this->arguments);
446 $arguments = $this->convertDomainObjectsToIdentityArrays($arguments);
447 $uri = 'mod.php?' . http_build_query($arguments, NULL, '&');
448 if ($this->section !== '') {
449 $uri .= '#' . $this->section;
450 }
451 if ($this->createAbsoluteUri === TRUE) {
452 $uri = $this->request->getBaseURI() . TYPO3_mainDir . $uri;
453 }
454 return $uri;
455 }
456
457 /**
458 * Builds the URI, frontend flavour
459 *
460 * @return string The URI
461 * @see buildTypolinkConfiguration()
462 */
463 public function buildFrontendUri() {
464 $typolinkConfiguration = $this->buildTypolinkConfiguration();
465
466 $uri = $this->contentObject->typoLink_URL($typolinkConfiguration);
467 if ($this->createAbsoluteUri === TRUE) {
468 $uri = $this->request->getBaseURI() . $uri;
469 }
470 return $uri;
471 }
472
473
474 /**
475 * Builds a TypoLink configuration array from the current settings
476 *
477 * @return array typolink configuration array
478 * @see TSref/typolink
479 */
480 protected function buildTypolinkConfiguration() {
481 $typolinkConfiguration = array();
482
483 $typolinkConfiguration['parameter'] = $this->targetPageUid !== NULL ? $this->targetPageUid : $GLOBALS['TSFE']->id;
484 if ($this->targetPageType !== 0) {
485 $typolinkConfiguration['parameter'] .= ',' . $this->targetPageType;
486 }
487
488 if (count($this->arguments) > 0) {
489 $arguments = $this->convertDomainObjectsToIdentityArrays($this->arguments);
490 $typolinkConfiguration['additionalParams'] = '&' . http_build_query($arguments, NULL, '&');
491 }
492
493 if ($this->addQueryString === TRUE) {
494 $typolinkConfiguration['addQueryString'] = 1;
495 if (count($this->argumentsToBeExcludedFromQueryString) > 0) {
496 $typolinkConfiguration['addQueryString.'] = array(
497 'exclude' => implode(',', $this->argumentsToBeExcludedFromQueryString)
498 );
499 }
500 }
501
502 if ($this->noCache === TRUE) {
503 $typolinkConfiguration['no_cache'] = 1;
504 } elseif ($this->useCacheHash) {
505 $typolinkConfiguration['useCacheHash'] = 1;
506 }
507
508 if ($this->section !== '') {
509 $typolinkConfiguration['section'] = $this->section;
510 }
511
512 if ($this->linkAccessRestrictedPages === TRUE) {
513 $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
514 }
515
516 return $typolinkConfiguration;
517 }
518
519 /**
520 * Recursively iterates through the specified arguments and turns instances of type Tx_Extbase_DomainObject_AbstractEntity
521 * into an arrays containing the uid of the domain object.
522 *
523 * @param array $arguments The arguments to be iterated
524 * @return array The modified arguments array
525 */
526 protected function convertDomainObjectsToIdentityArrays(array $arguments) {
527 foreach ($arguments as $argumentKey => $argumentValue) {
528 if ($argumentValue instanceof Tx_Extbase_DomainObject_AbstractEntity) {
529 $arguments[$argumentKey] = $argumentValue->getUid();
530 } elseif (is_array($argumentValue)) {
531 $arguments[$argumentKey] = $this->convertDomainObjectsToIdentityArrays($argumentValue);
532 }
533 }
534 return $arguments;
535 }
536
537 }
538 ?>