Skip to content

[make:entity] Property types, Types:: constant & type guessing #1147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function process(ContainerBuilder $container): void
$tagAttributes = ['command' => $class::getCommandName()];

if (!method_exists($class, 'getCommandDescription')) {
// no-op
// no-op
} elseif (class_exists(LazyCommand::class)) {
$tagAttributes['description'] = $class::getCommandDescription();
} else {
Expand Down
61 changes: 61 additions & 0 deletions src/Doctrine/DoctrineHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
Expand All @@ -24,6 +25,8 @@
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;

/**
* @author Fabien Potencier <fabien@symfony.com>
Expand Down Expand Up @@ -230,6 +233,64 @@ public function isClassAMappedEntity(string $className): bool
return (bool) $this->getMetadata($className);
}

/**
* Determines if the property-type will make the column type redundant.
*
* See ClassMetadataInfo::validateAndCompleteTypedFieldMapping()
*/
public static function canColumnTypeBeInferredByPropertyType(string $columnType, string $propertyType): bool
{
// todo: guessing on enum's could be added

return match ($propertyType) {
'\\'.\DateInterval::class => Types::DATEINTERVAL === $columnType,
'\\'.\DateTime::class => Types::DATETIME_MUTABLE === $columnType,
'\\'.\DateTimeImmutable::class => Types::DATETIME_IMMUTABLE === $columnType,
'array' => Types::JSON === $columnType,
'bool' => Types::BOOLEAN === $columnType,
'float' => Types::FLOAT === $columnType,
'int' => Types::INTEGER === $columnType,
'string' => Types::STRING === $columnType,
default => false,
};
}

public static function getPropertyTypeForColumn(string $columnType): ?string
{
return match ($columnType) {
Types::STRING, Types::TEXT, Types::GUID, Types::BIGINT, Types::DECIMAL => 'string',
Types::ARRAY, Types::SIMPLE_ARRAY, Types::JSON => 'array',
Types::BOOLEAN => 'bool',
Types::INTEGER, Types::SMALLINT => 'int',
Types::FLOAT => 'float',
Types::DATETIME_MUTABLE, Types::DATETIMETZ_MUTABLE, Types::DATE_MUTABLE, Types::TIME_MUTABLE => '\\'.\DateTimeInterface::class,
Types::DATETIME_IMMUTABLE, Types::DATETIMETZ_IMMUTABLE, Types::DATE_IMMUTABLE, Types::TIME_IMMUTABLE => '\\'.\DateTimeImmutable::class,
Types::DATEINTERVAL => '\\'.\DateInterval::class,
Types::OBJECT => 'object',
'uuid' => '\\'.Uuid::class,
'ulid' => '\\'.Ulid::class,
default => null,
};
}

/**
* Given the string "column type", this returns the "Types::STRING" constant.
*
* This is, effectively, a reverse lookup: given the final string, give us
* the constant to be used in the generated code.
*/
public static function getTypeConstant(string $columnType): ?string
{
$reflection = new \ReflectionClass(Types::class);
$constants = array_flip($reflection->getConstants());

if (!isset($constants[$columnType])) {
return null;
}

return sprintf('Types::%s', $constants[$columnType]);
}

private function isInstanceOf($object, string $class): bool
{
if (!\is_object($object)) {
Expand Down
3 changes: 1 addition & 2 deletions src/Doctrine/EntityClassGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use ApiPlatform\Metadata\ApiResource;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Mapping;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\MakerBundle\Generator;
use Symfony\Bundle\MakerBundle\Str;
Expand Down Expand Up @@ -48,7 +47,7 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $

$useStatements = new UseStatementGenerator([
$repoClassDetails->getFullName(),
[Mapping::class => 'ORM'],
['Doctrine\\ORM\\Mapping' => 'ORM'],
Comment on lines -51 to +50
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for code readability?

]);

if ($broadcast) {
Expand Down
2 changes: 1 addition & 1 deletion src/Maker/MakeFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
$pantherAvailable = trait_exists(PantherTestCaseTrait::class);

$useStatements = new UseStatementGenerator([
($pantherAvailable ? PantherTestCase::class : WebTestCase::class),
$pantherAvailable ? PantherTestCase::class : WebTestCase::class,
]);

$generator->generateClass(
Expand Down
4 changes: 2 additions & 2 deletions src/Maker/MakeResetPassword.php
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,15 @@ private function generateRequestEntity(Generator $generator, ClassNameDetails $r
CODE
);

$manipulator->addManyToOneRelation((new RelationManyToOne(
$manipulator->addManyToOneRelation(new RelationManyToOne(
propertyName: 'user',
targetClassName: $this->userClass,
mapInverseRelation: false,
avoidSetter: true,
isCustomReturnTypeNullable: false,
customReturnType: 'object',
isOwning: true,
)));
));

$this->fileManager->dumpFile($requestEntityPath, $manipulator->getSourceCode());

Expand Down
4 changes: 2 additions & 2 deletions src/Resources/skeleton/doctrine/Entity.tpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class <?= $class_name."\n" ?>
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;
#[ORM\Column()]
private ?int $id = null;

public function getId(): ?int
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function register(Request $request, <?= $password_hasher_class_details->g
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$user->set<?= ucfirst($password_field) ?>(
<?= $password_hasher_variable_name ?>-><?= $use_password_hasher ? 'hashPassword' : 'encodePassword' ?>(
<?= $password_hasher_variable_name ?>-><?= $use_password_hasher ? 'hashPassword' : 'encodePassword' ?>(
$user,
$form->get('plainPassword')->getData()
)
Expand Down
Loading