You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 line
6.0KB

  1. <?php
  2. namespace Lc\SovBundle\Repository;
  3. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  4. use Doctrine\ORM\QueryBuilder;
  5. use Knp\Component\Pager\PaginatorInterface;
  6. use Lc\SovBundle\Doctrine\EntityInterface;
  7. use Lc\SovBundle\Model\User\UserInterface;
  8. abstract class AbstractRepositoryQuery implements RepositoryQueryInterface
  9. {
  10. protected ServiceEntityRepository $repository;
  11. protected QueryBuilder $query;
  12. protected PaginatorInterface $paginator;
  13. protected string $id;
  14. public function __construct(ServiceEntityRepository $repository, string $id, PaginatorInterface $paginator = null)
  15. {
  16. $this->repository = $repository;
  17. $this->query = $repository->createQueryBuilder($id);
  18. $this->paginator = $paginator;
  19. $this->id = $id;
  20. }
  21. public function __call(string $name, $params): self
  22. {
  23. foreach ($params as $key => $value) {
  24. $this->populateDqlId($params[$key]);
  25. }
  26. call_user_func_array([$this->query, $name], $params);
  27. return $this;
  28. }
  29. public function create()
  30. {
  31. $class = get_called_class();
  32. return new $class($this->repository, $this->paginator);
  33. }
  34. public function call(callable $fn): self
  35. {
  36. $fn($this->query, $this);
  37. return $this;
  38. }
  39. public function count()
  40. {
  41. return $this->query->getQuery()
  42. ->getSingleScalarResult();
  43. }
  44. public function findOne()
  45. {
  46. return $this->query->getQuery()
  47. ->setMaxResults(1)
  48. ->getOneOrNullResult();
  49. }
  50. public function find(): array
  51. {
  52. return $this->query->getQuery()->getResult();
  53. }
  54. public function limit(int $maxResults):self
  55. {
  56. $this->query->setMaxResults($maxResults);
  57. return $this;
  58. }
  59. public function paginate(int $page = 1, int $limit = 20)
  60. {
  61. return $this->paginator->paginate($this->query->getQuery(), $page, $limit);
  62. }
  63. public function getRepository(): ServiceEntityRepository
  64. {
  65. return $this->repository;
  66. }
  67. public function getQueryBuilder(): QueryBuilder
  68. {
  69. return $this->query;
  70. }
  71. protected function populateDqlId(&$data)
  72. {
  73. if (is_string($data)) {
  74. $words = explode(' ', $data);
  75. foreach ($words as $k => $v) {
  76. if (isset($v[0]) && '.' === $v[0]) {
  77. $words[$k] = $this->id . $v;
  78. }
  79. }
  80. $data = implode(' ', $words);
  81. } elseif (is_array($data)) {
  82. foreach ($data as $k => $v) {
  83. $this->populateDqlId($data[$k]);
  84. }
  85. }
  86. return $data;
  87. }
  88. public function groupBy(string $field): self
  89. {
  90. if (strpos($field, '.')!==false) {
  91. $this->addGroupBy($field) ;
  92. } else {
  93. $this->addGroupBy('.'.$field) ;
  94. }
  95. return $this;
  96. }
  97. /*
  98. public function addGroupBy(string $field): self
  99. {
  100. if (strpos($field, '.')!==false) {
  101. $this->query->addGroupBy($field) ;
  102. } else {
  103. $this->query->addGroupBy('.'.$field) ;
  104. }
  105. return $this;
  106. }*/
  107. // @TODO : créer un addOrderBy et un orderBy
  108. public function orderBy(string $field, string $sort = 'ASC'): self
  109. {
  110. if (strpos($field, '.')!==false) {
  111. return $this->addOrderBy($field, $sort);
  112. } else {
  113. return $this->addOrderBy('.' . $field, $sort);
  114. }
  115. }
  116. public function filterById(int $id):self
  117. {
  118. return $this
  119. ->andWhere('.id = :id')
  120. ->setParameter('id', $id);
  121. }
  122. public function filterByCreatedBy(UserInterface $user):self
  123. {
  124. return $this
  125. ->andWhere('.createdBy = :user')
  126. ->setParameter('user', $user);
  127. }
  128. public function filterByUpdatedBy(UserInterface $user):self
  129. {
  130. return $this
  131. ->andWhere('.updatedBy = :user')
  132. ->setParameter('user', $user);
  133. }
  134. public function andWhereEqual($field, $value)
  135. {
  136. return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value);
  137. }
  138. public function filterByOldUrl(string $oldUrl): self
  139. {
  140. return $this->andWhere('.oldUrls LIKE :oldUrl')->setParameter('oldUrl', '%'.$oldUrl.'%');
  141. }
  142. public function resetRelationsJoin(): void
  143. {
  144. }
  145. /*
  146. * DEVALIAS
  147. */
  148. public function filterByDevAlias(string $devAlias): self
  149. {
  150. return $this
  151. ->andWhere('.devAlias = :devAlias')
  152. ->setParameter('devAlias', $devAlias);
  153. }
  154. /*
  155. * SLUG
  156. */
  157. public function filterBySlug(string $slug):self
  158. {
  159. return $this
  160. ->andWhere('.slug = :slug')
  161. ->setParameter('slug', $slug);
  162. }
  163. /*
  164. * TREE
  165. */
  166. public function filterIsParent():self
  167. {
  168. return $this->andWhere('.parent IS NULL');
  169. }
  170. public function filterIsChildren():self
  171. {
  172. return $this->andWhere('.parent IS NOT NULL');
  173. }
  174. public function filterByParent(EntityInterface $parent = null):self
  175. {
  176. return $this->andWhere('.parent = :parent')->setParameter('parent', $parent);
  177. }
  178. /*
  179. * STATUS
  180. */
  181. public function filterIsOffline():self
  182. {
  183. return $this->andWhereStatus($this->id, 0);
  184. }
  185. public function filterIsOnline():self
  186. {
  187. return $this->andWhereStatus($this->id, 1);
  188. }
  189. public function filterIsDeleted():self
  190. {
  191. return $this->andWhereStatus($this->id, -1);
  192. }
  193. public function filterIsOnlineAndOffline():self
  194. {
  195. return $this->andWhere('.status >= 0');
  196. }
  197. /*
  198. * POSITION
  199. */
  200. public function filterByPositionBiggerThan(int $position)
  201. {
  202. return $this->andWhere('.position > :position')->setParameter('position', $position);
  203. }
  204. public function filterByPositionSmallerThan(int $position)
  205. {
  206. return $this->andWhere('.position < :position')->setParameter('position', $position);
  207. }
  208. }