diff --git a/composer.json b/composer.json index 9a44ded75a1a9062008a1e9a001f9be90fa1396e..5c38462c4928a9c71f6d7f3320c43918495ab42c 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,8 @@ "require": { "php": "^8.3", "symfony/http-foundation": "^7.2.3", - "doctrine/orm": "^3.3.2" + "doctrine/orm": "^3.3.2", + "beberlei/doctrineextensions": "^1.5" }, "require-dev": { "phpunit/phpunit": "^12.0", diff --git a/src/Filter/Date.php b/src/Filter/Date.php new file mode 100644 index 0000000000000000000000000000000000000000..de40e23bacef67ef23e7996b399af79047745d8e --- /dev/null +++ b/src/Filter/Date.php @@ -0,0 +1,20 @@ +where( + 'strftime(\'%Y-%m-%d\', ' . $this->getColumn() . ') = \'' . $this->getHttpValue() . '\'', + ); + + return $queryBuilder; + } +} diff --git a/tests/FilterByDateTest.php b/tests/FilterByDateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9e01aadbf96b69480251adc29e8d872cdf848fc7 --- /dev/null +++ b/tests/FilterByDateTest.php @@ -0,0 +1,134 @@ +em->getRepository(Post::class); + + $date = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 12:00:00'); + + $post = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + $date, + ); + + $post2 = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + DateTimeImmutable::createFromInterface($this->faker->dateTime()), + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'createdAt' => Date::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'createdAt' => $date->format('Y-m-d'), + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertNotEmpty($result); + $this->assertCount(1, $result); + $this->assertEquals($date, current($result)->createdAt); + } + + public function testSuccessFilterDateRangeWithSeveralResults(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $firstDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 12:00:00'); + $secondDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 19:30:00'); + + $post = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + $firstDate, + ); + + $post2 = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + $secondDate, + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'createdAt' => Date::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'createdAt' => $firstDate->format('Y-m-d'), + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertNotEmpty($result); + $this->assertCount(2, $result); + } + + public function testSuccessFilterDateRangeWithoutResults(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $firstDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 14:00:00'); + + $post = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + $firstDate, + ); + + $post2 = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + DateTimeImmutable::createFromInterface($this->faker->dateTime()), + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'createdAt' => Date::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'createdAt' => $firstDate->add(new DateInterval('P1Y'))->format('Y-m-d'), + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertEmpty($result); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 0e6331875ee581bc32b723da9722a6b738b20662..bdb1212e22cda7d22582c4987c3a4dc8de224344 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,6 +12,7 @@ use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\ORMSetup; use Doctrine\ORM\Tools\SchemaTool; +use DoctrineExtensions\Query\Sqlite\StrfTime; use Faker\Factory; use Faker\Generator; use IQDEV\Packages\DoctrineHttpFilter\HttpFilterEntityRepository; @@ -59,6 +60,7 @@ abstract class TestCase extends BaseTestCase [__DIR__ . '/Entity'], true, ); + $config->addCustomStringFunction('strftime', StrfTime::class); $connection = DriverManager::getConnection([ 'driver' => 'pdo_sqlite',