Bug #66049

PropertyMapper fails mapping an ObjectStorage being passed to a controller action

Added by Bernhard Kraft over 6 years ago. Updated almost 5 years ago.

Status:
Rejected
Priority:
Should have
Category:
Extbase
Target version:
-
Start date:
2015-03-26
Due date:
% Done:

80%

Estimated time:
TYPO3 Version:
6.2
PHP Version:
5.5
Tags:
Complexity:
medium
Is Regression:
No
Sprint Focus:

Description

This bug only affects 6.2. In 7.x it should be solved because the old property mapper code relying on reflectionService in Mvc\Controller\Argument has been removed.

When a controller gets passed an ObjectStorage the property mapper fails to properly map the contents of the GET/POST array to the objects contained in the ObjectStorage.

Example for a controller action method:

  /**
    * action detail
    *
    * @param \Webconsulting\WebconWarndienst\Domain\Model\Warning $warning
    * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Webconsulting\WebconWarndienst\Domain\Model\Location> $location
    * @return void
    */
   public function detailAction(\Webconsulting\WebconWarndienst\Domain\Model\Warning $warning, $location = NULL) {

The $location parameter is explicitely not type-hinted as PHP type hinting does currently not support the "baseClas<elementType>" syntax. If only "ObjectStorage" would have been used as type hint the Mvc\Controller\Argument classes will only get passed the base class and not ever know about elementType. So not using a type hint but only a @param annotation is mandatory.

Now in the following situation the string "\TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Webconsulting\WebconWarndienst\Domain\Model\Location>" will get passed to "EXT:extbase/Classes/Mvc/Controller/Argument.php" constructor:
https://git.typo3.org/Packages/TYPO3.CMS.git/blob/refs/heads/TYPO3_6-2:/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php#l171

But then Argument.php will fail in method "injectReflectionService" because reflection service can't work on compound "baseClass<elementType>" class names.

So the compound class name has to get splitted up in the constructor using TypeUtility and the complete type has only get passed to the properyMapper->convert in the Argument.php "setValue" method:

https://git.typo3.org/Packages/TYPO3.CMS.git/blob/refs/heads/TYPO3_6-2:/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php#l374

A patch is provided on gerrit.

This problem has also been documented here:
http://wiki.typo3.org/Exception/CMS/1297759968#.231297759968:_Exception_while_property_mapping_at_property_path_.22yourProperty.22:It_is_not_allowed_to_map_property_.22_identity.22._You_need_to_use_.24propertyMappingConfiguration-.3EallowProperties.28.27_identity.27.29_to_enable_mapping_of_this_property.

Testing: For passing multiple arguments to a controller action using an ObjectStorage the propertyMapper configuration has to get slightly adjusted in initializeSomeAction():

   public function initializeDetailAction() {
      $locationMappingConfiguration = $this->arguments->getArgument('location')->getPropertyMappingConfiguration();
      $subConfiguration = $locationMappingConfiguration->forProperty('*');
   }
#1

Updated by Gerrit Code Review over 6 years ago

  • Status changed from New to Under Review

Patch set 1 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/38243

#2

Updated by Gerrit Code Review over 6 years ago

Patch set 1 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/38245

#3

Updated by Bernhard Kraft over 6 years ago

Another solution would be to use the reflection service only when the rewrittenPropertyMapper is not enabled. When the rewritten property mapper is enabled the data type class schema is not required in Argument.php. As the error only occurs when the class schema is retrieved from the reflection service it would be sufficient to only make those calls when necessary.

Sadly one of the calls to "getClassSchema" is from within a dependency injection method (injectReflectionService) and there the configurationManager is not already injected. So the call got getClassSchema would have to get moved to "initializeObject" (extbase initialization method / "poor mans constructor").

Both alternative solutions are provided on gerrit:
https://review.typo3.org/#/c/38245/
https://review.typo3.org/#/c/38243/

#4

Updated by Markus Sommer about 6 years ago

  • Assignee set to Bernhard Kraft
#5

Updated by Anja Leichsenring almost 5 years ago

  • Status changed from Under Review to Rejected

Also available in: Atom PDF