Completed
Push — master ( 1ec116...44391b )
by Julito
07:27
created

ResourceController::getGrid()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 183
Code Lines 99

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 99
nc 8
nop 3
dl 0
loc 183
rs 6.7773
c 0
b 0
f 0

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* 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\Component\Utils\Glide;
14
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
15
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
16
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
17
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
18
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
19
use Chamilo\CourseBundle\Controller\CourseControllerTrait;
20
use Chamilo\CourseBundle\Entity\CDocument;
21
use Chamilo\CourseBundle\Repository\CDocumentRepository;
22
use Doctrine\Common\Collections\ArrayCollection;
23
use Doctrine\Common\Collections\Criteria;
24
use Doctrine\ORM\QueryBuilder;
25
use FOS\CKEditorBundle\Form\Type\CKEditorType;
26
use League\Flysystem\Filesystem;
27
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
28
use Symfony\Component\HttpFoundation\File\UploadedFile;
29
use Symfony\Component\HttpFoundation\RedirectResponse;
30
use Symfony\Component\HttpFoundation\Request;
31
use Symfony\Component\HttpFoundation\Response;
32
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
33
use Symfony\Component\HttpFoundation\StreamedResponse;
34
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
35
use Symfony\Component\Routing\Annotation\Route;
36
use Symfony\Component\Routing\Router;
37
use Vich\UploaderBundle\Util\Transliterator;
38
use ZipStream\Option\Archive;
39
use ZipStream\ZipStream;
40
41
/**
42
 * Class ResourceController.
43
 *
44
 * @Route("/resources")
45
 *
46
 * @author Julio Montoya <[email protected]>.
47
 */
48
class ResourceController extends AbstractResourceController implements CourseControllerInterface
49
{
50
    use CourseControllerTrait;
51
52
    /**
53
     * @Route("/{tool}/{type}", name="chamilo_core_resource_index")
54
     *
55
     * Example: /document/files
56
     * For the tool value check the Tool entity.
57
     * For the type value check the ResourceType entity.
58
     *
59
     * @param Request $request
60
     *
61
     * @return Response
62
     */
63
    public function indexAction(Request $request, Grid $grid): Response
64
    {
65
        $tool = $request->get('tool');
66
        $type = $request->get('type');
67
68
        $grid = $this->getGrid( $request, $grid);
69
70
        $breadcrumb = $this->breadcrumbBlockService;
71
        $breadcrumb->addChild(
72
            $this->trans('Documents'),
73
            [
74
                'uri' => '#',
75
            ]
76
        );
77
78
        // The base resource node is the course.
79
        $id = $this->getCourse()->getResourceNode()->getId();
80
81
        return $grid->getGridResponse(
82
            '@ChamiloTheme/Resource/index.html.twig',
83
            ['tool' => $tool, 'type' => $type, 'id' => $id]
84
        );
85
    }
86
87
    /**
88
     * @param Request $request
89
     * @param Grid    $grid
90
     * @param int     $resourceNodeId
91
     *
92
     * @return Grid
93
     */
94
    public function getGrid(Request $request, Grid $grid, $resourceNodeId = 0)
95
    {
96
        $tool = $request->get('tool');
97
        $type = $request->get('type');
98
99
        $repository = $this->getRepositoryFromRequest($request);
100
        $class = $repository->getRepository()->getClassName();
101
        $source = new Entity($class);
102
103
        /*$tableAlias = $source->getTableAlias();
104
        $source->manipulateQuery(function (QueryBuilder $query) use ($tableAlias, $course) {
105
                $query->andWhere($tableAlias . '.cId = '.$course->getId());
106
                //$query->resetDQLPart('orderBy');
107
            }
108
        );*/
109
110
        $course = $this->getCourse();
111
        $session = $this->getSession();
112
113
        $parent = $course->getResourceNode();
114
        if (!empty($resourceNodeId)) {
115
            $parent = $repository->getResourceNodeRepository()->find($resourceNodeId);
116
        }
117
118
        $qb = $repository->getResourcesByCourse($course, $session, null, $parent);
119
120
        // 3. Set QueryBuilder to the source.
121
        $source->initQueryBuilder($qb);
122
        $grid->setSource($source);
123
124
        $title = $grid->getColumn('title');
125
        $title->setSafe(false);
126
127
        //$grid->hideFilters();
128
        $grid->setLimits(20);
129
        //$grid->isReadyForRedirect();
130
        //$grid->setMaxResults(1);
131
        //$grid->setLimits(2);
132
133
        $translation = $this->translator;
134
        $courseIdentifier = $course->getCode();
135
136
        $routeParams = ['tool' => $tool, 'type' => $type, 'cidReq' => $courseIdentifier, 'id'];
137
138
        // Title link.
139
        $grid->getColumn('title')->setTitle($this->trans('Name'));
140
        $grid->getColumn('filetype')->setTitle($this->trans('Type'));
141
142
        $grid->getColumn('title')->manipulateRenderCell(
143
            function ($value, Row $row, $router) use ($routeParams) {
144
145
                /** @var Router $router */
146
                /** @var CDocument $entity */
147
                $entity = $row->getEntity();
148
                $resourceNode = $entity->getResourceNode();
149
                $id = $resourceNode->getId();
150
151
                $myParams = $routeParams;
152
                $myParams['id'] = $id;
153
                unset($myParams[0]);
154
155
                if ($resourceNode->hasResourceFile()) {
156
                    $url = $router->generate(
157
                        'chamilo_core_resource_show',
158
                        $myParams
159
                    );
160
161
                    if ($resourceNode->isResourceFileAnImage()) {
162
                        $url = $router->generate(
163
                            'chamilo_core_resource_file',
164
                            $myParams
165
                        );
166
167
                        return '<a data-fancybox="gallery" href="'.$url.'">'.$value.'</a>';
168
                    }
169
170
                    if ($resourceNode->isResourceFileAVideo()) {
171
                        $url = $router->generate(
172
                            'chamilo_core_resource_file',
173
                            $myParams
174
                        );
175
176
                        return '
177
                        <video width="640" height="320" controls id="video'.$id.'" style="display:none;">
178
                            <source src="'.$url.'" type="video/mp4">
179
                            Your browser doesn\'t support HTML5 video tag.
180
                        </video>
181
                        <a data-fancybox="gallery"  data-width="640" data-height="360" href="#video'.$id.'">'.$value.'</a>';
182
                    }
183
                    return '<a data-fancybox="gallery" data-type="iframe" data-src="'.$url.'" href="javascript:;" >'.$value.'</a>';
184
                } else {
185
                    $url = $router->generate(
186
                        'chamilo_core_resource_list',
187
                        $myParams
188
                    );
189
190
                    return '<a href="'.$url.'">'.$value.'</a>';
191
                }
192
            }
193
        );
194
195
        $grid->getColumn('filetype')->manipulateRenderCell(
196
            function ($value, Row $row, $router) use ($routeParams) {
0 ignored issues
show
Unused Code introduced by
The parameter $router is not used and could be removed. ( Ignorable by Annotation )

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

196
            function ($value, Row $row, /** @scrutinizer ignore-unused */ $router) use ($routeParams) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The import $routeParams is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
197
                /** @var CDocument $entity */
198
                $entity = $row->getEntity();
199
                $resourceNode = $entity->getResourceNode();
200
201
                if ($resourceNode->hasResourceFile()) {
202
                    $file = $resourceNode->getResourceFile();
203
                    return $file->getMimeType();
204
                }
205
206
                return $this->trans('Folder');
207
            }
208
        );
209
210
        $grid->setHiddenColumns(['iid']);
211
212
        // Delete mass action.
213
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
214
            $deleteMassAction = new MassAction(
215
                'Delete',
216
                'ChamiloCoreBundle:Resource:deleteMass',
217
                true,
218
                $routeParams
219
            );
220
            $grid->addMassAction($deleteMassAction);
221
        }
222
223
        // Show resource action.
224
        $myRowAction = new RowAction(
225
            $translation->trans('View'),
226
            'chamilo_core_resource_show',
227
            false,
228
            '_self',
229
            ['class' => 'btn btn-secondary']
230
        );
231
232
        $setNodeParameters = function (RowAction $action, Row $row) use ($routeParams) {
233
            $id = $row->getEntity()->getResourceNode()->getId();
234
            $routeParams['id'] = $id;
235
            $action->setRouteParameters($routeParams);
236
237
            return $action;
238
        };
239
240
        $myRowAction->addManipulateRender($setNodeParameters);
241
        $grid->addRowAction($myRowAction);
242
243
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
244
            // Edit action.
245
            $myRowAction = new RowAction(
246
                $translation->trans('Edit'),
247
                'chamilo_core_resource_edit',
248
                false,
249
                '_self',
250
                ['class' => 'btn btn-secondary']
251
            );
252
            $myRowAction->addManipulateRender($setNodeParameters);
253
            $grid->addRowAction($myRowAction);
254
255
            // Delete action.
256
            $myRowAction = new RowAction(
257
                $translation->trans('Delete'),
258
                'chamilo_core_resource_delete',
259
                true,
260
                '_self',
261
                ['class' => 'btn btn-danger']
262
            );
263
            $myRowAction->addManipulateRender($setNodeParameters);
264
            $grid->addRowAction($myRowAction);
265
        }
266
267
        /*$grid->addExport(new CSVExport($translation->trans('CSV export'), 'export', ['course' => $courseIdentifier]));
268
        $grid->addExport(
269
            new ExcelExport(
270
                $translation->trans('Excel export'),
271
                'export',
272
                ['course' => $courseIdentifier]
273
            )
274
        );*/
275
276
        return $grid;
277
    }
278
279
    /**
280
     * @Route("/{tool}/{type}/{id}/list", name="chamilo_core_resource_list")
281
     *
282
     * If node has children show it
283
     *
284
     * @param Request $request
285
     *
286
     * @return Response
287
     */
288
    public function listAction(Request $request, Grid $grid): Response
289
    {
290
        $tool = $request->get('tool');
291
        $type = $request->get('type');
292
        $resourceNodeId = $request->get('id');
293
294
        $grid = $this->getGrid( $request, $grid,$resourceNodeId);
295
296
        $this->setBreadCrumb($request);
297
298
        return $grid->getGridResponse(
299
            '@ChamiloTheme/Resource/index.html.twig',
300
            ['parent_id' => $resourceNodeId, 'tool' => $tool, 'type' => $type, 'id' => $resourceNodeId]
301
        );
302
    }
303
304
    /**
305
     * @Route("/{tool}/{type}/{id}/new_folder", methods={"GET", "POST"}, name="chamilo_core_resource_new_folder")
306
     *
307
     * @param Request $request
308
     *
309
     * @return Response
310
     */
311
    public function newFolderAction(Request $request): Response
312
    {
313
        $this->setBreadCrumb($request);
314
315
        return $this->createResource($request, 'folder');
316
    }
317
318
    /**
319
     * @Route("/{tool}/{type}/{id}/new", methods={"GET", "POST"}, name="chamilo_core_resource_new")
320
     *
321
     * @param Request $request
322
     *
323
     * @return Response
324
     */
325
    public function newAction(Request $request): Response
326
    {
327
        $this->setBreadCrumb($request);
328
329
        return $this->createResource($request, 'file');
330
    }
331
332
    /**
333
     * @Route("/{tool}/{type}/{id}/edit", methods={"GET", "POST"})
334
     *
335
     * @param Request $request
336
     *
337
     * @return Response
338
     */
339
    public function editAction(Request $request): Response
340
    {
341
        $tool = $request->get('tool');
342
        $type = $request->get('type');
343
        $nodeId = $request->get('id');
344
345
        $this->setBreadCrumb($request);
346
347
        $repository = $this->getRepositoryFromRequest($request);
348
        /** @var AbstractResource $resource */
349
        $resource = $repository->getRepository()->findOneBy(['resourceNode' => $nodeId]);
350
        $node = $resource->getResourceNode();
351
        $resourceNodeParentId = $node->getId();
352
353
        $form = $repository->getForm($this->container->get('form.factory'), $resource);
354
355
        if ($node->isEditable()) {
356
            $form->add(
357
                'content',
358
                CKEditorType::class,
359
                [
360
                    'mapped' => false,
361
                    'config' => [
362
                        'filebrowserImageBrowseRoute' => 'editor_filemanager',
363
                        'filebrowserImageBrowseRouteParameters' => array(
364
                            'tool' => $tool,
365
                            'type' => $type,
366
                            'cidReq' => $this->getCourse()->getCode(),
367
                            'id' => $resourceNodeParentId
368
                        )
369
                    ],
370
                ]
371
            );
372
            $content = $repository->getResourceFileContent($resource);
373
            $form->get('content')->setData($content);
374
        }
375
376
        $form->handleRequest($request);
377
378
        if ($form->isSubmitted() && $form->isValid()) {
379
            /** @var CDocument $newResource */
380
            $newResource = $form->getData();
381
382
            if ($form->has('content')) {
383
                $data = $form->get('content')->getData();
384
                $repository->updateResourceFileContent($newResource, $data);
385
            }
386
387
            $newResource->setTitle($form->get('title')->getData());
388
            $repository->updateNodeForResource($newResource);
389
390
            /*$em->persist($newResource);
391
            $em->flush();*/
392
393
            $this->addFlash('success', $this->trans('Updated'));
394
395
            if ($newResource->getResourceNode()->hasResourceFile()) {
396
                $resourceNodeParentId = $newResource->getResourceNode()->getParent()->getId();
397
            }
398
399
            return $this->redirectToRoute(
400
                'chamilo_core_resource_list',
401
                [
402
                    'id' => $resourceNodeParentId,
403
                    'tool' => $tool,
404
                    'type' => $type,
405
                    'cidReq' => $this->getCourse()->getCode(),
406
                ]
407
            );
408
        }
409
410
        return $this->render(
411
            '@ChamiloTheme/Resource/edit.html.twig',
412
            [
413
                'form' => $form->createView(),
414
                'parent' => $resourceNodeParentId,
415
            ]
416
        );
417
    }
418
419
    /**
420
     * Shows a resource.
421
     *
422
     * @Route("/{tool}/{type}/{id}/show", methods={"GET"}, name="chamilo_core_resource_show")
423
     *
424
     * @param Request $request
425
     *
426
     * @return Response
427
     */
428
    public function showAction(Request $request): Response
429
    {
430
        $this->setBreadCrumb($request);
431
        $nodeId = $request->get('id');
432
433
        $repository = $this->getRepositoryFromRequest($request);
434
435
        /** @var AbstractResource $resource */
436
        $resource = $repository->getRepository()->findOneBy(['resourceNode' => $nodeId]);
437
438
        if (null === $resource) {
439
            throw new NotFoundHttpException();
440
        }
441
442
        $resourceNode = $resource->getResourceNode();
443
444
        if (null === $resourceNode) {
445
            throw new NotFoundHttpException();
446
        }
447
448
        $this->denyAccessUnlessGranted(
449
            ResourceNodeVoter::VIEW,
450
            $resourceNode,
451
            'Unauthorised access to resource'
452
        );
453
454
        $tool = $request->get('tool');
455
        $type = $request->get('type');
456
457
        $params = [
458
            'resource' => $resource,
459
            'tool' => $tool,
460
            'type' => $type,
461
        ];
462
463
        return $this->render('@ChamiloTheme/Resource/show.html.twig', $params);
464
    }
465
466
    /**
467
     * @Route("/{tool}/{type}/{id}", name="chamilo_core_resource_delete")
468
     *
469
     * @param Request $request
470
     *
471
     * @return Response
472
     */
473
    public function deleteAction(Request $request): Response
474
    {
475
        $tool = $request->get('tool');
476
        $type = $request->get('type');
477
478
        $em = $this->getDoctrine()->getManager();
479
480
        $id = $request->get('id');
481
        $resourceNode = $this->getDoctrine()->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
482
        $parentId = $resourceNode->getParent()->getId();
483
484
        if (null === $resourceNode) {
485
            throw new NotFoundHttpException();
486
        }
487
488
        $this->denyAccessUnlessGranted(
489
            ResourceNodeVoter::DELETE,
490
            $resourceNode,
491
            'Unauthorised access to resource'
492
        );
493
494
        $em->remove($resourceNode);
495
        $this->addFlash('success', $this->trans('Deleted'));
496
        $em->flush();
497
498
        return $this->redirectToRoute(
499
            'chamilo_core_resource_list',
500
            [
501
                'id' => $parentId,
502
                'tool' => $tool,
503
                'type' => $type,
504
                'cidReq' => $this->getCourse()->getCode(),
505
            ]
506
        );
507
    }
508
509
    /**
510
     * @Route("/{tool}/{type}/{id}", methods={"DELETE"}, name="chamilo_core_resource_delete_mass")
511
     *
512
     * @param Request $request
513
     *
514
     * @return Response
515
     */
516
    public function deleteMassAction($primaryKeys, $allPrimaryKeys, Request $request): Response
517
    {
518
        $tool = $request->get('tool');
519
        $type = $request->get('type');
520
        $em = $this->getDoctrine()->getManager();
521
        $repo = $this->getRepositoryFromRequest($request);
522
523
        $parentId = 0;
524
        foreach ($primaryKeys as $id) {
525
            $resource = $repo->find($id);
526
            $resourceNode = $resource->getResourceNode();
527
528
            if (null === $resourceNode) {
529
                continue;
530
            }
531
532
            $this->denyAccessUnlessGranted(
533
                ResourceNodeVoter::DELETE,
534
                $resourceNode,
535
                'Unauthorised access to resource'
536
            );
537
538
            $parentId = $resourceNode->getParent()->getId();
539
            $em->remove($resource);
540
        }
541
542
        $this->addFlash('success', $this->trans('Deleted'));
543
        $em->flush();
544
545
        return $this->redirectToRoute(
546
            'chamilo_core_resource_list',
547
            [
548
                'id' => $parentId,
549
                'tool' => $tool,
550
                'type' => $type,
551
                'cidReq' => $this->getCourse()->getCode(),
552
            ]
553
        );
554
    }
555
556
    /**
557
     * @Route("/{tool}/{type}/{id}/file", methods={"GET"}, name="chamilo_core_resource_file")
558
     *
559
     * @param Request $request
560
     * @param Glide   $glide
561
     *
562
     * @return Response
563
     */
564
    public function getResourceFileAction(Request $request, Glide $glide): Response
565
    {
566
        $id = $request->get('id');
567
        $filter = $request->get('filter');
568
        $mode = $request->get('mode');
569
        $em = $this->getDoctrine();
570
        $resourceNode = $em->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
571
572
        if ($resourceNode === null) {
573
            throw new FileNotFoundException('Resource not found');
574
        }
575
576
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
577
    }
578
579
    /**
580
     * Gets a document when calling route resources_document_get_file.
581
     *
582
     * @param Request             $request
583
     * @param CDocumentRepository $documentRepo
584
     * @param Glide               $glide
585
     *
586
     * @return Response
587
     * @throws \League\Flysystem\FileNotFoundException
588
     */
589
    public function getDocumentAction(Request $request, Glide $glide): Response
590
    {
591
        $file = $request->get('file');
592
        $mode = $request->get('mode');
593
594
        // see list of filters in config/services.yaml
595
        $filter = $request->get('filter');
596
        $mode = !empty($mode) ? $mode : 'show';
597
598
        $repository = $this->getRepository('document', 'files');
599
        $nodeRepository = $repository->getResourceNodeRepository();
600
601
        $title = basename($file);
602
        // @todo improve criteria to avoid giving the wrong file.
603
        $criteria = ['slug' => $title];
604
605
        $resourceNode = $nodeRepository->findOneBy($criteria);
606
607
        if (null === $resourceNode) {
608
            throw new NotFoundHttpException();
609
        }
610
611
        $this->denyAccessUnlessGranted(
612
            ResourceNodeVoter::VIEW,
613
            $resourceNode,
614
            'Unauthorised access to resource'
615
        );
616
617
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
618
    }
619
620
    /**
621
     * Downloads a folder.
622
     *
623
     * @param Request             $request
624
     * @param CDocumentRepository $documentRepo
625
     *
626
     * @return Response
627
     */
628
    public function downloadFolderAction(Request $request, CDocumentRepository $documentRepo)
629
    {
630
        $folderId = (int) $request->get('folderId');
631
        $courseNode = $this->getCourse()->getResourceNode();
632
633
        if (empty($folderId)) {
634
            $resourceNode = $courseNode;
635
        } else {
636
            $document = $documentRepo->find($folderId);
637
            $resourceNode = $document->getResourceNode();
638
        }
639
640
        $type = $documentRepo->getResourceType();
641
642
        if (null === $resourceNode || null === $courseNode) {
643
            throw new NotFoundHttpException();
644
        }
645
646
        $this->denyAccessUnlessGranted(
647
            ResourceNodeVoter::VIEW,
648
            $resourceNode,
649
            'Unauthorised access to resource'
650
        );
651
652
        $zipName = $resourceNode->getName().'.zip';
653
        $rootNodePath = $resourceNode->getPathForDisplay();
654
655
        /** @var Filesystem $fileSystem */
656
        $fileSystem = $this->get('oneup_flysystem.resources_filesystem');
657
658
        $resourceNodeRepo = $documentRepo->getResourceNodeRepository();
659
660
        $criteria = Criteria::create()
661
            ->where(Criteria::expr()->neq('resourceFile', null))
662
            ->andWhere(Criteria::expr()->eq('resourceType', $type))
663
        ;
664
665
        /** @var ArrayCollection|ResourceNode[] $children */
666
        /** @var QueryBuilder $children */
667
        $qb = $resourceNodeRepo->getChildrenQueryBuilder($resourceNode);
668
        $qb->addCriteria($criteria);
669
        $children = $qb->getQuery()->getResult();
670
671
        /** @var ResourceNode $node */
672
        foreach ($children as $node) {
673
            /*if ($node->hasResourceFile()) {
674
                $resourceFile = $node->getResourceFile();
675
                $systemName = $resourceFile->getFile()->getPathname();
676
                $stream = $fileSystem->readStream($systemName);
677
                //error_log($node->getPathForDisplay());
678
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
679
                var_dump($fileToDisplay);
680
            }*/
681
            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...
682
            //var_dump($node['path']);
683
        }
684
685
        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...
686
687
688
        $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...
689
        {
690
            // Define suitable options for ZipStream Archive.
691
            $options = new Archive();
692
            $options->setContentType('application/octet-stream');
693
            //initialise zipstream with output zip filename and options.
694
            $zip = new ZipStream($zipName, $options);
695
696
            /** @var ResourceNode $node */
697
            foreach ($children as $node) {
698
                $resourceFile = $node->getResourceFile();
699
                $systemName = $resourceFile->getFile()->getPathname();
700
                $stream = $fileSystem->readStream($systemName);
701
                //error_log($node->getPathForDisplay());
702
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
703
                $zip->addFileFromStream($fileToDisplay, $stream);
704
            }
705
            //$data = $repo->getDocumentContent($not_deleted_file['id']);
706
            //$zip->addFile($not_deleted_file['path'], $data);
707
            $zip->finish();
708
        });
709
710
        $disposition = $response->headers->makeDisposition(
711
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
712
            Transliterator::transliterate($zipName)
713
        );
714
        $response->headers->set('Content-Disposition', $disposition);
715
        $response->headers->set('Content-Type', 'application/octet-stream');
716
717
        return $response;
718
    }
719
720
    /**
721
     * Upload form.
722
     *
723
     * @Route("/{tool}/{type}/{id}/upload", name="chamilo_core_resource_upload", methods={"GET", "POST"},
724
     *                                      options={"expose"=true})
725
     */
726
    public function uploadAction(Request $request, $tool, $type, $id): Response
727
    {
728
        $this->setBreadCrumb( $request);
729
        //$helper = $this->container->get('oneup_uploader.templating.uploader_helper');
730
        //$endpoint = $helper->endpoint('courses');
731
        $session = $this->getSession();
732
        $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...
733
734
        return $this->render(
735
            '@ChamiloTheme/Resource/upload.html.twig',
736
            [
737
                'id' => $id,
738
                'type' => $type,
739
                'tool' => $tool,
740
                'cidReq' => $this->getCourse()->getCode(),
741
                'id_session' => $sessionId,
742
            ]
743
        );
744
    }
745
746
    /**
747
     * @param Request      $request
748
     * @param ResourceNode $resourceNode
749
     * @param Glide        $glide
750
     * @param string       $mode show or download
751
     * @param string       $filter
752
     *
753
     * @return mixed|StreamedResponse
754
     */
755
    private function showFile(Request $request, ResourceNode $resourceNode, Glide $glide, $mode = 'show', $filter = '')
756
    {
757
        $this->denyAccessUnlessGranted(
758
            ResourceNodeVoter::VIEW,
759
            $resourceNode,
760
            'Unauthorised access to resource'
761
        );
762
        $resourceFile = $resourceNode->getResourceFile();
763
764
        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...
765
            throw new NotFoundHttpException();
766
        }
767
768
        //$fileName = $resourceFile->getOriginalName();
769
        $fileName = $resourceNode->getSlug();
770
        $filePath = $resourceFile->getFile()->getPathname();
771
        $mimeType = $resourceFile->getMimeType();
772
773
        switch ($mode) {
774
            case 'download':
775
                $forceDownload = true;
776
                break;
777
            case 'show':
778
            default:
779
                $forceDownload = false;
780
                // If it's an image then send it to Glide.
781
                if (strpos($mimeType, 'image') !== false) {
782
                    $server = $glide->getServer();
783
                    $params = $request->query->all();
784
785
                    // The filter overwrites the params from get
786
                    if (!empty($filter)) {
787
                        $params = $glide->getFilters()[$filter] ?? [];
788
                    }
789
790
                    // The image was cropped manually by the user, so we force to render this version,
791
                    // no matter other crop parameters.
792
                    $crop = $resourceFile->getCrop();
793
                    if (!empty($crop)) {
794
                        $params['crop'] = $crop;
795
                    }
796
797
                    return $server->getImageResponse($filePath, $params);
798
                }
799
                break;
800
        }
801
802
        $stream = $this->fs->readStream($filePath);
803
        $response = new StreamedResponse(function () use ($stream): void {
804
            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

804
            stream_copy_to_stream($stream, /** @scrutinizer ignore-type */ fopen('php://output', 'wb'));
Loading history...
805
        });
806
        $disposition = $response->headers->makeDisposition(
807
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
808
            $fileName
809
            //Transliterator::transliterate($fileName)
810
        );
811
        $response->headers->set('Content-Disposition', $disposition);
812
        $response->headers->set('Content-Type', $mimeType ?: 'application/octet-stream');
813
814
        return $response;
815
    }
816
817
    /**
818
     * @param Request $request
819
     * @param string  $fileType
820
     *
821
     * @return RedirectResponse|Response
822
     */
823
    private function createResource(Request $request, $fileType = 'file')
824
    {
825
        $tool = $request->get('tool');
826
        $type = $request->get('type');
827
        $resourceNodeParentId = $request->get('id');
828
829
        $repository = $this->getRepositoryFromRequest($request);
830
831
        $form = $repository->getForm($this->container->get('form.factory'));
832
833
        if ($fileType === 'file') {
834
            $form->add(
835
                'content',
836
                CKEditorType::class,
837
                [
838
                    'mapped' => false,
839
                    'config' => [
840
                        'filebrowserImageBrowseRoute' => 'editor_filemanager',
841
                        'filebrowserImageBrowseRouteParameters' => array(
842
                            'tool' => $tool,
843
                            'type' => $type,
844
                            'cidReq' => $this->getCourse()->getCode(),
845
                            'id' => $resourceNodeParentId
846
                        )
847
                    ],
848
                ]
849
            );
850
        }
851
852
        $course = $this->getCourse();
853
        $session = $this->getSession();
854
        // Default parent node is course.
855
        $parentNode = $course->getResourceNode();
856
        if (!empty($resourceNodeParentId)) {
857
            // Get parent node.
858
            $parentNode = $repository->getResourceNodeRepository()->find($resourceNodeParentId);
859
        }
860
861
        $form->handleRequest($request);
862
        if ($form->isSubmitted() && $form->isValid()) {
863
            $em = $this->getDoctrine()->getManager();
864
865
            /** @var CDocument $newResource */
866
            $newResource = $form->getData();
867
868
            $newResource
869
                ->setCourse($course)
870
                ->setSession($session)
871
                ->setFiletype($fileType)
872
                //->setTitle($title) // already added in $form->getData()
873
                ->setReadonly(false)
874
            ;
875
876
            $file = null;
877
            if ($fileType === 'file') {
878
                $content = $form->get('content')->getViewData();
879
                $newResource->setTitle($newResource->getTitle().'.html');
880
                $fileName = $newResource->getTitle();
881
882
                $handle = tmpfile();
883
                fwrite($handle, $content);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of fwrite() 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

883
                fwrite(/** @scrutinizer ignore-type */ $handle, $content);
Loading history...
884
                $meta = stream_get_meta_data($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $stream of stream_get_meta_data() 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

884
                $meta = stream_get_meta_data(/** @scrutinizer ignore-type */ $handle);
Loading history...
885
                $file = new UploadedFile($meta['uri'], $fileName, null, null, true);
886
                $em->persist($newResource);
887
            }
888
889
            $resourceNode = $repository->createNodeForResource($newResource, $this->getUser(), $parentNode, $file);
890
            $em->persist($resourceNode);
891
892
            $repository->addResourceNodeToCourse(
893
                $resourceNode,
894
                ResourceLink::VISIBILITY_PUBLISHED,
895
                $course,
896
                $session,
897
                null
898
            );
899
900
            $em->flush();
901
902
            // Loops all sharing options
903
            /*foreach ($shareList as $share) {
904
                $idList = [];
905
                if (isset($share['search'])) {
906
                    $idList = explode(',', $share['search']);
907
                }
908
909
                $resourceRight = null;
910
                if (isset($share['mask'])) {
911
                    $resourceRight = new ResourceRight();
912
                    $resourceRight
913
                        ->setMask($share['mask'])
914
                        ->setRole($share['role'])
915
                    ;
916
                }
917
918
                // Build links
919
                switch ($share['sharing']) {
920
                    case 'everyone':
921
                        $repository->addResourceToEveryone(
922
                            $resourceNode,
923
                            $resourceRight
924
                        );
925
                        break;
926
                    case 'course':
927
                        $repository->addResourceToCourse(
928
                            $resourceNode,
929
                            $course,
930
                            $resourceRight
931
                        );
932
                        break;
933
                    case 'session':
934
                        $repository->addResourceToSession(
935
                            $resourceNode,
936
                            $course,
937
                            $session,
938
                            $resourceRight
939
                        );
940
                        break;
941
                    case 'user':
942
                        // Only for me
943
                        if (isset($share['only_me'])) {
944
                            $repository->addResourceOnlyToMe($resourceNode);
945
                        } else {
946
                            // To other users
947
                            $repository->addResourceToUserList($resourceNode, $idList);
948
                        }
949
                        break;
950
                    case 'group':
951
                        // @todo
952
                        break;
953
                }*/
954
            //}
955
            $em->flush();
956
            $this->addFlash('success', $this->trans('Saved'));
957
958
            return $this->redirectToRoute(
959
                'chamilo_core_resource_list',
960
                [
961
                    'id' => $resourceNodeParentId,
962
                    'tool' => $tool,
963
                    'type' => $type,
964
                    'cidReq' => $this->getCourse()->getCode(),
965
                ]
966
            );
967
        }
968
969
        switch ($fileType) {
970
            case 'folder':
971
                $template = '@ChamiloTheme/Resource/new_folder.html.twig';
972
                break;
973
            case 'file':
974
                $template = '@ChamiloTheme/Resource/new.html.twig';
975
                break;
976
        }
977
978
        return $this->render(
979
            $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...
980
            [
981
                'form' => $form->createView(),
982
                'parent' => $resourceNodeParentId,
983
                'file_type' => $fileType,
984
            ]
985
        );
986
    }
987
988
989
    /**
990
     * @param Request $request
991
     */
992
    public function setBreadCrumb(Request $request)
993
    {
994
        $tool = $request->get('tool');
995
        $type = $request->get('type');
996
        $resourceNodeId = $request->get('id');
997
        $courseCode = $request->get('cidReq');
998
999
        if (!empty($resourceNodeId)) {
1000
            $breadcrumb = $this->breadcrumbBlockService;
1001
1002
            // Root tool link
1003
            $breadcrumb->addChild(
1004
                $this->translator->trans('Documents'),
1005
                [
1006
                    'uri' => $this->generateUrl(
1007
                        'chamilo_core_resource_index',
1008
                        ['tool' => $tool, 'type' => $type, 'cidReq' => $courseCode]
1009
                    ),
1010
                ]
1011
            );
1012
1013
            $repo = $this->getRepositoryFromRequest($request);
1014
1015
            /** @var AbstractResource $parent */
1016
            $originalResource = $repo->findOneBy(['resourceNode' => $resourceNodeId]);
1017
            if ($originalResource === null) {
1018
                return;
1019
            }
1020
            $parent = $originalParent = $originalResource->getResourceNode();
1021
1022
            $parentList = [];
1023
            while ($parent !== null) {
1024
                if ($type !== $parent->getResourceType()->getName()) {
1025
                    break;
1026
                }
1027
                $parent = $parent->getParent();
1028
                if ($parent) {
1029
                    $resource = $repo->findOneBy(['resourceNode' => $parent->getId()]);
1030
                    if ($resource) {
1031
                        $parentList[] = $resource;
1032
                    }
1033
                }
1034
            }
1035
1036
            $parentList = array_reverse($parentList);
1037
            /** @var AbstractResource $item */
1038
            foreach ($parentList as $item) {
1039
                $breadcrumb->addChild(
1040
                    $item->getResourceName(),
1041
                    [
1042
                        'uri' => $this->generateUrl(
1043
                            'chamilo_core_resource_list',
1044
                            [
1045
                                'tool' => $tool,
1046
                                'type' => $type,
1047
                                'id' => $item->getResourceNode()->getId(),
1048
                                'cidReq' => $courseCode,
1049
                            ]
1050
                        ),
1051
                    ]
1052
                );
1053
            }
1054
1055
            $breadcrumb->addChild(
1056
                $originalResource->getResourceName(),
1057
                [
1058
                    'uri' => $this->generateUrl(
1059
                        'chamilo_core_resource_list',
1060
                        ['tool' => $tool, 'type' => $type, 'id' => $originalParent->getId(), 'cidReq' => $courseCode]
1061
                    ),
1062
                ]
1063
            );
1064
        }
1065
    }
1066
}
1067