diff --git a/src/Infrastructure/Persistence/Doctrine/Repository/ClassRepository.php b/src/Infrastructure/Persistence/Doctrine/Repository/ClassRepository.php index 1e5de6cb..bf77c1fd 100644 --- a/src/Infrastructure/Persistence/Doctrine/Repository/ClassRepository.php +++ b/src/Infrastructure/Persistence/Doctrine/Repository/ClassRepository.php @@ -13,9 +13,13 @@ use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Entity\Class_ as ClassEntity; use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\ClassHydrator; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use function version_compare; +use const PHP_VERSION; + /** * @since Release 3.2.0 * @author Laurent Laville @@ -52,7 +56,19 @@ public function getAll(): array */ public function getClassByName(string $name, bool $isInterface): ?Class_ { - $entity = $this->repository->findOneBy(['name' => $name, 'isInterface' => $isInterface]); + $criteria = new Criteria(); + $criteria->where(Criteria::expr()->eq('name', $name)); + $criteria->andWhere(Criteria::expr()->eq('isInterface', $isInterface)); + $criteria->orderBy(['phpMin' => 'desc']); + + $collection = $this->repository->matching($criteria); + + $entity = $collection->isEmpty() + ? null + : $collection->filter( + fn($function) => version_compare($function->getPhpMin(), PHP_VERSION, 'le') + )->first() + ; if (null === $entity) { // class does not exist diff --git a/src/Infrastructure/Persistence/Doctrine/Repository/ConstantRepository.php b/src/Infrastructure/Persistence/Doctrine/Repository/ConstantRepository.php index a66b9e58..94ce5307 100644 --- a/src/Infrastructure/Persistence/Doctrine/Repository/ConstantRepository.php +++ b/src/Infrastructure/Persistence/Doctrine/Repository/ConstantRepository.php @@ -13,9 +13,13 @@ use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Entity\Constant_ as ConstantEntity; use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\ConstantHydrator; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use function version_compare; +use const PHP_VERSION; + /** * @since Release 3.2.0 * @author Laurent Laville @@ -52,17 +56,26 @@ public function getAll(): array */ public function getConstantByName(string $name, ?string $declaringClass): ?Constant_ { + $criteria = new Criteria(); + if (strpos($name, '\\') === false) { // standard constant should be uppercase in database - $criteria = ['name' => strtoupper($name)]; + $criteria->where(Criteria::expr()->eq('name', strtoupper($name))); } else { // special case for constants that have namespace like in ast extension - $criteria = ['name' => $name]; - } - if ($declaringClass !== null) { - $criteria['declaringClass'] = $declaringClass; + $criteria->where(Criteria::expr()->eq('name', $name)); } - $entity = $this->repository->findOneBy($criteria); + $criteria->andWhere(Criteria::expr()->eq('declaringClass', $declaringClass)); + $criteria->orderBy(['phpMin' => 'desc']); + + $collection = $this->repository->matching($criteria); + + $entity = $collection->isEmpty() + ? null + : $collection->filter( + fn($function) => version_compare($function->getPhpMin(), PHP_VERSION, 'le') + )->first() + ; if (null === $entity) { // function does not exists diff --git a/src/Infrastructure/Persistence/Doctrine/Repository/FunctionRepository.php b/src/Infrastructure/Persistence/Doctrine/Repository/FunctionRepository.php index 958b9d1c..593b16e1 100644 --- a/src/Infrastructure/Persistence/Doctrine/Repository/FunctionRepository.php +++ b/src/Infrastructure/Persistence/Doctrine/Repository/FunctionRepository.php @@ -13,9 +13,13 @@ use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Entity\Function_ as FunctionEntity; use Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\FunctionHydrator; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; +use function version_compare; +use const PHP_VERSION; + /** * @since Release 3.2.0 * @author Laurent Laville @@ -52,7 +56,19 @@ public function getAll(): array */ public function getFunctionByName(string $name, ?string $declaringClass): ?Function_ { - $entity = $this->repository->findOneBy(['name' => $name, 'declaringClass' => $declaringClass]); + $criteria = new Criteria(); + $criteria->where(Criteria::expr()->eq('name', $name)); + $criteria->andWhere(Criteria::expr()->eq('declaringClass', $declaringClass)); + $criteria->orderBy(['phpMin' => 'desc']); + + $collection = $this->repository->matching($criteria); + + $entity = $collection->isEmpty() + ? null + : $collection->filter( + fn($function) => version_compare($function->getPhpMin(), PHP_VERSION, 'le') + )->first() + ; if (null === $entity) { // function does not exists diff --git a/tests/Database/ClassRepositoryTest.php b/tests/Database/ClassRepositoryTest.php new file mode 100644 index 00000000..7e873caf --- /dev/null +++ b/tests/Database/ClassRepositoryTest.php @@ -0,0 +1,58 @@ +createFromInput(new ArrayInput([])); + + $this->entityManager = $container->get(EntityManagerInterface::class); + + $this->classRepository = new ClassRepository($this->entityManager); + } + + protected function tearDown(): void + { + $this->entityManager->close(); + } + + public function testGetClassByName(): void + { + $class = $this->classRepository->getClassByName('AMQPException', false); + + if (version_compare(PHP_VERSION, '7.4.0', 'ge')) { + $expectedVersion = '7.4.0'; + } else { + $expectedVersion = '5.2.0'; + } + $this->assertSame($expectedVersion, $class->getPhpMin()); + } +} diff --git a/tests/Database/ConstantRepositoryTest.php b/tests/Database/ConstantRepositoryTest.php new file mode 100644 index 00000000..41284e0c --- /dev/null +++ b/tests/Database/ConstantRepositoryTest.php @@ -0,0 +1,58 @@ +createFromInput(new ArrayInput([])); + + $this->entityManager = $container->get(EntityManagerInterface::class); + + $this->constantRepository = new ConstantRepository($this->entityManager); + } + + protected function tearDown(): void + { + $this->entityManager->close(); + } + + public function testGetConstantByName(): void + { + $constant = $this->constantRepository->getConstantByName('T_BAD_CHARACTER', null); + + if (version_compare(PHP_VERSION, '7.4.0', 'ge')) { + $expectedVersion = '7.4.0beta1'; + } else { + $expectedVersion = '4.2.0'; + } + $this->assertSame($expectedVersion, $constant->getPhpMin()); + } +} diff --git a/tests/Database/FunctionRepositoryTest.php b/tests/Database/FunctionRepositoryTest.php new file mode 100644 index 00000000..a5e935ea --- /dev/null +++ b/tests/Database/FunctionRepositoryTest.php @@ -0,0 +1,58 @@ +createFromInput(new ArrayInput([])); + + $this->entityManager = $container->get(EntityManagerInterface::class); + + $this->functionRepository = new FunctionRepository($this->entityManager); + } + + protected function tearDown(): void + { + $this->entityManager->close(); + } + + public function testGetFunctionByName(): void + { + $constant = $this->functionRepository->getFunctionByName('random_int', null); + + if (version_compare(PHP_VERSION, '8.2.0', 'ge')) { + $expectedVersion = '8.2.0'; + } else { + $expectedVersion = '7.0.2'; + } + $this->assertSame($expectedVersion, $constant->getPhpMin()); + } +}