diff --git a/.github/workflows/ci-linux.yaml b/.github/workflows/ci-linux.yaml
index b771d6ee8..083c68956 100644
--- a/.github/workflows/ci-linux.yaml
+++ b/.github/workflows/ci-linux.yaml
@@ -11,6 +11,7 @@ on:
env:
PHPUNIT_FLAGS: "-v"
SYMFONY_PHPUNIT_DIR: "$HOME/symfony-bridge/.phpunit"
+ MAKER_SKIP_MERCURE_TEST: 1
jobs:
coding-standards:
diff --git a/composer.json b/composer.json
index 2c7db2232..00f629c37 100644
--- a/composer.json
+++ b/composer.json
@@ -29,7 +29,7 @@
"require-dev": {
"composer/semver": "^3.0",
"doctrine/doctrine-bundle": "^2.5.0",
- "doctrine/orm": "^2.10.0",
+ "doctrine/orm": "^2.15|^3",
"symfony/http-client": "^6.4|^7.0",
"symfony/phpunit-bridge": "^6.4.1|^7.0",
"symfony/security-core": "^6.4|^7.0",
@@ -41,8 +41,8 @@
"sort-packages": true
},
"conflict": {
- "doctrine/orm": "<2.10",
- "doctrine/doctrine-bundle": "<2.4"
+ "doctrine/orm": "<2.15",
+ "doctrine/doctrine-bundle": "<2.10"
},
"autoload": {
"psr-4": { "Symfony\\Bundle\\MakerBundle\\": "src/" }
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 38d9c5c04..d35e0fca4 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -19,6 +19,8 @@
+
+
diff --git a/src/Doctrine/DoctrineHelper.php b/src/Doctrine/DoctrineHelper.php
index 07f76fdfb..53ae3cfef 100644
--- a/src/Doctrine/DoctrineHelper.php
+++ b/src/Doctrine/DoctrineHelper.php
@@ -17,13 +17,13 @@
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
use Doctrine\ORM\Mapping\NamingStrategy;
-use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
+use Doctrine\Persistence\Mapping\StaticReflectionService;
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;
@@ -174,8 +174,8 @@ public function getMetadata(string $classOrNamespace = null, bool $disconnected
$loaded = $this->isInstanceOf($cmf, AbstractClassMetadataFactory::class) ? $cmf->getLoadedMetadata() : [];
}
- $cmf = new DisconnectedClassMetadataFactory();
- $cmf->setEntityManager($em);
+ // Set the reflection service that was used in the now removed DisconnectedClassMetadataFactory::class
+ $cmf->setReflectionService(new StaticReflectionService());
foreach ($loaded as $m) {
$cmf->setMetadataFor($m->getName(), $m);
diff --git a/src/Doctrine/EntityRegenerator.php b/src/Doctrine/EntityRegenerator.php
index 8dee3eabe..df0473a59 100644
--- a/src/Doctrine/EntityRegenerator.php
+++ b/src/Doctrine/EntityRegenerator.php
@@ -12,11 +12,13 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;
use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\Mapping\EmbeddedClassMapping;
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\ClassSource\Model\ClassProperty;
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
/**
@@ -75,7 +77,8 @@ public function regenerateEntities(string $classOrNamespace): void
continue;
}
- $className = $mapping['class'];
+ /** @legacy - Remove conditional when ORM 2.x is no longer supported. */
+ $className = ($mapping instanceof EmbeddedClassMapping) ? $mapping->class : $mapping['class'];
$embeddedClasses[$fieldName] = $this->getPathOfClass($className);
@@ -93,7 +96,10 @@ public function regenerateEntities(string $classOrNamespace): void
if (str_contains($fieldName, '.')) {
[$fieldName, $embeddedFiledName] = explode('.', $fieldName);
- $operations[$embeddedClasses[$fieldName]]->addEntityField($embeddedFiledName, $mapping);
+ $property = ClassProperty::createFromObject($mapping);
+ $property->propertyName = $embeddedFiledName;
+
+ $operations[$embeddedClasses[$fieldName]]->addEntityField($property);
continue;
}
@@ -102,18 +108,9 @@ public function regenerateEntities(string $classOrNamespace): void
continue;
}
- $manipulator->addEntityField($fieldName, $mapping);
+ $manipulator->addEntityField(ClassProperty::createFromObject($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;
@@ -121,52 +118,19 @@ public function regenerateEntities(string $classOrNamespace): void
switch ($mapping['type']) {
case ClassMetadata::MANY_TO_ONE:
- $relation = (new RelationManyToOne(
- propertyName: $mapping['fieldName'],
- targetClassName: $mapping['targetEntity'],
- targetPropertyName: $mapping['inversedBy'],
- mapInverseRelation: null !== $mapping['inversedBy'],
- isOwning: true,
- isNullable: $getIsNullable($mapping),
- ));
-
- $manipulator->addManyToOneRelation($relation);
+ $manipulator->addManyToOneRelation(RelationManyToOne::createFromObject($mapping));
break;
case ClassMetadata::ONE_TO_MANY:
- $relation = (new RelationOneToMany(
- propertyName: $mapping['fieldName'],
- targetClassName: $mapping['targetEntity'],
- targetPropertyName: $mapping['mappedBy'],
- orphanRemoval: $mapping['orphanRemoval'],
- ));
-
- $manipulator->addOneToManyRelation($relation);
+ $manipulator->addOneToManyRelation(RelationOneToMany::createFromObject($mapping));
break;
case ClassMetadata::MANY_TO_MANY:
- $relation = (new RelationManyToMany(
- propertyName: $mapping['fieldName'],
- targetClassName: $mapping['targetEntity'],
- targetPropertyName: $mapping['mappedBy'],
- mapInverseRelation: $mapping['isOwningSide'] ? (null !== $mapping['inversedBy']) : true,
- isOwning: $mapping['isOwningSide'],
- ));
-
- $manipulator->addManyToManyRelation($relation);
+ $manipulator->addManyToManyRelation(RelationManyToMany::createFromObject($mapping));
break;
case ClassMetadata::ONE_TO_ONE:
- $relation = (new RelationOneToOne(
- propertyName: $mapping['fieldName'],
- targetClassName: $mapping['targetEntity'],
- targetPropertyName: $mapping['isOwningSide'] ? $mapping['inversedBy'] : $mapping['mappedBy'],
- mapInverseRelation: $mapping['isOwningSide'] ? (null !== $mapping['inversedBy']) : true,
- isOwning: $mapping['isOwningSide'],
- isNullable: $getIsNullable($mapping),
- ));
-
- $manipulator->addOneToOneRelation($relation);
+ $manipulator->addOneToOneRelation(RelationOneToOne::createFromObject($mapping));
break;
default:
diff --git a/src/Doctrine/RelationManyToMany.php b/src/Doctrine/RelationManyToMany.php
index eaf0599d1..f9aa5ef2a 100644
--- a/src/Doctrine/RelationManyToMany.php
+++ b/src/Doctrine/RelationManyToMany.php
@@ -11,6 +11,8 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;
+use Doctrine\ORM\Mapping\ManyToManyInverseSideMapping;
+use Doctrine\ORM\Mapping\ManyToManyOwningSideMapping;
use Symfony\Bundle\MakerBundle\Str;
/**
@@ -27,4 +29,36 @@ public function getTargetRemoverMethodName(): string
{
return 'remove'.Str::asCamelCase(Str::pluralCamelCaseToSingular($this->getTargetPropertyName()));
}
+
+ public static function createFromObject(ManyToManyInverseSideMapping|ManyToManyOwningSideMapping|array $mapping): self
+ {
+ /* @legacy Remove conditional when ORM 2.x is no longer supported! */
+ if (\is_array($mapping)) {
+ return new self(
+ propertyName: $mapping['fieldName'],
+ targetClassName: $mapping['targetEntity'],
+ targetPropertyName: $mapping['mappedBy'],
+ mapInverseRelation: !$mapping['isOwningSide'] || null !== $mapping['inversedBy'],
+ isOwning: $mapping['isOwningSide'],
+ );
+ }
+
+ if ($mapping instanceof ManyToManyOwningSideMapping) {
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->inversedBy,
+ mapInverseRelation: (null !== $mapping->inversedBy),
+ isOwning: $mapping->isOwningSide(),
+ );
+ }
+
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->mappedBy,
+ mapInverseRelation: true,
+ isOwning: $mapping->isOwningSide(),
+ );
+ }
}
diff --git a/src/Doctrine/RelationManyToOne.php b/src/Doctrine/RelationManyToOne.php
index 97c26c619..d7bfa6ba1 100644
--- a/src/Doctrine/RelationManyToOne.php
+++ b/src/Doctrine/RelationManyToOne.php
@@ -11,9 +11,34 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;
+use Doctrine\ORM\Mapping\ManyToOneAssociationMapping;
+
/**
* @internal
*/
final class RelationManyToOne extends BaseRelation
{
+ public static function createFromObject(ManyToOneAssociationMapping|array $mapping): self
+ {
+ /* @legacy Remove conditional when ORM 2.x is no longer supported! */
+ if (\is_array($mapping)) {
+ return new self(
+ propertyName: $mapping['fieldName'],
+ targetClassName: $mapping['targetEntity'],
+ targetPropertyName: $mapping['inversedBy'],
+ mapInverseRelation: null !== $mapping['inversedBy'],
+ isOwning: true,
+ isNullable: $mapping['joinColumns'][0]['nullable'] ?? true,
+ );
+ }
+
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->inversedBy,
+ mapInverseRelation: null !== $mapping->inversedBy,
+ isOwning: true,
+ isNullable: $mapping->joinColumns[0]->nullable ?? true,
+ );
+ }
}
diff --git a/src/Doctrine/RelationOneToMany.php b/src/Doctrine/RelationOneToMany.php
index 1fa43dd30..7970f2f29 100644
--- a/src/Doctrine/RelationOneToMany.php
+++ b/src/Doctrine/RelationOneToMany.php
@@ -11,6 +11,7 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;
+use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
use Symfony\Bundle\MakerBundle\Str;
/**
@@ -32,4 +33,24 @@ public function isMapInverseRelation(): bool
{
throw new \Exception('OneToMany IS the inverse side!');
}
+
+ public static function createFromObject(OneToManyAssociationMapping|array $mapping): self
+ {
+ /* @legacy Remove conditional when ORM 2.x is no longer supported! */
+ if (\is_array($mapping)) {
+ return new self(
+ propertyName: $mapping['fieldName'],
+ targetClassName: $mapping['targetEntity'],
+ targetPropertyName: $mapping['mappedBy'],
+ orphanRemoval: $mapping['orphanRemoval'],
+ );
+ }
+
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->mappedBy,
+ orphanRemoval: $mapping->orphanRemoval,
+ );
+ }
}
diff --git a/src/Doctrine/RelationOneToOne.php b/src/Doctrine/RelationOneToOne.php
index 8b970a9bd..72ecd5cc7 100644
--- a/src/Doctrine/RelationOneToOne.php
+++ b/src/Doctrine/RelationOneToOne.php
@@ -11,6 +11,8 @@
namespace Symfony\Bundle\MakerBundle\Doctrine;
+use Doctrine\ORM\Mapping\OneToOneInverseSideMapping;
+use Doctrine\ORM\Mapping\OneToOneOwningSideMapping;
use Symfony\Bundle\MakerBundle\Str;
/**
@@ -27,4 +29,39 @@ public function getTargetSetterMethodName(): string
{
return 'set'.Str::asCamelCase($this->getTargetPropertyName());
}
+
+ public static function createFromObject(OneToOneInverseSideMapping|OneToOneOwningSideMapping|array $mapping): self
+ {
+ /* @legacy Remove conditional when ORM 2.x is no longer supported! */
+ if (\is_array($mapping)) {
+ return new self(
+ propertyName: $mapping['fieldName'],
+ targetClassName: $mapping['targetEntity'],
+ targetPropertyName: $mapping['isOwningSide'] ? $mapping['inversedBy'] : $mapping['mappedBy'],
+ mapInverseRelation: !$mapping['isOwningSide'] || null !== $mapping['inversedBy'],
+ isOwning: $mapping['isOwningSide'],
+ isNullable: $mapping['joinColumns'][0]['nullable'] ?? true,
+ );
+ }
+
+ if ($mapping instanceof OneToOneOwningSideMapping) {
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->inversedBy,
+ mapInverseRelation: (null !== $mapping->inversedBy),
+ isOwning: true,
+ isNullable: $mapping->joinColumns[0]->nullable ?? true,
+ );
+ }
+
+ return new self(
+ propertyName: $mapping->fieldName,
+ targetClassName: $mapping->targetEntity,
+ targetPropertyName: $mapping->mappedBy,
+ mapInverseRelation: true,
+ isOwning: false,
+ isNullable: $mapping->joinColumns[0]->nullable ?? true,
+ );
+ }
}
diff --git a/src/Maker/MakeEntity.php b/src/Maker/MakeEntity.php
index 07896c675..cc3818185 100644
--- a/src/Maker/MakeEntity.php
+++ b/src/Maker/MakeEntity.php
@@ -28,6 +28,7 @@
use Symfony\Bundle\MakerBundle\Util\ClassDetails;
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
use Symfony\Bundle\MakerBundle\Util\CliOutputHelper;
+use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassProperty;
use Symfony\Bundle\MakerBundle\Util\PhpCompatUtil;
use Symfony\Bundle\MakerBundle\Validator;
use Symfony\Component\Console\Command\Command;
@@ -227,12 +228,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
$fileManagerOperations = [];
$fileManagerOperations[$entityPath] = $manipulator;
- if (\is_array($newField)) {
- $annotationOptions = $newField;
- unset($annotationOptions['fieldName']);
- $manipulator->addEntityField($newField['fieldName'], $annotationOptions);
+ if ($newField instanceof ClassProperty) {
+ $manipulator->addEntityField($newField);
- $currentFields[] = $newField['fieldName'];
+ $currentFields[] = $newField->propertyName;
} elseif ($newField instanceof EntityRelation) {
// both overridden below for OneToMany
$newFieldName = $newField->getOwningProperty();
@@ -329,7 +328,7 @@ public function configureDependencies(DependencyBuilder $dependencies, InputInte
ORMDependencyBuilder::buildDependencies($dependencies);
}
- private function askForNextField(ConsoleStyle $io, array $fields, string $entityClass, bool $isFirstField): EntityRelation|array|null
+ private function askForNextField(ConsoleStyle $io, array $fields, string $entityClass, bool $isFirstField): EntityRelation|ClassProperty|null
{
$io->writeln('');
@@ -407,23 +406,24 @@ private function askForNextField(ConsoleStyle $io, array $fields, string $entity
}
// this is a normal field
- $data = ['fieldName' => $fieldName, 'type' => $type];
+ $classProperty = new ClassProperty(propertyName: $fieldName, type: $type);
+
if ('string' === $type) {
// default to 255, avoid the question
- $data['length'] = $io->ask('Field length', 255, [Validator::class, 'validateLength']);
+ $classProperty->length = $io->ask('Field length', 255, [Validator::class, 'validateLength']);
} elseif ('decimal' === $type) {
// 10 is the default value given in \Doctrine\DBAL\Schema\Column::$_precision
- $data['precision'] = $io->ask('Precision (total number of digits stored: 100.00 would be 5)', 10, [Validator::class, 'validatePrecision']);
+ $classProperty->precision = $io->ask('Precision (total number of digits stored: 100.00 would be 5)', 10, [Validator::class, 'validatePrecision']);
// 0 is the default value given in \Doctrine\DBAL\Schema\Column::$_scale
- $data['scale'] = $io->ask('Scale (number of decimals to store: 100.00 would be 2)', 0, [Validator::class, 'validateScale']);
+ $classProperty->scale = $io->ask('Scale (number of decimals to store: 100.00 would be 2)', 0, [Validator::class, 'validateScale']);
}
if ($io->confirm('Can this field be null in the database (nullable)', false)) {
- $data['nullable'] = true;
+ $classProperty->nullable = true;
}
- return $data;
+ return $classProperty;
}
private function printAvailableTypes(ConsoleStyle $io): void
diff --git a/src/Security/UserClassBuilder.php b/src/Security/UserClassBuilder.php
index 376879f11..f77bfd132 100644
--- a/src/Security/UserClassBuilder.php
+++ b/src/Security/UserClassBuilder.php
@@ -13,6 +13,7 @@
use PhpParser\Node;
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
+use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassProperty;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
@@ -52,13 +53,12 @@ private function addGetUsername(ClassSourceManipulator $manipulator, UserClassCo
if ($userClassConfig->isEntity()) {
// add entity property
$manipulator->addEntityField(
- $userClassConfig->getIdentityPropertyName(),
- [
- 'type' => 'string',
- // https://github.com/FriendsOfSymfony/FOSUserBundle/issues/1919
- 'length' => 180,
- 'unique' => true,
- ]
+ new ClassProperty(
+ propertyName: $userClassConfig->getIdentityPropertyName(),
+ type: 'string',
+ length: 180,
+ unique: true,
+ )
);
} else {
// add normal property
@@ -99,10 +99,7 @@ private function addGetRoles(ClassSourceManipulator $manipulator, UserClassConfi
if ($userClassConfig->isEntity()) {
// add entity property
$manipulator->addEntityField(
- 'roles',
- [
- 'type' => 'json',
- ]
+ new ClassProperty(propertyName: 'roles', type: 'json')
);
} else {
// add normal property
@@ -202,11 +199,7 @@ private function addGetPassword(ClassSourceManipulator $manipulator, UserClassCo
if ($userClassConfig->isEntity()) {
// add entity property
$manipulator->addEntityField(
- 'password',
- [
- 'type' => 'string',
- ],
- [$propertyDocs]
+ new ClassProperty(propertyName: 'password', type: 'string', comments: [$propertyDocs])
);
} else {
// add normal property
diff --git a/src/Test/MakerTestProcess.php b/src/Test/MakerTestProcess.php
index 9257c7206..dc3acb301 100644
--- a/src/Test/MakerTestProcess.php
+++ b/src/Test/MakerTestProcess.php
@@ -45,6 +45,11 @@ public function setInput($input): self
public function run($allowToFail = false, array $envVars = []): self
{
+ if (false !== ($timeout = getenv('MAKER_PROCESS_TIMEOUT'))) {
+ // Setting a value of null allows for step debugging
+ $this->process->setTimeout($timeout);
+ }
+
$this->process->run(null, $envVars);
if (!$allowToFail && !$this->process->isSuccessful()) {
diff --git a/src/Test/MakerTestRunner.php b/src/Test/MakerTestRunner.php
index 72583409c..3ef18139f 100644
--- a/src/Test/MakerTestRunner.php
+++ b/src/Test/MakerTestRunner.php
@@ -173,13 +173,18 @@ public function configureDatabase(bool $createSchema = true): void
// this looks silly, but it's the only way to drop the database *for sure*,
// as doctrine:database:drop will error if there is no database
- // also, skip for SQLITE, as it does not support --if-not-exists
- if (!str_starts_with(getenv('TEST_DATABASE_DSN'), 'sqlite://')) {
+ if (!$usingSqlite = str_starts_with(getenv('TEST_DATABASE_DSN'), 'sqlite')) {
+ // --if-not-exists not supported on SQLite
$this->runConsole('doctrine:database:create', [], '--env=test --if-not-exists');
}
+
$this->runConsole('doctrine:database:drop', [], '--env=test --force');
- $this->runConsole('doctrine:database:create', [], '--env=test');
+ if (!$usingSqlite) {
+ // d:d:create not supported on SQLite
+ $this->runConsole('doctrine:database:create', [], '--env=test');
+ }
+
if ($createSchema) {
$this->runConsole('doctrine:schema:create', [], '--env=test');
}
diff --git a/src/Util/ClassSource/Model/ClassProperty.php b/src/Util/ClassSource/Model/ClassProperty.php
new file mode 100644
index 000000000..220c42029
--- /dev/null
+++ b/src/Util/ClassSource/Model/ClassProperty.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\MakerBundle\Util\ClassSource\Model;
+
+use Doctrine\ORM\Mapping\FieldMapping;
+use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
+
+/**
+ * @author Jesse Rushlow
+ *
+ * @internal
+ */
+final class ClassProperty
+{
+ public function __construct(
+ public string $propertyName,
+ public string $type,
+ public array $comments = [],
+ public ?int $length = null,
+ public ?bool $id = null,
+ public ?bool $nullable = null,
+ public array $options = [],
+ public ?int $precision = null,
+ public ?int $scale = null,
+ public bool $needsTypeHint = true,
+ public bool $unique = false,
+ ) {
+ }
+
+ public function getAttributes(): array
+ {
+ $attributes = [];
+
+ if ($this->needsTypeHint) {
+ $attributes['type'] = $this->type;
+ }
+
+ if (!empty($this->options)) {
+ $attributes['options'] = $this->options;
+ }
+
+ if ($this->unique) {
+ $attributes['unique'] = true;
+ }
+
+ foreach (['length', 'id', 'nullable', 'precision', 'scale'] as $property) {
+ if (null !== $this->$property) {
+ $attributes[$property] = $this->$property;
+ }
+ }
+
+ return $attributes;
+ }
+
+ public static function createFromObject(FieldMapping|array $data): self
+ {
+ if ($data instanceof FieldMapping) {
+ return new self(
+ propertyName: $data->fieldName,
+ type: $data->type,
+ length: $data->length,
+ id: $data->id ?? false,
+ nullable: $data->nullable ?? false,
+ options: $data->options ?? [],
+ precision: $data->precision,
+ scale: $data->scale,
+ unique: $data->unique ?? false,
+ );
+ }
+
+ /* @legacy Remove when ORM 2.x is no longer supported. */
+ if (empty($data['fieldName']) || empty($data['type'])) {
+ throw new RuntimeCommandException('Cannot create property model - "fieldName" & "type" are required.');
+ }
+
+ return new self(
+ propertyName: $data['fieldName'],
+ type: $data['type'],
+ comments: $data['comments'] ?? [],
+ length: $data['length'] ?? null,
+ id: $data['id'] ?? false,
+ nullable: $data['nullable'] ?? false,
+ options: $data['options'] ?? [],
+ precision: $data['precision'] ?? null,
+ scale: $data['scale'] ?? null,
+ unique: $data['unique'] ?? false,
+ );
+ }
+}
diff --git a/src/Util/ClassSourceManipulator.php b/src/Util/ClassSourceManipulator.php
index 833b80dcb..9d429624d 100644
--- a/src/Util/ClassSourceManipulator.php
+++ b/src/Util/ClassSourceManipulator.php
@@ -38,6 +38,7 @@
use Symfony\Bundle\MakerBundle\Doctrine\RelationOneToMany;
use Symfony\Bundle\MakerBundle\Doctrine\RelationOneToOne;
use Symfony\Bundle\MakerBundle\Str;
+use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassProperty;
/**
* @internal
@@ -96,27 +97,27 @@ public function getSourceCode(): string
return $this->sourceCode;
}
- public function addEntityField(string $propertyName, array $columnOptions, array $comments = []): void
+ public function addEntityField(ClassProperty $mapping): void
{
- $typeHint = DoctrineHelper::getPropertyTypeForColumn($columnOptions['type']);
- if ($typeHint && DoctrineHelper::canColumnTypeBeInferredByPropertyType($columnOptions['type'], $typeHint)) {
- unset($columnOptions['type']);
+ $typeHint = DoctrineHelper::getPropertyTypeForColumn($mapping->type);
+ if ($typeHint && DoctrineHelper::canColumnTypeBeInferredByPropertyType($mapping->type, $typeHint)) {
+ $mapping->needsTypeHint = false;
}
- if (isset($columnOptions['type'])) {
- $typeConstant = DoctrineHelper::getTypeConstant($columnOptions['type']);
+ if ($mapping->needsTypeHint) {
+ $typeConstant = DoctrineHelper::getTypeConstant($mapping->type);
if ($typeConstant) {
$this->addUseStatementIfNecessary(Types::class);
- $columnOptions['type'] = $typeConstant;
+ $mapping->type = $typeConstant;
}
}
// 2) USE property type on property below, nullable
// 3) If default value, then NOT nullable
- $nullable = $columnOptions['nullable'] ?? false;
- $isId = (bool) ($columnOptions['id'] ?? false);
- $attributes[] = $this->buildAttributeNode(Column::class, $columnOptions, 'ORM');
+ $nullable = $mapping->nullable ?? false;
+
+ $attributes[] = $this->buildAttributeNode(Column::class, $mapping->getAttributes(), 'ORM');
$defaultValue = null;
if ('array' === $typeHint && !$nullable) {
@@ -132,15 +133,15 @@ public function addEntityField(string $propertyName, array $columnOptions, array
}
$this->addProperty(
- name: $propertyName,
+ name: $mapping->propertyName,
defaultValue: $defaultValue,
attributes: $attributes,
- comments: $comments,
+ comments: $mapping->comments,
propertyType: $propertyType
);
$this->addGetter(
- $propertyName,
+ $mapping->propertyName,
$typeHint,
// getter methods always have nullable return values
// because even though these are required in the db, they may not be set yet
@@ -149,8 +150,8 @@ public function addEntityField(string $propertyName, array $columnOptions, array
);
// don't generate setters for id fields
- if (!$isId) {
- $this->addSetter($propertyName, $typeHint, $nullable);
+ if (!($mapping->id ?? false)) {
+ $this->addSetter($mapping->propertyName, $typeHint, $nullable);
}
}
@@ -310,7 +311,7 @@ public function addConstructor(array $params, string $methodBody): void
/**
* @param Node[] $params
*/
- public function addMethodBuilder(Builder\Method $methodBuilder, array $params = [], string $methodBody = null): void
+ public function addMethodBuilder(Builder\Method $methodBuilder, array $params = [], ?string $methodBody = null): void
{
$this->addMethodParams($methodBuilder, $params);
@@ -359,7 +360,7 @@ public function createMethodLevelBlankLine()
/**
* @param array $attributes
*/
- public function addProperty(string $name, $defaultValue = self::DEFAULT_VALUE_NONE, array $attributes = [], array $comments = [], string $propertyType = null): void
+ public function addProperty(string $name, $defaultValue = self::DEFAULT_VALUE_NONE, array $attributes = [], array $comments = [], ?string $propertyType = null): void
{
if ($this->propertyExists($name)) {
// we never overwrite properties
@@ -843,7 +844,7 @@ public function addUseStatementIfNecessary(string $class): string
* @param array $options The named arguments for the attribute ($key = argument name, $value = argument value)
* @param ?string $attributePrefix If a prefix is provided, the node is built using the prefix. E.g. #[ORM\Column()]
*/
- public function buildAttributeNode(string $attributeClass, array $options, string $attributePrefix = null): Node\Attribute
+ public function buildAttributeNode(string $attributeClass, array $options, ?string $attributePrefix = null): Node\Attribute
{
$options = $this->sortOptionsByClassConstructorParameters($options, $attributeClass);
diff --git a/tests/Util/ClassSourceManipulatorTest.php b/tests/Util/ClassSourceManipulatorTest.php
index 33c44fb9c..193587b79 100644
--- a/tests/Util/ClassSourceManipulatorTest.php
+++ b/tests/Util/ClassSourceManipulatorTest.php
@@ -13,6 +13,7 @@
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
+use Doctrine\ORM\Mapping\FieldMapping;
use PhpParser\Builder\Param;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\MakerBundle\Doctrine\RelationManyToMany;
@@ -20,6 +21,7 @@
use Symfony\Bundle\MakerBundle\Doctrine\RelationOneToMany;
use Symfony\Bundle\MakerBundle\Doctrine\RelationOneToOne;
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
+use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassProperty;
use Symfony\Component\Security\Core\User\UserInterface;
class ClassSourceManipulatorTest extends TestCase
@@ -213,97 +215,70 @@ public function getAttributeClassTests(): \Generator
/**
* @dataProvider getAddEntityFieldTests
*/
- public function testAddEntityField(string $sourceFilename, string $propertyName, array $fieldOptions, $expectedSourceFilename): void
+ public function testAddEntityField(string $sourceFilename, ClassProperty $propertyModel, $expectedSourceFilename): void
{
$sourcePath = __DIR__.'/fixtures/source';
$expectedPath = __DIR__.'/fixtures/add_entity_field';
$this->runAddEntityFieldTests(
file_get_contents(sprintf('%s/%s', $sourcePath, $sourceFilename)),
- $propertyName,
- $fieldOptions,
+ $propertyModel,
file_get_contents(sprintf('%s/%s', $expectedPath, $expectedSourceFilename))
);
}
- private function runAddEntityFieldTests(string $source, string $propertyName, array $fieldOptions, string $expected): void
+ private function runAddEntityFieldTests(string $source, ClassProperty $fieldOptions, string $expected): void
{
$manipulator = new ClassSourceManipulator($source, false);
- $manipulator->addEntityField($propertyName, $fieldOptions);
+ $manipulator->addEntityField($fieldOptions);
$this->assertSame($expected, $manipulator->getSourceCode());
}
public function getAddEntityFieldTests(): \Generator
{
+ /** @legacy - Remove when Doctrine/ORM 2.x is no longer supported. */
+ $isLegacy = !class_exists(FieldMapping::class);
+
yield 'entity_normal_add' => [
'User_simple.php',
- 'fooProp',
- [
- 'type' => 'string',
- 'length' => 255,
- 'nullable' => false,
- 'options' => ['comment' => 'new field'],
- ],
+ new ClassProperty(propertyName: 'fooProp', type: 'string', length: 255, nullable: false, options: ['comment' => 'new field']),
'User_simple.php',
];
yield 'entity_add_datetime' => [
'User_simple.php',
- 'createdAt',
- [
- 'type' => 'datetime',
- 'nullable' => true,
- ],
+ new ClassProperty(propertyName: 'createdAt', type: 'datetime', nullable: true),
'User_simple_datetime.php',
];
yield 'entity_field_property_already_exists' => [
'User_some_props.php',
- 'firstName',
- [
- 'type' => 'string',
- 'length' => 255,
- 'nullable' => false,
- ],
+ new ClassProperty(propertyName: 'firstName', type: 'string', length: 255, nullable: false),
'User_simple_prop_already_exists.php',
];
yield 'entity_field_property_zero' => [
'User_simple.php',
- 'decimal',
- [
- 'type' => 'decimal',
- 'precision' => 6,
- 'scale' => 0,
- ],
+ new ClassProperty(propertyName: 'decimal', type: 'decimal', precision: 6, scale: 0),
'User_simple_prop_zero.php',
];
yield 'entity_add_object' => [
'User_simple.php',
- 'someObject',
- [
- 'type' => 'object',
- ],
- 'User_simple_object.php',
+ new ClassProperty(propertyName: 'someObject', type: 'object'),
+ $isLegacy ? 'legacy/User_simple_object.php' : 'User_simple_object.php',
];
yield 'entity_add_uuid' => [
'User_simple.php',
- 'uuid',
- [
- 'type' => 'uuid',
- ],
+ new ClassProperty(propertyName: 'uuid', type: 'uuid'),
'User_simple_uuid.php',
];
yield 'entity_add_ulid' => [
'User_simple.php',
- 'ulid',
- [
- 'type' => 'ulid',
- ],
+ new ClassProperty(propertyName: 'ulid', type: 'ulid'),
'User_simple_ulid.php',
];
}
@@ -414,6 +389,11 @@ public function testAddOneToManyRelation(string $sourceFilename, string $expecte
$sourcePath = __DIR__.'/fixtures/source';
$expectedPath = __DIR__.'/fixtures/add_one_to_many_relation';
+ /** @legacy - Remove when Doctrine/ORM 2.x is no longer supported. */
+ if (!class_exists(FieldMapping::class)) {
+ $expectedPath.= '/legacy';
+ }
+
$this->runAddOneToManyRelationTests(
file_get_contents(sprintf('%s/%s', $sourcePath, $sourceFilename)),
file_get_contents(sprintf('%s/%s', $expectedPath, $expectedSourceFilename)),
@@ -551,6 +531,9 @@ private function runAddOneToOneRelation(string $source, string $expected, Relati
public function getAddOneToOneRelationTests(): \Generator
{
+ /** @legacy - Remove when Doctrine/ORM 2.x is no longer supported. */
+ $isLegacy = !class_exists(FieldMapping::class);
+
yield 'one_to_one_owning' => [
'User_simple.php',
'User_simple_owning.php',
@@ -566,7 +549,7 @@ public function getAddOneToOneRelationTests(): \Generator
// a relationship to yourself - return type is self
yield 'one_to_one_owning_self' => [
'User_simple.php',
- 'User_simple_self.php',
+ $isLegacy ? 'legacy/User_simple_self.php' : 'User_simple_self.php',
new RelationOneToOne(
propertyName: 'embeddedUser',
targetClassName: \App\Entity\User::class,
diff --git a/tests/Util/fixtures/add_entity_field/User_simple_object.php b/tests/Util/fixtures/add_entity_field/User_simple_object.php
index 0ed05a87b..c4c9524f9 100644
--- a/tests/Util/fixtures/add_entity_field/User_simple_object.php
+++ b/tests/Util/fixtures/add_entity_field/User_simple_object.php
@@ -2,7 +2,6 @@
namespace App\Entity;
-use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
@@ -13,7 +12,7 @@ class User
#[ORM\Column()]
private ?int $id = null;
- #[ORM\Column(type: Types::OBJECT)]
+ #[ORM\Column(type: 'object')]
private ?object $someObject = null;
public function getId(): ?int
diff --git a/tests/Util/fixtures/add_entity_field/legacy/User_simple_object.php b/tests/Util/fixtures/add_entity_field/legacy/User_simple_object.php
new file mode 100644
index 000000000..0ed05a87b
--- /dev/null
+++ b/tests/Util/fixtures/add_entity_field/legacy/User_simple_object.php
@@ -0,0 +1,35 @@
+id;
+ }
+
+ public function getSomeObject(): ?object
+ {
+ return $this->someObject;
+ }
+
+ public function setSomeObject(object $someObject): static
+ {
+ $this->someObject = $someObject;
+
+ return $this;
+ }
+}
diff --git a/tests/Util/fixtures/add_one_to_many_relation/User_simple.php b/tests/Util/fixtures/add_one_to_many_relation/User_simple.php
index e742e7ef0..915cae2a6 100644
--- a/tests/Util/fixtures/add_one_to_many_relation/User_simple.php
+++ b/tests/Util/fixtures/add_one_to_many_relation/User_simple.php
@@ -14,7 +14,7 @@ class User
#[ORM\Column()]
private ?int $id = null;
- #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserAvatarPhoto::class)]
+ #[ORM\OneToMany(targetEntity: UserAvatarPhoto::class, mappedBy: 'user')]
private Collection $avatarPhotos;
public function __construct()
diff --git a/tests/Util/fixtures/add_one_to_many_relation/User_simple_orphan_removal.php b/tests/Util/fixtures/add_one_to_many_relation/User_simple_orphan_removal.php
index e76e70d81..effc715bf 100644
--- a/tests/Util/fixtures/add_one_to_many_relation/User_simple_orphan_removal.php
+++ b/tests/Util/fixtures/add_one_to_many_relation/User_simple_orphan_removal.php
@@ -14,7 +14,7 @@ class User
#[ORM\Column()]
private ?int $id = null;
- #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserAvatarPhoto::class, orphanRemoval: true)]
+ #[ORM\OneToMany(targetEntity: UserAvatarPhoto::class, mappedBy: 'user', orphanRemoval: true)]
private Collection $avatarPhotos;
public function __construct()
diff --git a/tests/Util/fixtures/add_one_to_many_relation/User_with_use_statements.php b/tests/Util/fixtures/add_one_to_many_relation/User_with_use_statements.php
index 698741299..bf907e58c 100644
--- a/tests/Util/fixtures/add_one_to_many_relation/User_with_use_statements.php
+++ b/tests/Util/fixtures/add_one_to_many_relation/User_with_use_statements.php
@@ -17,7 +17,7 @@ class User
#[ORM\Column()]
private ?int $id = null;
- #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserAvatarPhoto::class)]
+ #[ORM\OneToMany(targetEntity: UserAvatarPhoto::class, mappedBy: 'user')]
private Collection $avatarPhotos;
public function __construct()
diff --git a/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple.php b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple.php
new file mode 100644
index 000000000..e742e7ef0
--- /dev/null
+++ b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple.php
@@ -0,0 +1,59 @@
+avatarPhotos = new ArrayCollection();
+ }
+
+ public function getId(): ?int
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return Collection
+ */
+ public function getAvatarPhotos(): Collection
+ {
+ return $this->avatarPhotos;
+ }
+
+ public function addAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if (!$this->avatarPhotos->contains($avatarPhoto)) {
+ $this->avatarPhotos->add($avatarPhoto);
+ $avatarPhoto->setUser($this);
+ }
+
+ return $this;
+ }
+
+ public function removeAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if ($this->avatarPhotos->removeElement($avatarPhoto)) {
+ // set the owning side to null (unless already changed)
+ if ($avatarPhoto->getUser() === $this) {
+ $avatarPhoto->setUser(null);
+ }
+ }
+
+ return $this;
+ }
+}
diff --git a/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple_orphan_removal.php b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple_orphan_removal.php
new file mode 100644
index 000000000..e76e70d81
--- /dev/null
+++ b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_simple_orphan_removal.php
@@ -0,0 +1,59 @@
+avatarPhotos = new ArrayCollection();
+ }
+
+ public function getId(): ?int
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return Collection
+ */
+ public function getAvatarPhotos(): Collection
+ {
+ return $this->avatarPhotos;
+ }
+
+ public function addAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if (!$this->avatarPhotos->contains($avatarPhoto)) {
+ $this->avatarPhotos->add($avatarPhoto);
+ $avatarPhoto->setUser($this);
+ }
+
+ return $this;
+ }
+
+ public function removeAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if ($this->avatarPhotos->removeElement($avatarPhoto)) {
+ // set the owning side to null (unless already changed)
+ if ($avatarPhoto->getUser() === $this) {
+ $avatarPhoto->setUser(null);
+ }
+ }
+
+ return $this;
+ }
+}
diff --git a/tests/Util/fixtures/add_one_to_many_relation/legacy/User_with_use_statements.php b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_with_use_statements.php
new file mode 100644
index 000000000..698741299
--- /dev/null
+++ b/tests/Util/fixtures/add_one_to_many_relation/legacy/User_with_use_statements.php
@@ -0,0 +1,62 @@
+avatarPhotos = new ArrayCollection();
+ }
+
+ public function getId(): ?int
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return Collection
+ */
+ public function getAvatarPhotos(): Collection
+ {
+ return $this->avatarPhotos;
+ }
+
+ public function addAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if (!$this->avatarPhotos->contains($avatarPhoto)) {
+ $this->avatarPhotos->add($avatarPhoto);
+ $avatarPhoto->setUser($this);
+ }
+
+ return $this;
+ }
+
+ public function removeAvatarPhoto(UserAvatarPhoto $avatarPhoto): static
+ {
+ if ($this->avatarPhotos->removeElement($avatarPhoto)) {
+ // set the owning side to null (unless already changed)
+ if ($avatarPhoto->getUser() === $this) {
+ $avatarPhoto->setUser(null);
+ }
+ }
+
+ return $this;
+ }
+}
diff --git a/tests/Util/fixtures/add_one_to_one_relation/User_simple_self.php b/tests/Util/fixtures/add_one_to_one_relation/User_simple_self.php
index 22e44cc9d..6ee090a86 100644
--- a/tests/Util/fixtures/add_one_to_one_relation/User_simple_self.php
+++ b/tests/Util/fixtures/add_one_to_one_relation/User_simple_self.php
@@ -12,7 +12,7 @@ class User
#[ORM\Column()]
private ?int $id = null;
- #[ORM\OneToOne(inversedBy: 'user', targetEntity: self::class, cascade: ['persist', 'remove'])]
+ #[ORM\OneToOne(targetEntity: self::class, inversedBy: 'user', cascade: ['persist', 'remove'])]
private ?self $embeddedUser = null;
public function getId(): ?int
diff --git a/tests/Util/fixtures/add_one_to_one_relation/legacy/User_simple_self.php b/tests/Util/fixtures/add_one_to_one_relation/legacy/User_simple_self.php
new file mode 100644
index 000000000..22e44cc9d
--- /dev/null
+++ b/tests/Util/fixtures/add_one_to_one_relation/legacy/User_simple_self.php
@@ -0,0 +1,34 @@
+id;
+ }
+
+ public function getEmbeddedUser(): ?self
+ {
+ return $this->embeddedUser;
+ }
+
+ public function setEmbeddedUser(?self $embeddedUser): static
+ {
+ $this->embeddedUser = $embeddedUser;
+
+ return $this;
+ }
+}
diff --git a/tests/fixtures/make-form/tests/it_generates_form_with_many_to_many_relation.php b/tests/fixtures/make-form/tests/it_generates_form_with_many_to_many_relation.php
index 6652306b8..5be663aa6 100644
--- a/tests/fixtures/make-form/tests/it_generates_form_with_many_to_many_relation.php
+++ b/tests/fixtures/make-form/tests/it_generates_form_with_many_to_many_relation.php
@@ -6,10 +6,10 @@
use App\Entity\Book;
use App\Form\BookType;
use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
@@ -80,7 +80,7 @@ protected function getExtensions(): array
[Library::class, new ClassMetadata(Library::class)],
]);
- $execute = $this->createMock(AbstractQuery::class);
+ $execute = $this->createMock(Query::class);
$execute->method('execute')
->willReturn([
(new Library())->setName('foo'),
diff --git a/tests/fixtures/make-form/tests/it_generates_form_with_many_to_one_relation.php b/tests/fixtures/make-form/tests/it_generates_form_with_many_to_one_relation.php
index 49e5626c0..f73845cd5 100644
--- a/tests/fixtures/make-form/tests/it_generates_form_with_many_to_one_relation.php
+++ b/tests/fixtures/make-form/tests/it_generates_form_with_many_to_one_relation.php
@@ -5,10 +5,10 @@
use App\Entity\Author;
use App\Entity\Book;
use App\Form\BookType;
-use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
@@ -53,17 +53,16 @@ protected function getExtensions(): array
])
;
- $execute = $this->createMock(AbstractQuery::class);
+ $execute = $this->createMock(Query::class);
$execute->method('execute')
->willReturn([
- (new Author())->setName('foo')
+ (new Author())->setName('foo'),
]);
$query = $this->createMock(QueryBuilder::class);
$query->method('getQuery')
->willReturn($execute);
-
$entityRepository = $this->createMock(EntityRepository::class);
$entityRepository->method('createQueryBuilder')
->willReturn($query)
diff --git a/tests/fixtures/make-form/tests/it_generates_form_with_one_to_one_relation.php b/tests/fixtures/make-form/tests/it_generates_form_with_one_to_one_relation.php
index ef5b6de47..deb501726 100644
--- a/tests/fixtures/make-form/tests/it_generates_form_with_one_to_one_relation.php
+++ b/tests/fixtures/make-form/tests/it_generates_form_with_one_to_one_relation.php
@@ -5,10 +5,10 @@
use App\Entity\Librarian;
use App\Entity\Library;
use App\Form\LibraryType;
-use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
@@ -53,17 +53,16 @@ protected function getExtensions(): array
])
;
- $execute = $this->createMock(AbstractQuery::class);
+ $execute = $this->createMock(Query::class);
$execute->method('execute')
->willReturn([
- (new Librarian())->setName('foo')
+ (new Librarian())->setName('foo'),
]);
$query = $this->createMock(QueryBuilder::class);
$query->method('getQuery')
->willReturn($execute);
-
$entityRepository = $this->createMock(EntityRepository::class);
$entityRepository->method('createQueryBuilder')
->willReturn($query)