Builder::getQuerySelect()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * AnimeDb package.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/GPL-3.0 GPL v3
8
 */
9
10
namespace AnimeDb\Bundle\CatalogBundle\Service\Item\Search\Selector;
11
12
use Doctrine\Bundle\DoctrineBundle\Registry;
13
use AnimeDb\Bundle\CatalogBundle\Entity\Search;
14
use Doctrine\ORM\QueryBuilder;
15
use AnimeDb\Bundle\CatalogBundle\Entity\Type;
16
use AnimeDb\Bundle\CatalogBundle\Entity\Country;
17
use AnimeDb\Bundle\CatalogBundle\Entity\Storage;
18
use AnimeDb\Bundle\CatalogBundle\Entity\Studio;
19
20
/**
21
 * Search selector builder.
22
 *
23
 * @author  Peter Gribanov <[email protected]>
24
 */
25
class Builder
26
{
27
    /**
28
     * @var QueryBuilder
29
     */
30
    protected $select;
31
32
    /**
33
     * @var QueryBuilder
34
     */
35
    protected $total;
36
37
    /**
38
     * @param Registry $doctrine
39
     */
40 34
    public function __construct(Registry $doctrine)
41
    {
42 34
        $this->select = $doctrine->getRepository('AnimeDbCatalogBundle:Item')
43 34
            ->createQueryBuilder('i')
44 34
            ->groupBy('i');
45 34
        $this->total = $doctrine->getRepository('AnimeDbCatalogBundle:Item')
46 34
            ->createQueryBuilder('i')
47 34
            ->select('COUNT(DISTINCT i)');
48 34
    }
49
50
    /**
51
     * @return QueryBuilder
52
     */
53 1
    public function getQuerySelect()
54
    {
55 1
        return $this->select;
56
    }
57
58
    /**
59
     * @return QueryBuilder
60
     */
61 1
    public function getQueryTotal()
62
    {
63 1
        return $this->total;
64
    }
65
66
    /**
67
     * @param Search $entity
68
     *
69
     * @return Builder
70
     */
71 6
    public function addName(Search $entity)
72
    {
73 6
        if ($entity->getName()) {
74 5
            $name = mb_strtolower($entity->getName(), 'UTF8');
75
            $this->add(function (QueryBuilder $query) use ($name) {
76
                $query
77 5
                    ->innerJoin('i.names', 'n')
78 5
                    ->andWhere('LOWER(i.name) LIKE :name OR LOWER(n.name) LIKE :name')
79 5
                    ->setParameter('name', preg_replace('/%+/', '%%', $name).'%');
80 5
            });
81 5
        }
82
83 6
        return $this;
84
    }
85
86
    /**
87
     * @param Search $entity
88
     *
89
     * @return Builder
90
     */
91 2 View Code Duplication
    public function addDateAdd(Search $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
    {
93 2
        if ($entity->getDateAdd() instanceof \DateTime) {
94
            $this->add(function (QueryBuilder $query) use ($entity) {
95
                $query
96 1
                    ->andWhere('i.date_add >= :date_add')
97 1
                    ->setParameter('date_add', $entity->getDateAdd()->format('Y-m-d'));
98 1
            });
99 1
        }
100
101 2
        return $this;
102
    }
103
104
    /**
105
     * @param Search $entity
106
     *
107
     * @return Builder
108
     */
109 2 View Code Duplication
    public function addDatePremiere(Search $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
    {
111 2
        if ($entity->getDatePremiere() instanceof \DateTime) {
112
            $this->add(function (QueryBuilder $query) use ($entity) {
113
                $query
114 1
                    ->andWhere('i.date_premiere >= :date_premiere')
115 1
                    ->setParameter('date_premiere', $entity->getDatePremiere()->format('Y-m-d'));
116 1
            });
117 1
        }
118
119 2
        return $this;
120
    }
121
122
    /**
123
     * @param Search $entity
124
     *
125
     * @return Builder
126
     */
127 2 View Code Duplication
    public function addDateEnd(Search $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
    {
129 2
        if ($entity->getDateEnd() instanceof \DateTime) {
130
            $this->add(function (QueryBuilder $query) use ($entity) {
131
                $query
132 1
                    ->andWhere('i.date_end <= :date_end')
133 1
                    ->setParameter('date_end', $entity->getDateEnd()->format('Y-m-d'));
134 1
            });
135 1
        }
136
137 2
        return $this;
138
    }
139
140
    /**
141
     * @param Search $entity
142
     *
143
     * @return Builder
144
     */
145 2
    public function addCountry(Search $entity)
146
    {
147 2
        if ($entity->getCountry() instanceof Country) {
148
            $this->add(function (QueryBuilder $query) use ($entity) {
149
                $query
150 1
                    ->andWhere('i.country = :country')
151 1
                    ->setParameter('country', $entity->getCountry()->getId());
152 1
            });
153 1
        }
154
155 2
        return $this;
156
    }
157
158
    /**
159
     * @param Search $entity
160
     *
161
     * @return Builder
162
     */
163 2
    public function addStorage(Search $entity)
164
    {
165 2
        if ($entity->getStorage() instanceof Storage) {
166
            $this->add(function (QueryBuilder $query) use ($entity) {
167
                $query
168 1
                    ->andWhere('i.storage = :storage')
169 1
                    ->setParameter('storage', $entity->getStorage()->getId());
170 1
            });
171 1
        }
172
173 2
        return $this;
174
    }
175
176
    /**
177
     * @param Search $entity
178
     *
179
     * @return Builder
180
     */
181 2
    public function addType(Search $entity)
182
    {
183 2
        if ($entity->getType() instanceof Type) {
184
            $this->add(function (QueryBuilder $query) use ($entity) {
185
                $query
186 1
                    ->andWhere('i.type = :type')
187 1
                    ->setParameter('type', $entity->getType()->getId());
188 1
            });
189 1
        }
190
191 2
        return $this;
192
    }
193
194
    /**
195
     * @param Search $entity
196
     *
197
     * @return Builder
198
     */
199 2 View Code Duplication
    public function addGenres(Search $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
200
    {
201 2
        if ($entity->getGenres()->count()) {
202
            $this->add(function (QueryBuilder $query) use ($entity) {
203 1
                $ids = [];
204 1
                foreach ($entity->getGenres() as $genre) {
205 1
                    $ids[] = (int) $genre->getId();
206 1
                }
207
                $query
208 1
                    ->innerJoin('i.genres', 'g')
209 1
                    ->andWhere('g.id IN ('.implode(',', $ids).')');
210 1
            });
211 1
            $this->select->andHaving('COUNT(i.id) = '.$entity->getGenres()->count());
212 1
        }
213
214 2
        return $this;
215
    }
216
217
    /**
218
     * Add labels.
219
     *
220
     * @param Search $entity
221
     *
222
     * @return Builder
223
     */
224 2 View Code Duplication
    public function addLabels(Search $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
    {
226 2
        if ($entity->getLabels()->count()) {
227
            $this->add(function (QueryBuilder $query) use ($entity) {
228 1
                $ids = [];
229 1
                foreach ($entity->getLabels() as $label) {
230 1
                    $ids[] = (int) $label->getId();
231 1
                }
232
                $query
233 1
                    ->innerJoin('i.labels', 'l')
234 1
                    ->andWhere('l.id IN ('.implode(',', $ids).')');
235 1
            });
236 1
            $this->select->andHaving('COUNT(i.id) = '.$entity->getLabels()->count());
237 1
        }
238
239 2
        return $this;
240
    }
241
242
    /**
243
     * @param Search $entity
244
     *
245
     * @return Builder
246
     */
247 2
    public function addStudio(Search $entity)
248
    {
249 2
        if ($entity->getStudio() instanceof Studio) {
250 1
            $this->add(function (QueryBuilder $query) use ($entity) {
251
                $query
252 1
                    ->andWhere('i.studio = :studio')
253 1
                    ->setParameter('studio', $entity->getStudio()->getId());
254 1
            });
255 1
        }
256
257 2
        return $this;
258
    }
259
260
    /**
261
     * Do add data to queries.
262
     *
263
     * @param \Closure $adder
264
     */
265 14
    protected function add(\Closure $adder)
266
    {
267 14
        $adder($this->select);
268 14
        $adder($this->total);
269 14
    }
270
271
    /**
272
     * @param int $limit
273
     *
274
     * @return Builder
275
     */
276 3
    public function limit($limit)
277
    {
278 3
        if ($limit > 0) {
279 1
            $this->select->setMaxResults($limit);
280 1
        }
281
282 3
        return $this;
283
    }
284
285
    /**
286
     * @param int $offset
287
     *
288
     * @return Builder
289
     */
290 3
    public function offset($offset)
291
    {
292 3
        if ($offset > 0) {
293 1
            $this->select->setFirstResult($offset);
294 1
        }
295
296 3
        return $this;
297
    }
298
299
    /**
300
     * @param string $column
301
     * @param string $direction
302
     *
303
     * @return Builder
304
     */
305 1
    public function sort($column, $direction)
306
    {
307 1
        $this->select->orderBy('i.'.$column, $direction);
308
309 1
        return $this;
310
    }
311
}
312