diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index eba728cf74..247d2f3c00 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -11,7 +11,7 @@ env: jobs: phpunit: - name: "PHPUnit ${{ matrix.php-version }} (${{ matrix.deps }})${{ matrix.dbal-version && format(' - DBAL {0}', matrix.dbal-version) || '' }}" + name: "PHPUnit ${{ matrix.php-version }} (${{ matrix.deps }})" runs-on: "ubuntu-20.04" services: @@ -30,17 +30,9 @@ jobs: - "8.3" deps: - "highest" - dbal-version: - - "" include: - deps: "lowest" php-version: "7.4" - - deps: "highest" - php-version: "8.3" - dbal-version: "^2.13.1" - - deps: "highest" - php-version: "8.3" - dbal-version: "^3.2" - deps: "highest" php-version: "8.1" @@ -57,10 +49,6 @@ jobs: extensions: mongodb coverage: "pcov" - - name: "Restrict DBAL version" - if: "${{ matrix.dbal-version }}" - run: "composer require --dev --no-update doctrine/dbal:${{ matrix.dbal-version }}" - # Remove PHP-CS-Fixer to avoid conflicting dependency ranges (i.e. doctrine/annotations) - name: "Remove PHP-CS-Fixer" run: "composer remove --dev --no-update friendsofphp/php-cs-fixer" diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c45197a3e..0d58794624 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,9 +18,13 @@ a release. --- ## [Unreleased] +### Added +- Tree: Added `@template` and `@template-extends` annotations to the Tree repositories + ### Changed - Dropped support for PHP < 7.4 - Dropped support for Symfony < 5.4 +- Dropped support for doctrine/dbal < 3.2 ### Deprecated - Calling `Gedmo\Mapping\Event\Adapter\ORM::getObjectManager()` and `getObject()` on EventArgs that do not implement `getObjectManager()` and `getObject()` (such as old EventArgs implementing `getEntityManager()` and `getEntity()`) diff --git a/composer.json b/composer.json index 2d638e90b8..eda27befa0 100644 --- a/composer.json +++ b/composer.json @@ -53,7 +53,7 @@ }, "require-dev": { "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/dbal": "^3.2", "doctrine/doctrine-bundle": "^2.3", "doctrine/mongodb-odm": "^2.3", "doctrine/orm": "^2.14.0", @@ -69,7 +69,7 @@ "symfony/yaml": "^5.4 || ^6.0" }, "conflict": { - "doctrine/dbal": "<2.13.1 || ^3.0 <3.2", + "doctrine/dbal": "<3.2", "doctrine/mongodb-odm": "<2.3", "doctrine/orm": "<2.14.0 || 2.16.0 || 2.16.1", "sebastian/comparator": "<2.0" diff --git a/example/app/Entity/Repository/CategoryRepository.php b/example/app/Entity/Repository/CategoryRepository.php index e21b8bd5d8..543ea30ee5 100644 --- a/example/app/Entity/Repository/CategoryRepository.php +++ b/example/app/Entity/Repository/CategoryRepository.php @@ -11,8 +11,12 @@ namespace App\Entity\Repository; +use App\Entity\Category; use Gedmo\Tree\Entity\Repository\NestedTreeRepository; +/** + * @template-extends NestedTreeRepository + */ final class CategoryRepository extends NestedTreeRepository { } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 64c4f9f338..77e18b9602 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -616,7 +616,7 @@ parameters: path: tests/Gedmo/Timestampable/Fixture/ArticleCarbon.php - - message: "#^Property Gedmo\\\\Tests\\\\Tree\\\\MaterializedPathODMMongoDBRepositoryTest\\:\\:\\$repo \\(Gedmo\\\\Tree\\\\Document\\\\MongoDB\\\\Repository\\\\MaterializedPathRepository\\) does not accept Doctrine\\\\ORM\\\\EntityRepository\\\\.$#" + message: "#^Property Gedmo\\\\Tests\\\\Tree\\\\MaterializedPathODMMongoDBRepositoryTest\\:\\:\\$repo \\(Gedmo\\\\Tree\\\\Document\\\\MongoDB\\\\Repository\\\\MaterializedPathRepository\\\\) does not accept Doctrine\\\\ORM\\\\EntityRepository\\\\.$#" count: 1 path: tests/Gedmo/Tree/MaterializedPathODMMongoDBRepositoryTest.php diff --git a/src/Mapping/ExtensionMetadataFactory.php b/src/Mapping/ExtensionMetadataFactory.php index 011f29164b..aa66605fed 100644 --- a/src/Mapping/ExtensionMetadataFactory.php +++ b/src/Mapping/ExtensionMetadataFactory.php @@ -12,7 +12,8 @@ use Doctrine\Bundle\DoctrineBundle\Mapping\MappingDriver as DoctrineBundleMappingDriver; use Doctrine\Common\Annotations\Reader; use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as DocumentClassMetadata; -use Doctrine\ORM\Mapping\ClassMetadataInfo as EntityClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadata as EntityClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo as LegacyEntityClassMetadata; use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator; use Doctrine\Persistence\Mapping\Driver\MappingDriver; @@ -95,7 +96,7 @@ public function __construct(ObjectManager $objectManager, string $extensionNames /** * Reads extension metadata * - * @param ClassMetadata&(DocumentClassMetadata|EntityClassMetadata) $meta + * @param ClassMetadata&(DocumentClassMetadata|EntityClassMetadata|LegacyEntityClassMetadata) $meta * * @return array the metatada configuration */ @@ -116,7 +117,7 @@ public function getExtensionMetadata($meta) $class = $this->objectManager->getClassMetadata($parentClass); - assert($class instanceof DocumentClassMetadata || $class instanceof EntityClassMetadata); + assert($class instanceof DocumentClassMetadata || $class instanceof EntityClassMetadata || $class instanceof LegacyEntityClassMetadata); $extendedMetadata = $this->driver->readExtendedMetadata($class, $config); diff --git a/src/Mapping/MappedEventSubscriber.php b/src/Mapping/MappedEventSubscriber.php index d93815a39b..73800fb27c 100644 --- a/src/Mapping/MappedEventSubscriber.php +++ b/src/Mapping/MappedEventSubscriber.php @@ -17,7 +17,8 @@ use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as DocumentClassMetadata; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\ClassMetadataInfo as EntityClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadata as EntityClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo as LegacyEntityClassMetadata; use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory; use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\ObjectManager; @@ -229,7 +230,7 @@ final public function setCacheItemPool(CacheItemPoolInterface $cacheItemPool): v */ public function loadMetadataForObjectClass(ObjectManager $objectManager, $metadata) { - assert($metadata instanceof DocumentClassMetadata || $metadata instanceof EntityClassMetadata); + assert($metadata instanceof DocumentClassMetadata || $metadata instanceof EntityClassMetadata || $metadata instanceof LegacyEntityClassMetadata); $factory = $this->getExtensionMetadataFactory($objectManager); diff --git a/src/References/Mapping/Event/Adapter/ODM.php b/src/References/Mapping/Event/Adapter/ODM.php index 7ca6f30df6..b302171467 100644 --- a/src/References/Mapping/Event/Adapter/ODM.php +++ b/src/References/Mapping/Event/Adapter/ODM.php @@ -11,7 +11,7 @@ use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Proxy\Proxy as ORMProxy; +use Doctrine\Persistence\Proxy as PersistenceProxy; use Gedmo\Mapping\Event\Adapter\ODM as BaseAdapterODM; use Gedmo\References\Mapping\Event\ReferencesAdapter; use ProxyManager\Proxy\GhostObjectInterface; @@ -32,7 +32,7 @@ public function getIdentifier($om, $object, $single = true) } if ($om instanceof EntityManagerInterface) { - if ($object instanceof ORMProxy) { + if ($object instanceof PersistenceProxy) { $id = $om->getUnitOfWork()->getEntityIdentifier($object); } else { $meta = $om->getClassMetadata(get_class($object)); diff --git a/src/References/Mapping/Event/Adapter/ORM.php b/src/References/Mapping/Event/Adapter/ORM.php index 407612f4a3..1f116c122a 100644 --- a/src/References/Mapping/Event/Adapter/ORM.php +++ b/src/References/Mapping/Event/Adapter/ORM.php @@ -12,7 +12,7 @@ use Doctrine\ODM\MongoDB\DocumentManager as MongoDocumentManager; use Doctrine\ODM\PHPCR\DocumentManager as PhpcrDocumentManager; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Proxy\Proxy as ORMProxy; +use Doctrine\Persistence\Proxy as PersistenceProxy; use Gedmo\Exception\InvalidArgumentException; use Gedmo\Mapping\Event\Adapter\ORM as BaseAdapterORM; use Gedmo\References\Mapping\Event\ReferencesAdapter; @@ -79,7 +79,7 @@ public function getSingleReference($om, $class, $identifier) public function extractIdentifier($om, $object, $single = true) { - if ($object instanceof ORMProxy) { + if ($object instanceof PersistenceProxy) { $id = $om->getUnitOfWork()->getEntityIdentifier($object); } else { $meta = $om->getClassMetadata(get_class($object)); diff --git a/src/Tool/Wrapper/EntityWrapper.php b/src/Tool/Wrapper/EntityWrapper.php index d1a4c8cd82..63bbe6187f 100644 --- a/src/Tool/Wrapper/EntityWrapper.php +++ b/src/Tool/Wrapper/EntityWrapper.php @@ -12,7 +12,6 @@ use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Proxy\Proxy; use Doctrine\Persistence\Proxy as PersistenceProxy; /** diff --git a/src/Tree/Document/MongoDB/Repository/AbstractTreeRepository.php b/src/Tree/Document/MongoDB/Repository/AbstractTreeRepository.php index 10cd066590..f86552f840 100644 --- a/src/Tree/Document/MongoDB/Repository/AbstractTreeRepository.php +++ b/src/Tree/Document/MongoDB/Repository/AbstractTreeRepository.php @@ -22,7 +22,11 @@ use Gedmo\Tree\TreeListener; /** - * @phpstan-extends DocumentRepository + * @template T of object + * + * @phpstan-extends DocumentRepository + * + * @phpstan-implements RepositoryInterface */ abstract class AbstractTreeRepository extends DocumentRepository implements RepositoryInterface { @@ -40,6 +44,7 @@ abstract class AbstractTreeRepository extends DocumentRepository implements Repo */ protected $repoUtils; + /** @param ClassMetadata $class */ public function __construct(DocumentManager $em, UnitOfWork $uow, ClassMetadata $class) { parent::__construct($em, $uow, $class); diff --git a/src/Tree/Document/MongoDB/Repository/MaterializedPathRepository.php b/src/Tree/Document/MongoDB/Repository/MaterializedPathRepository.php index b3d87172f5..d135c914db 100644 --- a/src/Tree/Document/MongoDB/Repository/MaterializedPathRepository.php +++ b/src/Tree/Document/MongoDB/Repository/MaterializedPathRepository.php @@ -24,6 +24,10 @@ * * @author Gustavo Falco * @author Gediminas Morkevicius + * + * @template T of object + * + * @template-extends AbstractTreeRepository */ class MaterializedPathRepository extends AbstractTreeRepository { diff --git a/src/Tree/Entity/Repository/AbstractTreeRepository.php b/src/Tree/Entity/Repository/AbstractTreeRepository.php index d2ab20bb7a..d06aded5b5 100644 --- a/src/Tree/Entity/Repository/AbstractTreeRepository.php +++ b/src/Tree/Entity/Repository/AbstractTreeRepository.php @@ -23,7 +23,11 @@ use Gedmo\Tree\TreeListener; /** - * @phpstan-extends EntityRepository + * @template T of object + * + * @template-extends EntityRepository + * + * @template-implements RepositoryInterface */ abstract class AbstractTreeRepository extends EntityRepository implements RepositoryInterface { @@ -41,6 +45,7 @@ abstract class AbstractTreeRepository extends EntityRepository implements Reposi */ protected $repoUtils; + /** @param ClassMetadata $class */ public function __construct(EntityManagerInterface $em, ClassMetadata $class) { parent::__construct($em, $class); diff --git a/src/Tree/Entity/Repository/ClosureTreeRepository.php b/src/Tree/Entity/Repository/ClosureTreeRepository.php index 61677bf7a2..30e6cb081b 100644 --- a/src/Tree/Entity/Repository/ClosureTreeRepository.php +++ b/src/Tree/Entity/Repository/ClosureTreeRepository.php @@ -23,6 +23,10 @@ * * @author Gustavo Adrian * @author Gediminas Morkevicius + * + * @template T of object + * + * @template-extends AbstractTreeRepository */ class ClosureTreeRepository extends AbstractTreeRepository { diff --git a/src/Tree/Entity/Repository/MaterializedPathRepository.php b/src/Tree/Entity/Repository/MaterializedPathRepository.php index 5c8c280e86..88d416d9e6 100644 --- a/src/Tree/Entity/Repository/MaterializedPathRepository.php +++ b/src/Tree/Entity/Repository/MaterializedPathRepository.php @@ -21,6 +21,10 @@ * * @author Gustavo Falco * @author Gediminas Morkevicius + * + * @template T of object + * + * @template-extends AbstractTreeRepository */ class MaterializedPathRepository extends AbstractTreeRepository { diff --git a/src/Tree/Entity/Repository/NestedTreeRepository.php b/src/Tree/Entity/Repository/NestedTreeRepository.php index e7a01dac4d..d894dc682e 100644 --- a/src/Tree/Entity/Repository/NestedTreeRepository.php +++ b/src/Tree/Entity/Repository/NestedTreeRepository.php @@ -10,9 +10,9 @@ namespace Gedmo\Tree\Entity\Repository; use Doctrine\ORM\Exception\ORMException; -use Doctrine\ORM\Proxy\Proxy; use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\Proxy; use Gedmo\Exception\InvalidArgumentException; use Gedmo\Exception\RuntimeException; use Gedmo\Exception\UnexpectedValueException; @@ -28,6 +28,10 @@ * * @author Gediminas Morkevicius * + * @template T of object + * + * @template-extends AbstractTreeRepository + * * @method persistAsFirstChild($node) * @method persistAsFirstChildOf($node, $parent) * @method persistAsLastChild($node) diff --git a/src/Tree/RepositoryInterface.php b/src/Tree/RepositoryInterface.php index 5c4009e834..d6b88f882e 100644 --- a/src/Tree/RepositoryInterface.php +++ b/src/Tree/RepositoryInterface.php @@ -16,6 +16,8 @@ * * @author Gustavo Falco * @author Gediminas Morkevicius + * + * @template T of object */ interface RepositoryInterface extends RepositoryUtilsInterface { @@ -26,6 +28,8 @@ interface RepositoryInterface extends RepositoryUtilsInterface * @param string $direction * * @return iterable + * + * @phpstan-return iterable */ public function getRootNodes($sortByField = null, $direction = 'asc'); @@ -38,6 +42,10 @@ public function getRootNodes($sortByField = null, $direction = 'asc'); * @param bool $includeNode Flag indicating whether the given node should be included in the results * * @return array + * + * @phpstan-param T $node + * + * @phpstan-return iterable */ public function getNodesHierarchy($node = null, $direct = false, array $options = [], $includeNode = false); @@ -53,6 +61,9 @@ public function getNodesHierarchy($node = null, $direct = false, array $options * @return iterable List of children * * @phpstan-param 'asc'|'desc'|'ASC'|'DESC'|array $direction + * @phpstan-param T|null $node + * + * @phpstan-return iterable */ public function getChildren($node = null, $direct = false, $sortByField = null, $direction = 'ASC', $includeNode = false); diff --git a/src/Tree/RepositoryUtils.php b/src/Tree/RepositoryUtils.php index d39e9d6d8e..cad3eafe91 100644 --- a/src/Tree/RepositoryUtils.php +++ b/src/Tree/RepositoryUtils.php @@ -19,10 +19,12 @@ /** * @final since gedmo/doctrine-extensions 3.11 + * + * @template T of object */ class RepositoryUtils implements RepositoryUtilsInterface { - /** @var ClassMetadata */ + /** @var ClassMetadata */ protected $meta; /** @var TreeListener */ @@ -31,7 +33,7 @@ class RepositoryUtils implements RepositoryUtilsInterface /** @var ObjectManager&(DocumentManager|EntityManagerInterface) */ protected $om; - /** @var RepositoryInterface */ + /** @var RepositoryInterface */ protected $repo; /** @@ -44,8 +46,9 @@ class RepositoryUtils implements RepositoryUtilsInterface /** * @param ObjectManager&(DocumentManager|EntityManagerInterface) $om + * @param ClassMetadata $meta * @param TreeListener $listener - * @param RepositoryInterface $repo + * @param RepositoryInterface $repo */ public function __construct(ObjectManager $om, ClassMetadata $meta, $listener, $repo) { @@ -56,7 +59,7 @@ public function __construct(ObjectManager $om, ClassMetadata $meta, $listener, $ } /** - * @return ClassMetadata + * @return ClassMetadata */ public function getClassMetadata() { diff --git a/src/Tree/Strategy/ORM/Nested.php b/src/Tree/Strategy/ORM/Nested.php index a60e2fd74f..fed285638b 100644 --- a/src/Tree/Strategy/ORM/Nested.php +++ b/src/Tree/Strategy/ORM/Nested.php @@ -12,7 +12,7 @@ use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Persistence\Proxy; use Gedmo\Exception\InvalidArgumentException; use Gedmo\Exception\UnexpectedValueException; use Gedmo\Mapping\Event\AdapterInterface; diff --git a/tests/Gedmo/Blameable/Fixture/Document/Article.php b/tests/Gedmo/Blameable/Fixture/Document/Article.php index 367696a7c8..a8973fd6c9 100644 --- a/tests/Gedmo/Blameable/Fixture/Document/Article.php +++ b/tests/Gedmo/Blameable/Fixture/Document/Article.php @@ -36,10 +36,10 @@ class Article private ?string $title = null; /** - * @ODM\ReferenceOne(targetDocument="Type") + * @ODM\ReferenceOne(targetDocument="Gedmo\Tests\Blameable\Fixture\Document\Type") */ #[Odm\ReferenceOne(targetDocument: Type::class)] - private ?\Gedmo\Tests\Blameable\Fixture\Document\Type $type = null; + private ?Type $type = null; /** * @ODM\Field(type="string") @@ -60,7 +60,7 @@ class Article private ?string $updated = null; /** - * @ODM\ReferenceOne(targetDocument="User") + * @ODM\ReferenceOne(targetDocument="Gedmo\Tests\Blameable\Fixture\Document\User") * * @Gedmo\Blameable(on="create") */ diff --git a/tests/Gedmo/Mapping/Fixture/Document/User.php b/tests/Gedmo/Mapping/Fixture/Document/User.php index 29687f3c5d..420bbb9889 100644 --- a/tests/Gedmo/Mapping/Fixture/Document/User.php +++ b/tests/Gedmo/Mapping/Fixture/Document/User.php @@ -12,11 +12,13 @@ namespace Gedmo\Tests\Mapping\Fixture\Document; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; +use Doctrine\ODM\MongoDB\Types\Type; use Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping as Ext; /** * @ODM\Document(collection="test_users") */ +#[ODM\Document(collection: 'test_users')] class User { /** @@ -24,6 +26,7 @@ class User * * @ODM\Id */ + #[ODM\Id] private $id; /** @@ -31,6 +34,8 @@ class User * * @ODM\Field(type="string") */ + #[Ext\Encode(type: 'sha1', secret: 'xxx')] + #[ODM\Field(type: Type::STRING)] private ?string $name = null; /** @@ -38,6 +43,8 @@ class User * * @ODM\Field(type="string") */ + #[Ext\Encode(type: 'md5')] + #[ODM\Field(type: Type::STRING)] private ?string $password = null; public function setName(?string $name): void diff --git a/tests/Gedmo/Mapping/Fixture/MappedSuperClass.php b/tests/Gedmo/Mapping/Fixture/MappedSuperClass.php index c9d59543e5..60592871d4 100644 --- a/tests/Gedmo/Mapping/Fixture/MappedSuperClass.php +++ b/tests/Gedmo/Mapping/Fixture/MappedSuperClass.php @@ -38,6 +38,7 @@ class MappedSuperClass * * @Ext\Encode(type="md5") */ + #[Ext\Encode(type: 'md5')] #[ORM\Column(length: 32)] private ?string $content = null; diff --git a/tests/Gedmo/Mapping/Fixture/User.php b/tests/Gedmo/Mapping/Fixture/User.php index b617783645..fe3949ab33 100644 --- a/tests/Gedmo/Mapping/Fixture/User.php +++ b/tests/Gedmo/Mapping/Fixture/User.php @@ -40,6 +40,7 @@ class User * * @ORM\Column(length=64) */ + #[Ext\Encode(type: 'sha1', secret: 'xxx')] #[ORM\Column(length: 64)] private ?string $name = null; @@ -48,6 +49,7 @@ class User * * @ORM\Column(length=32) */ + #[Ext\Encode(type: 'md5')] #[ORM\Column(length: 32)] private ?string $password = null; diff --git a/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Annotation.php b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Annotation.php index 5a95e1aaaa..1341862561 100644 --- a/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Annotation.php +++ b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Annotation.php @@ -11,26 +11,13 @@ namespace Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping\Driver; -use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\Persistence\Mapping\Driver\MappingDriver; -use Gedmo\Mapping\Driver; +use Gedmo\Mapping\Driver\AbstractAnnotationDriver; use Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping\Encode; -class Annotation implements Driver +class Annotation extends AbstractAnnotationDriver { - /** - * original driver if it is available - * - * @var MappingDriver - */ - protected $_originalDriver; - public function readExtendedMetadata($meta, array &$config) { - $reader = new AnnotationReader(); - // set annotation namespace and alias - // $reader->setAnnotationNamespaceAlias('Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping\\', 'ext'); - $class = $meta->getReflectionClass(); // check only property annotations foreach ($class->getProperties() as $property) { @@ -41,8 +28,9 @@ public function readExtendedMetadata($meta, array &$config) ) { continue; } + // now lets check if property has our annotation - if ($encode = $reader->getPropertyAnnotation($property, Encode::class)) { + if ($encode = $this->reader->getPropertyAnnotation($property, Encode::class)) { $field = $property->getName(); // check if field is mapped if (!$meta->hasField($field)) { @@ -67,12 +55,4 @@ public function readExtendedMetadata($meta, array &$config) return $config; } - - /** - * Passes in the mapping read by original driver - */ - public function setOriginalDriver($driver): void - { - $this->_originalDriver = $driver; - } } diff --git a/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Attribute.php b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Attribute.php new file mode 100644 index 0000000000..fb52e3b5c2 --- /dev/null +++ b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Driver/Attribute.php @@ -0,0 +1,18 @@ + http://www.gediminasm.org + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping\Driver; + +use Gedmo\Mapping\Driver\AttributeDriverInterface; + +class Attribute extends Annotation implements AttributeDriverInterface +{ +} diff --git a/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Encode.php b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Encode.php index 8b3d341c7a..eb6c5ebc1e 100644 --- a/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Encode.php +++ b/tests/Gedmo/Mapping/Mock/Extension/Encoder/Mapping/Encode.php @@ -11,12 +11,15 @@ namespace Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping; -use Doctrine\Common\Annotations\Annotation; +use Gedmo\Mapping\Annotation\Annotation as GedmoAnnotation; /** * @Annotation + * + * @NamedArgumentConstructor */ -final class Encode extends Annotation +#[\Attribute(\Attribute::TARGET_PROPERTY)] +final class Encode implements GedmoAnnotation { /** * @var string @@ -27,4 +30,10 @@ final class Encode extends Annotation * @var string|null */ public $secret; + + public function __construct(string $type = 'md5', ?string $secret = null) + { + $this->type = $type; + $this->secret = $secret; + } } diff --git a/tests/Gedmo/Sluggable/Fixture/Document/Handler/TreeSlug.php b/tests/Gedmo/Sluggable/Fixture/Document/Handler/TreeSlug.php index e116dda904..c9a4545138 100644 --- a/tests/Gedmo/Sluggable/Fixture/Document/Handler/TreeSlug.php +++ b/tests/Gedmo/Sluggable/Fixture/Document/Handler/TreeSlug.php @@ -54,10 +54,10 @@ class TreeSlug private $alias; /** - * @ODM\ReferenceOne(targetDocument="TreeSlug") + * @ODM\ReferenceOne(targetDocument="Gedmo\Tests\Sluggable\Fixture\Document\Handler\TreeSlug") */ #[ODM\ReferenceOne(targetDocument: self::class)] - private ?\Gedmo\Tests\Sluggable\Fixture\Document\Handler\TreeSlug $parent = null; + private ?TreeSlug $parent = null; public function setParent(?self $parent = null): void { diff --git a/tests/Gedmo/Sortable/Fixture/CustomerType.php b/tests/Gedmo/Sortable/Fixture/CustomerType.php index 7fb77bbfa0..9492aa443a 100644 --- a/tests/Gedmo/Sortable/Fixture/CustomerType.php +++ b/tests/Gedmo/Sortable/Fixture/CustomerType.php @@ -14,7 +14,6 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Driver\PDO\Exception as PDODriverException; -use Doctrine\DBAL\Driver\PDOException as LegacyPDOException; use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; @@ -124,12 +123,6 @@ public function postRemove(): void $pdoException = new \PDOException('SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails', 23000); - // @todo: This check can be removed when dropping support for doctrine/dbal 2.x. - if (class_exists(LegacyPDOException::class)) { - // @phpstan-ignore-next-line - throw new ForeignKeyConstraintViolationException(sprintf('An exception occurred while deleting the customer type with id %s.', $this->getId()), new LegacyPDOException($pdoException)); - } - throw new ForeignKeyConstraintViolationException(PDODriverException::new($pdoException), null); } } diff --git a/tests/Gedmo/Timestampable/TimestampableTest.php b/tests/Gedmo/Timestampable/TimestampableTest.php index 46bc8f49b0..47fe59e62e 100644 --- a/tests/Gedmo/Timestampable/TimestampableTest.php +++ b/tests/Gedmo/Timestampable/TimestampableTest.php @@ -12,8 +12,7 @@ namespace Gedmo\Tests\Timestampable; use Doctrine\Common\EventManager; -use Doctrine\ORM\Proxy\Proxy; -use Gedmo\Tests\Mapping\Fixture\Xml\Timestampable; +use Doctrine\Persistence\Proxy; use Gedmo\Tests\Timestampable\Fixture\Article; use Gedmo\Tests\Timestampable\Fixture\Author; use Gedmo\Tests\Timestampable\Fixture\Comment; diff --git a/tests/Gedmo/Tool/BaseTestCaseMongoODM.php b/tests/Gedmo/Tool/BaseTestCaseMongoODM.php index cd9dda45cf..0d31c5d59f 100644 --- a/tests/Gedmo/Tool/BaseTestCaseMongoODM.php +++ b/tests/Gedmo/Tool/BaseTestCaseMongoODM.php @@ -99,6 +99,10 @@ protected function getMockMappedDocumentManager(?EventManager $evm = null, ?Conf */ protected function getMetadataDriverImplementation(): MappingDriver { + if (PHP_VERSION_ID >= 80000) { + return new AttributeDriver(); + } + return new AnnotationDriver($_ENV['annotation_reader']); } diff --git a/tests/Gedmo/Tool/BaseTestCaseORM.php b/tests/Gedmo/Tool/BaseTestCaseORM.php index 1bb864253f..3e77c9d360 100644 --- a/tests/Gedmo/Tool/BaseTestCaseORM.php +++ b/tests/Gedmo/Tool/BaseTestCaseORM.php @@ -12,7 +12,6 @@ namespace Gedmo\Tests\Tool; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Driver; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Logging\Middleware; use Doctrine\ORM\Configuration; @@ -28,9 +27,7 @@ use Gedmo\Timestampable\TimestampableListener; use Gedmo\Translatable\TranslatableListener; use Gedmo\Tree\TreeListener; -use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Psr\Log\LoggerInterface; /** * Base test case contains common mock objects @@ -41,24 +38,13 @@ */ abstract class BaseTestCaseORM extends TestCase { - /** - * @var EntityManager|null - */ - protected $em; + protected ?EntityManager $em = null; - /** - * @var QueryAnalyzer - */ - protected $queryAnalyzer; - - /** - * @var MockObject&LoggerInterface - */ - protected $queryLogger; + protected QueryLogger $queryLogger; protected function setUp(): void { - $this->queryLogger = $this->createMock(LoggerInterface::class); + $this->queryLogger = new QueryLogger(); } /** @@ -86,22 +72,6 @@ protected function getDefaultMockSqliteEntityManager(?EventManager $evm = null, return $this->em = $em; } - /** - * TODO: Remove this method when dropping support of doctrine/dbal 2. - * - * Starts query statistic log - * - * @throws \RuntimeException - */ - protected function startQueryLog(): void - { - if (null === $this->em) { - throw new \RuntimeException('EntityManager must be initialized.'); - } - $this->queryAnalyzer = new QueryAnalyzer($this->em->getConnection()->getDatabasePlatform()); - $this->em->getConfiguration()->setSQLLogger($this->queryAnalyzer); - } - /** * Creates default mapping driver */ @@ -129,13 +99,9 @@ protected function getDefaultConfiguration(): Configuration $config->setProxyDir(TESTS_TEMP_DIR); $config->setProxyNamespace('Proxy'); $config->setMetadataDriverImpl($this->getMetadataDriverImplementation()); - - // TODO: Remove the "if" check when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $config->setMiddlewares([ - new Middleware($this->queryLogger), - ]); - } + $config->setMiddlewares([ + new Middleware($this->queryLogger), + ]); return $config; } diff --git a/tests/Gedmo/Tool/QueryAnalyzer.php b/tests/Gedmo/Tool/QueryAnalyzer.php deleted file mode 100644 index 30f23ed90d..0000000000 --- a/tests/Gedmo/Tool/QueryAnalyzer.php +++ /dev/null @@ -1,133 +0,0 @@ - http://www.gediminasm.org - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Gedmo\Tests\Tool; - -use Doctrine\DBAL\Logging\SQLLogger; -use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\Type; - -/** - * TODO: Remove it when dropping support of doctrine/dbal 2 - * - * @author Gediminas Morkevicius - */ -final class QueryAnalyzer implements SQLLogger -{ - /** - * Used database platform - */ - private AbstractPlatform $platform; - - /** - * List of queries executed - * - * @var string[] - */ - private $queries = []; - - public function __construct(AbstractPlatform $platform) - { - $this->platform = $platform; - } - - public function startQuery($sql, ?array $params = null, ?array $types = null): void - { - $this->queries[] = $this->generateSql($sql, $params, $types); - } - - public function stopQuery(): void - { - } - - public function cleanUp(): self - { - $this->queries = []; - - return $this; - } - - /** - * @return string[] - */ - public function getExecutedQueries(): array - { - return $this->queries; - } - - public function getNumExecutedQueries(): int - { - return count($this->queries); - } - - /** - * Create the SQL with mapped parameters - * - * @param array|null $params - * @param array|null $types - */ - private function generateSql(string $sql, ?array $params, ?array $types): string - { - if (null === $params || [] === $params) { - return $sql; - } - $converted = $this->getConvertedParams($params, $types); - if (is_int(key($params))) { - $index = key($converted); - $sql = preg_replace_callback('@\?@sm', static function ($match) use (&$index, $converted) { - return $converted[$index++]; - }, $sql); - } else { - foreach ($converted as $key => $value) { - $sql = str_replace(':'.$key, $value, $sql); - } - } - - return $sql; - } - - /** - * Get the converted parameter list - * - * @param array $params - * @param array $types - * - * @return array - */ - private function getConvertedParams(array $params, array $types): array - { - $result = []; - foreach ($params as $position => $value) { - if (isset($types[$position])) { - $type = $types[$position]; - if (is_string($type)) { - $type = Type::getType($type); - } - if ($type instanceof Type) { - $value = $type->convertToDatabaseValue($value, $this->platform); - } - } else { - if ($value instanceof \DateTimeInterface) { - $value = $value->format($this->platform->getDateTimeFormatString()); - } elseif (null !== $value) { - $type = Type::getType(gettype($value)); - $value = $type->convertToDatabaseValue($value, $this->platform); - } - } - if (is_string($value)) { - $value = "'{$value}'"; - } elseif (null === $value) { - $value = 'NULL'; - } - $result[$position] = $value; - } - - return $result; - } -} diff --git a/tests/Gedmo/Tool/QueryLogger.php b/tests/Gedmo/Tool/QueryLogger.php new file mode 100644 index 0000000000..760a2b14db --- /dev/null +++ b/tests/Gedmo/Tool/QueryLogger.php @@ -0,0 +1,38 @@ + http://www.gediminasm.org + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gedmo\Tests\Tool; + +use Psr\Log\AbstractLogger; + +final class QueryLogger extends AbstractLogger +{ + /** @var array */ + public array $queries = []; + + /** + * @param mixed $level + * @param string $message + * @param mixed[] $context + */ + public function log($level, $message, array $context = []): void + { + $this->queries[] = [ + 'message' => $message, + 'context' => $context, + ]; + } + + public function reset(): void + { + $this->queries = []; + } +} diff --git a/tests/Gedmo/Translatable/Issue/Issue84Test.php b/tests/Gedmo/Translatable/Issue/Issue84Test.php index a7e465764e..ae2628ff16 100644 --- a/tests/Gedmo/Translatable/Issue/Issue84Test.php +++ b/tests/Gedmo/Translatable/Issue/Issue84Test.php @@ -12,7 +12,7 @@ namespace Gedmo\Tests\Translatable\Issue; use Doctrine\Common\EventManager; -use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Persistence\Proxy; use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Translatable\Fixture\Article; use Gedmo\Translatable\Entity\Translation; diff --git a/tests/Gedmo/Translatable/PersonalTranslationTest.php b/tests/Gedmo/Translatable/PersonalTranslationTest.php index 9f316510c5..c218a1b14e 100644 --- a/tests/Gedmo/Translatable/PersonalTranslationTest.php +++ b/tests/Gedmo/Translatable/PersonalTranslationTest.php @@ -12,7 +12,6 @@ namespace Gedmo\Tests\Translatable; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Logging\Middleware; use Doctrine\DBAL\ParameterType; use Doctrine\ORM\Query; use Gedmo\Tests\Tool\BaseTestCaseORM; @@ -68,35 +67,29 @@ public function testShouldTranslateTheRecord(): void $this->populate(); $this->translatableListener->setTranslatableLocale('lt'); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(2)) - ->method('debug') - ->withConsecutive( - ['Executing statement: {sql} (parameters: {params}, types: {types})', [ - 'sql' => 'SELECT t0.id AS id_1, t0.title AS title_2 FROM Article t0 WHERE t0.id = ?', - 'params' => [1 => 1], - 'types' => [1 => ParameterType::INTEGER], - ]], - ['Executing statement: {sql} (parameters: {params}, types: {types})', [ - 'sql' => 'SELECT t0.id AS id_1, t0.locale AS locale_2, t0.field AS field_3, t0.content AS content_4, t0.object_id AS object_id_5 FROM article_translations t0 WHERE t0.object_id = ?', - 'params' => [1 => 1], - 'types' => [1 => ParameterType::INTEGER], - ]] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); $article = $this->em->find(self::ARTICLE, ['id' => 1]); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - $sqlQueriesExecuted = $this->queryAnalyzer->getExecutedQueries(); - static::assertCount(2, $sqlQueriesExecuted); - static::assertSame('SELECT t0.id AS id_1, t0.locale AS locale_2, t0.field AS field_3, t0.content AS content_4, t0.object_id AS object_id_5 FROM article_translations t0 WHERE t0.object_id = 1', $sqlQueriesExecuted[1]); - } + static::assertCount(2, $this->queryLogger->queries); + + static::assertSame([ + 'message' => 'Executing statement: {sql} (parameters: {params}, types: {types})', + 'context' => [ + 'sql' => 'SELECT t0.id AS id_1, t0.title AS title_2 FROM Article t0 WHERE t0.id = ?', + 'params' => [1 => 1], + 'types' => [1 => ParameterType::INTEGER], + ], + ], $this->queryLogger->queries[0]); + + static::assertSame([ + 'message' => 'Executing statement: {sql} (parameters: {params}, types: {types})', + 'context' => [ + 'sql' => 'SELECT t0.id AS id_1, t0.locale AS locale_2, t0.field AS field_3, t0.content AS content_4, t0.object_id AS object_id_5 FROM article_translations t0 WHERE t0.object_id = ?', + 'params' => [1 => 1], + 'types' => [1 => ParameterType::INTEGER], + ], + ], $this->queryLogger->queries[1]); static::assertSame('lt', $article->getTitle()); } @@ -191,29 +184,7 @@ public function testShouldFindFromIdentityMap(): void $this->em->persist($article); $this->em->flush(); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(3)) - ->method('debug') - ->withConsecutive( - ['Beginning transaction'], - ['Executing statement: {sql} (parameters: {params}, types: {types})', [ - 'sql' => 'UPDATE article_translations SET content = ? WHERE id = ?', - 'params' => [ - 1 => 'change lt', - 2 => 1, - ], - 'types' => [ - 1 => ParameterType::STRING, - 2 => ParameterType::INTEGER, - ], - ]], - ['Committing transaction'] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); $this->translatableListener->setTranslatableLocale('lt'); $article->setTitle('change lt'); @@ -221,12 +192,32 @@ public function testShouldFindFromIdentityMap(): void $this->em->persist($article); $this->em->flush(); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - $sqlQueriesExecuted = $this->queryAnalyzer->getExecutedQueries(); - static::assertCount(3, $sqlQueriesExecuted); // one update, transaction start - commit - static::assertSame("UPDATE article_translations SET content = 'change lt' WHERE id = 1", $sqlQueriesExecuted[1]); - } + static::assertCount(3, $this->queryLogger->queries); + + static::assertSame([ + 'message' => 'Beginning transaction', + 'context' => [], + ], $this->queryLogger->queries[0]); + + static::assertSame([ + 'message' => 'Executing statement: {sql} (parameters: {params}, types: {types})', + 'context' => [ + 'sql' => 'UPDATE article_translations SET content = ? WHERE id = ?', + 'params' => [ + 1 => 'change lt', + 2 => 1, + ], + 'types' => [ + 1 => ParameterType::STRING, + 2 => ParameterType::INTEGER, + ], + ], + ], $this->queryLogger->queries[1]); + + static::assertSame([ + 'message' => 'Committing transaction', + 'context' => [], + ], $this->queryLogger->queries[2]); } public function testShouldBeAbleToUseTranslationQueryHint(): void @@ -239,31 +230,21 @@ public function testShouldBeAbleToUseTranslationQueryHint(): void ->setHint(TranslatableListener::HINT_TRANSLATABLE_LOCALE, 'lt') ; - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(1)) - ->method('debug') - ->withConsecutive( - ['Executing query: {sql}', [ - 'sql' => "SELECT CAST(t1_.content AS VARCHAR(128)) AS title_0 FROM Article a0_ LEFT JOIN article_translations t1_ ON t1_.locale = 'lt' AND t1_.field = 'title' AND t1_.object_id = a0_.id", - ]] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); $result = $query->getArrayResult(); static::assertCount(1, $result); static::assertSame('lt', $result[0]['title']); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - $sqlQueriesExecuted = $this->queryAnalyzer->getExecutedQueries(); - static::assertCount(1, $sqlQueriesExecuted); - static::assertSame("SELECT CAST(t1_.content AS VARCHAR(128)) AS title_0 FROM Article a0_ LEFT JOIN article_translations t1_ ON t1_.locale = 'lt' AND t1_.field = 'title' AND t1_.object_id = a0_.id", $sqlQueriesExecuted[0]); - } + static::assertCount(1, $this->queryLogger->queries); + + static::assertSame([ + 'message' => 'Executing query: {sql}', + 'context' => [ + 'sql' => "SELECT CAST(t1_.content AS VARCHAR(128)) AS title_0 FROM Article a0_ LEFT JOIN article_translations t1_ ON t1_.locale = 'lt' AND t1_.field = 'title' AND t1_.object_id = a0_.id", + ], + ], $this->queryLogger->queries[0]); } protected function getUsedEntityFixtures(): array diff --git a/tests/Gedmo/Translatable/TranslationQueryWalkerTest.php b/tests/Gedmo/Translatable/TranslationQueryWalkerTest.php index f1e533f3e7..554899e4f6 100644 --- a/tests/Gedmo/Translatable/TranslationQueryWalkerTest.php +++ b/tests/Gedmo/Translatable/TranslationQueryWalkerTest.php @@ -12,7 +12,6 @@ namespace Gedmo\Tests\Translatable; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Logging\Middleware; use Doctrine\ORM\Query; use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Translatable\Fixture\Article; @@ -146,27 +145,13 @@ public function testShouldSelectWithTranslationFallbackOnSimpleObjectHydration() $this->translatableListener->setTranslatableLocale('ru_ru'); $this->translatableListener->setTranslationFallback(false); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(2)) - ->method('debug') - ->withConsecutive( - ['Executing query: {sql}'], - ['Executing query: {sql}'] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); // simple object hydration $result = $q->getResult(Query::HYDRATE_SIMPLEOBJECT); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - $this->queryAnalyzer->cleanUp(); - } + static::assertCount(1, $this->queryLogger->queries); + $this->queryLogger->reset(); static::assertNull($result[0]->getTitle()); static::assertNull($result[0]->getContent()); @@ -175,10 +160,7 @@ public function testShouldSelectWithTranslationFallbackOnSimpleObjectHydration() $result = $q->getResult(Query::HYDRATE_SIMPLEOBJECT); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - } + static::assertCount(1, $this->queryLogger->queries); // Default translation is en_us, so we expect the results in that locale static::assertSame('Food', $result[0]->getTitle()); @@ -195,27 +177,13 @@ public function testSelectWithTranslationFallbackOnArrayHydration(): void $this->translatableListener->setTranslatableLocale('ru_ru'); $this->translatableListener->setTranslationFallback(false); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(2)) - ->method('debug') - ->withConsecutive( - ['Executing query: {sql}'], - ['Executing query: {sql}'] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); // array hydration $result = $q->getArrayResult(); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - $this->queryAnalyzer->cleanUp(); - } + static::assertCount(1, $this->queryLogger->queries); + $this->queryLogger->reset(); static::assertNull($result[0]['title']); static::assertNull($result[0]['content']); @@ -224,10 +192,7 @@ public function testSelectWithTranslationFallbackOnArrayHydration(): void $result = $q->getArrayResult(); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - } + static::assertCount(1, $this->queryLogger->queries); // Default translation is en_us, so we expect the results in that locale static::assertSame('Food', $result[0]['title']); @@ -248,27 +213,13 @@ public function testSelectWithOptionalFallbackOnSimpleObjectHydration(): void $this->translatableListener->setTranslatableLocale('ru_ru'); $this->translatableListener->setTranslationFallback(false); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(2)) - ->method('debug') - ->withConsecutive( - ['Executing query: {sql}'], - ['Executing query: {sql}'] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); // simple object hydration $result = $q->getResult(Query::HYDRATE_SIMPLEOBJECT); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - $this->queryAnalyzer->cleanUp(); - } + static::assertCount(1, $this->queryLogger->queries); + $this->queryLogger->reset(); static::assertNull($result[0]->getTitle()); static::assertSame('John Doe', $result[0]->getAuthor()); // optional fallback is true, force fallback @@ -277,10 +228,7 @@ public function testSelectWithOptionalFallbackOnSimpleObjectHydration(): void $this->translatableListener->setTranslationFallback(true); $result = $q->getResult(Query::HYDRATE_SIMPLEOBJECT); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - } + static::assertCount(1, $this->queryLogger->queries); // Default translation is en_us, so we expect the results in that locale static::assertSame('Food', $result[0]->getTitle()); @@ -361,29 +309,13 @@ public function testShouldSelectWithTranslationFallbackOnObjectHydration(): void $this->translatableListener->setTranslatableLocale('ru_ru'); $this->translatableListener->setTranslationFallback(false); - // TODO: Remove the "if" check and "else" body when dropping support of doctrine/dbal 2. - if (class_exists(Middleware::class)) { - $this->queryLogger - ->expects(static::exactly(4)) - ->method('debug') - ->withConsecutive( - ['Executing query: {sql}'], - ['Executing query: {sql}'], - ['Executing query: {sql}'], - ['Executing query: {sql}'] - ); - } else { - $this->startQueryLog(); - } + $this->queryLogger->reset(); // object hydration $result = $q->getResult(); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - $this->queryAnalyzer->cleanUp(); - } + static::assertCount(1, $this->queryLogger->queries); + $this->queryLogger->reset(); static::assertNull($result[0]->getTitle()); static::assertNull($result[0]->getContent()); @@ -391,10 +323,7 @@ public function testShouldSelectWithTranslationFallbackOnObjectHydration(): void $this->translatableListener->setTranslationFallback(true); $result = $q->getResult(); - // TODO: Remove the "if" block when dropping support of doctrine/dbal 2. - if (!class_exists(Middleware::class)) { - static::assertSame(1, $this->queryAnalyzer->getNumExecutedQueries()); - } + static::assertCount(1, $this->queryLogger->queries); // Default translation is en_us, so we expect the results in that locale static::assertSame('Food', $result[0]->getTitle()); diff --git a/tests/Gedmo/Tree/Fixture/Document/Article.php b/tests/Gedmo/Tree/Fixture/Document/Article.php index 465457b20f..2f47ab76c6 100644 --- a/tests/Gedmo/Tree/Fixture/Document/Article.php +++ b/tests/Gedmo/Tree/Fixture/Document/Article.php @@ -56,11 +56,11 @@ class Article /** * @Gedmo\TreeParent * - * @Mongo\ReferenceOne(targetDocument="Article") + * @Mongo\ReferenceOne(targetDocument="Gedmo\Tests\Tree\Fixture\Document\Article") */ #[Mongo\ReferenceOne(targetDocument: self::class)] #[Gedmo\TreeParent] - private ?\Gedmo\Tests\Tree\Fixture\Document\Article $parent = null; + private ?Article $parent = null; /** * @var int|null diff --git a/tests/Gedmo/Tree/Fixture/Repository/BehavioralCategoryRepository.php b/tests/Gedmo/Tree/Fixture/Repository/BehavioralCategoryRepository.php index f1e1d2e65f..a3ce3ff266 100644 --- a/tests/Gedmo/Tree/Fixture/Repository/BehavioralCategoryRepository.php +++ b/tests/Gedmo/Tree/Fixture/Repository/BehavioralCategoryRepository.php @@ -11,8 +11,12 @@ namespace Gedmo\Tests\Tree\Fixture\Repository; +use Gedmo\Tests\Tree\Fixture\BehavioralCategory; use Gedmo\Tree\Entity\Repository\NestedTreeRepository; +/** + * @template-extends NestedTreeRepository + */ final class BehavioralCategoryRepository extends NestedTreeRepository { } diff --git a/tests/Gedmo/Tree/MaterializedPathODMMongoDBRepositoryTest.php b/tests/Gedmo/Tree/MaterializedPathODMMongoDBRepositoryTest.php index 71f0fe3a6c..4476405fd0 100644 --- a/tests/Gedmo/Tree/MaterializedPathODMMongoDBRepositoryTest.php +++ b/tests/Gedmo/Tree/MaterializedPathODMMongoDBRepositoryTest.php @@ -30,9 +30,9 @@ final class MaterializedPathODMMongoDBRepositoryTest extends BaseTestCaseMongoOD private const CATEGORY = Category::class; /** - * @var MaterializedPathRepository + * @var MaterializedPathRepository */ - protected $repo; + private MaterializedPathRepository $repo; protected function setUp(): void { diff --git a/tests/Gedmo/Tree/MaterializedPathORMRepositoryTest.php b/tests/Gedmo/Tree/MaterializedPathORMRepositoryTest.php index 1abc6aff04..1f244d9981 100644 --- a/tests/Gedmo/Tree/MaterializedPathORMRepositoryTest.php +++ b/tests/Gedmo/Tree/MaterializedPathORMRepositoryTest.php @@ -12,6 +12,7 @@ namespace Gedmo\Tests\Tree; use Doctrine\Common\EventManager; +use Doctrine\Persistence\Proxy; use Gedmo\Exception\InvalidArgumentException; use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Tree\Fixture\MPCategory; @@ -30,8 +31,8 @@ final class MaterializedPathORMRepositoryTest extends BaseTestCaseORM private const CATEGORY = MPCategory::class; private const CATEGORY_WITH_TRIMMED_SEPARATOR = MPCategoryWithTrimmedSeparator::class; - /** @var MaterializedPathRepository */ - protected $repo; + /** @var MaterializedPathRepository */ + private MaterializedPathRepository $repo; private TreeListener $listener; @@ -147,11 +148,11 @@ public function testGetChildrenForEntityWithTrimmedSeparators(): void { $this->populate(self::CATEGORY_WITH_TRIMMED_SEPARATOR); - $this->repo = $this->em->getRepository(self::CATEGORY_WITH_TRIMMED_SEPARATOR); - $root = $this->repo->findOneBy(['title' => 'Food']); + $repo = $this->em->getRepository(self::CATEGORY_WITH_TRIMMED_SEPARATOR); + $root = $repo->findOneBy(['title' => 'Food']); // Get all children from the root, NOT including it - $result = $this->repo->getChildren($root, false, 'title'); + $result = $repo->getChildren($root, false, 'title'); static::assertCount(4, $result); static::assertSame('Carrots', $result[0]->getTitle()); @@ -160,7 +161,7 @@ public function testGetChildrenForEntityWithTrimmedSeparators(): void static::assertSame('Vegitables', $result[3]->getTitle()); // Get all children from the root, including it - $result = $this->repo->getChildren($root, false, 'title', 'asc', true); + $result = $repo->getChildren($root, false, 'title', 'asc', true); static::assertCount(5, $result); static::assertSame('Carrots', $result[0]->getTitle()); @@ -170,13 +171,13 @@ public function testGetChildrenForEntityWithTrimmedSeparators(): void static::assertSame('Vegitables', $result[4]->getTitle()); // Get direct children from the root, NOT including it - $result = $this->repo->getChildren($root, true, 'title', 'asc'); + $result = $repo->getChildren($root, true, 'title', 'asc'); static::assertCount(2, $result); static::assertSame('Fruits', $result[0]->getTitle()); static::assertSame('Vegitables', $result[1]->getTitle()); // Get direct children from the root, including it - $result = $this->repo->getChildren($root, true, 'title', 'asc', true); + $result = $repo->getChildren($root, true, 'title', 'asc', true); static::assertCount(3, $result); static::assertSame('Food', $result[0]->getTitle()); @@ -184,7 +185,7 @@ public function testGetChildrenForEntityWithTrimmedSeparators(): void static::assertSame('Vegitables', $result[2]->getTitle()); // Get ALL nodes - $result = $this->repo->getChildren(null, false, 'title'); + $result = $repo->getChildren(null, false, 'title'); static::assertCount(9, $result); static::assertSame('Best Whisky', $result[0]->getTitle()); @@ -198,7 +199,7 @@ public function testGetChildrenForEntityWithTrimmedSeparators(): void static::assertSame('Whisky', $result[8]->getTitle()); // Get ALL root nodes - $result = $this->repo->getChildren(null, true, 'title'); + $result = $repo->getChildren(null, true, 'title'); static::assertCount(3, $result); static::assertSame('Drinks', $result[0]->getTitle()); @@ -334,6 +335,7 @@ public function testIssue458(): void $newNode = $this->createCategory(); $parent = $node->getParent(); + static::assertInstanceOf(Proxy::class, $parent); static::assertFalse($parent->__isInitialized()); $newNode->setTitle('New Node'); diff --git a/tests/Gedmo/Tree/NestedTreeRootRepositoryTest.php b/tests/Gedmo/Tree/NestedTreeRootRepositoryTest.php index 41dc4a68eb..9b8c853a90 100644 --- a/tests/Gedmo/Tree/NestedTreeRootRepositoryTest.php +++ b/tests/Gedmo/Tree/NestedTreeRootRepositoryTest.php @@ -255,7 +255,6 @@ public function testShouldRemoveRootNodeFromTree(): void */ public function testGetPathAsStringWithInvalidStringMethod($stringMethod): void { - /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(self::CATEGORY); $carrots = $repo->findOneBy(['title' => 'Carrots']); @@ -278,7 +277,7 @@ public static function invalidStringMethods(): iterable public function testShouldHandleBasicRepositoryMethods(): void { - /** @var NestedTreeRepository $repo */ + /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(self::CATEGORY); $carrots = $repo->findOneBy(['title' => 'Carrots']); @@ -330,7 +329,7 @@ public function testShouldHandleBasicRepositoryMethods(): void public function testShouldHandleAdvancedRepositoryFunctions(): void { $this->populateMore(); - /** @var NestedTreeRepository $repo */ + /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(self::CATEGORY); // verification diff --git a/tests/Gedmo/Tree/NestedTreeRootTest.php b/tests/Gedmo/Tree/NestedTreeRootTest.php index 24b97b1c0b..247b2de40b 100644 --- a/tests/Gedmo/Tree/NestedTreeRootTest.php +++ b/tests/Gedmo/Tree/NestedTreeRootTest.php @@ -16,7 +16,6 @@ use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Tree\Fixture\ForeignRootCategory; use Gedmo\Tests\Tree\Fixture\RootCategory; -use Gedmo\Tree\Entity\Repository\NestedTreeRepository; use Gedmo\Tree\TreeListener; /** @@ -332,7 +331,6 @@ public function testRemoval(): void public function testTreeWithRootPointingAtAnotherTable(): void { // depopulate, i don't want the other stuff in db - /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(ForeignRootCategory::class); $all = $repo->findAll(); foreach ($all as $one) { diff --git a/tests/Gedmo/Tree/TreeObjectHydratorTest.php b/tests/Gedmo/Tree/TreeObjectHydratorTest.php index a10069f8cc..4a34172972 100644 --- a/tests/Gedmo/Tree/TreeObjectHydratorTest.php +++ b/tests/Gedmo/Tree/TreeObjectHydratorTest.php @@ -12,7 +12,6 @@ namespace Gedmo\Tests\Tree; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\Query; use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Tree\Fixture\Category; @@ -48,8 +47,7 @@ public function testFullTreeHydration(): void $this->populate(); $this->em->clear(); - $stack = new DebugStack(); - $this->em->getConfiguration()->setSQLLogger($stack); + $this->queryLogger->reset(); $repo = $this->em->getRepository(self::ROOT_CATEGORY); @@ -90,7 +88,7 @@ public function testFullTreeHydration(): void static::assertCount(0, $citrons->getChildren()); // Make sure only one query was executed - static::assertCount(1, $stack->queries); + static::assertCount(1, $this->queryLogger->queries); } public function testPartialTreeHydration(): void @@ -98,10 +96,9 @@ public function testPartialTreeHydration(): void $this->populate(); $this->em->clear(); - $stack = new DebugStack(); - $this->em->getConfiguration()->setSQLLogger($stack); + $this->queryLogger->reset(); - /** @var NestedTreeRepository $repo */ + /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(self::ROOT_CATEGORY); $fruits = $repo->findOneBy(['title' => 'Fruits']); @@ -124,7 +121,7 @@ public function testPartialTreeHydration(): void static::assertSame('Citrons', $citrons->getTitle()); static::assertCount(0, $citrons->getChildren()); - static::assertCount(2, $stack->queries); + static::assertCount(2, $this->queryLogger->queries); } public function testMultipleRootNodesTreeHydration(): void @@ -132,10 +129,9 @@ public function testMultipleRootNodesTreeHydration(): void $this->populate(); $this->em->clear(); - $stack = new DebugStack(); - $this->em->getConfiguration()->setSQLLogger($stack); + $this->queryLogger->reset(); - /** @var NestedTreeRepository $repo */ + /** @var NestedTreeRepository $repo */ $repo = $this->em->getRepository(self::ROOT_CATEGORY); $food = $repo->findOneBy(['title' => 'Food']); @@ -170,7 +166,7 @@ public function testMultipleRootNodesTreeHydration(): void static::assertSame('Citrons', $citrons->getTitle()); static::assertCount(0, $citrons->getChildren()); - static::assertCount(2, $stack->queries); + static::assertCount(2, $this->queryLogger->queries); } protected function getUsedEntityFixtures(): array diff --git a/tests/Gedmo/Wrapper/EntityWrapperTest.php b/tests/Gedmo/Wrapper/EntityWrapperTest.php index 1ee6d359db..8c7cce50d9 100644 --- a/tests/Gedmo/Wrapper/EntityWrapperTest.php +++ b/tests/Gedmo/Wrapper/EntityWrapperTest.php @@ -12,7 +12,7 @@ namespace Gedmo\Tests\Wrapper; use Doctrine\Common\EventManager; -use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Persistence\Proxy; use Gedmo\Tests\Tool\BaseTestCaseORM; use Gedmo\Tests\Wrapper\Fixture\Entity\Article; use Gedmo\Tests\Wrapper\Fixture\Entity\Composite;