Generates the magic setter (currently unused).

@param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class

@return string
354504
private function generateMagicSet(ClassMetadata $class)
    {
        $lazyPublicProperties = $this->getLazyLoadedPublicProperties($class);
        $hasParentSet         = $class->getReflectionClass()->hasMethod('__set');

        if (empty($lazyPublicProperties) && ! $hasParentSet) {
            return '';
        }

        $inheritDoc = $hasParentSet ? '{@inheritDoc}' : '';
        $magicSet   = <<<EOT
    /**
     * $inheritDoc
     * @param string \$name
     * @param mixed  \$value
     */
    public function __set(\$name, \$value)
    {

EOT;

        if ( ! empty($lazyPublicProperties)) {
            $magicSet .= <<<'EOT'
        if (array_key_exists($name, $this->__getLazyProperties())) {
            $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]);

            $this->$name = $value;

            return;
        }


EOT;
        }

        if ($hasParentSet) {
            $magicSet .= <<<'EOT'
        $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]);

        return parent::__set($name, $value);
EOT;
        } else {
            $magicSet .= "        \$this->\$name = \$value;";
        }

        $magicSet .= "\n    }";

        return $magicSet;
    }
123740
public function source(string $class): RecordSource
    {
        $source = $this->define($class, self::R_SOURCE_CLASS);

        if (empty($source)) {
            //Let's use default source
            $source = RecordSource::class;
        }

        $handles = $source::RECORD;
        if (empty($handles)) {
            //Force class to be handled
            $handles = $class;
        }

        return $this->getFactory()->make($source, [
            'class' => $handles,
            'orm'   => $this
        ]);
    }
234519
private static function getMethodsTpl($ref, $class)
    {
        $tpl = '';
        foreach($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
        {
            if($method->isStatic() || '__construct' === $method->name || $method->isFinal() || !static::hasAop($ref, $method))
            {
                continue;
            }
            $paramsTpls = static::getMethodParamTpls($method);
            $methodReturnType = static::getMethodReturnType($method);
            $returnsReference = $method->returnsReference() ? '&' : '';
            $tpl .= <<<TPL
    public function {$returnsReference}{$method->name}({$paramsTpls['define']}){$methodReturnType}
    {
        \$__args__ = func_get_args();
        {$paramsTpls['set_args']}
        \$__result__ = \$this->beanProxy->call(
            '{$method->name}',
            function({$paramsTpls['define']}){
                \$__args__ = func_get_args();
                {$paramsTpls['set_args']}
                return parent::{$method->name}(...\$__args__);
            },
            \$__args__
        );
        return \$__result__;
    }

TPL;
        }
        return $tpl;
    }
188122
public function generateXmlEntityClass(ClassMetadataInfo $metadata)
    {
        $placeHolders = array(
            '<namespace>',
            '<imports>',
            '<xmlEntityAnnotation>',
            '<xmlEntityClassName>',
            '<xmlEntityBody>'
        );

        $replacements = array(
            $this->generateXmlEntityNamespace($metadata),
            $this->generateXmlEntityImports($metadata),
            $this->generateXmlEntityDocBlock($metadata),
            $this->generateXmlEntityClassName($metadata),
            $this->generateXmlEntityBody($metadata)
        );

        $code = str_replace($placeHolders, $replacements, self::$classTemplate);
        return str_replace('<spaces>', $this->spaces, $code);
    }
795657
private function loadTranslatableMetadata(\ReflectionClass $class) {
        $classMetadata = new TranslatableMetadata($class->name);

        foreach ($class->getProperties() as $property) {
            if ($property->class !== $class->name) {
                continue;
            }

            $propertyMetadata = new PropertyMetadata($class->name, $property->getName());

            if ($this->reader->getPropertyAnnotation($property, 'Prezent\\Doctrine\\Translatable\\Annotation\\CurrentLocale')) {
                $classMetadata->currentLocale = $propertyMetadata;
                $classMetadata->addPropertyMetadata($propertyMetadata);
            }
            
            if ($this->reader->getPropertyAnnotation($property, 'Prezent\\Doctrine\\Translatable\\Annotation\\FallbackLocale')) {
                $classMetadata->fallbackLocale = $propertyMetadata;
                $classMetadata->addPropertyMetadata($propertyMetadata);
            }
            
            if ($annot = $this->reader->getPropertyAnnotation($property, 'Prezent\\Doctrine\\Translatable\\Annotation\\Translations')) {
                $classMetadata->targetEntity = $annot->targetEntity;
                $classMetadata->translations = $propertyMetadata;
                $classMetadata->addPropertyMetadata($propertyMetadata);
            }
        }

        return $classMetadata;
    }
1275518
private function getSlugsMetadata($entityClass)
    {
        if (!isset($this->slugsMetadata[$entityClass])) {
            $meta = $this->extendedMetadataFactory->getExtendedMetadata($entityClass);

            if (!isset($meta['slugs']) || empty($meta['slugs'])) {
                $message = sprintf(
                    'At least one property of class "%s" must be annotated with "%s" annotation in order to generate slug.',
                    $entityClass,
                    Slug::class
                );

                throw new SluggableException($message);
            }

            $this->slugsMetadata[$entityClass] = $meta['slugs'];
        }

        return $this->slugsMetadata[$entityClass];
    }
77499
private function generateMethods(ClassMetadata $class)
    {
        $methods           = '';
        $methodNames       = [];
        $reflectionMethods = $class->getReflectionClass()->getMethods(\ReflectionMethod::IS_PUBLIC);
        $skippedMethods    = [
            '__sleep'   => true,
            '__clone'   => true,
            '__wakeup'  => true,
            '__get'     => true,
            '__set'     => true,
            '__isset'   => true,
        ];

        foreach ($reflectionMethods as $method) {
            $name = $method->getName();

            if ($method->isConstructor() ||
                isset($skippedMethods[strtolower($name)]) ||
                isset($methodNames[$name]) ||
                $method->isFinal() ||
                $method->isStatic() ||
                ( ! $method->isPublic())
            ) {
                continue;
            }

            $methodNames[$name] = true;
            $methods           .= "\n    /**\n"
                . "     * {@inheritDoc}\n"
                . "     */\n"
                . '    public function ';

            if ($method->returnsReference()) {
                $methods .= '&';
            }

            $methods .= $name . '(' . $this->buildParametersString($method->getParameters()) . ')';
            $methods .= $this->getMethodReturnType($method);
            $methods .= "\n" . '    {' . "\n";

            if ($this->isShortIdentifierGetter($method, $class)) {
                $identifier = lcfirst(substr($name, 3));
                $fieldType  = $class->getTypeOfField($identifier);
                $cast       = in_array($fieldType, ['integer', 'smallint']) ? '(int) ' : '';

                $methods .= '        if ($this->__isInitialized__ === false) {' . "\n";
                $methods .= '            ';
                $methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : '';
                $methods .= $cast . ' parent::' . $method->getName() . "();\n";
                $methods .= '        }' . "\n\n";
            }

            $invokeParamsString = implode(', ', $this->getParameterNamesForInvoke($method->getParameters()));
            $callParamsString   = implode(', ', $this->getParameterNamesForParentCall($method->getParameters()));

            $methods .= "\n        \$this->__initializer__ "
                . "&& \$this->__initializer__->__invoke(\$this, " . var_export($name, true)
                . ", [" . $invokeParamsString . "]);"
                . "\n\n        "
                . ($this->shouldProxiedMethodReturn($method) ? 'return ' : '')
                . "parent::" . $name . '(' . $callParamsString . ');'
                . "\n" . '    }' . "\n";
        }

        return $methods;
    }
727209
protected function instantiator(string $class): InstantiatorInterface
    {
        if (isset($this->instantiators[$class])) {
            return $this->instantiators[$class];
        }

        //Potential optimization
        $instantiator = $this->getFactory()->make(
            $this->define($class, self::R_INSTANTIATOR),
            [
                'class'  => $class,
                'orm'    => $this,
                'schema' => $this->define($class, self::R_SCHEMA)
            ]
        );

        //Constructing instantiator and storing it in cache
        return $this->instantiators[$class] = $instantiator;
    }
400776
public function getManagerForClass($class)
    {
        // Check for namespace alias
        if (strpos($class, ':') !== false) {
            list($namespaceAlias, $simpleClassName) = explode(':', $class, 2);
            $class                                  = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
        }

        $proxyClass = new ReflectionClass($class);
        if ($proxyClass->implementsInterface(Proxy::class)) {
            $class = $proxyClass->getParentClass()->getName();
        }

        $managerNames = $this->getManagerNames();

        if (count($managerNames) === 1) {
            return $this->getManager(reset($managerNames));
        }

        foreach ($managerNames as $name) {
            $manager = $this->getManager($name);

            if (!$manager->getMetadataFactory()->isTransient($class)) {
                foreach ($manager->getMetadataFactory()->getAllMetadata() as $metadata) {
                    if ($metadata->getName() === $class) {
                        return $manager;
                    }
                }
            }
        }
    }
103106
protected function pStmt_Class(Class_ $class): string
    {
        $shouldReindex = false;

        foreach ($class->stmts as $key => $stmt) {
            if ($stmt instanceof TraitUse) {
                // remove empty ones
                if (count($stmt->traits) === 0) {
                    unset($class->stmts[$key]);
                    $shouldReindex = true;
                }
            }
        }

        if ($shouldReindex) {
            $class->stmts = array_values($class->stmts);
        }

        return parent::pStmt_Class($class);
    }
1000621
private function getName($class)
    {
        $class = preg_replace('/(.*[^\\\]+)Interface$/', '$1', $class);

        if (isset($this->entityOverride[$class])) {
            $class = $this->entityOverride[$class];
        }
        if ($this->sectionConfig->hasSection($class)) {
            return $this->sectionConfig->getSection($class)->getAlias();
        }

        return $this->objectNamer->name($class);
    }
1004612
public function loadMetadataForClass(\ReflectionClass $class)
    {
        $classMetadata = new ClassMetadata($class->name);
        $classMetadata->fileResources[] = $class->getFilename();

        foreach ($this->reader->getClassAnnotations($class) as $annotation) {
            if ($annotation instanceOf Schema) {
                $classMetadata->schema = $annotation->name;
            }
            if ($annotation instanceOf Inherit) {
                $classMetadata->inherit = $annotation->name;
            }
        }

        if (null !== $classMetadata->schema) {
            return $classMetadata;
        }

        return null;
    }
773366
public function generateEntityClass(EntityMetadata $meta)
    {
        $placeholders = array(
            '<namespace>',
            '<classAnnotations>',
            '<className>',
            '<implements>',
            '<traits>'
        );

        $replacements = array(
            $this->namespace,
            $this->generateClassAnnotations($meta->getTraits()),
            $meta->getClassName(),
            $this->generateImplements($meta->getInterfaces()),
            $this->generateTraitStatements($meta->getTraits())
        );

        $code = str_replace($placeholders, $replacements, self::$template);
        return str_replace('<spaces>', self::$spaces, $code);
    }
224804
public function loadMetadataForClass(\ReflectionClass $class)
    {
        foreach ($this->drivers as $driver) {
            if (null !== $metadata = $driver->loadMetadataForClass($class)) {
                return $metadata;
            }
        }
    }
380891
public function mapManyReference(ClassMetadata $class, $type = Type::LIST_)
    {
        $this->reference = true;
        $this->type      = $type;

        $this->mapAttribute($class);
    }
1359165
private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, $fileName)
    {
        $code           = '';
        $inverseRefOnes = [];

        foreach ($class->propertyMetadata as $attributeName => $mapping) {
            if (isset($mapping->alsoLoadAttributes)) {
                foreach ($mapping->alsoLoadAttributes as $name) {
                    $code .= sprintf(<<<EOF

        /** @AlsoLoad("$name") */
        if (!array_key_exists('%1\$s', \$data) && array_key_exists('$name', \$data)) {
            \$data['%1\$s'] = \$data['$name'];
        }

EOF
                        ,
                        $mapping->attributeName
                    );
                }
            }

            if (!isset($mapping->association)) {
                $clone = $mapping->type === 'date' || $mapping->type === 'time' || $mapping->type === 'datetime' ? 'clone' : '';
                $code  .= sprintf(<<<EOF

        /** @Attribute(type="{$mapping->type}") */
        if (isset(\$data['%1\$s'])) {
            \$mapping = \$this->class->getPropertyMetadata('%2\$s');
            \$value = \$data['%1\$s'];
            if (\$mapping->notSaved) {
                \$return = Type::convertUnmappedToPHPValue(\$value);
            } else {
                \$type = \$mapping->getType();
                \$return = \$type->convertToPHPValue(\$value);
            }
            \$mapping->setValue(\$document, $clone \$return);
            \$hydratedData['%2\$s'] = \$return;
        }

EOF
                    ,
                    $mapping->attributeName,
                    $mapping->name
                );
            } elseif ($mapping->association === PropertyMetadata::ASSOCIATION_TYPE_REFERENCE_ONE && $mapping->isOwningSide) {
                $code .= sprintf(<<<EOF

        /** @ReferenceOne */
        if (isset(\$data['%1\$s'])) {
            \$mapping = \$this->class->getPropertyMetadata('%2\$s');
            \$identifier = \$this->unitOfWork->getAssociationPersister()->loadReference(\$mapping, \$data['%1\$s']);
            \$return = \$identifier->getDocument(\$this->dm);
            \$mapping->setValue(\$document, \$return);
            \$hydratedData['%2\$s'] = \$return;
        }

EOF
                    ,
                    $mapping->attributeName,
                    $mapping->name
                );
            } elseif ($mapping->association === PropertyMetadata::ASSOCIATION_TYPE_REFERENCE_ONE && $mapping->isInverseSide) {
                if (isset($mapping->repositoryMethod) && $mapping->repositoryMethod) {
                    $code .= sprintf(<<<EOF

        /** @ReferenceOne */
        \$mapping = \$this->class->getPropertyMetadata('%2\$s');
        \$className = \$mapping->targetDocument;
        \$return = \$this->dm->getRepository(\$className)->%3\$s(\$document);
        \$mapping->setValue(\$document, \$return);
        \$hydratedData['%2\$s'] = \$return;

EOF
                        ,
                        $mapping->attributeName,
                        $mapping->name,
                        $mapping->repositoryMethod
                    );
                } else {
                    //handled last, see below
                    $inverseRefOnes[] = $mapping;
                }
            } elseif ($mapping->association === PropertyMetadata::ASSOCIATION_TYPE_REFERENCE_MANY || $mapping->association === PropertyMetadata::ASSOCIATION_TYPE_EMBED_MANY) {
                $code .= sprintf(<<<EOF

        /** @Many */
        \$mapping = \$this->class->getPropertyMetadata('%2\$s');
        \$collectionData = isset(\$data['%1\$s']) ? \$data['%1\$s'] : null;
        \$return = \$this->dm->getConfiguration()->getPersistentCollectionFactory()->create(\$this->dm, \$mapping);
        \$return->setOwner(\$document, \$mapping);
        \$return->setInitialized(false);
        \$return->setReadOnly(\$readOnly);
        if (\$collectionData) {
            \$type = \$mapping->getType();
            \$collectionData = \$type->convertToPHPValue(\$collectionData);
            \$return->setRawData(\$collectionData);
        }
        \$mapping->setValue(\$document, \$return);
        \$hydratedData['%2\$s'] = \$return;

EOF
                    ,
                    $mapping->attributeName,
                    $mapping->name
                );
            } elseif ($mapping->association === PropertyMetadata::ASSOCIATION_TYPE_EMBED_ONE) {
                $code .= sprintf(<<<EOF

        /** @EmbedOne */
        if (isset(\$data['%1\$s'])) {            
            \$mapping = \$this->class->getPropertyMetadata('%2\$s');
            \$return = \$this->unitOfWork->getAssociationPersister()->loadEmbed(\$mapping, \$data['%1\$s'], \$document, null, \$readOnly);
            \$mapping->setValue(\$document, \$return);
            \$hydratedData['%2\$s'] = \$return;
        }

EOF
                    ,
                    $mapping->attributeName,
                    $mapping->name
                );
            }
        }

        //processed last to ensure the identifier value(s) are hydrated first
        foreach ($inverseRefOnes as $mapping) {
            $code .= sprintf(<<<EOF

        /** @ReferenceOne */
        \$mapping = \$this->class->getPropertyMetadata('%2\$s');
        \$className = \$mapping->targetDocument;
        \$query = \$this->unitOfWork->getDocumentPersister(\$className)->createReferenceInverseSideQuery(\$mapping, \$document);
        \$return = \$query->execute()->current();
        \$mapping->setValue(\$document, \$return);
        \$hydratedData['%2\$s'] = \$return;

EOF
                    ,
                    $mapping->attributeName,
                    $mapping->name
                );
        }

        $namespace = $this->hydratorNamespace;
        $code      = sprintf(<<<EOF
<?php

namespace $namespace;

use Cloudtek\DynamoDM\DocumentManager;
use Cloudtek\DynamoDM\Mapping\ClassMetadata;
use Cloudtek\DynamoDM\Hydrator\HydratorInterface;
use Cloudtek\DynamoDM\UnitOfWork;
use Cloudtek\DynamoDM\Type\Type;

/**
 * THIS CLASS WAS GENERATED BY DYNAMODM. DO NOT EDIT THIS FILE.
 */
class $hydratorClassName implements HydratorInterface
{
    private \$dm;
    private \$unitOfWork;
    private \$class;

    public function __construct(DocumentManager \$dm, UnitOfWork \$uow, ClassMetadata \$class)
    {
        \$this->dm = \$dm;
        \$this->unitOfWork = \$uow;
        \$this->class = \$class;
    }

    public function hydrate(\$document, \$data, \$readOnly = false)
    {
        \$hydratedData = array();
%s
        return \$hydratedData;
    }
}
EOF
            ,
            $code
        );

        if ($fileName === false) {
            if (!class_exists($namespace . '\\' . $hydratorClassName)) {
                eval(substr($code, 5));
            }
        } else {
            $parentDirectory = dirname($fileName);

            if (!is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) {
                throw HydratorException::hydratorDirectoryNotWritable();
            }

            if (!is_writable($parentDirectory)) {
                throw HydratorException::hydratorDirectoryNotWritable();
            }

            $tmpFileName = $fileName . '.' . uniqid('', true);
            file_put_contents($tmpFileName, $code);
            rename($tmpFileName, $fileName);
        }
    }
153018
private function generateProxyShortClassName(ClassMetadata $class)
    {
        $proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace);
        $parts          = explode('\\', strrev($proxyClassName), 2);

        return strrev($parts[0]);
    }