Skip to content

Commit

Permalink
Added support for datetime (#6)
Browse files Browse the repository at this point in the history
Fixes #3
  • Loading branch information
mariusbalcytis authored Aug 6, 2020
1 parent 822e4b6 commit ef2696a
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 4 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"php": ">=7.0",
"doctrine/orm": "^2.0",
"psr/log": "^1.0",
"symfony/property-access": "^2.8|^3.0|^4.0|^5.0"
"symfony/property-access": "^2.8|^3.0|^4.0|^5.0",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
Expand Down
18 changes: 15 additions & 3 deletions src/Service/CursorBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Paysera\Pagination\Service;

use DateTimeInterface;
use Paysera\Pagination\Entity\OrderingConfiguration;
use Paysera\Pagination\Entity\ParsedCursor;
use Paysera\Pagination\Exception\InvalidCursorException;
Expand Down Expand Up @@ -68,13 +69,24 @@ public function getCursorFromItem($item, array $orderingConfigurations): string
return $this->convertArrayToCursor($cursor);
}

private function getCursorItemValue($item, OrderingConfiguration $orderingConfiguration)
private function getCursorItemValue($item, OrderingConfiguration $orderingConfiguration): string
{
if ($orderingConfiguration->getAccessorPath() !== null) {
return (string)$this->propertyAccessor->getValue($item, $orderingConfiguration->getAccessorPath());
$value = $this->propertyAccessor->getValue($item, $orderingConfiguration->getAccessorPath());
} else {
$value = call_user_func($orderingConfiguration->getAccessorClosure(), $item);
}

return call_user_func($orderingConfiguration->getAccessorClosure(), $item);
return $this->processValue($value);
}

private function processValue($value): string
{
if ($value instanceof DateTimeInterface) {
return $value->format('Y-m-d H:i:s');
}

return (string)$value;
}

private function convertArrayToCursor(array $cursorElements): string
Expand Down
58 changes: 58 additions & 0 deletions tests/Functional/Fixtures/DateTimeEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);

namespace Paysera\Pagination\Tests\Functional\Fixtures;

use DateTime;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;

/**
* @Entity
*/
class DateTimeEntity
{
/**
* @var int|null
*
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
private $id;

/**
* @var DateTime|null
*
* @Column(type="datetime")
*/
private $createdAt;

/**
* @return int|null
*/
public function getId()
{
return $this->id;
}

/**
* @return DateTime|null
*/
public function getCreatedAt()
{
return $this->createdAt;
}

/**
* @param DateTime $createdAt
* @return $this
*/
public function setCreatedAt(DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
}
2 changes: 2 additions & 0 deletions tests/Functional/Service/Doctrine/DoctrineTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Tools\SchemaTool;
use Paysera\Pagination\Tests\Functional\Fixtures\ChildTestEntity;
use Paysera\Pagination\Tests\Functional\Fixtures\DateTimeEntity;
use Paysera\Pagination\Tests\Functional\Fixtures\ParentTestEntity;
use PHPUnit\Framework\TestCase;
use Doctrine\ORM\Configuration;
Expand All @@ -31,6 +32,7 @@ protected function createTestEntityManager()
$metadataFactory = $entityManager->getMetadataFactory();
$metadataFactory->getMetadataFor(ParentTestEntity::class);
$metadataFactory->getMetadataFor(ChildTestEntity::class);
$metadataFactory->getMetadataFor(DateTimeEntity::class);
$metadata = $metadataFactory->getLoadedMetadata();
$schemaTool->dropSchema($metadata);
$schemaTool->createSchema($metadata);
Expand Down
94 changes: 94 additions & 0 deletions tests/Functional/Service/Doctrine/ResultProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Paysera\Pagination\Tests\Functional\Service\Doctrine;

use DateTime;
use Doctrine\ORM\QueryBuilder;
use Paysera\Pagination\Entity\OrderingConfiguration;
use Doctrine\ORM\EntityManager;
Expand All @@ -17,6 +18,7 @@
use Paysera\Pagination\Exception\TooLargeOffsetException;
use Paysera\Pagination\Service\CursorBuilder;
use Paysera\Pagination\Tests\Functional\Fixtures\ChildTestEntity;
use Paysera\Pagination\Tests\Functional\Fixtures\DateTimeEntity;
use Paysera\Pagination\Tests\Functional\Fixtures\ParentTestEntity;
use Symfony\Component\PropertyAccess\PropertyAccess;

Expand Down Expand Up @@ -517,6 +519,98 @@ public function getResultProviderForSeveralLevelOrdering()
];
}

/**
* @dataProvider getResultProviderForDateTimeField
* @param Result $expectedResult
* @param Pager $pager
*/
public function testGetResultForQueryWithDateTimeField(Result $expectedResult, Pager $pager)
{
$entityManager = $this->createTestEntityManager();
$this->createDateTimeRelatedData($entityManager);

$queryBuilder = $entityManager->createQueryBuilder()
->select('d')
->from('PaginationTest:DateTimeEntity', 'd')
;

$configuredQuery = (new ConfiguredQuery($queryBuilder))->addOrderingConfiguration(
'created_at',
new OrderingConfiguration('d.createdAt', 'createdAt')
);

$result = $this->resultProvider->getResultForQuery($configuredQuery, $pager);
$result->setItems(array_map(function (DateTimeEntity $item) {
return (string)$item->getId();
}, $result->getItems()));

$this->assertEquals($expectedResult, $result);
}

private function createDateTimeRelatedData(EntityManager $entityManager)
{
for ($i = 0; $i < 30; $i++) {
$entity1 = (new DateTimeEntity())->setCreatedAt(new DateTime(sprintf('2020-02-02 12:00:%s', $i)));
$entity2 = (new DateTimeEntity())->setCreatedAt(new DateTime(sprintf('2020-02-02 12:00:%s', $i)));
$entityManager->persist($entity1);
$entityManager->persist($entity2);
}

$entityManager->flush();
}

public function getResultProviderForDateTimeField()
{
return [
'first page' => [
(new Result())
->setItems([1, 2, 3])
->setHasNext(true)
->setHasPrevious(false)
->setPreviousCursor('"2020-02-02 12:00:00","1"')
->setNextCursor('"2020-02-02 12:00:01","3"'),
(new Pager())
->setLimit(3)
->addOrderBy(new OrderingPair('created_at', true)),
],
'second page' => [
(new Result())
->setItems([4, 5, 6])
->setHasNext(true)
->setHasPrevious(true)
->setPreviousCursor('"2020-02-02 12:00:01","4"')
->setNextCursor('"2020-02-02 12:00:02","6"'),
(new Pager())
->setLimit(3)
->addOrderBy(new OrderingPair('created_at', true))
->setAfter('"2020-02-02 12:00:01","3"'),
],
'first page from second' => [
(new Result())
->setItems([1, 2, 3])
->setHasNext(true)
->setHasPrevious(false)
->setPreviousCursor('"2020-02-02 12:00:00","1"')
->setNextCursor('"2020-02-02 12:00:01","3"'),
(new Pager())
->setLimit(3)
->addOrderBy(new OrderingPair('created_at', true))
->setBefore('"2020-02-02 12:00:01","4"'),
],
'desc order' => [
(new Result())
->setItems([60, 59, 58])
->setHasNext(true)
->setHasPrevious(false)
->setPreviousCursor('"2020-02-02 12:00:29","60"')
->setNextCursor('"2020-02-02 12:00:28","58"'),
(new Pager())
->setLimit(3)
->addOrderBy(new OrderingPair('created_at', false)),
],
];
}

public function testGetResultForQueryWithCustomAccessor()
{
$entityManager = $this->createTestEntityManager();
Expand Down

0 comments on commit ef2696a

Please sign in to comment.