|
1
|
|
|
<?php |
|
2
|
|
|
declare(strict_types=1); |
|
3
|
|
|
|
|
4
|
|
|
namespace AlexTartan\Paginator; |
|
5
|
|
|
|
|
6
|
|
|
use AlexTartan\Helpers\ReflectionHelper; |
|
7
|
|
|
use ArrayIterator; |
|
8
|
|
|
use Doctrine\ORM\Query; |
|
9
|
|
|
use Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker; |
|
10
|
|
|
use Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker; |
|
11
|
|
|
use Doctrine\ORM\Tools\Pagination\Paginator; |
|
12
|
|
|
use Doctrine\ORM\Tools\Pagination\WhereInWalker; |
|
13
|
|
|
use Ramsey\Uuid\UuidInterface; |
|
14
|
|
|
use function array_map; |
|
15
|
|
|
use function count; |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* @method Query cloneQuery(Query $query) |
|
19
|
|
|
* @method bool useOutputWalker(Query $query) |
|
20
|
|
|
* @method void appendTreeWalker(Query $query, string $walkerClass) |
|
21
|
|
|
* @method void unbindUnusedQueryParams(Query $query) |
|
22
|
|
|
* |
|
23
|
|
|
* @property Query $query |
|
24
|
|
|
* @property bool $fetchJoinCollection |
|
25
|
|
|
*/ |
|
26
|
|
|
class BinaryUuidSafePaginator extends Paginator |
|
27
|
|
|
{ |
|
28
|
|
|
/** |
|
29
|
|
|
* @return mixed |
|
30
|
|
|
*/ |
|
31
|
|
|
public function __call(string $name, array $arguments) |
|
32
|
|
|
{ |
|
33
|
|
|
return ReflectionHelper::callPrivateMethod($this, $name, $arguments); |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @return mixed |
|
38
|
|
|
*/ |
|
39
|
|
|
public function __get(string $name) |
|
40
|
|
|
{ |
|
41
|
|
|
return ReflectionHelper::getPrivatePropertyValue($this, $name, Paginator::class); |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
public function getIterator(): ArrayIterator |
|
45
|
|
|
{ |
|
46
|
|
|
if (!$this->fetchJoinCollection) { |
|
47
|
|
|
return parent::getIterator(); |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
$offset = $this->query->getFirstResult(); |
|
51
|
|
|
$length = $this->query->getMaxResults(); |
|
52
|
|
|
|
|
53
|
|
|
$subQuery = $this->cloneQuery($this->query); |
|
54
|
|
|
|
|
55
|
|
|
if ($this->useOutputWalker($subQuery)) { |
|
56
|
|
|
$subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); |
|
57
|
|
|
} else { |
|
58
|
|
|
$this->appendTreeWalker($subQuery, LimitSubqueryWalker::class); |
|
59
|
|
|
$this->unbindUnusedQueryParams($subQuery); |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
$subQuery->setFirstResult($offset)->setMaxResults($length); |
|
63
|
|
|
|
|
64
|
|
|
$ids = array_map('current', $subQuery->getScalarResult()); |
|
65
|
|
|
// don't do this for an empty id array |
|
66
|
|
|
if (count($ids) === 0) { |
|
67
|
|
|
return new ArrayIterator([]); |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
foreach ($ids as $key => $id) { |
|
71
|
|
|
if ($id instanceof UuidInterface) { |
|
72
|
|
|
$ids[$key] = $id->getBytes(); |
|
73
|
|
|
} |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
$whereInQuery = $this->cloneQuery($this->query); |
|
77
|
|
|
|
|
78
|
|
|
$this->appendTreeWalker($whereInQuery, WhereInWalker::class); |
|
79
|
|
|
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids)); |
|
80
|
|
|
$whereInQuery->setFirstResult(null)->setMaxResults(null); |
|
81
|
|
|
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids); |
|
82
|
|
|
$whereInQuery->setCacheable($this->query->isCacheable()); |
|
83
|
|
|
|
|
84
|
|
|
return new ArrayIterator($whereInQuery->getResult($this->query->getHydrationMode())); |
|
85
|
|
|
} |
|
86
|
|
|
} |
|
87
|
|
|
|