Completed
Pull Request — 3.x (#996)
by Peter
01:53
created

Pager::countCompositePrimaryKey()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.2888
c 0
b 0
f 0
cc 5
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrineORMAdminBundle\Datagrid;
15
16
use Doctrine\ORM\Query;
17
use Sonata\AdminBundle\Datagrid\Pager as BasePager;
18
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
19
20
/**
21
 * Doctrine pager class.
22
 *
23
 * @author Jonathan H. Wage <[email protected]>
24
 */
25
class Pager extends BasePager
26
{
27
    /**
28
     * Use separator in CONCAT() function for correct determinate similar records.
29
     */
30
    public const CONCAT_SEPARATOR = '|';
31
32
    /**
33
     * NEXT_MAJOR: remove this property.
34
     *
35
     * @deprecated since sonata-project/doctrine-orm-admin-bundle 2.4 and will be removed in 4.0
36
     */
37
    protected $queryBuilder = null;
38
39
    public function computeNbResult()
40
    {
41
        $countQuery = clone $this->getQuery();
42
43
        if (\count($this->getParameters()) > 0) {
44
            $countQuery->setParameters($this->getParameters());
45
        }
46
47
        if (\count($this->getCountColumn()) > 1) {
48
            $this->countCompositePrimaryKey($countQuery);
49
        } else {
50
            $this->countSinglePrimaryKey($countQuery);
51
        }
52
53
        return array_sum(array_column(
54
            $countQuery->resetDQLPart('orderBy')->getQuery()->getResult(Query::HYDRATE_SCALAR),
55
            'cnt'
56
        ));
57
    }
58
59
    public function getResults($hydrationMode = Query::HYDRATE_OBJECT)
60
    {
61
        return $this->getQuery()->execute([], $hydrationMode);
62
    }
63
64
    public function getQuery()
65
    {
66
        return $this->query;
67
    }
68
69
    public function init()
70
    {
71
        $this->resetIterator();
72
73
        $this->setNbResults($this->computeNbResult());
74
75
        $this->getQuery()->setFirstResult(null);
76
        $this->getQuery()->setMaxResults(null);
77
78
        if (\count($this->getParameters()) > 0) {
79
            $this->getQuery()->setParameters($this->getParameters());
80
        }
81
82
        if (0 === $this->getPage() || 0 === $this->getMaxPerPage() || 0 === $this->getNbResults()) {
83
            $this->setLastPage(0);
84
        } else {
85
            $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
86
87
            $this->setLastPage((int) ceil($this->getNbResults() / $this->getMaxPerPage()));
88
89
            $this->getQuery()->setFirstResult($offset);
90
            $this->getQuery()->setMaxResults($this->getMaxPerPage());
91
        }
92
    }
93
94
    private function countCompositePrimaryKey(ProxyQueryInterface $countQuery)
95
    {
96
        $rootAliases = current($countQuery->getRootAliases());
97
        $countQuery->setParameter('concat_separator', self::CONCAT_SEPARATOR);
98
        $columns = [];
99
100
        foreach ($this->getCountColumn() as $column) {
101
            if ($columns) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $columns of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
102
                $columns[] = ':concat_separator';
103
            }
104
105
            $columns[] = sprintf('%s.%s', $rootAliases, $column);
106
        }
107
108
        $countQuery->select(sprintf(
109
            'count(%s concat(%s)) as cnt',
110
            $countQuery instanceof ProxyQuery && !$countQuery->isDistinct() ? null : 'DISTINCT',
111
            implode(', ', $columns)
112
        ));
113
    }
114
115
    private function countSinglePrimaryKey(ProxyQueryInterface $countQuery): void
116
    {
117
        $countQuery->select(sprintf(
118
            'count(%s %s.%s) as cnt',
119
            $countQuery instanceof ProxyQuery && !$countQuery->isDistinct() ? null : 'DISTINCT',
120
            current($countQuery->getRootAliases()),
121
            current($this->getCountColumn())
122
        ));
123
    }
124
}
125