Completed
Push — master ( 3742bc...55196a )
by Julito
13:21
created

ResourceController   F

Complexity

Total Complexity 62

Size/Duplication

Total Lines 929
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 412
dl 0
loc 929
rs 3.44
c 0
b 0
f 0
wmc 62

17 Methods

Rating   Name   Duplication   Size   Complexity  
A deleteAction() 0 32 2
A deleteMassAction() 0 36 3
A uploadAction() 0 16 2
A getResourceFileAction() 0 13 2
B downloadFolderAction() 0 91 6
B getGrid() 0 138 5
A getDocumentAction() 0 21 3
A newAction() 0 5 1
A indexAction() 0 21 1
B showFile() 0 58 9
A editAction() 0 42 4
A showAction() 0 29 2
B setBreadCrumb() 0 69 8
A newFolderAction() 0 5 1
B upload() 0 35 6
B createResource() 0 129 6
A listAction() 0 13 1

How to fix   Complexity   

Complex Class

Complex classes like ResourceController 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.

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 ResourceController, and based on these observations, apply Extract Interface, too.

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\Row;
12
use APY\DataGridBundle\Grid\Source\Entity;
13
use Chamilo\CoreBundle\Block\BreadcrumbBlockService;
14
use Chamilo\CoreBundle\Component\Utils\Glide;
15
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
16
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
17
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
18
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
19
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
20
use Chamilo\CourseBundle\Controller\CourseControllerTrait;
21
use Chamilo\CourseBundle\Entity\CDocument;
22
use Chamilo\CourseBundle\Repository\CDocumentRepository;
23
use Doctrine\Common\Collections\ArrayCollection;
24
use Doctrine\Common\Collections\Criteria;
25
use Doctrine\ORM\QueryBuilder;
26
use FOS\RestBundle\View\View;
27
use League\Flysystem\Filesystem;
28
use Oneup\UploaderBundle\Uploader\Response\EmptyResponse;
29
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
30
use Sylius\Component\Resource\Exception\UpdateHandlingException;
31
use Sylius\Component\Resource\ResourceActions;
32
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
33
use Symfony\Component\HttpFoundation\File\Exception\UploadException;
34
use Symfony\Component\HttpFoundation\File\UploadedFile;
35
use Symfony\Component\HttpFoundation\JsonResponse;
36
use Symfony\Component\HttpFoundation\RedirectResponse;
37
use Symfony\Component\HttpFoundation\Request;
38
use Symfony\Component\HttpFoundation\Response;
39
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
40
use Symfony\Component\HttpFoundation\StreamedResponse;
41
use Symfony\Component\HttpKernel\Exception\HttpException;
42
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
43
use Symfony\Component\Routing\Annotation\Route;
44
use Vich\UploaderBundle\Util\Transliterator;
45
use ZipStream\Option\Archive;
46
use ZipStream\ZipStream;
47
48
/**
49
 * Class ResourceController.
50
 *
51
 * @Route("/resources")
52
 *
53
 * @author Julio Montoya <[email protected]>.
54
 */
55
class ResourceController extends AbstractResourceController implements CourseControllerInterface
56
{
57
    use CourseControllerTrait;
58
59
    /**
60
     * @Route("/{tool}/{type}", name="chamilo_core_resource_index")
61
     *
62
     * Example: /document/files
63
     * For the tool value check the Tool entity.
64
     * For the type value check the ResourceType entity.
65
     *
66
     * @param Request $request
67
     *
68
     * @return Response
69
     */
70
    public function indexAction(Request $request, Grid $grid): Response
71
    {
72
        $tool = $request->get('tool');
73
        $type = $request->get('type');
74
75
        $grid = $this->getGrid( $request, $grid);
76
77
        $breadcrumb = $this->breadcrumbBlockService;
78
        $breadcrumb->addChild(
79
            $this->trans('Documents'),
80
            [
81
                'uri' => '#',
82
            ]
83
        );
84
85
        // The base resource node is the course.
86
        $id = $this->getCourse()->getResourceNode()->getId();
87
88
        return $grid->getGridResponse(
89
            '@ChamiloTheme/Resource/index.html.twig',
90
            ['tool' => $tool, 'type' => $type, 'id' => $id]
91
        );
92
    }
93
94
    /**
95
     * @param Request $request
96
     * @param Grid    $grid
97
     * @param int     $resourceNodeId
98
     *
99
     * @return Grid
100
     */
101
    public function getGrid(Request $request, Grid $grid, $resourceNodeId = 0)
102
    {
103
        $tool = $request->get('tool');
104
        $type = $request->get('type');
105
106
        $repository = $this->getRepositoryFromRequest($request);
107
        $class = $repository->getRepository()->getClassName();
108
        $source = new Entity($class);
109
110
        /*$tableAlias = $source->getTableAlias();
111
        $source->manipulateQuery(function (QueryBuilder $query) use ($tableAlias, $course) {
112
                $query->andWhere($tableAlias . '.cId = '.$course->getId());
113
                //$query->resetDQLPart('orderBy');
114
            }
115
        );*/
116
117
        $course = $this->getCourse();
118
        $session = $this->getSession();
119
120
        $parent = $course->getResourceNode();
121
        if (!empty($resourceNodeId)) {
122
            $parent = $repository->getResourceNodeRepository()->find($resourceNodeId);
123
        }
124
125
        $qb = $repository->getResourcesByCourse($course, $session, null, $parent);
126
127
        // 3. Set QueryBuilder to the source.
128
        $source->initQueryBuilder($qb);
129
        $grid->setSource($source);
130
131
        $title = $grid->getColumn('title');
132
        $title->setSafe(false);
133
134
        //$grid->hideFilters();
135
        $grid->setLimits(20);
136
        //$grid->isReadyForRedirect();
137
        //$grid->setMaxResults(1);
138
        //$grid->setLimits(2);
139
140
        $translation = $this->translator;
141
        $courseIdentifier = $course->getCode();
142
143
        $routeParams = ['tool' => $tool, 'type' => $type, 'cidReq' => $courseIdentifier, 'id'];
144
145
        $grid->getColumn('title')->manipulateRenderCell(
146
            function ($value, Row $row, $router) use ($routeParams) {
147
                /** @var CDocument $entity */
148
                $entity = $row->getEntity();
149
                $resourceNode = $entity->getResourceNode();
150
                $id = $resourceNode->getId();
151
152
                $myParams = $routeParams;
153
                $myParams['id'] = $id;
154
                unset($myParams[0]);
155
156
                if ($resourceNode->hasResourceFile()) {
157
                    $url = $router->generate(
158
                        'chamilo_core_resource_show',
159
                        $myParams
160
                    );
161
                } else {
162
                    $url = $router->generate(
163
                        'chamilo_core_resource_list',
164
                        $myParams
165
                    );
166
                }
167
168
                return '<a href="'.$url.'">'.$value.'</a>';
169
            }
170
        );
171
172
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
173
            $deleteMassAction = new MassAction(
174
                'Delete',
175
                'ChamiloCoreBundle:Resource:deleteMass',
176
                true,
177
                $routeParams
178
            );
179
            $grid->addMassAction($deleteMassAction);
180
        }
181
182
        // Show resource data
183
        $myRowAction = new RowAction(
184
            $translation->trans('View'),
185
            'chamilo_core_resource_show',
186
            false,
187
            '_self',
188
            ['class' => 'btn btn-secondary']
189
        );
190
        $myRowAction->setRouteParameters($routeParams);
191
192
        $setNodeParameters = function (RowAction $action, Row $row) use ($routeParams) {
193
            $id = $row->getEntity()->getResourceNode()->getId();
194
            $routeParams['id'] = $id;
195
            $action->setRouteParameters($routeParams);
196
            return $action;
197
        };
198
        $myRowAction->addManipulateRender($setNodeParameters);
199
200
        $grid->addRowAction($myRowAction);
201
202
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
203
            // Edit
204
            $myRowAction = new RowAction(
205
                $translation->trans('Edit'),
206
                'chamilo_core_resource_edit',
207
                false,
208
                '_self',
209
                ['class' => 'btn btn-secondary']
210
            );
211
            $myRowAction->setRouteParameters($routeParams);
212
            $myRowAction->addManipulateRender($setNodeParameters);
213
214
            $grid->addRowAction($myRowAction);
215
216
            // Delete
217
            $myRowAction = new RowAction(
218
                $translation->trans('Delete'),
219
                'chamilo_core_resource_delete',
220
                false,
221
                '_self',
222
                ['class' => 'btn btn-danger', 'form_delete' => true]
223
            );
224
            $myRowAction->setRouteParameters($routeParams);
225
            $myRowAction->addManipulateRender($setNodeParameters);
226
            $grid->addRowAction($myRowAction);
227
        }
228
229
        /*$grid->addExport(new CSVExport($translation->trans('CSV export'), 'export', ['course' => $courseIdentifier]));
230
        $grid->addExport(
231
            new ExcelExport(
232
                $translation->trans('Excel export'),
233
                'export',
234
                ['course' => $courseIdentifier]
235
            )
236
        );*/
237
238
        return $grid;
239
    }
240
241
    /**
242
     * @Route("/{tool}/{type}/{id}/list", name="chamilo_core_resource_list")
243
     *
244
     * If node has children show it
245
     *
246
     * @param Request $request
247
     *
248
     * @return Response
249
     */
250
    public function listAction(Request $request, Grid $grid): Response
251
    {
252
        $tool = $request->get('tool');
253
        $type = $request->get('type');
254
        $resourceNodeId = $request->get('id');
255
256
        $grid = $this->getGrid( $request, $grid,$resourceNodeId);
257
258
        $this->setBreadCrumb($request);
259
260
        return $grid->getGridResponse(
261
            '@ChamiloTheme/Resource/index.html.twig',
262
            ['parent_id' => $resourceNodeId, 'tool' => $tool, 'type' => $type, 'id' => $resourceNodeId]
263
        );
264
    }
265
266
    /**
267
     * @Route("/{tool}/{type}/{id}/new_folder", methods={"GET", "POST"}, name="chamilo_core_resource_new_folder")
268
     *
269
     * @param Request $request
270
     *
271
     * @return Response
272
     */
273
    public function newFolderAction(Request $request): Response
274
    {
275
        $this->setBreadCrumb($request);
276
277
        return $this->createResource($request, 'folder');
278
    }
279
280
    /**
281
     * @Route("/{tool}/{type}/{id}/new", methods={"GET", "POST"}, name="chamilo_core_resource_new")
282
     *
283
     * @param Request $request
284
     *
285
     * @return Response
286
     */
287
    public function newAction(Request $request): Response
288
    {
289
        $this->setBreadCrumb($request);
290
291
        return $this->createResource($request, 'file');
292
    }
293
294
    /**
295
     * @Route("/{tool}/{type}/{id}/edit", methods={"GET", "POST"})
296
     *
297
     * @param Request $request
298
     *
299
     * @return Response
300
     */
301
    public function editAction(Request $request): Response
302
    {
303
        $tool = $request->get('tool');
304
        $type = $request->get('type');
305
        $nodeId = $request->get('id');
306
307
        $repository = $this->getRepositoryFromRequest($request);
308
        $resource = $repository->getRepository()->findOneBy(['resourceNode' => $nodeId]);
309
        $resourceNodeParentId = $resource->getResourceNode()->getId();
310
311
        $form = $repository->getForm($this->container->get('form.factory'), $resource);
312
313
        $form->handleRequest($request);
314
315
        if ($form->isSubmitted() && $form->isValid()) {
316
            /** @var CDocument $newResource */
317
            $newResource = $form->getData();
318
            $em = $this->getDoctrine()->getManager();
319
            $em->persist($newResource);
320
            $em->flush();
321
            $this->addFlash('success', $this->trans('Updated'));
322
323
            if ($newResource->getResourceNode()->hasResourceFile()) {
324
                $resourceNodeParentId = $newResource->getResourceNode()->getParent()->getId();
325
            }
326
327
            return $this->redirectToRoute(
328
                'chamilo_core_resource_list',
329
                [
330
                    'id' => $resourceNodeParentId,
331
                    'tool' => $tool,
332
                    'type' => $type,
333
                    'cidReq' => $this->getCourse()->getCode(),
334
                ]
335
            );
336
        }
337
338
        return $this->render(
339
            '@ChamiloTheme/Resource/edit.html.twig',
340
            [
341
                'form' => $form->createView(),
342
                'parent' => $resourceNodeParentId,
343
            ]
344
        );
345
346
347
    }
348
349
    /**
350
     * Shows a resource.
351
     *
352
     * @Route("/{tool}/{type}/{id}/show", methods={"GET"}, name="chamilo_core_resource_show")
353
     *
354
     * @param Request $request
355
     *
356
     * @return Response
357
     */
358
    public function showAction(Request $request): Response
359
    {
360
        $this->setBreadCrumb($request);
361
362
        $em = $this->getDoctrine();
363
364
        $id = $request->get('id');
365
        $resourceNode = $em->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
366
367
        if (null === $resourceNode) {
368
            throw new NotFoundHttpException();
369
        }
370
371
        $this->denyAccessUnlessGranted(
372
            ResourceNodeVoter::VIEW,
373
            $resourceNode,
374
            'Unauthorised access to resource'
375
        );
376
377
        $tool = $request->get('tool');
378
        $type = $request->get('type');
379
380
        $params = [
381
            'resource_node' => $resourceNode,
382
            'tool' => $tool,
383
            'type' => $type,
384
        ];
385
386
        return $this->render('@ChamiloTheme/Resource/show.html.twig', $params);
387
    }
388
389
    /**
390
     * @Route("/{tool}/{type}/{id}", methods={"DELETE"}, name="chamilo_core_resource_delete")
391
     *
392
     * @param Request $request
393
     *
394
     * @return Response
395
     */
396
    public function deleteAction(Request $request): Response
397
    {
398
        $tool = $request->get('tool');
399
        $type = $request->get('type');
400
401
        $em = $this->getDoctrine()->getManager();
402
403
        $id = $request->get('id');
404
        $resourceNode = $this->getDoctrine()->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
405
        $parentId = $resourceNode->getParent()->getId();
406
407
        if (null === $resourceNode) {
408
            throw new NotFoundHttpException();
409
        }
410
411
        $this->denyAccessUnlessGranted(
412
            ResourceNodeVoter::DELETE,
413
            $resourceNode,
414
            'Unauthorised access to resource'
415
        );
416
417
        $em->remove($resourceNode);
418
        $this->addFlash('success', $this->trans('Deleted'));
419
        $em->flush();
420
421
        return $this->redirectToRoute(
422
            'chamilo_core_resource_list',
423
            [
424
                'id' => $parentId,
425
                'tool' => $tool,
426
                'type' => $type,
427
                'cidReq' => $this->getCourse()->getCode(),
428
            ]
429
        );
430
    }
431
432
    /**
433
     * @Route("/{tool}/{type}/{id}", methods={"DELETE"}, name="chamilo_core_resource_delete_mass")
434
     *
435
     * @param Request $request
436
     *
437
     * @return Response
438
     */
439
    public function deleteMassAction($primaryKeys, $allPrimaryKeys, Request $request): Response
440
    {
441
        $tool = $request->get('tool');
442
        $type = $request->get('type');
443
        $em = $this->getDoctrine()->getManager();
444
        $repo = $this->getRepositoryFromRequest($request);
445
446
        $parentId = 0;
447
        foreach ($primaryKeys as $id) {
448
            $resource = $repo->find($id);
449
            $resourceNode = $resource->getResourceNode();
450
451
            if (null === $resourceNode) {
452
                continue;
453
            }
454
455
            $this->denyAccessUnlessGranted(
456
                ResourceNodeVoter::DELETE,
457
                $resourceNode,
458
                'Unauthorised access to resource'
459
            );
460
461
            $parentId = $resourceNode->getParent()->getId();
462
            $em->remove($resource);
463
        }
464
465
        $this->addFlash('success', $this->trans('Deleted'));
466
        $em->flush();
467
468
        return $this->redirectToRoute(
469
            'chamilo_core_resource_list',
470
            [
471
                'id' => $parentId,
472
                'tool' => $tool,
473
                'type' => $type,
474
                'cidReq' => $this->getCourse()->getCode(),
475
            ]
476
        );
477
    }
478
479
    /**
480
     * @Route("/{tool}/{type}/{id}/file", methods={"GET"}, name="chamilo_core_resource_file")
481
     *
482
     * @param Request $request
483
     * @param Glide   $glide
484
     *
485
     * @return Response
486
     */
487
    public function getResourceFileAction(Request $request, Glide $glide): Response
488
    {
489
        $id = $request->get('id');
490
        $filter = $request->get('filter');
491
        $mode = $request->get('mode');
492
        $em = $this->getDoctrine();
493
        $resourceNode = $em->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
494
495
        if ($resourceNode === null) {
496
            throw new FileNotFoundException('Not found');
497
        }
498
499
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
500
    }
501
502
    /**
503
     * Gets a document when calling route resources_document_get_file.
504
     *
505
     * @param Request             $request
506
     * @param CDocumentRepository $documentRepo
507
     * @param Glide               $glide
508
     *
509
     * @return Response
510
     * @throws \League\Flysystem\FileNotFoundException
511
     */
512
    public function getDocumentAction(Request $request, CDocumentRepository $documentRepo, Glide $glide): Response
513
    {
514
        $file = $request->get('file');
515
        $mode = $request->get('mode');
516
        // see list of filters in config/services.yaml
517
        $filter = $request->get('filter');
518
        $mode = !empty($mode) ? $mode : 'show';
519
        $criteria = [
520
            'path' => "/$file",
521
            'course' => $this->getCourse(),
522
        ];
523
524
        $document = $documentRepo->findOneBy($criteria);
525
526
        if (null === $document) {
527
            throw new NotFoundHttpException();
528
        }
529
        /** @var ResourceNode $resourceNode */
530
        $resourceNode = $document->getResourceNode();
531
532
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
533
    }
534
535
    /**
536
     * Downloads a folder.
537
     *
538
     * @param Request             $request
539
     * @param CDocumentRepository $documentRepo
540
     *
541
     * @return Response
542
     */
543
    public function downloadFolderAction(Request $request, CDocumentRepository $documentRepo)
544
    {
545
        $folderId = (int) $request->get('folderId');
546
        $courseNode = $this->getCourse()->getResourceNode();
547
548
        if (empty($folderId)) {
549
            $resourceNode = $courseNode;
550
        } else {
551
            $document = $documentRepo->find($folderId);
552
            $resourceNode = $document->getResourceNode();
553
        }
554
555
        $type = $documentRepo->getResourceType();
556
557
        if (null === $resourceNode || null === $courseNode) {
558
            throw new NotFoundHttpException();
559
        }
560
561
        $this->denyAccessUnlessGranted(
562
            ResourceNodeVoter::VIEW,
563
            $resourceNode,
564
            'Unauthorised access to resource'
565
        );
566
567
        $zipName = $resourceNode->getName().'.zip';
568
        $rootNodePath = $resourceNode->getPathForDisplay();
569
570
        /** @var Filesystem $fileSystem */
571
        $fileSystem = $this->get('oneup_flysystem.resources_filesystem');
572
573
        $resourceNodeRepo = $documentRepo->getResourceNodeRepository();
574
575
        $criteria = Criteria::create()
576
            ->where(Criteria::expr()->neq('resourceFile', null))
577
            ->andWhere(Criteria::expr()->eq('resourceType', $type))
578
        ;
579
580
        /** @var ArrayCollection|ResourceNode[] $children */
581
        /** @var QueryBuilder $children */
582
        $qb = $resourceNodeRepo->getChildrenQueryBuilder($resourceNode);
583
        $qb->addCriteria($criteria);
584
        $children = $qb->getQuery()->getResult();
585
586
        /** @var ResourceNode $node */
587
        foreach ($children as $node) {
588
            /*if ($node->hasResourceFile()) {
589
                $resourceFile = $node->getResourceFile();
590
                $systemName = $resourceFile->getFile()->getPathname();
591
                $stream = $fileSystem->readStream($systemName);
592
                //error_log($node->getPathForDisplay());
593
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
594
                var_dump($fileToDisplay);
595
            }*/
596
            var_dump($node->getPathForDisplay());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($node->getPathForDisplay()) looks like debug code. Are you sure you do not want to remove it?
Loading history...
597
            //var_dump($node['path']);
598
        }
599
600
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
601
602
603
        $response = new StreamedResponse(function() use($rootNodePath, $zipName, $children, $fileSystem)
0 ignored issues
show
Unused Code introduced by
$response = new Symfony\...ion(...) { /* ... */ }) 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...
604
        {
605
            // Define suitable options for ZipStream Archive.
606
            $options = new Archive();
607
            $options->setContentType('application/octet-stream');
608
            //initialise zipstream with output zip filename and options.
609
            $zip = new ZipStream($zipName, $options);
610
611
            /** @var ResourceNode $node */
612
            foreach ($children as $node) {
613
                $resourceFile = $node->getResourceFile();
614
                $systemName = $resourceFile->getFile()->getPathname();
615
                $stream = $fileSystem->readStream($systemName);
616
                //error_log($node->getPathForDisplay());
617
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
618
                error_log($fileToDisplay);
619
                $zip->addFileFromStream($fileToDisplay, $stream);
620
            }
621
            //$data = $repo->getDocumentContent($not_deleted_file['id']);
622
            //$zip->addFile($not_deleted_file['path'], $data);
623
            $zip->finish();
624
        });
625
626
        $disposition = $response->headers->makeDisposition(
627
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
628
            Transliterator::transliterate($zipName)
629
        );
630
        $response->headers->set('Content-Disposition', $disposition);
631
        $response->headers->set('Content-Type', 'application/octet-stream');
632
633
        return $response;
634
    }
635
636
    /**
637
     * Upload form.
638
     *
639
     * @Route("/{tool}/{type}/{id}/upload", name="chamilo_core_resource_upload", methods={"GET", "POST"},
640
     *                                      options={"expose"=true})
641
     */
642
    public function uploadAction(Request $request, $tool, $type, $id): Response
643
    {
644
        $this->setBreadCrumb( $request);
645
        //$helper = $this->container->get('oneup_uploader.templating.uploader_helper');
646
        //$endpoint = $helper->endpoint('courses');
647
        $session = $this->getSession();
648
        $sessionId = $session ? $session->getId() : 0;
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
649
650
        return $this->render(
651
            '@ChamiloTheme/Resource/upload.html.twig',
652
            [
653
                'id' => $id,
654
                'type' => $type,
655
                'tool' => $tool,
656
                'cidReq' => $this->getCourse()->getCode(),
657
                'id_session' => $sessionId,
658
            ]
659
        );
660
    }
661
662
    /**
663
     * @return JsonResponse
664
     */
665
    public function upload()
666
    {
667
        error_log('upload!!!');
668
        return;
669
        $request = $this->getRequest();
0 ignored issues
show
Unused Code introduced by
$request = $this->getRequest() 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...
670
        $response = new EmptyResponse();
671
        $files = $this->getFiles($request->files);
672
673
        $chunked = null !== $request->headers->get('content-range');
674
675
        try {
676
            /** @var UploadedFile $file */
677
            foreach ($files as $file) {
678
                try {
679
                    $file->getFilename();
680
                    $type = $request->get('type');
681
682
                    if ($type === 'course') {
683
                        $courseCode = $request->get('identifier');
684
                        $this->container->get('');
685
                    }
686
687
                    $chunked ?
688
                        $this->handleChunkedUpload($file, $response, $request) :
689
                        $this->handleUpload($file, $response, $request);
690
                } catch (UploadException $e) {
691
                    $this->errorHandler->addException($response, $e);
692
                }
693
            }
694
        } catch (UploadException $e) {
695
            // return nothing
696
            return new JsonResponse([]);
697
        }
698
699
        return $this->createSupportedJsonResponse($response->assemble());
700
    }
701
702
703
    /**
704
     * @param Request      $request
705
     * @param ResourceNode $resourceNode
706
     * @param Glide        $glide
707
     * @param string       $mode show or download
708
     * @param string       $filter
709
     *
710
     * @return mixed|StreamedResponse
711
     */
712
    private function showFile(Request $request, ResourceNode $resourceNode, Glide $glide, $mode = 'show', $filter = '')
713
    {
714
        $this->denyAccessUnlessGranted(
715
            ResourceNodeVoter::VIEW,
716
            $resourceNode,
717
            'Unauthorised access to resource'
718
        );
719
        $resourceFile = $resourceNode->getResourceFile();
720
721
        if (!$resourceFile) {
0 ignored issues
show
introduced by
$resourceFile is of type Chamilo\CoreBundle\Entity\Resource\ResourceFile, thus it always evaluated to true.
Loading history...
722
            throw new NotFoundHttpException();
723
        }
724
725
        $fileName = $resourceNode->getName();
726
        $filePath = $resourceFile->getFile()->getPathname();
727
        $mimeType = $resourceFile->getMimeType();
728
729
        switch ($mode) {
730
            case 'download':
731
                $forceDownload = true;
732
                break;
733
            case 'show':
734
            default:
735
                $forceDownload = false;
736
                // If it's an image then send it to Glide.
737
                if (strpos($mimeType, 'image') !== false) {
738
                    $server = $glide->getServer();
739
                    $params = $request->query->all();
740
741
                    // The filter overwrites the params from get
742
                    if (!empty($filter)) {
743
                        $params = $glide->getFilters()[$filter] ?? [];
744
                    }
745
746
                    // The image was cropped manually by the user, so we force to render this version,
747
                    // no matter other crop parameters.
748
                    $crop = $resourceFile->getCrop();
749
                    if (!empty($crop)) {
750
                        $params['crop'] = $crop;
751
                    }
752
753
                    return $server->getImageResponse($filePath, $params);
754
                }
755
                break;
756
        }
757
758
        $stream = $this->fs->readStream($filePath);
759
        $response = new StreamedResponse(function () use ($stream): void {
760
            stream_copy_to_stream($stream, fopen('php://output', 'wb'));
0 ignored issues
show
Bug introduced by
It seems like fopen('php://output', 'wb') can also be of type false; however, parameter $dest of stream_copy_to_stream() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

760
            stream_copy_to_stream($stream, /** @scrutinizer ignore-type */ fopen('php://output', 'wb'));
Loading history...
761
        });
762
        $disposition = $response->headers->makeDisposition(
763
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
764
            Transliterator::transliterate($fileName)
765
        );
766
        $response->headers->set('Content-Disposition', $disposition);
767
        $response->headers->set('Content-Type', $mimeType ?: 'application/octet-stream');
768
769
        return $response;
770
    }
771
772
    /**
773
     * @param Request $request
774
     * @param string  $fileType
775
     *
776
     * @return RedirectResponse|Response
777
     */
778
    private function createResource(Request $request, $fileType = 'file')
779
    {
780
        $tool = $request->get('tool');
781
        $type = $request->get('type');
782
        $resourceNodeParentId = $request->get('id');
783
784
        $repository = $this->getRepositoryFromRequest($request);
785
786
        $form = $repository->getForm($this->container->get('form.factory'));
787
788
        $course = $this->getCourse();
789
        $session = $this->getSession();
790
        $parentNode = $course->getResourceNode();
791
        if (!empty($resourceNodeParentId)) {
792
            $parentNode = $repository->getResourceNodeRepository()->find($resourceNodeParentId);
793
        }
794
795
        $form->handleRequest($request);
796
        if ($form->isSubmitted() && $form->isValid()) {
797
            /** @var CDocument $newResource */
798
            $newResource = $form->getData();
799
800
            $newResource
801
                ->setCourse($course)
802
                ->setSession($session)
803
                ->setFiletype($fileType)
804
                //->setTitle($title) // already added in $form->getData()
805
                //->setComment($comment)
806
                ->setReadonly(false)
807
            ;
808
809
            $em = $this->getDoctrine()->getManager();
810
            $em->persist($newResource);
811
            $em->flush();
812
813
            $resourceNode = $repository->addResourceNodeParent($newResource, $this->getUser(), $parentNode);
814
815
            $repository->addResourceNodeToCourse(
816
                $resourceNode,
817
                ResourceLink::VISIBILITY_PUBLISHED,
818
                $course,
819
                $session,
820
                null
821
            );
822
823
            $em->flush();
824
825
            // Loops all sharing options
826
            /*foreach ($shareList as $share) {
827
                $idList = [];
828
                if (isset($share['search'])) {
829
                    $idList = explode(',', $share['search']);
830
                }
831
832
                $resourceRight = null;
833
                if (isset($share['mask'])) {
834
                    $resourceRight = new ResourceRight();
835
                    $resourceRight
836
                        ->setMask($share['mask'])
837
                        ->setRole($share['role'])
838
                    ;
839
                }
840
841
                // Build links
842
                switch ($share['sharing']) {
843
                    case 'everyone':
844
                        $repository->addResourceToEveryone(
845
                            $resourceNode,
846
                            $resourceRight
847
                        );
848
                        break;
849
                    case 'course':
850
                        $repository->addResourceToCourse(
851
                            $resourceNode,
852
                            $course,
853
                            $resourceRight
854
                        );
855
                        break;
856
                    case 'session':
857
                        $repository->addResourceToSession(
858
                            $resourceNode,
859
                            $course,
860
                            $session,
861
                            $resourceRight
862
                        );
863
                        break;
864
                    case 'user':
865
                        // Only for me
866
                        if (isset($share['only_me'])) {
867
                            $repository->addResourceOnlyToMe($resourceNode);
868
                        } else {
869
                            // To other users
870
                            $repository->addResourceToUserList($resourceNode, $idList);
871
                        }
872
                        break;
873
                    case 'group':
874
                        // @todo
875
                        break;
876
                }*/
877
            //}
878
            $em->flush();
879
            $this->addFlash('success', $this->trans('Saved'));
880
881
            return $this->redirectToRoute(
882
                'chamilo_core_resource_list',
883
                [
884
                    'id' => $resourceNodeParentId,
885
                    'tool' => $tool,
886
                    'type' => $type,
887
                    'cidReq' => $this->getCourse()->getCode(),
888
                ]
889
            );
890
        }
891
892
        switch ($fileType) {
893
            case 'folder':
894
                $template = '@ChamiloTheme/Resource/new_folder.html.twig';
895
                break;
896
            case 'file':
897
                $template = '@ChamiloTheme/Resource/new.html.twig';
898
                break;
899
        }
900
901
        return $this->render(
902
            $template,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $template does not seem to be defined for all execution paths leading up to this point.
Loading history...
903
            [
904
                'form' => $form->createView(),
905
                'parent' => $resourceNodeParentId,
906
                'file_type' => $fileType,
907
            ]
908
        );
909
    }
910
911
912
    /**
913
     * @param Request $request
914
     */
915
    public function setBreadCrumb(Request $request)
916
    {
917
        $tool = $request->get('tool');
918
        $type = $request->get('type');
919
        $resourceNodeId = $request->get('id');
920
        $courseCode = $request->get('cidReq');
921
922
        if (!empty($resourceNodeId)) {
923
            $breadcrumb = $this->breadcrumbBlockService;
924
925
            // Root tool link
926
            $breadcrumb->addChild(
927
                $this->translator->trans('Documents'),
928
                [
929
                    'uri' => $this->generateUrl(
930
                        'chamilo_core_resource_index',
931
                        ['tool' => $tool, 'type' => $type, 'cidReq' => $courseCode]
932
                    ),
933
                ]
934
            );
935
936
            $repo = $this->getRepositoryFromRequest($request);
937
938
            /** @var ResourceNode $parent */
939
            $originalResource = $repo->findOneBy([ 'resourceNode' => $resourceNodeId]);
940
            if ($originalResource === null) {
941
                return;
942
            }
943
            $parent = $originalParent = $originalResource->getResourceNode();
944
945
            $parentList = [];
946
            while ($parent !== null) {
947
                if ($type !== $parent->getResourceType()->getName()){
948
                    break;
949
                }
950
                $parent = $parent->getParent();
951
                if ($parent) {
952
                    $resource = $repo->findOneBy([ 'resourceNode' => $parent->getId()]);
953
                    if ($resource) {
954
                        $parentList[] = $resource;
955
                    }
956
                }
957
            }
958
959
            $parentList = array_reverse($parentList);
960
            /** @var AbstractResource $item */
961
            foreach ($parentList as $item) {
962
                $breadcrumb->addChild(
963
                    $item->getResourceName(),
964
                    [
965
                        'uri' => $this->generateUrl(
966
                            'chamilo_core_resource_list',
967
                            [
968
                                'tool' => $tool,
969
                                'type' => $type,
970
                                'id' => $item->getResourceNode()->getId(),
971
                                'cidReq' => $courseCode,
972
                            ]
973
                        ),
974
                    ]
975
                );
976
            }
977
978
            $breadcrumb->addChild(
979
                $originalResource->getResourceName(),
980
                [
981
                    'uri' => $this->generateUrl(
982
                        'chamilo_core_resource_list',
983
                        ['tool' => $tool, 'type' => $type, 'id' => $originalParent->getId(), 'cidReq' => $courseCode]
984
                    ),
985
                ]
986
            );
987
        }
988
    }
989
}
990