Generates and writes entity class to disk for the given ClassMetadataInfo instance.

@param ClassMetadataInfo $metadata
@param string            $outputDirectory

@return void

@throws \RuntimeException
431757
public function writeEntityClass(ClassMetadataInfo $metadata, $outputDirectory)
    {
        $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->extension;
        $dir = dirname($path);

        if ( ! is_dir($dir)) {
            mkdir($dir, 0775, true);
        }

        $this->isNew = !file_exists($path) || (file_exists($path) && $this->regenerateEntityIfExists);

        if ( ! $this->isNew) {
            $this->parseTokensInEntityFile(file_get_contents($path));
        } else {
            $this->staticReflection[$metadata->name] = array('properties' => array(), 'methods' => array());
        }

        if ($this->backupExisting && file_exists($path)) {
            $backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . "~";
            if (!copy($path, $backupPath)) {
                throw new \RuntimeException("Attempt to backup overwritten entity file but copy operation failed.");
            }
        }

        // If entity doesn't exist or we're re-generating the entities entirely
        if ($this->isNew) {
            file_put_contents($path, $this->generateEntityClass($metadata));
        // If entity exists and we're allowed to update the entity class
        } elseif ( ! $this->isNew && $this->updateEntityIfExists) {
            file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path));
        }
        chmod($path, 0664);
    }
214027
public function generate($namespace, $basePath, ClassMetadata $metadata)
    {
        $out = array();
        $out[] = $this->generateManagers($namespace, $basePath, $metadata);
        $out[] = $this->generateAdmins($namespace, $basePath, $metadata);

        $out = array_merge(
            $out,
            $this->updateExtension($namespace, $basePath)
        );

        return $out;
    }
441153
private function mapTranslation(ClassMetadata $metadata): void
    {
        $className = $metadata->name;

        try {
            $resourceMetadata = $this->resourceMetadataRegistry->getByClass($className);
        } catch (\InvalidArgumentException $exception) {
            return;
        }

        /** @var MetadataInterface $translatableResourceMetadata */
        $translatableResourceMetadata = $this->resourceMetadataRegistry->get(str_replace('_translation', '', $resourceMetadata->getAlias()));

        if (!$metadata->hasAssociation('translatable')) {
            $metadata->mapManyToOne([
                'fieldName' => 'translatable',
                'targetEntity' => $translatableResourceMetadata->getClass('model'),
                'inversedBy' => 'translations',
                'joinColumns' => [[
                    'name' => 'translatable_id',
                    'referencedColumnName' => 'id',
                    'onDelete' => 'CASCADE',
                    'nullable' => false,
                ]],
            ]);
        }

        if (!$metadata->hasField('locale')) {
            $metadata->mapField([
                'fieldName' => 'locale',
                'type' => 'string',
                'nullable' => false,
            ]);
        }

        // Map unique index.
        $columns = [
            $metadata->getSingleAssociationJoinColumnName('translatable'),
            'locale',
        ];

        if (!$this->hasUniqueConstraint($metadata, $columns)) {
            $constraints = $metadata->table['uniqueConstraints'] ?? [];

            $constraints[$metadata->getTableName() . '_uniq_trans'] = [
                'columns' => $columns,
            ];

            $metadata->setPrimaryTable([
                'uniqueConstraints' => $constraints,
            ]);
        }
    }
533074
public function process(MetadataInterface $metadata, $subject): void
    {
        $metadata->identifier = true;

        if ('auto' === $subject->strategy) {
            $metadata->documentMetadata->idGeneratorType = DocumentMetadata::GENERATOR_TYPE_AUTO;
        } else {
            $metadata->documentMetadata->idGeneratorType = DocumentMetadata::GENERATOR_TYPE_NONE;
        }
    }
865048
private function dispatchMetadataEvent($eventName, EntityMetadata $metadata)
    {
        $metadataArgs = new Events\MetadataArguments($metadata);
        $this->dispatcher->dispatch($eventName, $metadataArgs);
    }
767553
protected function _generateOutputPath(ClassMetadataInfo $metadata)
    {
        return $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension;
    }
458871
private function buildIndexes(ClassMetadataInfo $metadata)
    {
        $tableName = $metadata->table['name'];
        $indexes   = $this->tables[$tableName]->getIndexes();

        foreach($indexes as $index){
            if ($index->isPrimary()) {
                continue;
            }

            $indexName      = $index->getName();
            $indexColumns   = $index->getColumns();
            $constraintType = $index->isUnique()
                ? 'uniqueConstraints'
                : 'indexes';

            $metadata->table[$constraintType][$indexName]['columns'] = $indexColumns;
        }
    }
405647
public function generateUpdatedXmlEntityClass(ClassMetadataInfo $metadata, $path)
    {
        $currentCode = file_get_contents($path);

        $body = $this->generateXmlEntityBody($metadata);
        $body = str_replace('<spaces>', $this->spaces, $body);
        $last = strrpos($currentCode, '}');

        return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : ''). "}";
    }
1003073
private function buildFieldMappings(ClassMetadataInfo $metadata)
    {
        $tableName      = $metadata->table['name'];
        $columns        = $this->tables[$tableName]->getColumns();
        $primaryKeys    = $this->getTablePrimaryKeys($this->tables[$tableName]);
        $foreignKeys    = $this->getTableForeignKeys($this->tables[$tableName]);
        $allForeignKeys = array();

        foreach ($foreignKeys as $foreignKey) {
            $allForeignKeys = array_merge($allForeignKeys, $foreignKey->getLocalColumns());
        }

        $ids           = array();
        $fieldMappings = array();

        foreach ($columns as $column) {
            if (in_array($column->getName(), $allForeignKeys)) {
                continue;
            }

            $fieldMapping = $this->buildFieldMapping($tableName, $column);

            if ($primaryKeys && in_array($column->getName(), $primaryKeys)) {
                $fieldMapping['id'] = true;
                $ids[] = $fieldMapping;
            }

            $fieldMappings[] = $fieldMapping;
        }

        // We need to check for the columns here, because we might have associations as id as well.
        if ($ids && count($primaryKeys) == 1) {
            $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
        }

        foreach ($fieldMappings as $fieldMapping) {
            $metadata->mapField($fieldMapping);
        }
    }
1326270
public function loadMetadataForClass($className, ClassMetadata $metadata)
    {
        $class = $metadata->getReflectionClass();

        if (!$class) {
            $class = new \ReflectionClass((string) $className);
        }

        $classAnnotations = $this->reader->getClassAnnotations($class);
        
        $classMapping = array();
        $validMapping = false;
        foreach ($classAnnotations as $annotation) {
            switch(get_class($annotation)) {
                case 'Doctrine\Search\Mapping\Annotations\ElasticSearchable':
                    $classMapping = (array) $annotation;
                    $classMapping['class'] = 'ElasticSearchable';
                    $validMapping = true;
                    break;
                case 'Doctrine\Search\Mapping\Annotations\Searchable':
                    $classMapping = (array) $annotation;
                    $classMapping['class'] = 'Searchable';
                    $validMapping = true;
                    break;
                case 'Doctrine\Search\Mapping\Annotations\ElasticRoot':
                    $rootMapping = (array) $annotation;
                    $metadata->mapRoot($this->rootToArray($rootMapping));
                    break;
            }
        }
        
        if (!$validMapping) {
            throw MappingException::classIsNotAValidDocument($className);
        }
        
        $this->annotateClassMetadata($classMapping, $metadata);

        $properties = $class->getProperties();
        foreach ($properties as $property) {
            $propertyAnnotations = $this->reader->getPropertyAnnotations($property);
            foreach ($propertyAnnotations as $annotation) {
                switch (get_class($annotation)) {
                    case 'Doctrine\Search\Mapping\Annotations\Id':
                        $metadata->identifier = $property->getName();
                        break;
                    case 'Doctrine\Search\Mapping\Annotations\Parameter':
                        $mapping = $this->parameterToArray($property->getName(), (array) $annotation);
                        $metadata->mapParameter($mapping);
                        break;
                    case 'Doctrine\Search\Mapping\Annotations\Field':
                    case 'Doctrine\Search\Mapping\Annotations\ElasticField':
                    case 'Doctrine\Search\Mapping\Annotations\SolrField':
                        $mapping = $this->fieldToArray($property->getName(), (array) $annotation);
                        $metadata->mapField($mapping);
                        break;
                }
            }
        }
    }
502124
public function processClassMetadata(ClassMetadata $metadata, $property, $prefix)
    {
        if (in_array($metadata->getName(), $this->processedClasses)) {
            return;
        }

        $metadata->mapEmbedded([
            'fieldName'    => $property,
            'class'        => $this->embeddableMetadata->getName(),
            'columnPrefix' => empty($prefix) ? false : $prefix,
        ]);

        $metadata->inlineEmbeddable($property, $this->embeddableMetadata);

        $this->processedClasses[] = $metadata->getName();
    }
1265030
public function injectEntityManager(EntityManagerInterface $entityManager, ClassMetadata $classMetadata) : void
    {
        if ($entityManager !== self::$entityManager) {
            throw new RuntimeException(
                'Trying to use PersistentObject with different EntityManager instances. ' .
                'Was PersistentObject::setEntityManager() called?'
            );
        }

        $this->cm = $classMetadata;
    }
75372
private function serialize(EntityMetadata $metadata)
    {
        switch ($this->serializer) {
            case self::SERIALIZER_PHP:
                return serialize($metadata);
            case self::SERIALIZER_IGBINARY:
                return igbinary_serialize($metadata);
            default:
                throw new RuntimeException('Unable to handle serialization of the metadata object');
        }
    }
1000091
public function generate($metadata, $saveMode=false)
    {
        // clean or make (if not exists) model storage directory
        if (! $this->files->exists($this->path)) {
            $this->files->makeDirectory($this->path);
        }

        // clear existing models if save mode is off
        if (! $saveMode) {
            $this->clean();
        }

        // create models
        foreach ($metadata as $entityMetadata) {
            $this->generateModel($entityMetadata);
        }

        // create .gitignore
        $this->files->put($this->path . '/.gitignore', '*' . PHP_EOL . '!.gitignore');

        // create json file for metadata
        $contents = json_encode($metadata, JSON_PRETTY_PRINT);
        $this->files->put($this->path . '/entities.json', $contents);
    }
480485
private function displayEntity($entityName, EntityManagerInterface $entityManager, OutputInterface $output)
    {
        $table = new Table($output);

        $table->setHeaders(array('Field', 'Value'));

        $metadata = $this->getClassMetadata($entityName, $entityManager);

        array_map(
            array($table, 'addRow'),
            array_merge(
                array(
                    $this->formatField('Name', $metadata->name),
                    $this->formatField('Root entity name', $metadata->rootEntityName),
                    $this->formatField('Custom generator definition', $metadata->customGeneratorDefinition),
                    $this->formatField('Custom repository class', $metadata->customRepositoryClassName),
                    $this->formatField('Mapped super class?', $metadata->isMappedSuperclass),
                    $this->formatField('Embedded class?', $metadata->isEmbeddedClass),
                    $this->formatField('Parent classes', $metadata->parentClasses),
                    $this->formatField('Sub classes', $metadata->subClasses),
                    $this->formatField('Embedded classes', $metadata->subClasses),
                    $this->formatField('Named queries', $metadata->namedQueries),
                    $this->formatField('Named native queries', $metadata->namedNativeQueries),
                    $this->formatField('SQL result set mappings', $metadata->sqlResultSetMappings),
                    $this->formatField('Identifier', $metadata->identifier),
                    $this->formatField('Inheritance type', $metadata->inheritanceType),
                    $this->formatField('Discriminator column', $metadata->discriminatorColumn),
                    $this->formatField('Discriminator value', $metadata->discriminatorValue),
                    $this->formatField('Discriminator map', $metadata->discriminatorMap),
                    $this->formatField('Generator type', $metadata->generatorType),
                    $this->formatField('Table', $metadata->table),
                    $this->formatField('Composite identifier?', $metadata->isIdentifierComposite),
                    $this->formatField('Foreign identifier?', $metadata->containsForeignIdentifier),
                    $this->formatField('Sequence generator definition', $metadata->sequenceGeneratorDefinition),
                    $this->formatField('Table generator definition', $metadata->tableGeneratorDefinition),
                    $this->formatField('Change tracking policy', $metadata->changeTrackingPolicy),
                    $this->formatField('Versioned?', $metadata->isVersioned),
                    $this->formatField('Version field', $metadata->versionField),
                    $this->formatField('Read only?', $metadata->isReadOnly),

                    $this->formatEntityListeners($metadata->entityListeners),
                ),
                array($this->formatField('Association mappings:', '')),
                $this->formatMappings($metadata->associationMappings),
                array($this->formatField('Field mappings:', '')),
                $this->formatMappings($metadata->fieldMappings)
            )
        );

        $table->render();
    }
304459
private function exportSequenceInformation(\SimpleXMLElement $identifierXmlNode, ClassMetadataInfo $metadata)
    {
        $sequenceDefinition = $metadata->sequenceGeneratorDefinition;

        if (! ($metadata->generatorType === ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE && $sequenceDefinition)) {
            return;
        }

        $sequenceGeneratorXml = $identifierXmlNode->addChild('sequence-generator');

        $sequenceGeneratorXml->addAttribute('sequence-name', $sequenceDefinition['sequenceName']);
        $sequenceGeneratorXml->addAttribute('allocation-size', $sequenceDefinition['allocationSize']);
        $sequenceGeneratorXml->addAttribute('initial-value', $sequenceDefinition['initialValue']);
    }
1359353
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
    {
        $this->metadata = $metadata;
        $this->loadMappingFile($this->findMappingFile($className));
    }