Completed
Push — master ( 0b4911...4851fa )
by Valentyn
04:19 queued 11s
created

Genre::getIntersectIds()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
c 0
b 0
f 0
ccs 12
cts 12
cp 1
rs 9.568
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
namespace App\Filters\Movie;
4
5
use App\Filters\Filter;
6
use Doctrine\ORM\QueryBuilder;
7
use Symfony\Component\HttpFoundation\ParameterBag;
8
9
/**
10
 * /api/movies?g[]=2&g[]=1&gt=AND => Will display all movies in genres with ids 1 & 2 (In both)
11
 * /api/movies?g[]=2&g[]=1 => Will display all movies in genres with ids 1 & 2 (At least in one of them)
12
 */
13
class Genre implements Filter
14
{
15
    private const CONDITION_TYPE_OR = 'OR';
16
    private const CONDITION_TYPE_AND = 'AND';
17
18 31
    public function handle(ParameterBag $params, QueryBuilder $qb): QueryBuilder
19
    {
20 31
        $conditionType = $params->get('gt', self::CONDITION_TYPE_OR);
21 31
        $genres = $params->get('g', []);
22
23 31
        if (count($genres) === 0) {
24 27
            return $qb;
25
        }
26
27
        array_walk($genres, static function ($id) { return (int)$id; });
28
29 4
        if ($conditionType === self::CONDITION_TYPE_OR) {
30
            return $qb
31 3
                ->leftJoin('m.genres', 'mg')
32 3
                ->andWhere('mg.id IN (:filter_genres)')
33 3
                ->setParameter('filter_genres', $genres);
34
        }
35
36 1
        $moviesIds = $this->getIntersectIds($qb, $genres);
37 1
        return $qb->andWhere($qb->expr()->in('m.id', $moviesIds));
38
    }
39
40 1
    private function getIntersectIds(QueryBuilder $qb, array $genres): array
41
    {
42 1
        $newQb = clone $qb;
43
        $query = $newQb
44 1
            ->select('m.id')
45 1
            ->leftJoin('m.genres', 'mg')
46 1
            ->andWhere('mg.id = :filter_genre_id')
47 1
            ->getQuery()
48
        ;
49
50 1
        $ids = [];
51 1
        foreach ($genres as $genreId) {
52 1
            $ids[] = array_map(
53
                static function($item) { return $item['id']; },
54
                $query
55 1
                    ->setParameter('filter_genre_id', $genreId)
56 1
                    ->getArrayResult()
57
            );
58
        }
59
60 1
        return array_intersect(...$ids);
61
    }
62
}