1<?php
2
3namespace dipl\Db\Zf1;
4
5use Zend_Db_Select as ZfSelect;
6
7class CountQuery
8{
9    /** @var ZfSelect */
10    private $query;
11
12    private $maxRows;
13
14    /**
15     * ZfCountQuery constructor.
16     * @param ZfSelect $query
17     */
18    public function __construct(ZfSelect $query)
19    {
20        $this->query = $query;
21    }
22
23    public function setMaxRows($max)
24    {
25        $this->maxRows = $max;
26        return $this;
27    }
28
29    public function getQuery()
30    {
31        if ($this->needsSubQuery()) {
32            return $this->buildSubQuery();
33        } else {
34            return $this->buildSimpleQuery();
35        }
36    }
37
38    protected function hasOneOf($parts)
39    {
40        foreach ($parts as $part) {
41            if ($this->hasPart($part)) {
42                return true;
43            }
44        }
45
46        return false;
47    }
48
49    protected function hasPart($part)
50    {
51        $values = $this->query->getPart($part);
52        return ! empty($values);
53    }
54
55    protected function needsSubQuery()
56    {
57        return null !== $this->maxRows || $this->hasOneOf([
58            ZfSelect::GROUP,
59            ZfSelect::UNION
60        ]);
61    }
62
63    protected function buildSubQuery()
64    {
65        $sub = clone($this->query);
66        $sub->limit(null, null);
67        $query = new ZfSelect($this->query->getAdapter());
68        $query->from($sub, ['cnt' => 'COUNT(*)']);
69        if (null !== $this->maxRows) {
70            $sub->limit($this->maxRows + 1);
71        }
72
73        return $query;
74    }
75
76    protected function buildSimpleQuery()
77    {
78        $query = clone($this->query);
79        $query->reset(ZfSelect::COLUMNS);
80        $query->reset(ZfSelect::ORDER);
81        $query->reset(ZfSelect::LIMIT_COUNT);
82        $query->reset(ZfSelect::LIMIT_OFFSET);
83        $query->columns(['cnt' => 'COUNT(*)']);
84        return $query;
85    }
86}
87