Completed
Push — master ( 172eb0...3032f7 )
by Julito
09:41
created

ResourceController::createAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Controller;
5
6
use APY\DataGridBundle\Grid\Action\MassAction;
7
use APY\DataGridBundle\Grid\Action\RowAction;
8
use APY\DataGridBundle\Grid\Export\CSVExport;
9
use APY\DataGridBundle\Grid\Export\ExcelExport;
10
use APY\DataGridBundle\Grid\Grid;
11
use APY\DataGridBundle\Grid\Source\Entity;
12
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
13
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
14
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
15
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
16
use Chamilo\CourseBundle\Controller\CourseControllerTrait;
17
use Chamilo\CourseBundle\Entity\CDocument;
18
use Chamilo\CourseBundle\Repository\CDocumentRepository;
19
use FOS\RestBundle\View\View;
20
use Liip\ImagineBundle\Service\FilterService;
21
use Sonata\MediaBundle\Provider\ImageProvider;
22
use Sonata\MediaBundle\Provider\MediaProviderInterface;
23
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
24
use Sylius\Component\Resource\Exception\UpdateHandlingException;
25
use Sylius\Component\Resource\ResourceActions;
26
use Symfony\Component\HttpFoundation\BinaryFileResponse;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
use Symfony\Component\HttpKernel\Exception\HttpException;
30
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
31
32
/**
33
 * Class ResourceController.
34
 *
35
 * @author Julio Montoya <[email protected]>.
36
 *
37
 * @package Chamilo\CoreBundle\Controller
38
 */
39
class ResourceController extends BaseController implements CourseControllerInterface
40
{
41
    use CourseControllerTrait;
42
43
    /**
44
     * @param Request $request
45
     *
46
     * @return Response
47
     */
48
    public function indexAction(Request $request): Response
49
    {
50
        return [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the type-hinted return Symfony\Component\HttpFoundation\Response.
Loading history...
51
52
        $source = new Entity('ChamiloCourseBundle:CDocument');
0 ignored issues
show
Unused Code introduced by
$source = new APY\DataGr...ourseBundle:CDocument') is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
53
54
        /* @var Grid $grid */
55
        $grid = $this->get('grid');
56
57
        /*$tableAlias = $source->getTableAlias();
58
        $source->manipulateQuery(function (QueryBuilder $query) use ($tableAlias, $course) {
59
                $query->andWhere($tableAlias . '.cId = '.$course->getId());
60
                //$query->resetDQLPart('orderBy');
61
            }
62
        );*/
63
64
        $repository = $this->get('Chamilo\CourseBundle\Repository\CDocumentRepository');
65
66
        $course = $this->getCourse();
67
        $tool = $repository->getTool('document');
68
69
        $parentId = $request->get('parent');
70
        $parent = null;
71
        if (!empty($parentId)) {
72
            $parent = $repository->find($parentId);
73
        }
74
        $resources = $repository->getResourceByCourse($course, $tool, $parent);
75
76
        $source->setData($resources);
77
        $grid->setSource($source);
78
79
        //$grid->hideFilters();
80
        $grid->setLimits(20);
81
        //$grid->isReadyForRedirect();
82
        //$grid->setMaxResults(1);
83
        //$grid->setLimits(2);
84
        /*$grid->getColumn('id')->manipulateRenderCell(
85
            function ($value, $row, $router) use ($course) {
86
                //$router = $this->get('router');
87
                return $router->generate(
88
                    'chamilo_notebook_show',
89
                    array('id' => $row->getField('id'), 'course' => $course)
90
                );
91
            }
92
        );*/
93
94
        $courseIdentifier = $course->getCode();
95
96
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
97
            $deleteMassAction = new MassAction(
98
                'Delete',
99
                'chamilo.controller.notebook:deleteMassAction',
100
                true,
101
                ['course' => $courseIdentifier]
102
            );
103
            $grid->addMassAction($deleteMassAction);
104
        }
105
106
        $translation = $this->container->get('translator');
107
108
        $myRowAction = new RowAction(
109
            $translation->trans('View'),
110
            'app_document_show',
111
            false,
112
            '_self',
113
            ['class' => 'btn btn-secondary']
114
        );
115
        $myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
116
        $grid->addRowAction($myRowAction);
117
118
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
119
            $myRowAction = new RowAction(
120
                $translation->trans('Edit'),
121
                'app_document_update',
122
                false,
123
                '_self',
124
                ['class' => 'btn btn-secondary']
125
            );
126
            $myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
127
            $grid->addRowAction($myRowAction);
128
129
            $myRowAction = new RowAction(
130
                $translation->trans('Delete'),
131
                'app_document_delete',
132
                false,
133
                '_self',
134
                ['class' => 'btn btn-danger', 'form_delete' => true]
135
            );
136
            $myRowAction->setRouteParameters(['course' => $courseIdentifier, 'id']);
137
            $grid->addRowAction($myRowAction);
138
        }
139
140
        $grid->addExport(new CSVExport($translation->trans('CSV Export'), 'export', ['course' => $courseIdentifier]));
141
142
        $grid->addExport(
143
            new ExcelExport(
144
                $translation->trans('Excel Export'),
145
                'export',
146
                ['course' => $courseIdentifier]
147
            )
148
        );
149
150
        return $grid->getGridResponse('ChamiloCoreBundle:Document:index.html.twig', ['parent_id' => $parentId]);
151
    }
152
153
    /**
154
     * @param Request $request
155
     * @param string  $fileType
156
     *
157
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response|null
158
     */
159
    public function createResource(Request $request, $fileType = 'file')
160
    {
161
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
162
163
        $this->isGrantedOr403($configuration, ResourceActions::CREATE);
164
        /** @var CDocument $newResource */
165
        $newResource = $this->newResourceFactory->create($configuration, $this->factory);
166
        $form = $this->resourceFormFactory->create($configuration, $newResource);
167
168
        $course = $this->getCourse();
169
        $session = $this->getSession();
170
        $newResource->setCourse($course);
171
        $newResource->c_id = $course->getId();
172
        $newResource->setFiletype($fileType);
173
        $form->setData($newResource);
174
175
        $parentId = $request->get('parent');
176
        $parent = null;
177
        if (!empty($parentId)) {
178
            /** @var CDocument $parent */
179
            $parent = $this->repository->find($parentId);
180
        }
181
182
        if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
183
            /** @var CDocument $newResource */
184
            $newResource = $form->getData();
185
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
186
187
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
188
                throw new HttpException($event->getErrorCode(), $event->getMessage());
189
            }
190
            if ($event->isStopped()) {
191
                $this->flashHelper->addFlashFromEvent($configuration, $event);
192
193
                if ($event->hasResponse()) {
194
                    return $event->getResponse();
195
                }
196
197
                return $this->redirectHandler->redirectToIndex($configuration, $newResource);
198
            }
199
200
            if ($configuration->hasStateMachine()) {
201
                $this->stateMachine->apply($configuration, $newResource);
202
            }
203
204
            //$sharedType = $form->get('shared')->getData();
205
            $shareList = [];
206
            $sharedType = 'this_course';
207
208
            switch ($sharedType) {
209
                case 'this_course':
210
                    if (empty($course)) {
211
                        break;
212
                    }
213
                    // Default Chamilo behaviour:
214
                    // Teachers can edit and students can see
215
                    $shareList = [
216
                        [
217
                            'sharing' => 'course',
218
                            'mask' => ResourceNodeVoter::getReaderMask(),
219
                            'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT,
220
                            'search' => $course->getId(),
221
                        ],
222
                        [
223
                            'sharing' => 'course',
224
                            'mask' => ResourceNodeVoter::getEditorMask(),
225
                            'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER,
226
                            'search' => $course->getId(),
227
                        ],
228
                    ];
229
                    break;
230
                case 'shared':
231
                    $shareList = $form->get('rights')->getData();
232
                    break;
233
                case 'only_me':
234
                    $shareList = [
235
                        [
236
                            'sharing' => 'user',
237
                            'only_me' => true,
238
                        ],
239
                    ];
240
                    break;
241
            }
242
243
            $resourceNode = $repository->addResourceNode($newResource, $this->getUser(), $parent);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $repository seems to be never defined.
Loading history...
244
245
            // Loops all sharing options
246
            foreach ($shareList as $share) {
247
                $idList = [];
248
                if (isset($share['search'])) {
249
                    $idList = explode(',', $share['search']);
250
                }
251
252
                $resourceRight = null;
253
                if (isset($share['mask'])) {
254
                    $resourceRight = new ResourceRight();
255
                    $resourceRight
256
                        ->setMask($share['mask'])
257
                        ->setRole($share['role'])
258
                    ;
259
                }
260
261
                // Build links
262
                switch ($share['sharing']) {
263
                    case 'everyone':
264
                        $repository->addResourceToEveryone(
265
                            $resourceNode,
266
                            $resourceRight
267
                        );
268
                        break;
269
                    case 'course':
270
                        $repository->addResourceToCourse(
271
                            $resourceNode,
272
                            $course,
273
                            $resourceRight
274
                        );
275
                        break;
276
                    case 'session':
277
                        $repository->addResourceToSession(
278
                            $resourceNode,
279
                            $course,
280
                            $session,
281
                            $resourceRight
282
                        );
283
                        break;
284
                    case 'user':
285
                        // Only for me
286
                        if (isset($share['only_me'])) {
287
                            $repository->addResourceOnlyToMe($resourceNode);
288
                        } else {
289
                            // To other users
290
                            $repository->addResourceToUserList($resourceNode, $idList);
291
                        }
292
                        break;
293
                    case 'group':
294
                        // @todo
295
                        break;
296
                }
297
            }
298
299
            $newResource
300
                ->setCourse($course)
301
                ->setFiletype($fileType)
302
                ->setSession($session)
303
                //->setTitle($title)
304
                //->setComment($comment)
305
                ->setReadonly(false)
306
                ->setResourceNode($resourceNode)
307
            ;
308
309
            $path = \URLify::filter($newResource->getTitle());
310
311
            switch ($fileType) {
312
                case 'folder':
313
                    $newResource
314
                        ->setPath($path)
315
                        ->setSize(0)
316
                    ;
317
                    break;
318
                case 'file':
319
                    $newResource
320
                        ->setPath($path)
321
                        ->setSize(0)
322
                    ;
323
                    break;
324
            }
325
326
            $this->repository->add($newResource);
327
            $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
328
329
            $newResource->setId($newResource->getIid());
330
            $this->getDoctrine()->getManager()->persist($newResource);
331
            $this->getDoctrine()->getManager()->flush();
332
333
            if (!$configuration->isHtmlRequest()) {
334
                return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
335
            }
336
337
            $this->addFlash('success', 'saved');
338
339
            //$this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
340
            if ($postEvent->hasResponse()) {
341
                return $postEvent->getResponse();
342
            }
343
344
            return $this->redirectToRoute(
345
                'app_document_show',
346
                [
347
                    'id' => $newResource->getIid(),
348
                    'course' => $course->getCode(),
349
                    'parent_id' => $parentId,
350
                ]
351
            );
352
            //return $this->redirectHandler->redirectToResource($configuration, $newResource);
353
        }
354
355
        if (!$configuration->isHtmlRequest()) {
356
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
357
        }
358
359
        $initializeEvent = $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::CREATE, $configuration, $newResource);
360
        if ($initializeEvent->hasResponse()) {
361
            return $initializeEvent->getResponse();
362
        }
363
364
        $view = View::create()
365
            ->setData([
366
                'configuration' => $configuration,
367
                'metadata' => $this->metadata,
368
                'resource' => $newResource,
369
                $this->metadata->getName() => $newResource,
370
                'form' => $form->createView(),
371
                'parent_id' => $parentId,
372
                'file_type' => $fileType,
373
            ])
374
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE.'.html'))
375
        ;
376
377
        return $this->viewHandler->handle($configuration, $view);
378
    }
379
380
    /**
381
     * @param Request $request
382
     *
383
     * @return Response
384
     */
385
    public function createAction(Request $request): Response
386
    {
387
        return $this->createResource($request, 'folder');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->createResource($request, 'folder') could return the type null which is incompatible with the type-hinted return Symfony\Component\HttpFoundation\Response. Consider adding an additional type-check to rule them out.
Loading history...
388
    }
389
390
    /**
391
     * @param Request $request
392
     *
393
     * @return Response
394
     */
395
    public function createDocumentAction(Request $request): Response
396
    {
397
        return $this->createResource($request, 'file');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->createResource($request, 'file') could return the type null which is incompatible with the type-hinted return Symfony\Component\HttpFoundation\Response. Consider adding an additional type-check to rule them out.
Loading history...
398
    }
399
400
    /**
401
     * Shows a resource.
402
     *
403
     * @param Request             $request
404
     * @param CDocumentRepository $documentRepo
405
     * @param FilterService       $filterService
406
     *
407
     * @return Response
408
     */
409
    public function showAction(Request $request, CDocumentRepository $documentRepo, FilterService $filterService): Response
410
    {
411
        $file = $request->get('file');
412
        $type = $request->get('type');
413
        $filter = $request->get('filter');
414
415
        if (empty($type)) {
416
            $type = 'show';
417
        }
418
419
        $criteria = [
420
            'path' => "/$file",
421
            'course' => $this->getCourse(),
422
        ];
423
424
        $document = $documentRepo->findOneBy($criteria);
425
426
        if (null === $document) {
427
            throw new NotFoundHttpException();
428
        }
429
430
        /** @var ResourceNode $resourceNode */
431
        $resourceNode = $document->getResourceNode();
432
433
        $this->denyAccessUnlessGranted(
434
            ResourceNodeVoter::VIEW,
435
            $resourceNode,
436
            'Unauthorised access to resource'
437
        );
438
439
        $resourceFile = $resourceNode->getResourceFile();
440
        $media = $resourceFile->getMedia();
441
        $format = MediaProviderInterface::FORMAT_REFERENCE;
442
443
        if ($media) {
0 ignored issues
show
introduced by
$media is of type Chamilo\MediaBundle\Entity\Media, thus it always evaluated to true.
Loading history...
444
            switch ($type) {
445
                case 'show':
446
                    /** @var ImageProvider $provider */
447
                    $provider = $this->get('sonata.media.pool')->getProvider($media->getProviderName());
448
                    $filename = sprintf(
449
                        '%s/%s',
450
                        $provider->getFilesystem()->getAdapter()->getDirectory(),
451
                        $provider->generatePrivateUrl($media, $format)
452
                    );
453
454
                    if (!empty($filter)) {
455
                        $resourcePath = $filterService->getUrlOfFilteredImage(
456
                            $provider->generatePrivateUrl($media, $format),
457
                            $filter
458
                        );
459
                        if ($resourcePath) {
460
                            $cacheFolder = '/var/cache/resource/';
461
                            $pos = strpos($resourcePath, $cacheFolder);
462
                            $cacheValue = substr($resourcePath, $pos + strlen($cacheFolder), strlen($resourcePath));
463
                            $cachedFile = $this->get('kernel')->getResourceCacheDir().$cacheValue;
464
465
                            if (is_file($cachedFile)) {
466
                                $filename = $cachedFile;
467
                            }
468
                        }
469
                    }
470
471
                    return new BinaryFileResponse($filename);
472
473
                    return $this->render('@SonataMedia/Media/view.html.twig', [
0 ignored issues
show
Unused Code introduced by
return $this->render('@S..., 'format' => $format)) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
474
                        'media' => $media,
475
                        'formats' => $this->get('sonata.media.pool')->getFormatNamesByContext($media->getContext()),
476
                        'format' => $format,
477
                    ]);
478
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
479
                case 'download':
480
                    $provider = $this->get('sonata.media.pool')->getProvider($media->getProviderName());
481
                    $response = $provider->getDownloadResponse($media, $format, $this->get('sonata.media.pool')->getDownloadMode($media));
482
483
                    return $response;
484
                    break;
485
            }
486
        }
487
488
        throw new NotFoundHttpException();
489
        /*
490
491
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
492
        $this->isGrantedOr403($configuration, ResourceActions::SHOW);
493
494
        $resource = $this->findOr404($configuration);
495
        $resourceNode = $resource->getResourceNode();
496
497
        $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource);
498
499
        $this->denyAccessUnlessGranted(
500
            ResourceNodeVoter::VIEW,
501
            $resourceNode,
502
            'Unauthorised access to resource'
503
        );
504
505
        $view = View::create($resource);
506
507
        if ($configuration->isHtmlRequest()) {
508
            $view
509
                ->setTemplate($configuration->getTemplate(ResourceActions::SHOW.'.html'))
510
                ->setTemplateVar($this->metadata->getName())
511
                ->setData([
512
                    'configuration' => $configuration,
513
                    'metadata' => $this->metadata,
514
                    'resource' => $resource,
515
                    $this->metadata->getName() => $resource,
516
                ])
517
            ;
518
        }
519
520
        return $this->viewHandler->handle($configuration, $view);*/
521
    }
522
523
    /**
524
     * @param Request $request
525
     *
526
     * @return Response
527
     */
528
    public function updateAction(Request $request): Response
529
    {
530
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
531
532
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
533
        /** @var CDocument $resource */
534
        $resource = $this->findOr404($configuration);
535
        $resourceNode = $resource->getResourceNode();
536
537
        $this->denyAccessUnlessGranted(
538
            ResourceNodeVoter::EDIT,
539
            $resourceNode,
540
            'Unauthorised access to resource'
541
        );
542
543
        $form = $this->resourceFormFactory->create($configuration, $resource);
544
545
        if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->handleRequest($request)->isValid()) {
546
            $resource = $form->getData();
547
548
            /** @var ResourceControllerEvent $event */
549
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
550
551
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
552
                throw new HttpException($event->getErrorCode(), $event->getMessage());
553
            }
554
            if ($event->isStopped()) {
555
                $this->flashHelper->addFlashFromEvent($configuration, $event);
556
557
                if ($event->hasResponse()) {
558
                    return $event->getResponse();
559
                }
560
561
                return $this->redirectHandler->redirectToResource($configuration, $resource);
562
            }
563
564
            try {
565
                $this->resourceUpdateHandler->handle($resource, $configuration, $this->manager);
566
            } catch (UpdateHandlingException $exception) {
567
                if (!$configuration->isHtmlRequest()) {
568
                    return $this->viewHandler->handle(
569
                        $configuration,
570
                        View::create($form, $exception->getApiResponseCode())
571
                    );
572
                }
573
574
                $this->flashHelper->addErrorFlash($configuration, $exception->getFlash());
575
576
                return $this->redirectHandler->redirectToReferer($configuration);
577
            }
578
579
            $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
580
581
            if (!$configuration->isHtmlRequest()) {
582
                $view = $configuration->getParameters()->get('return_content', false) ? View::create($resource, Response::HTTP_OK) : View::create(null, Response::HTTP_NO_CONTENT);
583
584
                return $this->viewHandler->handle($configuration, $view);
585
            }
586
587
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
588
589
            if ($postEvent->hasResponse()) {
590
                return $postEvent->getResponse();
591
            }
592
593
            return $this->redirectHandler->redirectToResource($configuration, $resource);
594
        }
595
596
        if (!$configuration->isHtmlRequest()) {
597
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
598
        }
599
600
        $initializeEvent = $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::UPDATE, $configuration, $resource);
601
        if ($initializeEvent->hasResponse()) {
602
            return $initializeEvent->getResponse();
603
        }
604
605
        $view = View::create()
606
            ->setData([
607
                'configuration' => $configuration,
608
                'metadata' => $this->metadata,
609
                'resource' => $resource,
610
                $this->metadata->getName() => $resource,
611
                'form' => $form->createView(),
612
            ])
613
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE.'.html'))
614
        ;
615
616
        return $this->viewHandler->handle($configuration, $view);
617
    }
618
}
619