/
home
/
obinna
/
html
/
mixchief_app
/
vendor
/
symfony
/
maker-bundle
/
src
/
Doctrine
/
Upload File
HOME
<?php /* * This file is part of the Symfony MakerBundle package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Bundle\MakerBundle\Doctrine; use Doctrine\Common\Persistence\Mapping\MappingException as LegacyCommonMappingException; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException; use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; use Symfony\Bundle\MakerBundle\FileManager; use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator; /** * @internal */ final class EntityRegenerator { private $doctrineHelper; private $fileManager; private $generator; private $entityClassGenerator; private $overwrite; public function __construct(DoctrineHelper $doctrineHelper, FileManager $fileManager, Generator $generator, EntityClassGenerator $entityClassGenerator, bool $overwrite) { $this->doctrineHelper = $doctrineHelper; $this->fileManager = $fileManager; $this->generator = $generator; $this->entityClassGenerator = $entityClassGenerator; $this->overwrite = $overwrite; } public function regenerateEntities(string $classOrNamespace): void { try { $metadata = $this->doctrineHelper->getMetadata($classOrNamespace); } catch (MappingException|LegacyCommonMappingException|PersistenceMappingException $mappingException) { $metadata = $this->doctrineHelper->getMetadata($classOrNamespace, true); } if ($metadata instanceof ClassMetadata) { $metadata = [$metadata]; } elseif (class_exists($classOrNamespace)) { throw new RuntimeCommandException(sprintf('Could not find Doctrine metadata for "%s". Is it mapped as an entity?', $classOrNamespace)); } elseif (empty($metadata)) { throw new RuntimeCommandException(sprintf('No entities were found in the "%s" namespace.', $classOrNamespace)); } /** @var ClassSourceManipulator[] $operations */ $operations = []; foreach ($metadata as $classMetadata) { if (!class_exists($classMetadata->name)) { // the class needs to be generated for the first time! $classPath = $this->generateClass($classMetadata); } else { $classPath = $this->getPathOfClass($classMetadata->name); } $mappedFields = $this->getMappedFieldsInEntity($classMetadata); if ($classMetadata->customRepositoryClassName) { $this->generateRepository($classMetadata); } $manipulator = $this->createClassManipulator($classPath); $operations[$classPath] = $manipulator; $embeddedClasses = []; foreach ($classMetadata->embeddedClasses as $fieldName => $mapping) { if (false !== strpos($fieldName, '.')) { continue; } $className = $mapping['class']; $embeddedClasses[$fieldName] = $this->getPathOfClass($className); $operations[$embeddedClasses[$fieldName]] = $this->createClassManipulator($embeddedClasses[$fieldName]); if (!\in_array($fieldName, $mappedFields)) { continue; } $manipulator->addEmbeddedEntity($fieldName, $className); } foreach ($classMetadata->fieldMappings as $fieldName => $mapping) { // skip embedded fields if (false !== strpos($fieldName, '.')) { list($fieldName, $embeddedFiledName) = explode('.', $fieldName); $operations[$embeddedClasses[$fieldName]]->addEntityField($embeddedFiledName, $mapping); continue; } if (!\in_array($fieldName, $mappedFields)) { continue; } $manipulator->addEntityField($fieldName, $mapping); } $getIsNullable = function (array $mapping) { if (!isset($mapping['joinColumns'][0]['nullable'])) { // the default for relationships IS nullable return true; } return $mapping['joinColumns'][0]['nullable']; }; foreach ($classMetadata->associationMappings as $fieldName => $mapping) { if (!\in_array($fieldName, $mappedFields)) { continue; } switch ($mapping['type']) { case ClassMetadata::MANY_TO_ONE: $relation = (new RelationManyToOne()) ->setPropertyName($mapping['fieldName']) ->setIsNullable($getIsNullable($mapping)) ->setTargetClassName($mapping['targetEntity']) ->setTargetPropertyName($mapping['inversedBy']) ->setMapInverseRelation(null !== $mapping['inversedBy']) ; $manipulator->addManyToOneRelation($relation); break; case ClassMetadata::ONE_TO_MANY: $relation = (new RelationOneToMany()) ->setPropertyName($mapping['fieldName']) ->setTargetClassName($mapping['targetEntity']) ->setTargetPropertyName($mapping['mappedBy']) ->setOrphanRemoval($mapping['orphanRemoval']) ; $manipulator->addOneToManyRelation($relation); break; case ClassMetadata::MANY_TO_MANY: $relation = (new RelationManyToMany()) ->setPropertyName($mapping['fieldName']) ->setTargetClassName($mapping['targetEntity']) ->setTargetPropertyName($mapping['mappedBy']) ->setIsOwning($mapping['isOwningSide']) ->setMapInverseRelation($mapping['isOwningSide'] ? (null !== $mapping['inversedBy']) : true) ; $manipulator->addManyToManyRelation($relation); break; case ClassMetadata::ONE_TO_ONE: $relation = (new RelationOneToOne()) ->setPropertyName($mapping['fieldName']) ->setTargetClassName($mapping['targetEntity']) ->setTargetPropertyName($mapping['isOwningSide'] ? $mapping['inversedBy'] : $mapping['mappedBy']) ->setIsOwning($mapping['isOwningSide']) ->setMapInverseRelation($mapping['isOwningSide'] ? (null !== $mapping['inversedBy']) : true) ->setIsNullable($getIsNullable($mapping)) ; $manipulator->addOneToOneRelation($relation); break; default: throw new \Exception('Unknown association type.'); } } } foreach ($operations as $filename => $manipulator) { $this->fileManager->dumpFile( $filename, $manipulator->getSourceCode() ); } } private function generateClass(ClassMetadata $metadata): string { $path = $this->generator->generateClass( $metadata->name, 'Class.tpl.php', [] ); $this->generator->writeChanges(); return $path; } private function createClassManipulator(string $classPath): ClassSourceManipulator { return new ClassSourceManipulator( $this->fileManager->getFileContents($classPath), $this->overwrite, // use annotations // if properties need to be generated then, by definition, // some non-annotation config is being used, and so, the // properties should not have annotations added to them false ); } private function getPathOfClass(string $class): string { return (new \ReflectionClass($class))->getFileName(); } private function generateRepository(ClassMetadata $metadata): void { if (!$metadata->customRepositoryClassName) { return; } if (class_exists($metadata->customRepositoryClassName)) { // repository already exists return; } $this->entityClassGenerator->generateRepositoryClass( $metadata->customRepositoryClassName, $metadata->name, false ); $this->generator->writeChanges(); } private function getMappedFieldsInEntity(ClassMetadata $classMetadata): array { /** @var \ReflectionClass $classReflection */ $classReflection = $classMetadata->reflClass; $targetFields = array_merge( array_keys($classMetadata->fieldMappings), array_keys($classMetadata->associationMappings), array_keys($classMetadata->embeddedClasses) ); if ($classReflection) { // exclude traits $traitProperties = []; foreach ($classReflection->getTraits() as $trait) { foreach ($trait->getProperties() as $property) { $traitProperties[] = $property->getName(); } } $targetFields = array_diff($targetFields, $traitProperties); // exclude inherited properties $targetFields = array_filter($targetFields, function ($field) use ($classReflection) { return $classReflection->hasProperty($field) && $classReflection->getProperty($field)->getDeclaringClass()->getName() == $classReflection->getName(); }); } return $targetFields; } }