Generates an AST out of a given reflection class and a target hydrator name

@param string $realClass
@param string $hydratorClass

@return \PhpParser\Node[]
772755
protected function generateAst($realClass, $hydratorClass)
    {
        $originalClass = new \ReflectionClass($realClass);
        $builder = new ClassBuilder;
        $traverser = new NodeTraverser;

        $ast = $builder->fromReflection($originalClass);

        // Remove unused methods
        $traverser->addVisitor(new MethodDisablerVisitor(function() { return false; }));

        // Implement new methods and interfaces, extend original class
        $this->addMethodVisitors($originalClass, $traverser);
        $traverser->addVisitor(new ClassExtensionVisitor($realClass, $realClass));
        $traverser->addVisitor(new ClassImplementorVisitor($realClass, ['Indigo\\Hydra\\Hydrator']));

        // Renames class
        $traverser->addVisitor(new ClassRenamerVisitor($originalClass, $hydratorClass));

        return $traverser->traverse($ast);
    }
1114517
public static function hydrateCollection(array $customClasses)
    {
        $hydrated = [];

        foreach ($customClasses as $customClass) {
            $hydrated[] = self::hydrate($customClass);
        }

        return $hydrated;
    }
1094411
public static function getClassConstants(
        string $class,
        string $prefix = null
    ): array {
        $result = [];

        try {
            $reflection = new ReflectionClass($class);

            foreach ($reflection->getConstants() as $key => $value) {
                if (null === $prefix || 0 === strpos($key, $prefix)) {
                    $result[] = $value;
                }
            }
        } catch (ReflectionException $e) {
        }

        return $result;
    }
222551
public function generate(\ReflectionClass $originalClass, PhpClass $class)
    {
        $methods = ReflectionUtils::getOverrideableMethods($originalClass, true);

        // no public, non final methods
        if (empty($methods)) {
            return;
        }

        if (null !== $this->markerInterface) {
            $class->setImplementedInterfaces(array_merge(
                $class->getImplementedInterfaces(),
                array($this->markerInterface)
            ));
        }

        $initializer = new PhpProperty();
        $initializer->setName($this->prefix.'lazyInitializer');
        $initializer->setVisibility(PhpProperty::VISIBILITY_PRIVATE);
        $class->setProperty($initializer);

        $initialized = new PhpProperty();
        $initialized->setName($this->prefix.'initialized');
        $initialized->setDefaultValue(false);
        $initialized->setVisibility(PhpProperty::VISIBILITY_PRIVATE);
        $class->setProperty($initialized);

        $initializerSetter = new PhpMethod();
        $initializerSetter->setName($this->prefix.'setLazyInitializer');
        $initializerSetter->setBody('$this->'.$this->prefix.'lazyInitializer = $initializer;');

        $parameter = new PhpParameter();
        $parameter->setName('initializer');
        $parameter->setType('\CG\Proxy\LazyInitializerInterface');
        $initializerSetter->addParameter($parameter);
        $class->setMethod($initializerSetter);

        $this->addMethods($class, $methods);

        $initializingMethod = new PhpMethod();
        $initializingMethod->setName($this->prefix.'initialize');
        $initializingMethod->setVisibility(PhpMethod::VISIBILITY_PRIVATE);
        $initializingMethod->setBody(
            $this->writer
                ->reset()
                ->writeln('if (null === $this->'.$this->prefix.'lazyInitializer) {')
                    ->indent()
                    ->writeln('throw new \RuntimeException("'.$this->prefix.'setLazyInitializer() must be called prior to any other public method on this object.");')
                    ->outdent()
                ->write("}\n\n")
                ->writeln('$this->'.$this->prefix.'lazyInitializer->initializeObject($this);')
                ->writeln('$this->'.$this->prefix.'initialized = true;')
                ->getContent()
        );
        $class->setMethod($initializingMethod);
    }
767326
public static function getClassParameters(string $class, bool $toArray = false): array
    {
        if (!\class_exists($class)) {
            throw new \InvalidArgumentException("Class not exists: {$class} (autoloading failed)");
        }

        $reflection = new \ReflectionClass($class);

        if (!$reflection->isInstantiable()) {
            throw new \InvalidArgumentException("Unable to create instance of abstract class: {$class}");
        }

        $params = $reflection->getConstructor()->getParameters();

        if ($params === []) {
            return [];
        }

        if (!$toArray) {
            return $params;
        }

        return static::reflectionParameterToArray($params);
    }
989612
public function getHydratorFor($objectClass)
    {
        if (! isset($this->hydratorInstances[$objectClass])) {

            $this->hydratorInstances[$objectClass] = $this->createHydratorFor($objectClass);
        }

        return $this->hydratorInstances[$objectClass];
    }
558366
public function generate(\ReflectionClass $class) : MockedCode
    {
        // checks class modifiers
        $mod = $class->getModifiers();
    
        if (Util::isAllBitSet($mod, \ReflectionClass::IS_FINAL)){
            throw new MockCodeGeneratorException('Final class can not be mocked!');
        }
    
        // generate mock class code
        list($code, $mocked_class, $namespace) = $this->generateClassCode($class);
        $filename = $this->generateMockClassFilename($class);
    
        $namespace_dir = str_replace('\\', '/', $namespace);
        
        $file_path = $namespace_dir . '/' . $filename;
    
        // save mock class code into cache directory
        $file = vfsStream::newFile($file_path);
        $this->vfsRoot->addChild($file);
        
        $code = implode(PHP_EOL, $code);
        $file->setContent($code);
        
        return new MockedCode($this->vfsRoot, $mocked_class, $namespace, $file);
    }
672120
public function getHydratorFor(string $className) : HydratorInterface
    {
        if (isset($this->hydrators[$className])) {
            return $this->hydrators[$className];
        }
        $hydratorClassName = str_replace('\\', '', $className) . 'Hydrator';
        $fqn               = $this->hydratorNamespace . '\\' . $hydratorClassName;
        $class             = $this->dm->getClassMetadata($className);

        if (! class_exists($fqn, false)) {
            $fileName = $this->hydratorDir . DIRECTORY_SEPARATOR . $hydratorClassName . '.php';
            switch ($this->autoGenerate) {
                case Configuration::AUTOGENERATE_NEVER:
                    require $fileName;
                    break;

                case Configuration::AUTOGENERATE_ALWAYS:
                    $this->generateHydratorClass($class, $hydratorClassName, $fileName);
                    require $fileName;
                    break;

                case Configuration::AUTOGENERATE_FILE_NOT_EXISTS:
                    if (! file_exists($fileName)) {
                        $this->generateHydratorClass($class, $hydratorClassName, $fileName);
                    }
                    require $fileName;
                    break;

                case Configuration::AUTOGENERATE_EVAL:
                    $this->generateHydratorClass($class, $hydratorClassName, null);
                    break;
            }
        }
        $this->hydrators[$className] = new $fqn($this->dm, $this->unitOfWork, $class);
        return $this->hydrators[$className];
    }
738056
private function getClass(string $resourceClass, ResourceMetadata $resourceMetadata, string $shortName, string $prefixedShortName, array $context): array
    {
        $class = [
            '@id' => $prefixedShortName,
            '@type' => 'hydra:Class',
            'rdfs:label' => $shortName,
            'hydra:title' => $shortName,
            'hydra:supportedProperty' => $this->getHydraProperties($resourceClass, $resourceMetadata, $shortName, $prefixedShortName, $context),
            'hydra:supportedOperation' => $this->getHydraOperations($resourceClass, $resourceMetadata, $prefixedShortName, false),
        ];

        if (null !== $description = $resourceMetadata->getDescription()) {
            $class['hydra:description'] = $description;
        }

        if ($resourceMetadata->getAttribute('deprecation_reason')) {
            $class['owl:deprecated'] = true;
        }

        return $class;
    }
257151
protected function hydrateItem($objectClass, array $item)
    {
        $object = $this->createObjectToHydrate($objectClass);

        if (0 == count($item)) {
            return $object;
        }

        $hydrator = $this->objectManager->getHydratorFor($objectClass);

        return $hydrator->hydrate($item, $object);
    }
1364219
protected function createHydrator(string $class) : void
    {
        $config        = new Configuration($class);
        $hydratorClass = $config->createFactory()->getHydratorClass();

        $this->hydrator = new $hydratorClass();
    }
1118946
public static function getConstants($class, string $prefix = ''): array
    {
        static $constants = [];

        if (is_object($class)) {
            $class = get_class($class);
        }

        if (!isset($constants[$class])) {
            $constants[$class][''] = (new \ReflectionClass($class))->getConstants();
        }

        if (!isset($constants[$class][$prefix])) {
            $constants[$class][$prefix] = [];

            foreach ($constants[$class][''] as $name => $value) {
                if (Strings::startsWith($name, $prefix)) {
                    $constants[$class][$prefix][$name] = $value;
                }
            }
        }

        return $constants[$class][$prefix];
    }
945291
public function getHydrator()
    {
        if (!$this->hydrator) {
            $this->hydrator = new ClassMethods(true);
            $this->hydrator->addFilter(
                'hydrator',
                new MethodMatchFilter(
                    'getHydrator',
                    true // exclude
                ),
                FilterComposite::CONDITION_AND
            );
        }
        return $this->hydrator;
    }
290957
public function raw($class, array $attributes = [], $name = 'default')
    {
        return array_merge(
            call_user_func($this->definitions[$class][$name], $this->faker), $attributes
        );
    }
51711
static function classDOMTree( $class )
    {
        if ( !$class )
        {
            $retValue = false;
            return $retValue;
        }

        $dom = new DOMDocument( '1.0', 'utf-8' );
        $classNode = $dom->createElement( 'content-class' );
        $dom->appendChild( $classNode );

        $serializedNameListNode = $dom->createElement( 'serialized-name-list' );
        $serializedNameListNode->appendChild( $dom->createTextNode( $class->attribute( 'serialized_name_list' ) ) );
        $classNode->appendChild( $serializedNameListNode );

        $identifierNode = $dom->createElement( 'identifier' );
        $identifierNode->appendChild( $dom->createTextNode( $class->attribute( 'identifier' ) ) );
        $classNode->appendChild( $identifierNode );

        $serializedDescriptionListNode = $dom->createElement( 'serialized-description-list' );
        $serializedDescriptionListNode->appendChild( $dom->createTextNode( $class->attribute( 'serialized_description_list' ) ) );
        $classNode->appendChild( $serializedDescriptionListNode );

        $remoteIDNode = $dom->createElement( 'remote-id' );
        $remoteIDNode->appendChild( $dom->createTextNode( $class->attribute( 'remote_id' ) ) );
        $classNode->appendChild( $remoteIDNode );

        $objectNamePatternNode = $dom->createElement( 'object-name-pattern' );
        $objectNamePatternNode->appendChild( $dom->createTextNode( $class->attribute( 'contentobject_name' ) ) );
        $classNode->appendChild( $objectNamePatternNode );

        $urlAliasPatternNode = $dom->createElement( 'url-alias-pattern' );
        $urlAliasPatternNode->appendChild( $dom->createTextNode( $class->attribute( 'url_alias_name' ) ) );
        $classNode->appendChild( $urlAliasPatternNode );

        $isContainer = $class->attribute( 'is_container' ) ? 'true' : 'false';
        $classNode->setAttribute( 'is-container', $isContainer );
        $classNode->setAttribute( 'always-available', $class->attribute( 'always_available' ) ? 'true' : 'false' );
        $classNode->setAttribute( 'sort-field', eZContentObjectTreeNode::sortFieldName( $class->attribute( 'sort_field' ) ) );
        $classNode->setAttribute( 'sort-order', $class->attribute( 'sort_order' ) );

        // Remote data start
        $remoteNode = $dom->createElement( 'remote' );
        $classNode->appendChild( $remoteNode );

        $ini = eZINI::instance();
        $siteName = $ini->variable( 'SiteSettings', 'SiteURL' );

        $classURL = 'http://' . $siteName . '/class/view/' . $class->attribute( 'id' );
        $siteURL = 'http://' . $siteName . '/';

        $siteUrlNode = $dom->createElement( 'site-url' );
        $siteUrlNode->appendChild( $dom->createTextNode( $siteURL ) );
        $remoteNode->appendChild( $siteUrlNode );

        $urlNode = $dom->createElement( 'url' );
        $urlNode->appendChild( $dom->createTextNode( $classURL ) );
        $remoteNode->appendChild( $urlNode );

        $classGroupsNode = $dom->createElement( 'groups' );

        $classGroupList = eZContentClassClassGroup::fetchGroupList( $class->attribute( 'id' ),
                                                                    $class->attribute( 'version' ) );
        foreach ( $classGroupList as $classGroupLink )
        {
            $classGroup = eZContentClassGroup::fetch( $classGroupLink->attribute( 'group_id' ) );
            if ( $classGroup )
            {
                unset( $groupNode );
                $groupNode = $dom->createElement( 'group' );
                $groupNode->setAttribute( 'id', $classGroup->attribute( 'id' ) );
                $groupNode->setAttribute( 'name', $classGroup->attribute( 'name' ) );
                $classGroupsNode->appendChild( $groupNode );
            }
        }
        $remoteNode->appendChild( $classGroupsNode );

        $idNode = $dom->createElement( 'id' );
        $idNode->appendChild( $dom->createTextNode( $class->attribute( 'id' ) ) );
        $remoteNode->appendChild( $idNode );
        $createdNode = $dom->createElement( 'created' );
        $createdNode->appendChild( $dom->createTextNode( $class->attribute( 'created' ) ) );
        $remoteNode->appendChild( $createdNode );
        $modifiedNode = $dom->createElement( 'modified' );
        $modifiedNode->appendChild( $dom->createTextNode( $class->attribute( 'modified' ) ) );
        $remoteNode->appendChild( $modifiedNode );

        $creatorNode = $dom->createElement( 'creator' );
        $remoteNode->appendChild( $creatorNode );
        $creatorIDNode = $dom->createElement( 'user-id' );
        $creatorIDNode->appendChild( $dom->createTextNode( $class->attribute( 'creator_id' ) ) );
        $creatorNode->appendChild( $creatorIDNode );
        $creator = $class->attribute( 'creator' );
        if ( $creator )
        {
            $creatorLoginNode = $dom->createElement( 'user-login' );
            $creatorLoginNode->appendChild( $dom->createTextNode( $creator->attribute( 'login' ) ) );
            $creatorNode->appendChild( $creatorLoginNode );
        }

        $modifierNode = $dom->createElement( 'modifier' );
        $remoteNode->appendChild( $modifierNode );
        $modifierIDNode = $dom->createElement( 'user-id' );
        $modifierIDNode->appendChild( $dom->createTextNode( $class->attribute( 'modifier_id' ) ) );
        $modifierNode->appendChild( $modifierIDNode );
        $modifier = $class->attribute( 'modifier' );
        if ( $modifier )
        {
            $modifierLoginNode = $dom->createElement( 'user-login' );
            $modifierLoginNode->appendChild( $dom->createTextNode( $modifier->attribute( 'login' ) ) );
            $modifierNode->appendChild( $modifierLoginNode );
        }
        // Remote data end

        $attributesNode = $dom->createElementNS( 'http://ezpublish/contentclassattribute', 'ezcontentclass-attribute:attributes' );
        $classNode->appendChild( $attributesNode );

        $attributes = $class->fetchAttributes();
        foreach( $attributes as $attribute )
        {
            $attributeNode = $dom->createElement( 'attribute' );
            $attributeNode->setAttribute( 'datatype', $attribute->attribute( 'data_type_string' ) );
            $required = $attribute->attribute( 'is_required' ) ? 'true' : 'false';
            $attributeNode->setAttribute( 'required' , $required );
            $searchable = $attribute->attribute( 'is_searchable' ) ? 'true' : 'false';
            $attributeNode->setAttribute( 'searchable' , $searchable );
            $informationCollector = $attribute->attribute( 'is_information_collector' ) ? 'true' : 'false';
            $attributeNode->setAttribute( 'information-collector' , $informationCollector );
            $translatable = $attribute->attribute( 'can_translate' ) ? 'true' : 'false';
            $attributeNode->setAttribute( 'translatable' , $translatable );

            $attributeRemoteNode = $dom->createElement( 'remote' );
            $attributeNode->appendChild( $attributeRemoteNode );

            $attributeIDNode = $dom->createElement( 'id' );
            $attributeIDNode->appendChild( $dom->createTextNode( $attribute->attribute( 'id' ) ) );
            $attributeRemoteNode->appendChild( $attributeIDNode );

            $attributeSerializedNameListNode = $dom->createElement( 'serialized-name-list' );
            $attributeSerializedNameListNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_name_list' ) ) );
            $attributeNode->appendChild( $attributeSerializedNameListNode );

            $attributeIdentifierNode = $dom->createElement( 'identifier' );
            $attributeIdentifierNode->appendChild( $dom->createTextNode( $attribute->attribute( 'identifier' ) ) );
            $attributeNode->appendChild( $attributeIdentifierNode );

            $attributeSerializedDescriptionListNode = $dom->createElement( 'serialized-description-list' );
            $attributeSerializedDescriptionListNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_description_list' ) ) );
            $attributeNode->appendChild( $attributeSerializedDescriptionListNode );

            $attributeCategoryNode = $dom->createElement( 'category' );
            $attributeCategoryNode->appendChild( $dom->createTextNode( $attribute->attribute( 'category' ) ) );
            $attributeNode->appendChild( $attributeCategoryNode );

            $attributeSerializedDataTextNode = $dom->createElement( 'serialized-data-text' );
            $attributeSerializedDataTextNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_data_text' ) ) );
            $attributeNode->appendChild( $attributeSerializedDataTextNode );

            $attributePlacementNode = $dom->createElement( 'placement' );
            $attributePlacementNode->appendChild( $dom->createTextNode( $attribute->attribute( 'placement' ) ) );
            $attributeNode->appendChild( $attributePlacementNode );

            $attributeParametersNode = $dom->createElement( 'datatype-parameters' );
            $attributeNode->appendChild( $attributeParametersNode );

            $dataType = $attribute->dataType();
            if ( is_object( $dataType ) )
            {
                $dataType->serializeContentClassAttribute( $attribute, $attributeNode, $attributeParametersNode );
            }

            $attributesNode->appendChild( $attributeNode );
        }
        eZDebug::writeDebug( $dom->saveXML(), 'content class package XML' );
        return $classNode;
    }
802651
public function hydrate(array $data, $objectOrClass, array $map = null)
    {
        if (\is_object($objectOrClass)) {
            $object = $objectOrClass;
            $reflection = $this->getReflection(\get_class($object));
        } else {
            $reflection = $this->getReflection($objectOrClass);
            $object = $reflection->newInstanceWithoutConstructor();
        }

        if (!\is_array($map) || !$map) {
            $map = \array_keys($data);
            $map = \array_combine($map, $map);
        }
        foreach ($map as $fieldName => $propertyName) {
            if (isset($data[$fieldName]) && $reflection->hasProperty($propertyName)) {
                $property = $this->getProperty($reflection, $propertyName);
                $property->setValue($object, $data[$fieldName]);
            }
        }

        return $object;
    }
1091463
public function parse(RefClass $class)
    {
        $result = [];

        $annotations = $this->parseComment($class->docComment);
        foreach ($annotations as $annotation) {
            $annotation->originClass = $class->name;
            $result[]                = $annotation;
        }

        foreach ($class->constants as $constant) {
            foreach ($this->parseComment($constant->docComment) as $annotation) {
                $annotation->originClass    = $class->name;
                $annotation->originConstant = $constant->name;
                $result[]                   = $annotation;
            }
        }

        foreach ($class->properties as $property) {
            foreach ($this->parseComment($property->docComment) as $annotation) {
                $annotation->originClass    = $class->name;
                $annotation->originProperty = $property->name;
                $result[]                   = $annotation;
            }
        }

        foreach ($class->methods as $method) {
            foreach ($this->parseComment($method->docComment) as $annotation) {
                $annotation->originClass  = $class->name;
                $annotation->originMethod = $method->name;
                $result[]                 = $annotation;
            }
        }

        return $result;
    }