diff --git a/EntityGeneratorBundle/Doctrine/Dto/DtoManipulator.php b/EntityGeneratorBundle/Doctrine/Dto/DtoManipulator.php index 6fbfeef..2f6d491 100644 --- a/EntityGeneratorBundle/Doctrine/Dto/DtoManipulator.php +++ b/EntityGeneratorBundle/Doctrine/Dto/DtoManipulator.php @@ -162,7 +162,7 @@ public function addEntityField( $embedded ); - if ($nullable) { + if ($nullable || $isPk) { $paramDoc = '@param ' . $typeHint . '|null $' . $propertyName; } else { $paramDoc = '@param ' . $typeHint . ' $' . $propertyName; @@ -269,16 +269,15 @@ public function addSetter( $propertyName, $type, $isNullable, - $classMetadata, $commentLines, - $columnOptions, $visibility ); } public function addIdSetter( string $propertyName, - $type, + $targetClass, + $hint, bool $isNullable, $classMetadata, array $commentLines = [], @@ -287,11 +286,8 @@ public function addIdSetter( ) { $this->methods[] = new FkSetter( $propertyName, - $type, - $isNullable, - $classMetadata, - $commentLines, - $columnOptions, + $targetClass, + $hint, $visibility ); } @@ -414,12 +410,6 @@ private function addSingularRelation(BaseSingleRelation $relation, $classMetadat ); //// - $this->addIdSetter( - $relation->getPropertyName(), - $typeHint, - true, - $classMetadata, - ); $targetClassName = substr( $relation->getTargetClassName(), @@ -437,6 +427,14 @@ private function addSingularRelation(BaseSingleRelation $relation, $classMetadat $targetPkField["type"] ); + $this->addIdSetter( + $relation->getPropertyName(), + $typeHint, + $targetPkHint, + true, + $classMetadata, + ); + $this->addIdGetter( $relation->getPropertyName(), $relation->getCustomReturnType() ?: $targetPkHint, @@ -474,7 +472,7 @@ private function addCollectionRelation(BaseCollectionRelation $relation, $classM ); // Setter - $setterHint = '@param ' . $typeHint . '[] | null'; + $setterHint = '@param ' . $typeHint . '[] | null $' . $relation->getPropertyName(); $setterComments = [ $setterHint, diff --git a/EntityGeneratorBundle/Doctrine/Dto/DtoRegenerator.php b/EntityGeneratorBundle/Doctrine/Dto/DtoRegenerator.php index 8040831..57ac2ff 100644 --- a/EntityGeneratorBundle/Doctrine/Dto/DtoRegenerator.php +++ b/EntityGeneratorBundle/Doctrine/Dto/DtoRegenerator.php @@ -3,6 +3,7 @@ namespace IvozDevTools\EntityGeneratorBundle\Doctrine\Dto; use Doctrine\ORM\Mapping\ClassMetadata; +use IvozDevTools\EntityGeneratorBundle\Doctrine\EntityTypeTrait; use IvozDevTools\EntityGeneratorBundle\Doctrine\ManipulatorInterface; use IvozDevTools\EntityGeneratorBundle\Generator; use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper; @@ -18,6 +19,8 @@ */ final class DtoRegenerator { + use EntityTypeTrait; + private $fileManager; private $generator; private $doctrineHelper; @@ -146,6 +149,10 @@ private function getClassTemplate( ); } + $variables['pk_type_hint'] = $this->getEntityTypeHintByMetadata( + $metadata + ); + return [ $variables['relative_path'], $this->fileManager->parseTemplate( diff --git a/EntityGeneratorBundle/Doctrine/Dto/DtoSetter.php b/EntityGeneratorBundle/Doctrine/Dto/DtoSetter.php index e2b661f..b6017c7 100644 --- a/EntityGeneratorBundle/Doctrine/Dto/DtoSetter.php +++ b/EntityGeneratorBundle/Doctrine/Dto/DtoSetter.php @@ -7,34 +7,27 @@ class DtoSetter implements CodeGeneratorUnitInterface { - protected $propertyName; - protected $type; - protected $isNullable; - protected $comments = []; - protected $columnOptions = []; - protected $classMetadata; - protected $visibility; - public function __construct( - string $propertyName, - ?string $type, - bool $isNullable, - $classMetadata, - array $commentLines = [], - array $columnOptions = [], - string $visibility = 'protected' + private string $propertyName, + private ?string $type, + private bool $isNullable, + private array $comments = [], + private string $visibility = 'protected' ) { - $this->propertyName = $propertyName; - $this->type = $type; - $this->isNullable = $isNullable; - $this->comments = $commentLines; - $this->columnOptions = $columnOptions; - $this->classMetadata = $classMetadata; - $this->visibility = $visibility; } public function toString(string $nlLeftPad = ''): string { + $response = []; + $showComments = is_null($this->type) || $this->type === 'array'; + if (count($this->comments) && $showComments) { + $response = ['/**']; + foreach ($this->comments as $comment) { + $response[] = ' * ' . $comment; + } + $response[] = ' */'; + } + if ($this->isNullable && $this->type) { $typeHint = strpos($this->type, '|') !== false ? 'null|' . $this->type @@ -48,8 +41,6 @@ public function toString(string $nlLeftPad = ''): string } $methodName = 'set' . Str::asCamelCase($this->propertyName); - - $response = []; $response[] = sprintf( '%s function %s(%s%s): %s', $this->visibility, diff --git a/EntityGeneratorBundle/Doctrine/Dto/FkSetter.php b/EntityGeneratorBundle/Doctrine/Dto/FkSetter.php index 9e5e6a7..304a15e 100644 --- a/EntityGeneratorBundle/Doctrine/Dto/FkSetter.php +++ b/EntityGeneratorBundle/Doctrine/Dto/FkSetter.php @@ -5,23 +5,32 @@ use IvozDevTools\EntityGeneratorBundle\Doctrine\Setter; use Symfony\Bundle\MakerBundle\Str; -class FkSetter extends Setter +class FkSetter { + public function __construct( + private string $propertyName, + private ?string $targetClass, + private string $typeHint, + private string $visibility = 'protected' + ) { + } + public function toString(string $nlLeftPad = ''): string { $methodName = 'set' . Str::asCamelCase($this->propertyName); $response = []; $response[] = sprintf( - '%s function %sId($id): %s', + '%s function %sId(?%s $id): %s', $this->visibility, $methodName, + $this->typeHint, 'static' ); $response[] = '{'; $response[] = ' $value = !is_null($id)'; - $response[] = " ? new " . $this->type . '($id)'; + $response[] = " ? new " . $this->targetClass . '($id)'; $response[] = ' : null;'; $response[] = ''; $response[] = ' return $this->' . $methodName . '($value);'; diff --git a/EntityGeneratorBundle/Doctrine/Entity/EntityRegenerator.php b/EntityGeneratorBundle/Doctrine/Entity/EntityRegenerator.php index 5aa1ae3..ea02fb8 100644 --- a/EntityGeneratorBundle/Doctrine/Entity/EntityRegenerator.php +++ b/EntityGeneratorBundle/Doctrine/Entity/EntityRegenerator.php @@ -3,6 +3,7 @@ namespace IvozDevTools\EntityGeneratorBundle\Doctrine\Entity; use Doctrine\ORM\Mapping\ClassMetadata; +use IvozDevTools\EntityGeneratorBundle\Doctrine\EntityTypeTrait; use IvozDevTools\EntityGeneratorBundle\Doctrine\ManipulatorInterface; use IvozDevTools\EntityGeneratorBundle\Generator; use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper; @@ -15,6 +16,8 @@ */ final class EntityRegenerator { + use EntityTypeTrait; + private $fileManager; private $generator; private $doctrineHelper; @@ -29,11 +32,12 @@ public function __construct( $this->doctrineHelper = $doctrineHelper; } - public function makeAbstractEntity($classMetadata) + public function makeAbstractEntity($classMetadata, $parentMetadata) { [$classPath, $content] = $this->getClassTemplate( $classMetadata, - 'doctrine/AbstractEntity.tpl.php' + 'doctrine/AbstractEntity.tpl.php', + $parentMetadata, ); $manipulator = $this->createClassManipulator( @@ -52,28 +56,6 @@ public function makeAbstractEntity($classMetadata) ); } - public function makeEmptyInterface($classMetadata) - { - if (class_exists($classMetadata->name)) { - return; - } - - [$classPath, $content] = $this->getClassTemplate( - $classMetadata, - 'doctrine/EntityInterface.tpl.php' - ); - - $manipulator = $this->createClassManipulator( - $classPath, - $content - ); - - $this->dumpFile( - $classPath, - $manipulator - ); - } - public function makeEntity($classMetadata) { try { @@ -108,7 +90,8 @@ private function dumpFile(string $classPath, ManipulatorInterface $manipulator): private function getClassTemplate( ClassMetadata $metadata, - $templateName + $templateName, + ClassMetadata $parentMetadata = null, ): array { [$path, $variables] = $this->generator->generateClassContentVariables( @@ -127,6 +110,11 @@ private function getClassTemplate( ); } + $pkTypeHint = $this->getEntityTypeHintByMetadata( + $parentMetadata ?? $metadata + ); + $variables['pk_type_hint'] = $pkTypeHint ?? 'int'; + return [ $variables['relative_path'], $this->fileManager->parseTemplate( diff --git a/EntityGeneratorBundle/Doctrine/EntityTypeTrait.php b/EntityGeneratorBundle/Doctrine/EntityTypeTrait.php index efe5427..c6199a3 100644 --- a/EntityGeneratorBundle/Doctrine/EntityTypeTrait.php +++ b/EntityGeneratorBundle/Doctrine/EntityTypeTrait.php @@ -2,8 +2,26 @@ namespace IvozDevTools\EntityGeneratorBundle\Doctrine; +use Doctrine\ORM\Mapping\ClassMetadata; + trait EntityTypeTrait { + private function getEntityTypeHintByMetadata(ClassMetadata $metadata) + { + $identifier = $metadata->getIdentifier(); + if (empty($identifier)) { + return null; + } + + $pkField = $metadata->getFieldMapping( + current($identifier) + ); + + return $this->getEntityTypeHint( + $pkField["type"] + ); + } + private function getEntityTypeHint($doctrineType) { switch ($doctrineType) { diff --git a/EntityGeneratorBundle/Doctrine/Regenerator.php b/EntityGeneratorBundle/Doctrine/Regenerator.php index 386b44f..f7ab5e0 100644 --- a/EntityGeneratorBundle/Doctrine/Regenerator.php +++ b/EntityGeneratorBundle/Doctrine/Regenerator.php @@ -100,7 +100,12 @@ public function regenerateEntities(string $classOrNamespace) $classMetadata ); } elseif ($isMappedSuperclass) { - $this->entityRegenerator->makeAbstractEntity($classMetadata); + + try { + $parentMetadata = $this->getMetadata(substr($classOrNamespace, 0, strlen('Abstract') * -1)); + } catch (\Exception $e) {} + + $this->entityRegenerator->makeAbstractEntity($classMetadata, $parentMetadata ?? null); $this->dtoRegenerator->makeAbstractDto($classMetadata); } else { $this->interfaceRegenerator->makeEmptyInterface($classMetadata); diff --git a/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractDto.tpl.php b/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractDto.tpl.php index 059bc86..cf16f53 100644 --- a/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractDto.tpl.php +++ b/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractDto.tpl.php @@ -15,10 +15,7 @@ abstract class /*__dto_attributes*/ - /** - * @param string|int|null $id - */ - public function __construct($id = null) + public function __construct(? $id = null) { $this->setId($id); } diff --git a/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractEntity.tpl.php b/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractEntity.tpl.php index d8c9912..979fedd 100644 --- a/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractEntity.tpl.php +++ b/EntityGeneratorBundle/Resources/skeleton/doctrine/AbstractEntity.tpl.php @@ -47,7 +47,10 @@ protected function sanitizeValues(): void { } - public static function createDto(string|int|null $id = null): Dto + /** + * @param | null $id + */ + public static function createDto($id = null): Dto { return new Dto($id); } diff --git a/composer.json b/composer.json index e948890..db699d0 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "doctrine/doctrine-bundle": "^2.0", "symfony/console": "^5.1", "symfony/maker-bundle": "<=1.38", - "irontec/ivoz-core": "^4.17.0" + "irontec/ivoz-core": "^4.18.0" }, "require-dev": { "phpstan/phpstan": "^1.0"