[FEATURE] Automatically determine page type for URIs with format
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Web / Routing / UriBuilder.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Web\Routing;
3
4 /* *
5 * This script is part of the TYPO3 project - inspiring people to share! *
6 * *
7 * TYPO3 is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU General Public License version 2 as published by *
9 * the Free Software Foundation. *
10 * *
11 * This script is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
13 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
14 * Public License for more details. *
15 * */
16 /**
17 * An URI Builder
18 *
19 * @api
20 */
21 class UriBuilder {
22
23 /**
24 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
25 */
26 protected $configurationManager;
27
28 /**
29 * @var \TYPO3\CMS\Extbase\Service\ExtensionService
30 */
31 protected $extensionService;
32
33 /**
34 * An instance of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
35 *
36 * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
37 */
38 protected $contentObject;
39
40 /**
41 * @var \TYPO3\CMS\Extbase\Mvc\Web\Request
42 */
43 protected $request;
44
45 /**
46 * @var array
47 */
48 protected $arguments = array();
49
50 /**
51 * Arguments which have been used for building the last URI
52 *
53 * @var array
54 */
55 protected $lastArguments = array();
56
57 /**
58 * @var string
59 */
60 protected $section = '';
61
62 /**
63 * @var boolean
64 */
65 protected $createAbsoluteUri = FALSE;
66
67 /**
68 * @var string
69 */
70 protected $absoluteUriScheme = NULL;
71
72 /**
73 * @var boolean
74 */
75 protected $addQueryString = FALSE;
76
77 /**
78 * @var array
79 */
80 protected $argumentsToBeExcludedFromQueryString = array();
81
82 /**
83 * @var boolean
84 */
85 protected $linkAccessRestrictedPages = FALSE;
86
87 /**
88 * @var integer
89 */
90 protected $targetPageUid = NULL;
91
92 /**
93 * @var integer
94 */
95 protected $targetPageType = 0;
96
97 /**
98 * @var boolean
99 */
100 protected $noCache = FALSE;
101
102 /**
103 * @var boolean
104 */
105 protected $useCacheHash = TRUE;
106
107 /**
108 * @var string
109 */
110 protected $format = '';
111
112 /**
113 * @var string
114 */
115 protected $argumentPrefix = NULL;
116
117 /**
118 * @var \TYPO3\CMS\Extbase\Service\EnvironmentService
119 */
120 protected $environmentService;
121
122 /**
123 * @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
124 * @return void
125 */
126 public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager) {
127 $this->configurationManager = $configurationManager;
128 }
129
130 /**
131 * @param \TYPO3\CMS\Extbase\Service\ExtensionService $extensionService
132 * @return void
133 */
134 public function injectExtensionService(\TYPO3\CMS\Extbase\Service\ExtensionService $extensionService) {
135 $this->extensionService = $extensionService;
136 }
137
138 /**
139 * @param \TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService
140 * @return void
141 */
142 public function injectEnvironmentService(\TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService) {
143 $this->environmentService = $environmentService;
144 }
145
146 /**
147 * Life-cycle method that is called by the DI container as soon as this object is completely built
148 *
149 * @return void
150 */
151 public function initializeObject() {
152 $this->contentObject = $this->configurationManager->getContentObject();
153 }
154
155 /**
156 * Sets the current request
157 *
158 * @param \TYPO3\CMS\Extbase\Mvc\Request $request
159 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
160 */
161 public function setRequest(\TYPO3\CMS\Extbase\Mvc\Request $request) {
162 $this->request = $request;
163 return $this;
164 }
165
166 /**
167 * @return \TYPO3\CMS\Extbase\Mvc\Web\Request
168 */
169 public function getRequest() {
170 return $this->request;
171 }
172
173 /**
174 * Additional query parameters.
175 * If you want to "prefix" arguments, you can pass in multidimensional arrays:
176 * array('prefix1' => array('foo' => 'bar')) gets "&prefix1[foo]=bar"
177 *
178 * @param array $arguments
179 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
180 * @api
181 */
182 public function setArguments(array $arguments) {
183 $this->arguments = $arguments;
184 return $this;
185 }
186
187 /**
188 * @return array
189 * @api
190 */
191 public function getArguments() {
192 return $this->arguments;
193 }
194
195 /**
196 * If specified, adds a given HTML anchor to the URI (#...)
197 *
198 * @param string $section
199 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
200 * @api
201 */
202 public function setSection($section) {
203 $this->section = $section;
204 return $this;
205 }
206
207 /**
208 * @return string
209 * @api
210 */
211 public function getSection() {
212 return $this->section;
213 }
214
215 /**
216 * Specifies the format of the target (e.g. "html" or "xml")
217 *
218 * @param string $format
219 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
220 * @api
221 */
222 public function setFormat($format) {
223 $this->format = $format;
224 return $this;
225 }
226
227 /**
228 * @return string
229 * @api
230 */
231 public function getFormat() {
232 return $this->format;
233 }
234
235 /**
236 * If set, the URI is prepended with the current base URI. Defaults to FALSE.
237 *
238 * @param boolean $createAbsoluteUri
239 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
240 * @api
241 */
242 public function setCreateAbsoluteUri($createAbsoluteUri) {
243 $this->createAbsoluteUri = $createAbsoluteUri;
244 return $this;
245 }
246
247 /**
248 * @return boolean
249 * @api
250 */
251 public function getCreateAbsoluteUri() {
252 return $this->createAbsoluteUri;
253 }
254
255 /**
256 * @return string
257 */
258 public function getAbsoluteUriScheme() {
259 return $this->absoluteUriScheme;
260 }
261
262 /**
263 * Sets the scheme that should be used for absolute URIs in FE mode
264 *
265 * @param string $absoluteUriScheme the scheme to be used for absolute URIs
266 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
267 */
268 public function setAbsoluteUriScheme($absoluteUriScheme) {
269 $this->absoluteUriScheme = $absoluteUriScheme;
270 return $this;
271 }
272
273 /**
274 * If set, the current query parameters will be merged with $this->arguments. Defaults to FALSE.
275 *
276 * @param boolean $addQueryString
277 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
278 * @api
279 * @see TSref/typolink.addQueryString
280 */
281 public function setAddQueryString($addQueryString) {
282 $this->addQueryString = (boolean) $addQueryString;
283 return $this;
284 }
285
286 /**
287 * @return boolean
288 * @api
289 */
290 public function getAddQueryString() {
291 return $this->addQueryString;
292 }
293
294 /**
295 * A list of arguments to be excluded from the query parameters
296 * Only active if addQueryString is set
297 *
298 * @param array $argumentsToBeExcludedFromQueryString
299 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
300 * @api
301 * @see TSref/typolink.addQueryString.exclude
302 * @see setAddQueryString()
303 */
304 public function setArgumentsToBeExcludedFromQueryString(array $argumentsToBeExcludedFromQueryString) {
305 $this->argumentsToBeExcludedFromQueryString = $argumentsToBeExcludedFromQueryString;
306 return $this;
307 }
308
309 /**
310 * @return array
311 * @api
312 */
313 public function getArgumentsToBeExcludedFromQueryString() {
314 return $this->argumentsToBeExcludedFromQueryString;
315 }
316
317 /**
318 * Specifies the prefix to be used for all arguments.
319 *
320 * @param string $argumentPrefix
321 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
322 */
323 public function setArgumentPrefix($argumentPrefix) {
324 $this->argumentPrefix = (string) $argumentPrefix;
325 return $this;
326 }
327
328 /**
329 * @return string
330 */
331 public function getArgumentPrefix() {
332 return $this->argumentPrefix;
333 }
334
335 /**
336 * If set, URIs for pages without access permissions will be created
337 *
338 * @param boolean $linkAccessRestrictedPages
339 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
340 * @api
341 */
342 public function setLinkAccessRestrictedPages($linkAccessRestrictedPages) {
343 $this->linkAccessRestrictedPages = (boolean) $linkAccessRestrictedPages;
344 return $this;
345 }
346
347 /**
348 * @return boolean
349 * @api
350 */
351 public function getLinkAccessRestrictedPages() {
352 return $this->linkAccessRestrictedPages;
353 }
354
355 /**
356 * Uid of the target page
357 *
358 * @param integer $targetPageUid
359 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
360 * @api
361 */
362 public function setTargetPageUid($targetPageUid) {
363 $this->targetPageUid = $targetPageUid;
364 return $this;
365 }
366
367 /**
368 * returns $this->targetPageUid.
369 *
370 * @return integer
371 * @api
372 */
373 public function getTargetPageUid() {
374 return $this->targetPageUid;
375 }
376
377 /**
378 * Sets the page type of the target URI. Defaults to 0
379 *
380 * @param integer $targetPageType
381 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
382 * @api
383 */
384 public function setTargetPageType($targetPageType) {
385 $this->targetPageType = (integer) $targetPageType;
386 return $this;
387 }
388
389 /**
390 * @return integer
391 */
392 public function getTargetPageType() {
393 return $this->targetPageType;
394 }
395
396 /**
397 * by default FALSE; if TRUE, &no_cache=1 will be appended to the URI
398 * This overrules the useCacheHash setting
399 *
400 * @param boolean $noCache
401 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
402 * @api
403 */
404 public function setNoCache($noCache) {
405 $this->noCache = (boolean) $noCache;
406 return $this;
407 }
408
409 /**
410 * @return boolean
411 * @api
412 */
413 public function getNoCache() {
414 return $this->noCache;
415 }
416
417 /**
418 * by default TRUE; if FALSE, no cHash parameter will be appended to the URI
419 * If noCache is set, this setting will be ignored.
420 *
421 * @param boolean $useCacheHash
422 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
423 * @api
424 */
425 public function setUseCacheHash($useCacheHash) {
426 $this->useCacheHash = (boolean) $useCacheHash;
427 return $this;
428 }
429
430 /**
431 * @return boolean
432 * @api
433 */
434 public function getUseCacheHash() {
435 return $this->useCacheHash;
436 }
437
438 /**
439 * Returns the arguments being used for the last URI being built.
440 * This is only set after build() / uriFor() has been called.
441 *
442 * @return array The last arguments
443 */
444 public function getLastArguments() {
445 return $this->lastArguments;
446 }
447
448 /**
449 * Resets all UriBuilder options to their default value
450 *
451 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
452 * @api
453 */
454 public function reset() {
455 $this->arguments = array();
456 $this->section = '';
457 $this->format = '';
458 $this->createAbsoluteUri = FALSE;
459 $this->addQueryString = FALSE;
460 $this->argumentsToBeExcludedFromQueryString = array();
461 $this->linkAccessRestrictedPages = FALSE;
462 $this->targetPageUid = NULL;
463 $this->targetPageType = 0;
464 $this->noCache = FALSE;
465 $this->useCacheHash = TRUE;
466 $this->argumentPrefix = NULL;
467 return $this;
468 }
469
470 /**
471 * Creates an URI used for linking to an Extbase action.
472 * Works in Frontend and Backend mode of TYPO3.
473 *
474 * @param string $actionName Name of the action to be called
475 * @param array $controllerArguments Additional query parameters. Will be "namespaced" and merged with $this->arguments.
476 * @param string $controllerName Name of the target controller. If not set, current ControllerName is used.
477 * @param string $extensionName Name of the target extension, without underscores. If not set, current ExtensionName is used.
478 * @param string $pluginName Name of the target plugin. If not set, current PluginName is used.
479 * @return string the rendered URI
480 * @api
481 * @see build()
482 */
483 public function uriFor($actionName = NULL, $controllerArguments = array(), $controllerName = NULL, $extensionName = NULL, $pluginName = NULL) {
484 if ($actionName !== NULL) {
485 $controllerArguments['action'] = $actionName;
486 }
487 if ($controllerName !== NULL) {
488 $controllerArguments['controller'] = $controllerName;
489 } else {
490 $controllerArguments['controller'] = $this->request->getControllerName();
491 }
492 if ($extensionName === NULL) {
493 $extensionName = $this->request->getControllerExtensionName();
494 }
495 if ($pluginName === NULL && $this->environmentService->isEnvironmentInFrontendMode()) {
496 $pluginName = $this->extensionService->getPluginNameByAction($extensionName, $controllerArguments['controller'], $controllerArguments['action']);
497 }
498 if ($pluginName === NULL) {
499 $pluginName = $this->request->getPluginName();
500 }
501 if ($this->environmentService->isEnvironmentInFrontendMode() && $this->configurationManager->isFeatureEnabled('skipDefaultArguments')) {
502 $controllerArguments = $this->removeDefaultControllerAndAction($controllerArguments, $extensionName, $pluginName);
503 }
504 if ($this->targetPageUid === NULL && $this->environmentService->isEnvironmentInFrontendMode()) {
505 $this->targetPageUid = $this->extensionService->getTargetPidByPlugin($extensionName, $pluginName);
506 }
507 if ($this->format !== '') {
508 $controllerArguments['format'] = $this->format;
509 }
510 if ($this->argumentPrefix !== NULL) {
511 $prefixedControllerArguments = array($this->argumentPrefix => $controllerArguments);
512 } else {
513 $pluginNamespace = $this->extensionService->getPluginNamespace($extensionName, $pluginName);
514 $prefixedControllerArguments = array($pluginNamespace => $controllerArguments);
515 }
516 $this->arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($this->arguments, $prefixedControllerArguments);
517 return $this->build();
518 }
519
520 /**
521 * This removes controller and/or action arguments from given controllerArguments
522 * if they are equal to the default controller/action of the target plugin.
523 * Note: This is only active in FE mode and if feature "skipDefaultArguments" is enabled
524 *
525 * @see \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::isFeatureEnabled()
526 * @param array $controllerArguments the current controller arguments to be modified
527 * @param string $extensionName target extension name
528 * @param string $pluginName target plugin name
529 * @return array
530 */
531 protected function removeDefaultControllerAndAction(array $controllerArguments, $extensionName, $pluginName) {
532 $defaultControllerName = $this->extensionService->getDefaultControllerNameByPlugin($extensionName, $pluginName);
533 if (isset($controllerArguments['action'])) {
534 $defaultActionName = $this->extensionService->getDefaultActionNameByPluginAndController($extensionName, $pluginName, $controllerArguments['controller']);
535 if ($controllerArguments['action'] === $defaultActionName) {
536 unset($controllerArguments['action']);
537 }
538 }
539 if ($controllerArguments['controller'] === $defaultControllerName) {
540 unset($controllerArguments['controller']);
541 }
542 return $controllerArguments;
543 }
544
545 /**
546 * Builds the URI
547 * Depending on the current context this calls buildBackendUri() or buildFrontendUri()
548 *
549 * @return string The URI
550 * @api
551 * @see buildBackendUri()
552 * @see buildFrontendUri()
553 */
554 public function build() {
555 if ($this->environmentService->isEnvironmentInBackendMode()) {
556 return $this->buildBackendUri();
557 } else {
558 return $this->buildFrontendUri();
559 }
560 }
561
562 /**
563 * Builds the URI, backend flavour
564 * The resulting URI is relative and starts with "mod.php".
565 * The settings pageUid, pageType, noCache, useCacheHash & linkAccessRestrictedPages
566 * will be ignored in the backend.
567 *
568 * @return string The URI
569 */
570 public function buildBackendUri() {
571 if ($this->addQueryString === TRUE) {
572 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET();
573 foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
574 $argumentToBeExcluded = \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array($argumentToBeExcluded, TRUE);
575 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::arrayDiffAssocRecursive($arguments, $argumentToBeExcluded);
576 }
577 } else {
578 $arguments = array(
579 'M' => \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('M'),
580 'id' => \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('id')
581 );
582 }
583 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($arguments, $this->arguments);
584 $arguments = $this->convertDomainObjectsToIdentityArrays($arguments);
585 $this->lastArguments = $arguments;
586 $uri = 'mod.php?' . http_build_query($arguments, NULL, '&');
587 if ($this->section !== '') {
588 $uri .= '#' . $this->section;
589 }
590 if ($this->createAbsoluteUri === TRUE) {
591 $uri = $this->request->getBaseUri() . $uri;
592 }
593 return $uri;
594 }
595
596 /**
597 * Builds the URI, frontend flavour
598 *
599 * @return string The URI
600 * @see buildTypolinkConfiguration()
601 */
602 public function buildFrontendUri() {
603 $typolinkConfiguration = $this->buildTypolinkConfiguration();
604 if ($this->createAbsoluteUri === TRUE) {
605 $typolinkConfiguration['forceAbsoluteUrl'] = TRUE;
606 if ($this->absoluteUriScheme !== NULL) {
607 $typolinkConfiguration['forceAbsoluteUrl.']['scheme'] = $this->absoluteUriScheme;
608 }
609 }
610 $uri = $this->contentObject->typoLink_URL($typolinkConfiguration);
611 return $uri;
612 }
613
614 /**
615 * Builds a TypoLink configuration array from the current settings
616 *
617 * @return array typolink configuration array
618 * @see TSref/typolink
619 */
620 protected function buildTypolinkConfiguration() {
621 $typolinkConfiguration = array();
622 $typolinkConfiguration['parameter'] = $this->targetPageUid !== NULL ? $this->targetPageUid : $GLOBALS['TSFE']->id;
623 if ($this->targetPageType !== 0) {
624 $typolinkConfiguration['parameter'] .= ',' . $this->targetPageType;
625 } elseif ($this->format !== '') {
626 $targetPageType = $this->extensionService->getTargetPageTypeByFormat($this->request->getControllerExtensionKey(), $this->format);
627 $typolinkConfiguration['parameter'] .= ',' . $targetPageType;
628 }
629 if (count($this->arguments) > 0) {
630 $arguments = $this->convertDomainObjectsToIdentityArrays($this->arguments);
631 $this->lastArguments = $arguments;
632 $typolinkConfiguration['additionalParams'] = \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl(NULL, $arguments);
633 }
634 if ($this->addQueryString === TRUE) {
635 $typolinkConfiguration['addQueryString'] = 1;
636 if (count($this->argumentsToBeExcludedFromQueryString) > 0) {
637 $typolinkConfiguration['addQueryString.'] = array(
638 'exclude' => implode(',', $this->argumentsToBeExcludedFromQueryString)
639 );
640 }
641 }
642 if ($this->noCache === TRUE) {
643 $typolinkConfiguration['no_cache'] = 1;
644 } elseif ($this->useCacheHash) {
645 $typolinkConfiguration['useCacheHash'] = 1;
646 }
647 if ($this->section !== '') {
648 $typolinkConfiguration['section'] = $this->section;
649 }
650 if ($this->linkAccessRestrictedPages === TRUE) {
651 $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
652 }
653 return $typolinkConfiguration;
654 }
655
656 /**
657 * Recursively iterates through the specified arguments and turns instances of type \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
658 * into an arrays containing the uid of the domain object.
659 *
660 * @param array $arguments The arguments to be iterated
661 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentValueException
662 * @return array The modified arguments array
663 */
664 protected function convertDomainObjectsToIdentityArrays(array $arguments) {
665 foreach ($arguments as $argumentKey => $argumentValue) {
666 // if we have a LazyLoadingProxy here, make sure to get the real instance for further processing
667 if ($argumentValue instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
668 $argumentValue = $argumentValue->_loadRealInstance();
669 // also update the value in the arguments array, because the lazyLoaded object could be
670 // hidden and thus the $argumentValue would be NULL.
671 $arguments[$argumentKey] = $argumentValue;
672 }
673 if ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
674 if ($argumentValue->getUid() !== NULL) {
675 $arguments[$argumentKey] = $argumentValue->getUid();
676 } elseif ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject) {
677 $arguments[$argumentKey] = $this->convertTransientObjectToArray($argumentValue);
678 } else {
679 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentValueException('Could not serialize Domain Object ' . get_class($argumentValue) . '. It is neither an Entity with identity properties set, nor a Value Object.', 1260881688);
680 }
681 } elseif (is_array($argumentValue)) {
682 $arguments[$argumentKey] = $this->convertDomainObjectsToIdentityArrays($argumentValue);
683 }
684 }
685 return $arguments;
686 }
687
688 /**
689 * Converts a given object recursively into an array.
690 *
691 * @param \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object
692 * @return array
693 * @todo Refactore this into convertDomainObjectsToIdentityArrays()
694 */
695 public function convertTransientObjectToArray(\TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object) {
696 $result = array();
697 foreach ($object->_getProperties() as $propertyName => $propertyValue) {
698 if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
699 if ($propertyValue->getUid() !== NULL) {
700 $result[$propertyName] = $propertyValue->getUid();
701 } else {
702 $result[$propertyName] = $this->convertTransientObjectToArray($propertyValue);
703 }
704 } elseif (is_array($propertyValue)) {
705 $result[$propertyName] = $this->convertDomainObjectsToIdentityArrays($propertyValue);
706 } else {
707 $result[$propertyName] = $propertyValue;
708 }
709 }
710 return $result;
711 }
712
713 }
714
715 ?>