Completed
Push — master ( 5e76ce...dcd5e5 )
by Matt
05:37
created

ImageController::upload()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 54
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 6
eloc 26
c 2
b 1
f 0
nc 7
nop 5
dl 0
loc 54
rs 8.8817

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\LocationService;
11
use Doctrine\ORM\EntityManagerInterface;
12
use Exception;
13
use Knp\Component\Pager\PaginatorInterface;
14
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
15
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
16
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
17
use Symfony\Component\HttpFoundation\File\UploadedFile;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\HttpKernel\Exception\HttpException;
22
use Symfony\Component\Messenger\MessageBusInterface;
23
use Symfony\Component\Routing\Annotation\Route;
24
use Symfony\Component\Routing\Exception\InvalidParameterException;
25
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
26
use Symfony\Component\Serializer\Serializer;
27
use Symfony\Component\Serializer\SerializerInterface;
28
use Vich\UploaderBundle\Form\Type\VichImageType;
29
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
30
31
/**
32
 * @Route("/admin/image", name="admin_image_")
33
 */
34
class ImageController extends AbstractController
35
{
36
    /**
37
     * @Route("/", name="index", methods={"GET"})
38
     */
39
    public function index(ImageRepository $imageRepository, PaginatorInterface $paginator, Request $request): Response
40
    {
41
        $query = $imageRepository
42
            ->createQueryBuilder('i')
43
            // Nice orphan check: ->where('i.wanders is empty')
44
            ->orderBy('i.capturedAt', 'DESC')
45
            ->addOrderBy('i.id', 'DESC')
46
            ->getQuery();
47
48
        $pagination = $paginator->paginate(
49
            $query,
50
            $request->query->getInt('page', 1),
51
            10);
52
53
        return $this->render('admin/image/index.html.twig', [
54
            'pagination' => $pagination
55
        ]);
56
    }
57
58
    /**
59
     * @Route("/cluster", name="cluster", methods={"GET"})
60
     */
61
    public function cluster()
62
    {
63
        return $this->render('admin/image/cluster.html.twig', [
64
        ]);
65
    }
66
67
    /**
68
     * @Route("/upload", name="upload", methods={"GET", "POST"})
69
     */
70
    public function upload(
71
        Request $request,
72
        SerializerInterface $serializer,
73
        string $gpxDirectory, // TODO Fix this; it should be using the image uploads directory
74
        MessageBusInterface $messageBus,
75
        UploaderHelper $uploaderHelper
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
            // Queue up some image recognition
97
            $id = $image->getId();
98
            if ($id !== null) {
0 ignored issues
show
introduced by
The condition $id !== null is always true.
Loading history...
99
                $messageBus->dispatch(new RecogniseImage($id));
100
            }
101
102
            // And warm up the image cache the new image
103
            $imagePath = $uploaderHelper->asset($image);
104
            if ($imagePath !== null) {
105
                $messageBus->dispatch(new WarmImageCache($imagePath));
106
            }
107
108
            // It's not exactly an API response, but it'll do until we switch to handling this
109
            // a bit more properly. At least it's a JSON repsonse and *doesn't include the entire
110
            // file we just uploaded*, thanks to the IGNORED_ATTRIBUTES. Because we set up the
111
            // image URIs in a postPersist event listener, this also contains everything you'd
112
            // need to build an image in HTML.
113
            return new JsonResponse($serializer->serialize($image, 'jsonld', [AbstractNormalizer::IGNORED_ATTRIBUTES => ['imageFile']]), 201,[], true);
114
        }
115
116
        // Normal GET request.
117
        $disk = [];
118
        $disk['free'] = disk_free_space($gpxDirectory);
119
        $disk['total'] = disk_total_space($gpxDirectory);
120
        $disk['used'] = $disk['total'] - $disk['free'];
121
        $disk['percent'] = $disk['used'] / $disk['total'];
122
        return $this->render('admin/image/upload.html.twig', [
123
                'disk' => $disk
124
        ]);
125
    }
126
127
    /**
128
     * @Route("/{id}", name="show", methods={"GET"})
129
     */
130
    public function show(Image $image): Response
131
    {
132
        return $this->render('/admin/image/show.html.twig', [
133
            'image' => $image,
134
        ]);
135
    }
136
137
    /**
138
     * @Route("/{id}/edit", name="edit", methods={"GET","POST"})
139
     */
140
    public function edit(Request $request, Image $image): Response
141
    {
142
        $form = $this->createForm(ImageType::class, $image);
143
        $form->handleRequest($request);
144
        if ($form->isSubmitted() && $form->isValid()) {
145
            $this->getDoctrine()->getManager()->flush();
146
            //dd($form);
147
            return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
148
        }
149
150
        return $this->render('admin/image/edit.html.twig', [
151
            'image' => $image,
152
            'form' => $form->createView(),
153
        ]);
154
    }
155
156
    /**
157
     * @Route("/{id}", name="delete", methods={"DELETE"})
158
     */
159
    public function delete(Request $request, Image $image): Response
160
    {
161
        if ($this->isCsrfTokenValid('delete'.$image->getId(), $request->request->get('_token'))) {
162
            $entityManager = $this->getDoctrine()->getManager();
163
            $entityManager->remove($image);
164
            $entityManager->flush();
165
        }
166
167
        return $this->redirectToRoute('admin_image_index');
168
    }
169
170
    /**
171
     * @Route("/{id}/set_location", name="set_location", methods={"POST"})
172
     */
173
    public function setLocation(Request $request, Image $image, LocationService $locationService, EntityManagerInterface $entityManager): Response
174
    {
175
        if ($this->isCsrfTokenValid('set_location'.$image->getId(), $request->request->get('_token'))) {
176
            $neighbourhood  = $locationService->getLocationName($image->getLatitude(), $image->getLongitude());
177
            if ($neighbourhood !== null) {
178
                $image->setLocation($neighbourhood);
179
                $entityManager->persist($image);
180
                $entityManager->flush();
181
            }
182
        }
183
184
        return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
185
    }
186
187
    /**
188
     * @Route("/{id}/set_auto_tags", name="set_auto_tags", methods={"POST"})
189
     */
190
    public function setAutoTags(Request $request, Image $image, MessageBusInterface $messageBus): Response
191
    {
192
        if ($this->isCsrfTokenValid('set_auto_tags'.$image->getId(), $request->request->get('_token'))) {
193
            $imageId = $image->getId();
194
            if ($imageId === null) {
195
                throw new InvalidParameterException('No image id in setAutoTags');
196
            }
197
            $messageBus->dispatch(new RecogniseImage($imageId, true));
198
            $this->addFlash('success', 'Image re-queued for recognition.');
199
        }
200
        return $this->redirectToRoute('admin_image_show', ['id' => $image->getId()]);
201
    }
202
}
203