mia3 / crossmedia_fourallportal

0 stars 4 forks source link

[BUG] TYPO3 12: AbstractMapping - Determine property type leads to exceptions #31

Open 3l73 opened 2 months ago

3l73 commented 2 months ago

The class AbstractMapping uses the TYPO3 ReflectionService to determine the correct data type.

This leads currently to the following exception:

TypeError: TYPO3\CMS\Extbase\Reflection\ReflectionService::__construct():
Argument #1 ($cache) must be of type TYPO3\CMS\Core\Cache\Frontend\FrontendInterface, Acme\RoadRunner\Domain\Model\Coyote given,
called in vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php on line 511

Expected behavior

No exception occured.

To Reproduce

  1. Create a functional test for Mappings
  2. Execute the functional test

Used versions: TYPO3: v12.4.17 Extension version: 3e00a60366b14ba701e39256bcf21487052d6815 (@dev-master)

Additional context

This exception occured during a functional test.

The stacktrace is as followed:

vendor/typo3/cms-extbase/Classes/Reflection/ReflectionService.php:53
vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php:511
vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php:389
vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php:327
packages/acme_roadrunner/Classes/Mapping/CoyoteMapping.php:58
vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php:885
vendor/crossmedia/fourallportal/Classes/Mapping/AbstractMapping.php:133

The reflection service itself uses the frontend cache and an identifier as constructor arguments. Additionally it should be instantiated via GeneralUtility::makeInstance().

See: https://github.com/mia3/crossmedia_fourallportal/blob/3e00a60366b14ba701e39256bcf21487052d6815/Classes/Mapping/AbstractMapping.php#L511

The whole method seems to need refactoring, since the methods and there result of the reflection service changed.

Relates change log entries:

3l73 commented 2 months ago

A possible, not yet fully testet solution could be following code:

    if (property_exists(get_class($object), $propertyName)) {
        $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
        $classSchema = $reflectionService->getClassSchema($object);
        $property = $classSchema->getProperty($propertyName);
        if ($property->getPrimaryType()->isCollection()) {
            $types = array_map(
                function (Type $type) {
                    return $type->getClassName();
                },
                $property->getPrimaryType()->getCollectionValueTypes()
            );
            return $property->getPrimaryType()->getClassName() . '<' .  implode('|', $types) . '>';
        }
        return $property->getPrimaryType()->getBuiltinType();
    }