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
|
|
|
|