Passed
Pull Request — master (#164)
by Matt
04:41
created

ImageController::filterQueryByRating()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 4
nop 2
dl 0
loc 20
rs 9.4555
c 0
b 0
f 0
1
<?php
2
3
namespace App\Controller\Image;
4
5
use App\Entity\Image;
6
use App\Form\ImageFilterType;
7
use App\Repository\ImageRepository;
8
use Carbon\Carbon;
9
use Doctrine\ORM\QueryBuilder;
10
use Knp\Component\Pager\PaginatorInterface;
11
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12
use Symfony\Component\HttpFoundation\InputBag;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\Routing\Annotation\Route;
16
17
/**
18
 * @Route("/image", name="image_")
19
 */
20
class ImageController extends AbstractController
21
{
22
    /**
23
     * @Route("/{id}", name="show", methods={"GET"})
24
     */
25
    public function show(Image $image, ImageRepository $imageRepository): Response
26
    {
27
        $prev = $imageRepository->findPrev($image);
28
        $next = $imageRepository->findNext($image);
29
        return $this->render('image/show.html.twig', [
30
            'image' => $image,
31
            'prev' => $prev,
32
            'next' => $next
33
        ]);
34
    }
35
36
    /**
37
     * @Route("", name="index", methods={"GET"})
38
     */
39
    public function index(
40
        Request $request,
41
        ImageRepository $imageRepository,
42
        PaginatorInterface $paginator
43
    ): Response {
44
45
        $qb = $imageRepository->getReversePaginatorQueryBuilder();
46
47
        $this->filterQueryByYearAndMonth($request->query, $qb);
48
        $this->filterQueryByRating($request->query, $qb);
49
50
        if ($request->query->has('location')) {
51
            $qb->andWhere('i.location = :location')
52
                ->setParameter('location', $request->query->get('location'));
53
        }
54
55
        $query = $qb->getQuery();
56
57
        $page = $request->query->getInt('page', 1);
58
        $pagination = $paginator->paginate(
59
            $query,
60
            $page,
61
            20
62
        );
63
64
        return $this->render('image/index.html.twig', [
65
            'image_pagination' => $pagination
66
        ]);
67
    }
68
69
    private function filterQueryByYearAndMonth(InputBag $params, QueryBuilder &$qb): QueryBuilder
70
    {
71
        // Our year parameter can be entirely missing, or "any", as well as an
72
        // integer year.
73
        $year = intval($params->get('year', -1));
74
        if ($year > 1900 && $year < 5000) { // Don't want to send any implausible years to MySQL
75
            // We can optionally have a month to limit the date range
76
            // even further.
77
            $month = $params->getInt('month', 0);
78
            if ($month < 1 || $month > 12) {
79
                // Just the year
80
                $startDate = Carbon::create($year, 1, 1);
81
                $endDate = Carbon::create($year + 1, 1, 1);
82
            } else {
83
                // We're looking at a particular month of the year
84
                /** @var Carbon $startDate */
85
                $startDate = Carbon::create($year, $month, 1);
86
                $endDate = $startDate->copy()->addMonths(1);
87
            }
88
            $qb->andWhere('i.capturedAt >= :startDate')
89
                ->setParameter('startDate', $startDate)
90
                ->andWhere('i.capturedAt < :endDate')
91
                ->setParameter('endDate', $endDate);
92
        }
93
        return $qb;
94
    }
95
96
    private function filterQueryByRating(InputBag $params, QueryBuilder &$qb): QueryBuilder
97
    {
98
        $rating = $params->getInt('rating', -1);
99
        if ($rating >= 0 && $rating <= 5) {
100
            $ratingCompare = $params->get('rating_compare', 'eq');
101
            switch ($ratingCompare) {
102
                case 'lte':
103
                    $qb->andWhere($qb->expr()->lte('i.rating', ':rating'));
104
                    break;
105
                case 'gte':
106
                    $qb->andWhere($qb->expr()->gte('i.rating', ':rating'));
107
                    break;
108
                default:
109
                    // 'eq'
110
                    $qb->andWhere($qb->expr()->eq('i.rating', ':rating'));
111
                    break;
112
            }
113
            $qb->setParameter('rating', $rating);
114
        }
115
        return $qb;
116
    }
117
}
118