PaginatorFast   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 3
dl 0
loc 119
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getQueryBuilder() 0 4 1
A getItems() 0 7 1
B count() 0 63 6
1
<?php
2
3
namespace ZfcDatagrid\DataSource\Doctrine2;
4
5
use Doctrine\ORM\QueryBuilder;
6
use Zend\Paginator\Adapter\AdapterInterface;
7
8
class PaginatorFast implements AdapterInterface
9
{
10
    /**
11
     * @var QueryBuilder
12
     */
13
    protected $qb = null;
14
15
    /**
16
     * Total item count.
17
     *
18
     * @var int
19
     */
20
    protected $rowCount = null;
21
22
    /**
23
     * @param QueryBuilder $qb
24
     */
25
    public function __construct(QueryBuilder $qb)
26
    {
27
        $this->qb = $qb;
28
    }
29
30
    /**
31
     * @return \Doctrine\ORM\QueryBuilder
32
     */
33
    public function getQueryBuilder()
34
    {
35
        return $this->qb;
36
    }
37
38
    /**
39
     * Returns an array of items for a page.
40
     *
41
     * @param int $offset
42
     * @param int $itemCountPerPage
43
     *
44
     * @return array
45
     */
46
    public function getItems($offset, $itemCountPerPage)
47
    {
48
        $qb = $this->getQueryBuilder();
49
        $qb->setFirstResult($offset)->setMaxResults($itemCountPerPage);
50
51
        return $qb->getQuery()->getArrayResult();
52
    }
53
54
    /**
55
     * Returns the total number of rows in the result set.
56
     *
57
     * Partly adapted from Zend
58
     *
59
     * @see https://github.com/zendframework/zf1/blob/master/library/Zend/Paginator/Adapter/DbSelect.php#L198
60
     *
61
     * @return int
62
     */
63
    public function count()
64
    {
65
        if ($this->rowCount !== null) {
66
            return $this->rowCount;
67
        }
68
69
        $qbOriginal = $this->getQueryBuilder();
70
        $qb = clone $qbOriginal;
71
72
        $dqlParts = $qb->getDQLParts();
73
        $groupParts = $dqlParts['groupBy'];
74
75
        /*
76
         * Reset things
77
         */
78
        $qb->setFirstResult(null)
79
            ->setMaxResults(null)
80
            ->resetDQLParts([
81
            'orderBy',
82
            'select',
83
        ]);
84
85
        if (count($groupParts) > 1) {
86
            /*
87
             * UGLY WORKAROUND!!! @todo
88
             */
89
            // more than one group part...tricky!
90
            // @todo finde something better...
91
            $qb->resetDQLPart('groupBy');
92
            $qb->select('CONCAT('.implode(',', $groupParts).') as uniqueParts');
93
94
            $items = [];
95
            $result = $qb->getQuery()->getResult();
96
            foreach ($result as $row) {
97
                $items[] = $row['uniqueParts'];
98
            }
99
            $uniqueItems = array_unique($items);
100
101
            $this->rowCount = count($uniqueItems);
102
        } elseif (count($groupParts) == 1) {
103
            $groupPart = $groupParts[0];
104
105
            $qb->resetDQLPart('groupBy');
106
            $qb->select('COUNT(DISTINCT '.$groupPart.')');
107
108
            $this->rowCount = $qb->getQuery()->getSingleScalarResult();
109
        } else {
110
            // NO GROUP BY
111
            $countOneFunction = $qb->getEntityManager()
112
                ->getConfiguration()
113
                ->getCustomStringFunction('COUNT_ONE');
114
            if ($countOneFunction !== null) {
115
                $qb->select('COUNT_ONE() AS rowCount');
116
            } else {
117
                $fromPart = $dqlParts['from'];
118
                $qb->select('COUNT('.$fromPart[0]->getAlias().')');
119
            }
120
121
            $this->rowCount = $qb->getQuery()->getSingleScalarResult();
122
        }
123
124
        return $this->rowCount;
125
    }
126
}
127