Completed
Push — master ( 991c05...763044 )
by Matt
06:20
created

ImageController   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 58
c 2
b 1
f 0
dl 0
loc 151
rs 10
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A delete() 0 9 2
A show() 0 4 1
A edit() 0 13 3
A setLocation() 0 12 3
A upload() 0 38 4
A setAutoTags() 0 11 3
A cluster() 0 3 1
A index() 0 16 1
1
<?php
2
3
namespace App\Controller\Admin;
4
5
use App\Entity\Image;
6
use App\Form\ImageType;
7
use App\Message\RecogniseImage;
8
use App\Message\WarmImageCache;
9
use App\Repository\ImageRepository;
10
use App\Service\DiskStatsService;
11
use App\Service\LocationService;
12
use Doctrine\ORM\EntityManagerInterface;
13
use Exception;
14
use Knp\Component\Pager\PaginatorInterface;
15
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
16
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
17
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
18
use Symfony\Component\HttpFoundation\File\UploadedFile;
19
use Symfony\Component\HttpFoundation\JsonResponse;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\HttpKernel\Exception\HttpException;
23
use Symfony\Component\Messenger\MessageBusInterface;
24
use Symfony\Component\Routing\Annotation\Route;
25
use Symfony\Component\Routing\Exception\InvalidParameterException;
26
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
27
use Symfony\Component\Serializer\Serializer;
28
use Symfony\Component\Serializer\SerializerInterface;
29
use Vich\UploaderBundle\Form\Type\VichImageType;
30
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
31
32
/**
33
 * @Route("/admin/image", name="admin_image_")
34
 */
35
class ImageController extends AbstractController
36
{
37
    /**
38
     * @Route("/", name="index", methods={"GET"})
39
     */
40
    public function index(ImageRepository $imageRepository, PaginatorInterface $paginator, Request $request): Response
41
    {
42
        $query = $imageRepository
43
            ->createQueryBuilder('i')
44
            // Nice orphan check: ->where('i.wanders is empty')
45
            ->orderBy('i.capturedAt', 'DESC')
46
            ->addOrderBy('i.id', 'DESC')
47
            ->getQuery();
48
49
        $pagination = $paginator->paginate(
50
            $query,
51
            $request->query->getInt('page', 1),
52
            10);
53
54
        return $this->render('admin/image/index.html.twig', [
55
            'pagination' => $pagination
56
        ]);
57
    }
58
59
    /**
60
     * @Route("/cluster", name="cluster", methods={"GET"})
61
     */
62
    public function cluster()
63
    {
64
        return $this->render('admin/image/cluster.html.twig', [
65
        ]);
66
    }
67
68
    /**
69
     * @Route("/upload", name="upload", methods={"GET", "POST"})
70
     */
71
    public function upload(
72
            Request $request,
73
            SerializerInterface $serializer,
74
            string $imagesDirectory,
75
            DiskStatsService $diskStatsService
76
        ): Response
77
    {
78
        if ($request->isMethod('POST')) {
79
80
            $token = $request->request->get('token');
81
            if (!$this->isCsrfTokenValid('image_upload', $token)) {
82
                return $this->json([ 'error' => 'Invalid CSRF token'], 401);
83
            }
84
85
            $file = $request->files->get('file');
86
            if (!$file instanceof UploadedFile) {
87
                throw new HttpException(500, "No uploaded file found.");
88
            }
89
90
            $image = new Image();
91
            $image->setImageFile($file);
92
            $entityManager = $this->getDoctrine()->getManager();
93
            $entityManager->persist($image);
94
            $entityManager->flush();
95
96
            // It's not exactly an API response, but it'll do until we switch to handling this
97
            // a bit more properly. At least it's a JSON repsonse and *doesn't include the entire
98
            // file we just uploaded*, thanks to the IGNORED_ATTRIBUTES. Because we set up the
99
            // image URIs in a postPersist event listener, this also contains everything you'd
100
            // need to build an image in HTML.
101
            return new JsonResponse($serializer->serialize($image, 'jsonld', [AbstractNormalizer::IGNORED_ATTRIBUTES => ['imageFile']]), 201,[], true);
102
        }
103
104
        // Normal GET request.
105
        $disk = $diskStatsService->getDiskStats($imagesDirectory);
106
107
        return $this->render('admin/image/upload.html.twig', [
108
                'disk' => $disk
109
        ]);
110
    }
111
112
    /**
113
     * @Route("/{id}", name="show", methods={"GET"})
114
     */
115
    public function show(Image $image): Response
116
    {
117
        return $this->render('/admin/image/show.html.twig', [
118
            'image' => $image,
119
        ]);
120
    }
121
122
    /**
123
     * @Route("/{id}/edit", name="edit", methods={"GET","POST"})
124
     */
125
    public function edit(Request $request, Image $image): Response
126
    {
127
        $form = $this->createForm(ImageType::class, $image);
128
        $form->handleRequest($request);
129
        if ($form->isSubmitted() && $form->isValid()) {
130
            $this->getDoctrine()->getManager()->flush();
131
            //dd($form);
132
            return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
133
        }
134
135
        return $this->render('admin/image/edit.html.twig', [
136
            'image' => $image,
137
            'form' => $form->createView(),
138
        ]);
139
    }
140
141
    /**
142
     * @Route("/{id}", name="delete", methods={"DELETE"})
143
     */
144
    public function delete(Request $request, Image $image): Response
145
    {
146
        if ($this->isCsrfTokenValid('delete'.$image->getId(), $request->request->get('_token'))) {
147
            $entityManager = $this->getDoctrine()->getManager();
148
            $entityManager->remove($image);
149
            $entityManager->flush();
150
        }
151
152
        return $this->redirectToRoute('admin_image_index');
153
    }
154
155
    /**
156
     * @Route("/{id}/set_location", name="set_location", methods={"POST"})
157
     */
158
    public function setLocation(Request $request, Image $image, LocationService $locationService, EntityManagerInterface $entityManager): Response
159
    {
160
        if ($this->isCsrfTokenValid('set_location'.$image->getId(), $request->request->get('_token'))) {
161
            $neighbourhood  = $locationService->getLocationName($image->getLatitude(), $image->getLongitude());
162
            if ($neighbourhood !== null) {
163
                $image->setLocation($neighbourhood);
164
                $entityManager->persist($image);
165
                $entityManager->flush();
166
            }
167
        }
168
169
        return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
170
    }
171
172
    /**
173
     * @Route("/{id}/set_auto_tags", name="set_auto_tags", methods={"POST"})
174
     */
175
    public function setAutoTags(Request $request, Image $image, MessageBusInterface $messageBus): Response
176
    {
177
        if ($this->isCsrfTokenValid('set_auto_tags'.$image->getId(), $request->request->get('_token'))) {
178
            $imageId = $image->getId();
179
            if ($imageId === null) {
180
                throw new InvalidParameterException('No image id in setAutoTags');
181
            }
182
            $messageBus->dispatch(new RecogniseImage($imageId, true));
183
            $this->addFlash('success', 'Image re-queued for recognition.');
184
        }
185
        return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
186
    }
187
}
188