/src/Dime/TimetrackerBundle/Entity/ActivityRepository.php

https://github.com/phpugl/Dime · PHP · 265 lines · 151 code · 29 blank · 85 comment · 27 complexity · 4533d93b5131ab62b5b4933eefd8b34a MD5 · raw file

  1. <?php
  2. namespace Dime\TimetrackerBundle\Entity;
  3. use Dime\TimetrackerBundle\Entity\EntityRepository;
  4. use Doctrine\ORM\QueryBuilder;
  5. /**
  6. * ActivityRepository
  7. *
  8. * This class was generated by the Doctrine ORM. Add your own custom
  9. * repository methods below.
  10. */
  11. class ActivityRepository extends EntityRepository
  12. {
  13. protected $allowed_fields = array('customer', 'project', 'service', 'user');
  14. public function allowedFields() {
  15. return $this->allowed_fields;
  16. }
  17. /**
  18. * Simple search for description with like.
  19. *
  20. * @param string $text
  21. * @param \Doctrine\ORM\QueryBuilder $qb
  22. *
  23. * @return \Doctrine\ORM\QueryBuilder
  24. * @throws \Exception when $qb is null
  25. */
  26. public function search($text, QueryBuilder $qb = null)
  27. {
  28. if ($qb == null) {
  29. $qb = $this->builder;
  30. }
  31. $aliases = $qb->getRootAliases();
  32. $alias = array_shift($aliases);
  33. $qb->andWhere($qb->expr()->like($alias . '.description', ':text'));
  34. $qb->setParameter('text', '%' . $text . '%');
  35. return $this;
  36. }
  37. /**
  38. * Filter by date string or with array of 2 date strings.
  39. * TODO Filter by date - no datetime functions at the moment
  40. *
  41. * @param $date, date string or array with data string
  42. * @param \Doctrine\ORM\QueryBuilder $qb
  43. *
  44. * @return \Doctrine\ORM\QueryBuilder
  45. * @throws \Exception when $qb is null
  46. */
  47. public function scopeByDate($date, QueryBuilder $qb = null)
  48. {
  49. if ($qb == null) {
  50. $qb = $this->builder;
  51. }
  52. $aliases = $qb->getRootAliases();
  53. $alias = array_shift($aliases);
  54. if (is_array($date) && count($date) == 1) {
  55. $date = array_shift($date);
  56. }
  57. if (is_array($date)) {
  58. $qb->andWhere(
  59. $qb->expr()->between($alias . '.updatedAt', ':from', ':to')
  60. );
  61. $qb->setParameter('from', $date[0]. ' 00:00:00');
  62. $qb->setParameter('to', $date[1] . ' 23:59:59');
  63. } else {
  64. $qb->andWhere(
  65. $qb->expr()->like($alias . '.updatedAt', ':date')
  66. );
  67. $qb->setParameter('date', $date . '%');
  68. }
  69. //print($qb->getQuery()->getSQL());
  70. return $this;
  71. }
  72. /**
  73. * Filter active or non active activities. Active activities
  74. * has a timeslice where stoppedAt is null and duration is 0.
  75. *
  76. * @param $active, boolean
  77. * @param \Doctrine\ORM\QueryBuilder $qb
  78. *
  79. * @return \Doctrine\ORM\QueryBuilder
  80. * @throws \Exception when $qb is null
  81. */
  82. public function scopeByActive($active, QueryBuilder $qb = null)
  83. {
  84. if ($qb == null) {
  85. $qb = $this->builder;
  86. }
  87. $timesliceRepository = $this->getEntityManager()->getRepository('DimeTimetrackerBundle:Timeslice');
  88. $ids = $timesliceRepository->fetchRunningActivityIds();
  89. if ($active == 'true' || (is_bool($active) && $active)) {
  90. // empty id list, should produce no output on query
  91. if (empty($ids)) {
  92. $ids[] = 0;
  93. }
  94. $qb->andWhere(
  95. $qb->expr()->in('a.id', $ids)
  96. );
  97. } else {
  98. if (!empty($ids)) {
  99. $qb->andWhere(
  100. $qb->expr()->notIn('a.id', $ids)
  101. );
  102. }
  103. }
  104. return $this;
  105. }
  106. /**
  107. * Filter by customer id
  108. *
  109. * @param $id, integer
  110. * @param \Doctrine\ORM\QueryBuilder $qb
  111. *
  112. * @return \Doctrine\ORM\QueryBuilder
  113. */
  114. public function scopeByCustomer($id, QueryBuilder $qb = null)
  115. {
  116. return $this->scopeByField('customer', $id, $qb);
  117. }
  118. /**
  119. * Filter by project id
  120. *
  121. * @param $id, integer
  122. * @param \Doctrine\ORM\QueryBuilder $qb
  123. *
  124. * @return \Doctrine\ORM\QueryBuilder
  125. */
  126. public function scopeByProject($id, QueryBuilder $qb = null)
  127. {
  128. return $this->scopeByField('project', $id, $qb);
  129. }
  130. /**
  131. * Filter by service id
  132. *
  133. * @param $id, integer
  134. * @param \Doctrine\ORM\QueryBuilder $qb
  135. *
  136. * @return \Doctrine\ORM\QueryBuilder
  137. */
  138. public function scopeByService($id, QueryBuilder $qb = null)
  139. {
  140. return $this->scopeByField('service', $id, $qb);
  141. }
  142. /**
  143. * Filter by assigned tag
  144. *
  145. * @param integer|string $tagIdOrName
  146. * @param \Doctrine\ORM\QueryBuilder $qb
  147. *
  148. * @return \Doctrine\ORM\QueryBuilder
  149. */
  150. public function scopeWithTag($tagIdOrName, QueryBuilder $qb = null)
  151. {
  152. if ($qb == null) {
  153. $qb = $this->builder;
  154. }
  155. $aliases = $qb->getRootAliases();
  156. $alias = array_shift($aliases);
  157. if (!$this->existsJoinAlias($qb, 'x')) {
  158. $qb->innerJoin(
  159. $alias . '.tags',
  160. 'x',
  161. 'WITH',
  162. is_numeric($tagIdOrName) ? 'x.id = :tag' : 'x.name = :tag'
  163. );
  164. }
  165. $qb->setParameter('tag', $tagIdOrName);
  166. return $this;
  167. }
  168. /**
  169. * Filter by not-assigned tag
  170. *
  171. * @param integer|string $tagIdOrName
  172. * @param \Doctrine\ORM\QueryBuilder $qb
  173. *
  174. * @return \Doctrine\ORM\QueryBuilder
  175. */
  176. public function scopeWithoutTag($tagIdOrName, QueryBuilder $qb = null)
  177. {
  178. if ($qb == null) {
  179. $qb = $this->builder;
  180. }
  181. $aliases = $qb->getRootAliases();
  182. $alias = array_shift($aliases);
  183. $qb2 = clone $qb;
  184. $qb2->resetDqlParts();
  185. $qb->andWhere(
  186. $qb->expr()->notIn(
  187. $alias . '.id',
  188. $qb2->select('a2.id')
  189. ->from('Dime\TimetrackerBundle\Entity\Activity', 'a2')
  190. ->join('a2.tags', 'x2')
  191. ->where(is_numeric($tagIdOrName) ? 'x2.id = :tag' : 'x2.name = :tag')
  192. ->getDQL()
  193. )
  194. );
  195. $qb->setParameter('tag', $tagIdOrName);
  196. return $this;
  197. }
  198. /**
  199. * Add different filter option to query
  200. *
  201. * @param array $filter
  202. * @param \Doctrine\ORM\QueryBuilder $qb
  203. *
  204. * @return ActivityRepository
  205. */
  206. public function filter(array $filter, QueryBuilder $qb = null)
  207. {
  208. if ($qb == null) {
  209. $qb = $this->builder;
  210. }
  211. if ($filter != null) {
  212. foreach ($filter as $key => $value) {
  213. switch($key) {
  214. case 'active':
  215. $this->scopeByActive($value, $qb);
  216. break;
  217. case 'withTags':
  218. $this->scopeWithTags($value, $qb);
  219. break;
  220. case 'withoutTags':
  221. $this->scopeWithoutTags($value, $qb);
  222. break;
  223. case 'date':
  224. $this->scopeByDate($value, $qb);
  225. break;
  226. case 'search':
  227. $this->search($value, $qb);
  228. break;
  229. default:
  230. $this->scopeByField($key, $value, $qb);
  231. }
  232. }
  233. }
  234. return $this;
  235. }
  236. }