Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 149
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Tool
0.00% covered (danger)
0.00%
0 / 149
0.00% covered (danger)
0.00%
0 / 9
2352
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getModelClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addCollectivityClause
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 addOrder
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 count
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
 findPaginated
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 addTableWhere
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
420
 addTableOrder
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
182
 findAllByCollectivity
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * This file is part of the MADIS - RGPD Management application.
5 *
6 * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22declare(strict_types=1);
23
24namespace App\Infrastructure\ORM\Registry\Repository;
25
26use App\Application\Doctrine\Repository\CRUDRepository;
27use App\Application\Traits\RepositoryUtils;
28use App\Domain\Registry\Model;
29use App\Domain\Registry\Repository;
30use App\Domain\User\Model\Collectivity;
31use Doctrine\Common\Collections\Collection;
32use Doctrine\ORM\QueryBuilder;
33use Doctrine\ORM\Tools\Pagination\Paginator;
34use Doctrine\Persistence\ManagerRegistry;
35use Symfony\Component\Security\Core\Security;
36
37class Tool extends CRUDRepository implements Repository\Tool
38{
39    use RepositoryUtils;
40
41    /**
42     * @var Security
43     */
44    private $security;
45
46    public function __construct(ManagerRegistry $registry, Security $security)
47    {
48        parent::__construct($registry);
49        $this->security = $security;
50    }
51
52    protected function getModelClass(): string
53    {
54        return Model\Tool::class;
55    }
56
57    /**
58     * Add a collectivity appartenance clause.
59     */
60    protected function addCollectivityClause(QueryBuilder $qb, Collectivity $collectivity): QueryBuilder
61    {
62        return $qb
63            ->andWhere('o.collectivity = :collectivity')
64            ->setParameter('collectivity', $collectivity)
65        ;
66    }
67
68    /**
69     * Add an order to query.
70     */
71    protected function addOrder(QueryBuilder $qb, array $order = []): QueryBuilder
72    {
73        foreach ($order as $key => $dir) {
74            $qb->addOrderBy("o.{$key}", $dir);
75        }
76
77        return $qb;
78    }
79
80    public function count(array $criteria = [])
81    {
82        $qb = $this
83            ->createQueryBuilder()
84            ->leftJoin('o.collectivity', 'collectivity')
85            ->andWhere('collectivity.hasModuleTools = 1')
86            ->select('count(o.id)')
87        ;
88
89        if (isset($criteria['collectivity']) && $criteria['collectivity'] instanceof Collection) {
90            $qb->leftJoin('o.collectivity', 'collectivite');
91            $this->addInClauseCollectivities($qb, $criteria['collectivity']->toArray());
92            unset($criteria['collectivity']);
93        }
94
95        foreach ($criteria as $key => $value) {
96            $this->addWhereClause($qb, $key, $value);
97        }
98
99        return $qb
100            ->getQuery()
101            ->getSingleScalarResult()
102        ;
103    }
104
105    public function findPaginated($firstResult, $maxResults, $orderColumn, $orderDir, $searches, $criteria = [])
106    {
107        $query = $this->createQueryBuilder()
108            ->leftJoin('o.collectivity', 'collectivity')
109            ->leftJoin('o.treatments', 'treatments')
110            ->leftJoin('o.contractors', 'contractors')
111            ->leftJoin('o.service', 'service')
112            ->leftJoin('o.proofs', 'proofs')
113            ->leftJoin('o.mesurements', 'mesurements')
114            ->andWhere('collectivity.hasModuleTools = 1')
115        ;
116
117        if (isset($criteria['collectivity']) && $criteria['collectivity'] instanceof Collection) {
118            $query->leftJoin('o.collectivity', 'collectivite');
119            $this->addInClauseCollectivities($query, $criteria['collectivity']->toArray());
120            unset($criteria['collectivity']);
121        }
122
123        foreach ($criteria as $key => $value) {
124            $this->addWhereClause($query, $key, $value);
125        }
126        $this->addTableWhere($query, $searches);
127        $this->addTableOrder($query, $orderColumn, $orderDir);
128
129        $query = $query->getQuery();
130        $query->setFirstResult($firstResult);
131        $query->setMaxResults($maxResults);
132
133        return new Paginator($query);
134    }
135
136    private function addTableWhere(QueryBuilder $queryBuilder, array $searches)
137    {
138        foreach ($searches as $columnName => $search) {
139            switch ($columnName) {
140                case 'name':
141                    $queryBuilder->andWhere('o.name LIKE :name')
142                        ->setParameter('name', '%' . $search . '%');
143                    break;
144                case 'editor':
145                    $queryBuilder->andWhere('o.editor LIKE :editor')
146                        ->setParameter('editor', '%' . $search . '%');
147                    break;
148                case 'access_control':
149                    $queryBuilder->andWhere('o.access_control.check = :access_control')
150                        ->setParameter('access_control', $search);
151                    break;
152                case 'deletion':
153                    $queryBuilder->andWhere('o.deletion.check = :deletion')
154                        ->setParameter('deletion', $search);
155                    break;
156                case 'tracking':
157                    $queryBuilder->andWhere('o.tracking.check = :tracking')
158                        ->setParameter('tracking', $search);
159                    break;
160                case 'other':
161                    $queryBuilder->andWhere('o.other.check = :other')
162                        ->setParameter('other', $search);
163                    break;
164                case 'type':
165                    $this->addWhereClause($queryBuilder, $columnName, '%' . $search . '%', 'LIKE');
166                    break;
167                case 'collectivity':
168                    $queryBuilder->andWhere('collectivity.name LIKE :colnom')
169                        ->setParameter('colnom', '%' . $search . '%');
170                    break;
171                case 'service':
172                    $queryBuilder->andWhere('service.name LIKE :sernom')
173                        ->setParameter('sernom', '%' . $search . '%');
174                    break;
175                case 'treatments':
176                    $queryBuilder->andWhere('treatments.name LIKE :treatment')
177                        ->setParameter('treatment', '%' . $search . '%');
178                    break;
179                case 'contractors':
180                    $queryBuilder->andWhere('contractors.name LIKE :contractor')
181                        ->setParameter('contractor', '%' . $search . '%');
182                    break;
183                case 'proofs':
184                    $queryBuilder->andWhere('proofs.name LIKE :proof')
185                        ->setParameter('proof', '%' . $search . '%');
186                    break;
187                case 'mesurements':
188                    $queryBuilder->andWhere('mesurements.name LIKE :mesurement')
189                        ->setParameter('mesurement', '%' . $search . '%');
190                    break;
191                case 'createdAt':
192                    if (is_string($search)) {
193                        $queryBuilder->andWhere('o.createdAt BETWEEN :created_start_date AND :created_finish_date')
194                            ->setParameter('created_start_date', date_create_from_format('d/m/y', substr($search, 0, 8))->format('Y-m-d 00:00:00'))
195                            ->setParameter('created_finish_date', date_create_from_format('d/m/y', substr($search, 11, 8))->format('Y-m-d 23:59:59'));
196                    }
197                    break;
198                case 'updatedAt':
199                    if (is_string($search)) {
200                        $queryBuilder->andWhere('o.updatedAt BETWEEN :updated_start_date AND :updated_finish_date')
201                            ->setParameter('updated_start_date', date_create_from_format('d/m/y', substr($search, 0, 8))->format('Y-m-d 00:00:00'))
202                            ->setParameter('updated_finish_date', date_create_from_format('d/m/y', substr($search, 11, 8))->format('Y-m-d 23:59:59'));
203                    }
204                    break;
205                default:
206                    $queryBuilder->andWhere('o.' . $columnName . '.check = :search' . $columnName)
207                    ->setParameter(':search' . $columnName, $search);
208                    break;
209            }
210        }
211    }
212
213    private function addTableOrder(QueryBuilder $queryBuilder, $orderColumn, $orderDir)
214    {
215        switch ($orderColumn) {
216            case 'collectivity':
217                $queryBuilder->addOrderBy('collectivity.name', $orderDir);
218                break;
219            case 'service':
220                $queryBuilder->addOrderBy('service.name', $orderDir);
221                break;
222            case 'type':
223            case 'editor':
224            case 'createdAt':
225            case 'updatedAt':
226            case 'name':
227                $queryBuilder->addOrderBy('o.' . $orderColumn, $orderDir);
228                break;
229            case 'treatments':
230                $queryBuilder->addOrderBy('treatments.name', $orderDir);
231                break;
232            case 'contractors':
233                $queryBuilder->addOrderBy('contractors.name', $orderDir);
234                break;
235            case 'proofs':
236                $queryBuilder->addOrderBy('proofs.name', $orderDir);
237                break;
238            case 'mesurements':
239                $queryBuilder->addOrderBy('mesurements.name', $orderDir);
240                break;
241            default:
242                // $queryBuilder->leftJoin(Model\Embeddable\ComplexChoice::class, 'cc', 'WITH', 'cc')
243                $queryBuilder->addOrderBy('o.' . $orderColumn . '.check', $orderDir);
244                break;
245        }
246    }
247
248    public function findAllByCollectivity(?Collectivity $collectivity = null, array $order = [])
249    {
250        $qb = $this->createQueryBuilder();
251
252        if (!\is_null($collectivity)) {
253            $this->addCollectivityClause($qb, $collectivity);
254        }
255        $this->addOrder($qb, $order);
256
257        return $qb
258            ->getQuery()
259            ->getResult()
260        ;
261    }
262}