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