Completed
Pull Request — master (#1672)
by Derek Stephen
15:58
created

MediaController   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 525
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 58
lcom 1
cbo 14
dl 0
loc 525
rs 4.5599
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A showAction() 0 44 4
A deleteAction() 0 32 4
A bulkUploadAction() 0 9 1
F bulkUploadSubmitAction() 0 141 27
A returnJsonError() 0 14 1
A dropAction() 0 33 5
A createAction() 0 4 1
B createAndRedirect() 0 63 5
A createModalAction() 0 23 4
A moveMedia() 0 22 3
A bulkMoveAction() 0 37 3

How to fix   Complexity   

Complex Class

Complex classes like MediaController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MediaController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Kunstmaan\MediaBundle\Controller;
4
5
use Exception;
6
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
7
use Kunstmaan\MediaBundle\Entity\Folder;
8
use Kunstmaan\MediaBundle\Entity\Media;
9
use Kunstmaan\MediaBundle\Form\BulkMoveMediaType;
10
use Kunstmaan\MediaBundle\Helper\MediaManager;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
13
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
14
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
15
use Symfony\Component\HttpFoundation\File\File;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\RedirectResponse;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
21
/**
22
 * MediaController
23
 */
24
class MediaController extends Controller
25
{
26
27
    /**
28
     * @param Request $request
29
     * @param int     $mediaId
30
     *
31
     * @Route("/{mediaId}", requirements={"mediaId" = "\d+"}, name="KunstmaanMediaBundle_media_show")
32
     *
33
     * @return Response
34
     */
35
    public function showAction(Request $request, $mediaId)
36
    {
37
        $em = $this->getDoctrine()->getManager();
38
39
        /* @var Media $media */
40
        $media = $em->getRepository('KunstmaanMediaBundle:Media')->getMedia($mediaId);
41
        $folder = $media->getFolder();
42
43
        /* @var MediaManager $mediaManager */
44
        $mediaManager = $this->get('kunstmaan_media.media_manager');
45
        $handler = $mediaManager->getHandler($media);
46
        $helper = $handler->getFormHelper($media);
47
48
        $form = $this->createForm($handler->getFormType(), $helper, $handler->getFormTypeOptions());
49
50
        if ($request->isMethod('POST')) {
51
            $form->handleRequest($request);
52
            if ($form->isSubmitted() && $form->isValid()) {
53
                $media = $helper->getMedia();
54
                $em->getRepository('KunstmaanMediaBundle:Media')->save($media);
55
56
                return new RedirectResponse(
57
                    $this->generateUrl(
58
                        'KunstmaanMediaBundle_media_show',
59
                        ['mediaId' => $media->getId()]
60
                    )
61
                );
62
            }
63
        }
64
        $showTemplate = $mediaManager->getHandler($media)->getShowTemplate($media);
65
66
        return $this->render(
67
            $showTemplate,
68
            [
69
                'handler' => $handler,
70
                'foldermanager' => $this->get('kunstmaan_media.folder_manager'),
71
                'mediamanager' => $this->get('kunstmaan_media.media_manager'),
72
                'editform' => $form->createView(),
73
                'media' => $media,
74
                'helper' => $helper,
75
                'folder' => $folder,
76
            ]
77
        );
78
    }
79
80
    /**
81
     * @param Request $request
82
     * @param int     $mediaId
83
     *
84
     * @Route("/delete/{mediaId}", requirements={"mediaId" = "\d+"}, name="KunstmaanMediaBundle_media_delete")
85
     *
86
     * @return RedirectResponse
87
     */
88
    public function deleteAction(Request $request, $mediaId)
89
    {
90
        $em = $this->getDoctrine()->getManager();
91
92
        /* @var Media $media */
93
        $media = $em->getRepository('KunstmaanMediaBundle:Media')->getMedia($mediaId);
94
        $medianame = $media->getName();
95
        $folder = $media->getFolder();
96
97
        $em->getRepository('KunstmaanMediaBundle:Media')->delete($media);
98
99
        $this->addFlash(
100
            FlashTypes::SUCCESS,
101
            $this->get('translator')->trans(
102
                'kuma_admin.media.flash.deleted_success.%medianame%',
103
                [
104
                    '%medianame%' => $medianame,
105
                ]
106
            )
107
        );
108
109
        // If the redirect url is passed via the url we use it
110
        $redirectUrl = $request->query->get('redirectUrl');
111
        if (empty($redirectUrl) || (\strpos($redirectUrl, $request->getSchemeAndHttpHost()) !== 0 && \strpos($redirectUrl, '/') !== 0)) {
112
            $redirectUrl = $this->generateUrl(
113
                'KunstmaanMediaBundle_folder_show',
114
                ['folderId' => $folder->getId()]
115
            );
116
        }
117
118
        return new RedirectResponse($redirectUrl);
119
    }
120
121
    /**
122
     * @param int $folderId
123
     *
124
     * @Route("bulkupload/{folderId}", requirements={"folderId" = "\d+"}, name="KunstmaanMediaBundle_media_bulk_upload")
125
     * @Template()
126
     *
127
     * @return array|RedirectResponse
128
     */
129
    public function bulkUploadAction($folderId)
130
    {
131
        $em = $this->getDoctrine()->getManager();
132
133
        /* @var Folder $folder */
134
        $folder = $em->getRepository('KunstmaanMediaBundle:Folder')->getFolder($folderId);
135
136
        return ['folder' => $folder];
137
    }
138
139
    /**
140
     * @param Request $request
141
     * @param int     $folderId
142
     *
143
     * @Route("bulkuploadsubmit/{folderId}", requirements={"folderId" = "\d+"}, name="KunstmaanMediaBundle_media_bulk_upload_submit")
144
     * @Template()
145
     *
146
     * @return JsonResponse
147
     */
148
    public function bulkUploadSubmitAction(Request $request, $folderId)
149
    {
150
        // Settings
151
        if (\ini_get('upload_tmp_dir')) {
152
            $tempDir = \ini_get('upload_tmp_dir');
153
        } else {
154
            $tempDir = \sys_get_temp_dir();
155
        }
156
        $targetDir = \rtrim($tempDir, '/').DIRECTORY_SEPARATOR.'plupload';
157
        $cleanupTargetDir = true; // Remove old files
158
        $maxFileAge = 5 * 60 * 60; // Temp file age in seconds
159
160
        // Create target dir
161
        if (!\file_exists($targetDir)) {
162
            @\mkdir($targetDir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
163
        }
164
165
        // Get a file name
166
        if ($request->request->has('name')) {
167
            $fileName = $request->request->get('name');
168
        } elseif (0 !== $request->files->count()) {
169
            $fileName = $request->files->get('file')['name'];
170
        } else {
171
            $fileName = \uniqid('file_', false);
172
        }
173
        $filePath = $targetDir.DIRECTORY_SEPARATOR.$fileName;
174
175
        $chunk = 0;
176
        $chunks = 0;
177
        // Chunking might be enabled
178
        if ($request->request->has('chunk')) {
179
            $chunk = $request->request->getInt('chunk');
180
        }
181
        if ($request->request->has('chunks')) {
182
            $chunks = $request->request->getInt('chunks');
183
        }
184
185
        // Remove old temp files
186
        if ($cleanupTargetDir) {
187
            if (!\is_dir($targetDir) || !$dir = \opendir($targetDir)) {
188
189
                return $this->returnJsonError('100', 'Failed to open temp directory.');
190
            }
191
192
            while (($file = \readdir($dir)) !== false) {
193
                $tmpFilePath = $targetDir.DIRECTORY_SEPARATOR.$file;
194
195
                // If temp file is current file proceed to the next
196
                if ($tmpFilePath === "{$filePath}.part") {
197
198
                    continue;
199
                }
200
201
                // Remove temp file if it is older than the max age and is not the current file
202
                if (\preg_match('/\.part$/', $file) && (\filemtime($tmpFilePath) < \time() - $maxFileAge)) {
203
                    $success = @\unlink($tmpFilePath);
204
                    if ($success !== true) {
205
206
                        return $this->returnJsonError('106', 'Could not remove temp file: '.$filePath);
207
                    }
208
                }
209
            }
210
            \closedir($dir);
211
        }
212
213
        // Open temp file
214
        if (!$out = @\fopen("{$filePath}.part", $chunks ? 'ab' : 'wb')) {
215
216
            return $this->returnJsonError('102', 'Failed to open output stream.');
217
        }
218
219
        if (0 !== $request->files->count()) {
220
221
            $_file = $request->files->get('file');
222
            if ($_file->getError() > 0 || !\is_uploaded_file($_file->getRealPath())) {
223
                return $this->returnJsonError('103', 'Failed to move uploaded file.');
224
            }
225
226
            // Read binary input stream and append it to temp file
227
            if (!$input = @\fopen($_file->getRealPath(), 'rb')) {
228
229
                return $this->returnJsonError('101', 'Failed to open input stream.');
230
            }
231
        } else {
232
            if (!$input = @\fopen('php://input', 'rb')) {
233
234
                return $this->returnJsonError('101', 'Failed to open input stream.');
235
            }
236
        }
237
238
        while ($buff = \fread($input, 4096)) {
239
            \fwrite($out, $buff);
240
        }
241
242
        @\fclose($out);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
243
        @\fclose($input);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
244
245
        // Check if file has been uploaded
246
        if (!$chunks || $chunk === $chunks - 1) {
247
            // Strip the temp .part suffix off
248
            \rename("{$filePath}.part", $filePath);
249
        }
250
251
252
        $em = $this->getDoctrine()->getManager();
253
        /* @var Folder $folder */
254
        $folder = $em->getRepository('KunstmaanMediaBundle:Folder')->getFolder($folderId);
255
        $file = new File($filePath);
256
257
        try {
258
            /* @var Media $media */
259
            $media = $this->get('kunstmaan_media.media_manager')->getHandler($file)->createNew($file);
260
            $media->setFolder($folder);
261
            $em->getRepository(Media::class)->save($media);
262
        } catch (Exception $e) {
263
            return $this->returnJsonError('104', 'Failed performing save on media-manager');
264
        }
265
266
        $success = \unlink($filePath);
267
        if ($success !== true) {
268
269
            return $this->returnJsonError('105', 'Could not remove temp file: '.$filePath);
270
        }
271
272
273
        // Send headers making sure that the file is not cached (as it happens for example on iOS devices)
274
        $response = new JsonResponse(
275
            [
276
                'jsonrpc' => '2.0',
277
                'result' => '',
278
                'id' => 'id',
279
            ], JsonResponse::HTTP_OK, [
280
                'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
281
                'Last-Modified' => \gmdate('D, d M Y H:i:s').' GMT',
282
                'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
283
                'Pragma' => 'no-cache',
284
            ]
285
        );
286
287
        return $response;
288
    }
289
290
    private function returnJsonError($code, $message)
291
    {
292
293
        return new JsonResponse(
294
            [
295
                'jsonrpc' => '2.0',
296
                'error ' => [
297
                    'code' => $code,
298
                    'message' => $message,
299
                ],
300
                'id' => 'id',
301
            ]
302
        );
303
    }
304
305
    /**
306
     * @param Request $request
307
     * @param int     $folderId
308
     *
309
     * @Route("drop/{folderId}", requirements={"folderId" = "\d+"}, name="KunstmaanMediaBundle_media_drop_upload")
310
     * @Method({"GET", "POST"})
311
     *
312
     * @return JsonResponse
313
     */
314
    public function dropAction(Request $request, $folderId)
315
    {
316
        $em = $this->getDoctrine()->getManager();
317
318
        /* @var Folder $folder */
319
        $folder = $em->getRepository('KunstmaanMediaBundle:Folder')->getFolder($folderId);
320
321
        $drop = null;
0 ignored issues
show
Unused Code introduced by
$drop is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
322
323
        if ($request->files->has('files') && $request->files->get('files')['error'] === 0) {
324
            $drop = $request->files->get('files');
325
        } else {
326
            if ($request->files->get('file')) {
327
                $drop = $request->files->get('file');
328
            } else {
329
                $drop = $request->get('text');
330
            }
331
        }
332
        $media = $this->get('kunstmaan_media.media_manager')->createNew($drop);
333
        if ($media) {
334
            $media->setFolder($folder);
335
            $em->getRepository('KunstmaanMediaBundle:Media')->save($media);
336
337
            return new JsonResponse(['status' => $this->get('translator')->trans('kuma_admin.media.flash.drop_success')]);
338
        }
339
340
        $request->getSession()->getFlashBag()->add(
341
            FlashTypes::DANGER,
342
            $this->get('translator')->trans('kuma_admin.media.flash.drop_unrecognized')
343
        );
344
345
        return new JsonResponse(['status' => $this->get('translator')->trans('kuma_admin.media.flash.drop_unrecognized')]);
346
    }
347
348
    /**
349
     * @param Request $request
350
     * @param int     $folderId The folder id
351
     * @param string  $type     The type
352
     *
353
     * @Route("create/{folderId}/{type}", requirements={"folderId" = "\d+", "type" = ".+"}, name="KunstmaanMediaBundle_media_create")
354
     * @Method({"GET", "POST"})
355
     * @Template()
356
     *
357
     * @return array|RedirectResponse
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use RedirectResponse|array<s...t\Form\FormView|Folder>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
358
     */
359
    public function createAction(Request $request, $folderId, $type)
360
    {
361
        return $this->createAndRedirect($request, $folderId, $type, 'KunstmaanMediaBundle_folder_show');
362
    }
363
364
    /**
365
     * @param Request $request
366
     * @param int     $folderId    The folder Id
367
     * @param string  $type        The type
368
     * @param string  $redirectUrl The url where we want to redirect to on success
369
     * @param array   $extraParams The extra parameters that will be passed wen redirecting
370
     *
371
     * @return array|RedirectResponse
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use RedirectResponse|array<s...t\Form\FormView|Folder>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
372
     */
373
    private function createAndRedirect(Request $request, $folderId, $type, $redirectUrl, $extraParams = [], $isInModal = false)
374
    {
375
        $em = $this->getDoctrine()->getManager();
376
377
        /* @var Folder $folder */
378
        $folder = $em->getRepository('KunstmaanMediaBundle:Folder')->getFolder($folderId);
379
380
        /* @var MediaManager $mediaManager */
381
        $mediaManager = $this->get('kunstmaan_media.media_manager');
382
        $handler = $mediaManager->getHandlerForType($type);
383
        $media = new Media();
384
        $helper = $handler->getFormHelper($media);
385
386
        $form = $this->createForm($handler->getFormType(), $helper, $handler->getFormTypeOptions());
387
388
        if ($request->isMethod('POST')) {
389
            $params = ['folderId' => $folder->getId()];
390
            $params = \array_merge($params, $extraParams);
391
392
            $form->handleRequest($request);
393
394
            if ($form->isSubmitted() && $form->isValid()) {
395
                $media = $helper->getMedia();
396
                $media->setFolder($folder);
397
                $em->getRepository('KunstmaanMediaBundle:Media')->save($media);
398
399
                $mediaId = $media->getId();
400
                $params['mediaId'] = $mediaId;
401
402
                $this->addFlash(
403
                    FlashTypes::SUCCESS,
404
                    $this->get('translator')->trans(
405
                        'media.flash.created',
406
                        [
407
                            '%medianame%' => $media->getName(),
408
                        ]
409
                    )
410
                );
411
412
                return new RedirectResponse($this->generateUrl($redirectUrl, $params));
413
            }
414
415
            if ($isInModal) {
416
                $this->addFlash(
417
                    FlashTypes::ERROR,
418
                    $this->get('translator')->trans(
419
                        'media.flash.not_created',
420
                        [
421
                            '%mediaerrors%' => $form->getErrors(true, true),
422
                        ]
423
                    )
424
                );
425
426
                return new RedirectResponse($this->generateUrl($redirectUrl, $params));
427
            }
428
        }
429
430
        return [
431
            'type' => $type,
432
            'form' => $form->createView(),
433
            'folder' => $folder,
434
        ];
435
    }
436
437
    /**
438
     * @param Request $request
439
     * @param int     $folderId The folder id
440
     * @param string  $type     The type
441
     *
442
     * @Route("create/modal/{folderId}/{type}", requirements={"folderId" = "\d+", "type" = ".+"}, name="KunstmaanMediaBundle_media_modal_create")
443
     * @Method({"GET", "POST"})
444
     * @Template()
445
     *
446
     * @return array|RedirectResponse
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use RedirectResponse|array<s...t\Form\FormView|Folder>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
447
     */
448
    public function createModalAction(Request $request, $folderId, $type)
449
    {
450
        $cKEditorFuncNum = $request->get('CKEditorFuncNum');
451
        $linkChooser     = $request->get('linkChooser');
452
        $redirect        = $request->get('redirect') ?: 'KunstmaanMediaBundle_chooser_show_folder';
453
454
        $extraParams = [];
455
        if (!empty($cKEditorFuncNum)) {
456
            $extraParams['CKEditorFuncNum'] = $cKEditorFuncNum;
457
        }
458
        if (!empty($linkChooser)) {
459
            $extraParams['linkChooser'] = $linkChooser;
460
        }
461
462
        return $this->createAndRedirect(
463
            $request,
464
            $folderId,
465
            $type,
466
            $redirect,
467
            $extraParams,
468
            true
469
        );
470
    }
471
472
    /**
473
     * @param Request $request
474
     *
475
     * @Route("move/", name="KunstmaanMediaBundle_media_move")
476
     * @Method({"POST"})
477
     *
478
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be JsonResponse?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
479
     */
480
    public function moveMedia(Request $request)
481
    {
482
        @trigger_error(sprintf('The "%s" controller action is deprecated in KunstmaanMediaBundle 5.1 and will be removed in KunstmaanMediaBundle 6.0.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
483
484
        $mediaId = $request->request->get('mediaId');
485
        $folderId = $request->request->get('folderId');
486
487
        if (empty($mediaId) || empty($folderId)) {
488
            return new JsonResponse(['error' => ['title' => 'Missing media id or folder id']], 400);
489
        }
490
491
        $em = $this->getDoctrine()->getManager();
492
        $mediaRepo = $em->getRepository('KunstmaanMediaBundle:Media');
493
494
        $media = $mediaRepo->getMedia($mediaId);
495
        $folder = $em->getRepository('KunstmaanMediaBundle:Folder')->getFolder($folderId);
496
497
        $media->setFolder($folder);
498
        $mediaRepo->save($media);
499
500
        return new JsonResponse();
501
    }
502
503
    /**
504
     * @Route("/bulk-move", name="KunstmaanMediaBundle_media_bulk_move")
505
     *
506
     * @param Request $request
507
     *
508
     * @return JsonResponse|Response
509
     * @throws \Doctrine\DBAL\DBALException
510
     */
511
    public function bulkMoveAction(Request $request)
512
    {
513
        $em = $this->getDoctrine()->getManager();
514
        $mediaRepo = $em->getRepository('KunstmaanMediaBundle:Media');
515
        $form = $this->createForm(BulkMoveMediaType::class);
516
517
        $form->handleRequest($request);
518
519
        if ($form->isSubmitted() && $form->isValid()) {
520
            /** @var Folder $folder */
521
            $folder = $form->getData()['folder'];
522
            $mediaIds = explode(',', $form->getData()['media']);
523
524
            $mediaRepo->createQueryBuilder('m')
525
                ->update()
526
                ->set('m.folder', $folder->getId())
527
                ->where('m.id in (:mediaIds)')
528
                ->setParameter('mediaIds', $mediaIds)
529
                ->getQuery()
530
                ->execute();
531
532
            $this->addFlash(FlashTypes::SUCCESS, $this->get('translator')->trans('media.folder.bulk_move.success.text'));
533
534
            return new JsonResponse(
535
                [
536
                    'Success' => 'The media is moved',
537
                ]
538
            );
539
        }
540
541
        return $this->render(
542
            '@KunstmaanMedia/Folder/bulk-move-modal_form.html.twig',
543
            [
544
                'form' => $form->createView(),
545
            ]
546
        );
547
    }
548
}
549