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

Pager::countSinglePrimaryKey()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 1
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
    private const CONCAT_SEPARATOR = '|';
28
29
    /**
30
     * NEXT_MAJOR: remove this property.
31
     *
32
     * @deprecated since sonata-project/doctrine-orm-admin-bundle 2.4 and will be removed in 4.0
33
     */
34
    protected $queryBuilder = null;
35
36
    public function computeNbResult()
37
    {
38
        $countQuery = clone $this->getQuery();
39
40
        if (\count($this->getParameters()) > 0) {
41
            $countQuery->setParameters($this->getParameters());
42
        }
43
44
        if (\count($this->getCountColumn()) > 1) {
45
            $this->countCompositePrimaryKey($countQuery);
46
        } else {
47
            $this->countSinglePrimaryKey($countQuery);
48
        }
49
50
        return array_sum(array_column(
51
            $countQuery->resetDQLPart('orderBy')->getQuery()->getResult(Query::HYDRATE_SCALAR),
52
            'cnt'
53
        ));
54
    }
55
56
    public function getResults($hydrationMode = Query::HYDRATE_OBJECT)
57
    {
58
        return $this->getQuery()->execute([], $hydrationMode);
59
    }
60
61
    public function getQuery()
62
    {
63
        return $this->query;
64
    }
65
66
    public function init()
67
    {
68
        $this->resetIterator();
69
70
        $this->setNbResults($this->computeNbResult());
71
72
        $this->getQuery()->setFirstResult(null);
73
        $this->getQuery()->setMaxResults(null);
74
75
        if (\count($this->getParameters()) > 0) {
76
            $this->getQuery()->setParameters($this->getParameters());
77
        }
78
79
        if (0 === $this->getPage() || 0 === $this->getMaxPerPage() || 0 === $this->getNbResults()) {
80
            $this->setLastPage(0);
81
        } else {
82
            $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
83
84
            $this->setLastPage((int) ceil($this->getNbResults() / $this->getMaxPerPage()));
85
86
            $this->getQuery()->setFirstResult($offset);
87
            $this->getQuery()->setMaxResults($this->getMaxPerPage());
88
        }
89
    }
90
91
    private function countCompositePrimaryKey(ProxyQueryInterface $countQuery)
92
    {
93
        $root_aliases = current($countQuery->getRootAliases());
94
        $countQuery->setParameter('concat_separator', self::CONCAT_SEPARATOR);
95
        $columns = [];
96
97
        foreach ($this->getCountColumn() as $column) {
98
            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...
99
                $columns[] = ':concat_separator';
100
            }
101
102
            $columns[] = sprintf('%s.%s', $root_aliases, $column);
103
        }
104
105
        $countQuery->select(sprintf(
106
            'count(%s concat(%s)) as cnt',
107
            $countQuery instanceof ProxyQuery && !$countQuery->isDistinct() ? null : 'DISTINCT',
108
            implode(',', $columns)
109
        ));
110
    }
111
112
    private function countSinglePrimaryKey(ProxyQueryInterface $countQuery)
113
    {
114
        $countQuery->select(sprintf(
115
            'count(%s %s.%s) as cnt',
116
            $countQuery instanceof ProxyQuery && !$countQuery->isDistinct() ? null : 'DISTINCT',
117
            current($countQuery->getRootAliases()),
118
            current($this->getCountColumn())
119
        ));
120
    }
121
}
122