Neos\Flow\ObjectManagement\ObjectSerializer::serializeObjectAsPropertyArray PHP Method

serializeObjectAsPropertyArray() public method

Serializes an object as property array.
public serializeObjectAsPropertyArray ( object $object, boolean $isTopLevelItem = true ) : array
$object object The object to store in the registry
$isTopLevelItem boolean Internal flag for managing the recursion
return array The property array
    public function serializeObjectAsPropertyArray($object, $isTopLevelItem = true)
    {
        if ($isTopLevelItem) {
            $this->objectReferences = new \SplObjectStorage();
        }
        $this->objectReferences->attach($object);
        $className = get_class($object);
        $propertyArray = [];
        foreach ($this->reflectionService->getClassPropertyNames($className) as $propertyName) {
            if ($this->reflectionService->isPropertyTaggedWith($className, $propertyName, 'transient')) {
                continue;
            }
            $propertyReflection = new PropertyReflection($className, $propertyName);
            $propertyValue = $propertyReflection->getValue($object);
            if (is_object($propertyValue) && $propertyValue instanceof DependencyInjection\DependencyProxy) {
                continue;
            }
            if (is_object($propertyValue) && isset($this->objectReferences[$propertyValue])) {
                $propertyArray[$propertyName][self::TYPE] = 'object';
                $propertyArray[$propertyName][self::VALUE] = \spl_object_hash($propertyValue);
                continue;
            }
            $propertyClassName = is_object($propertyValue) ? get_class($propertyValue) : '';
            if ($propertyClassName === 'SplObjectStorage') {
                $propertyArray[$propertyName][self::TYPE] = 'SplObjectStorage';
                $propertyArray[$propertyName][self::VALUE] = [];
                foreach ($propertyValue as $storedObject) {
                    $propertyArray[$propertyName][self::VALUE][] = spl_object_hash($storedObject);
                    $this->serializeObjectAsPropertyArray($storedObject, false);
                }
            } elseif (is_object($propertyValue) && $propertyValue instanceof \Doctrine\Common\Collections\Collection) {
                $propertyArray[$propertyName][self::TYPE] = 'Collection';
                $propertyArray[$propertyName][self::CLASSNAME] = get_class($propertyValue);
                foreach ($propertyValue as $storedObject) {
                    $propertyArray[$propertyName][self::VALUE][] = spl_object_hash($storedObject);
                    $this->serializeObjectAsPropertyArray($storedObject, false);
                }
            } elseif (is_object($propertyValue) && $propertyValue instanceof \ArrayObject) {
                $propertyArray[$propertyName][self::TYPE] = 'ArrayObject';
                $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue->getArrayCopy());
            } elseif (is_object($propertyValue) && $this->persistenceManager->isNewObject($propertyValue) === false && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, ORM\Entity::class))) {
                $propertyArray[$propertyName][self::TYPE] = 'persistenceObject';
                $propertyArray[$propertyName][self::VALUE] = get_class($propertyValue) . ':' . $this->persistenceManager->getIdentifierByObject($propertyValue);
            } elseif (is_object($propertyValue)) {
                $propertyObjectName = $this->objectManager->getObjectNameByClassName($propertyClassName);
                if ($this->objectManager->getScope($propertyObjectName) === Configuration::SCOPE_SINGLETON) {
                    continue;
                }
                $propertyArray[$propertyName][self::TYPE] = 'object';
                $propertyArray[$propertyName][self::VALUE] = spl_object_hash($propertyValue);
                $this->serializeObjectAsPropertyArray($propertyValue, false);
            } elseif (is_array($propertyValue)) {
                $propertyArray[$propertyName][self::TYPE] = 'array';
                $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue);
            } else {
                $propertyArray[$propertyName][self::TYPE] = 'simple';
                $propertyArray[$propertyName][self::VALUE] = $propertyValue;
            }
        }
        $this->objectsAsArray[spl_object_hash($object)] = [self::CLASSNAME => $className, self::PROPERTIES => $propertyArray];
        if ($isTopLevelItem) {
            return $this->objectsAsArray;
        }
    }

Usage Example

    /**
     * @test
     */
    public function serializeObjectAsPropertyArrayForDoctrineCollectionPropertyBuildsTheCorrectArrayStructureAndStoresEveryObjectInsideSeparately()
    {
        $propertyClassName1 = 'DummyClass' . md5(uniqid(mt_rand(), true));
        $propertyClassName2 = 'DummyClass' . md5(uniqid(mt_rand(), true));
        eval('class ' . $propertyClassName1 . ' {}');
        eval('class ' . $propertyClassName2 . ' {}');
        $propertyClass1 = new $propertyClassName1();
        $propertyClass2 = new $propertyClassName2();
        $className = 'DummyClass' . md5(uniqid(mt_rand(), true));
        eval('class ' . $className . ' {
			private $collectionProperty;

			public function __construct($object1, $object2) {
				$this->collectionProperty = new \\Doctrine\\Common\\Collections\\ArrayCollection();
				$this->collectionProperty->add($object1);
				$this->collectionProperty->add($object2);
			}

			public function getCollectionProperty() {
				return $this->collectionProperty;
			}
		}');
        $mockReflectionService = $this->getMockBuilder(ReflectionService::class)->disableOriginalConstructor()->getMock();
        $mockReflectionService->expects($this->at(0))->method('getClassPropertyNames')->with($className)->will($this->returnValue(['collectionProperty']));
        $mockReflectionService->expects($this->at(1))->method('getClassPropertyNames')->will($this->returnValue([]));
        $mockReflectionService->expects($this->at(2))->method('getClassPropertyNames')->will($this->returnValue([]));
        $mockReflectionService->expects($this->at(3))->method('getClassPropertyNames')->will($this->returnValue([]));
        $mockReflectionService->expects($this->any())->method('isPropertyTaggedWith')->with($className, 'collectionProperty', 'transient')->will($this->returnValue(false));
        $objectSerializer = new ObjectSerializer($this->getMockBuilder(SessionInterface::class)->disableOriginalConstructor()->getMock());
        $objectSerializer->injectReflectionService($mockReflectionService);
        $objectHash1 = spl_object_hash($propertyClass1);
        $objectHash2 = spl_object_hash($propertyClass2);
        $object = new $className($propertyClass1, $propertyClass2);
        $expectedArray = [$objectHash1 => [ObjectSerializer::CLASSNAME => $propertyClassName1, ObjectSerializer::PROPERTIES => []], $objectHash2 => [ObjectSerializer::CLASSNAME => $propertyClassName2, ObjectSerializer::PROPERTIES => []], spl_object_hash($object) => [ObjectSerializer::CLASSNAME => $className, ObjectSerializer::PROPERTIES => ['collectionProperty' => [ObjectSerializer::TYPE => 'Collection', ObjectSerializer::CLASSNAME => 'Doctrine\\Common\\Collections\\ArrayCollection', ObjectSerializer::VALUE => [$objectHash1, $objectHash2]]]]];
        $this->assertEquals($expectedArray, $objectSerializer->serializeObjectAsPropertyArray($object));
    }