Completed
Push — master ( 0c649e...1ec116 )
by Julito
08:09
created

ResourceController::createResource()   B

Complexity

Conditions 8
Paths 20

Size

Total Lines 161
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 70
nc 20
nop 2
dl 0
loc 161
rs 7.4101
c 1
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\Block\BreadcrumbBlockService;
14
use Chamilo\CoreBundle\Component\Utils\Glide;
15
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
16
use Chamilo\CoreBundle\Entity\Resource\ResourceFile;
17
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
18
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
19
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
20
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
21
use Chamilo\CourseBundle\Controller\CourseControllerTrait;
22
use Chamilo\CourseBundle\Entity\CDocument;
23
use Chamilo\CourseBundle\Repository\CDocumentRepository;
24
use Doctrine\Common\Collections\ArrayCollection;
25
use Doctrine\Common\Collections\Criteria;
26
use Doctrine\ORM\QueryBuilder;
27
use FOS\CKEditorBundle\Form\Type\CKEditorType;
28
use League\Flysystem\Filesystem;
29
use Oneup\UploaderBundle\Uploader\Response\EmptyResponse;
30
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
31
use Sylius\Component\Resource\Exception\UpdateHandlingException;
32
use Sylius\Component\Resource\ResourceActions;
33
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
34
use Symfony\Component\HttpFoundation\File\Exception\UploadException;
35
use Symfony\Component\HttpFoundation\File\UploadedFile;
36
use Symfony\Component\HttpFoundation\JsonResponse;
37
use Symfony\Component\HttpFoundation\RedirectResponse;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\HttpFoundation\Response;
40
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
41
use Symfony\Component\HttpFoundation\StreamedResponse;
42
use Symfony\Component\HttpKernel\Exception\HttpException;
43
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
44
use Symfony\Component\Routing\Annotation\Route;
45
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
46
use Symfony\Component\Routing\RouterInterface;
47
use Vich\UploaderBundle\Util\Transliterator;
48
use ZipStream\Option\Archive;
49
use ZipStream\ZipStream;
50
51
/**
52
 * Class ResourceController.
53
 *
54
 * @Route("/resources")
55
 *
56
 * @author Julio Montoya <[email protected]>.
57
 */
58
class ResourceController extends AbstractResourceController implements CourseControllerInterface
59
{
60
    use CourseControllerTrait;
61
62
    /**
63
     * @Route("/{tool}/{type}", name="chamilo_core_resource_index")
64
     *
65
     * Example: /document/files
66
     * For the tool value check the Tool entity.
67
     * For the type value check the ResourceType entity.
68
     *
69
     * @param Request $request
70
     *
71
     * @return Response
72
     */
73
    public function indexAction(Request $request, Grid $grid): Response
74
    {
75
        $tool = $request->get('tool');
76
        $type = $request->get('type');
77
78
        $grid = $this->getGrid( $request, $grid);
79
80
        $breadcrumb = $this->breadcrumbBlockService;
81
        $breadcrumb->addChild(
82
            $this->trans('Documents'),
83
            [
84
                'uri' => '#',
85
            ]
86
        );
87
88
        // The base resource node is the course.
89
        $id = $this->getCourse()->getResourceNode()->getId();
90
91
        return $grid->getGridResponse(
92
            '@ChamiloTheme/Resource/index.html.twig',
93
            ['tool' => $tool, 'type' => $type, 'id' => $id]
94
        );
95
    }
96
97
    /**
98
     * @param Request $request
99
     * @param Grid    $grid
100
     * @param int     $resourceNodeId
101
     *
102
     * @return Grid
103
     */
104
    public function getGrid(Request $request, Grid $grid, $resourceNodeId = 0)
105
    {
106
        $tool = $request->get('tool');
107
        $type = $request->get('type');
108
109
        $repository = $this->getRepositoryFromRequest($request);
110
        $class = $repository->getRepository()->getClassName();
111
        $source = new Entity($class);
112
113
        /*$tableAlias = $source->getTableAlias();
114
        $source->manipulateQuery(function (QueryBuilder $query) use ($tableAlias, $course) {
115
                $query->andWhere($tableAlias . '.cId = '.$course->getId());
116
                //$query->resetDQLPart('orderBy');
117
            }
118
        );*/
119
120
        $course = $this->getCourse();
121
        $session = $this->getSession();
122
123
        $parent = $course->getResourceNode();
124
        if (!empty($resourceNodeId)) {
125
            $parent = $repository->getResourceNodeRepository()->find($resourceNodeId);
126
        }
127
128
        $qb = $repository->getResourcesByCourse($course, $session, null, $parent);
129
130
        // 3. Set QueryBuilder to the source.
131
        $source->initQueryBuilder($qb);
132
        $grid->setSource($source);
133
134
        $title = $grid->getColumn('title');
135
        $title->setSafe(false);
136
137
        //$grid->hideFilters();
138
        $grid->setLimits(20);
139
        //$grid->isReadyForRedirect();
140
        //$grid->setMaxResults(1);
141
        //$grid->setLimits(2);
142
143
        $translation = $this->translator;
144
        $courseIdentifier = $course->getCode();
145
146
        $routeParams = ['tool' => $tool, 'type' => $type, 'cidReq' => $courseIdentifier, 'id'];
147
148
        // Title link.
149
        $grid->getColumn('title')->manipulateRenderCell(
150
            function ($value, Row $row, $router) use ($routeParams) {
151
                /** @var CDocument $entity */
152
                $entity = $row->getEntity();
153
                $resourceNode = $entity->getResourceNode();
154
                $id = $resourceNode->getId();
155
156
                $myParams = $routeParams;
157
                $myParams['id'] = $id;
158
                unset($myParams[0]);
159
160
                if ($resourceNode->hasResourceFile()) {
161
                    $url = $router->generate(
162
                        'chamilo_core_resource_show',
163
                        $myParams
164
                    );
165
                } else {
166
                    $url = $router->generate(
167
                        'chamilo_core_resource_list',
168
                        $myParams
169
                    );
170
                }
171
172
                return '<a href="'.$url.'">'.$value.'</a>';
173
            }
174
        );
175
176
        // Delete mass action.
177
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
178
            $deleteMassAction = new MassAction(
179
                'Delete',
180
                'ChamiloCoreBundle:Resource:deleteMass',
181
                true,
182
                $routeParams
183
            );
184
            $grid->addMassAction($deleteMassAction);
185
        }
186
187
        // Show resource action.
188
        $myRowAction = new RowAction(
189
            $translation->trans('View'),
190
            'chamilo_core_resource_show',
191
            false,
192
            '_self',
193
            ['class' => 'btn btn-secondary']
194
        );
195
196
        $setNodeParameters = function (RowAction $action, Row $row) use ($routeParams) {
197
            $id = $row->getEntity()->getResourceNode()->getId();
198
            $routeParams['id'] = $id;
199
            $action->setRouteParameters($routeParams);
200
201
            return $action;
202
        };
203
204
        $myRowAction->addManipulateRender($setNodeParameters);
205
        $grid->addRowAction($myRowAction);
206
207
        if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
208
            // Edit action.
209
            $myRowAction = new RowAction(
210
                $translation->trans('Edit'),
211
                'chamilo_core_resource_edit',
212
                false,
213
                '_self',
214
                ['class' => 'btn btn-secondary']
215
            );
216
            $myRowAction->addManipulateRender($setNodeParameters);
217
            $grid->addRowAction($myRowAction);
218
219
            // Delete action.
220
            $myRowAction = new RowAction(
221
                $translation->trans('Delete'),
222
                'chamilo_core_resource_delete',
223
                true,
224
                '_self',
225
                ['class' => 'btn btn-danger']
226
            );
227
            $myRowAction->addManipulateRender($setNodeParameters);
228
            $grid->addRowAction($myRowAction);
229
        }
230
231
        /*$grid->addExport(new CSVExport($translation->trans('CSV export'), 'export', ['course' => $courseIdentifier]));
232
        $grid->addExport(
233
            new ExcelExport(
234
                $translation->trans('Excel export'),
235
                'export',
236
                ['course' => $courseIdentifier]
237
            )
238
        );*/
239
240
        return $grid;
241
    }
242
243
    /**
244
     * @Route("/{tool}/{type}/{id}/list", name="chamilo_core_resource_list")
245
     *
246
     * If node has children show it
247
     *
248
     * @param Request $request
249
     *
250
     * @return Response
251
     */
252
    public function listAction(Request $request, Grid $grid): Response
253
    {
254
        $tool = $request->get('tool');
255
        $type = $request->get('type');
256
        $resourceNodeId = $request->get('id');
257
258
        $grid = $this->getGrid( $request, $grid,$resourceNodeId);
259
260
        $this->setBreadCrumb($request);
261
262
        return $grid->getGridResponse(
263
            '@ChamiloTheme/Resource/index.html.twig',
264
            ['parent_id' => $resourceNodeId, 'tool' => $tool, 'type' => $type, 'id' => $resourceNodeId]
265
        );
266
    }
267
268
    /**
269
     * @Route("/{tool}/{type}/{id}/new_folder", methods={"GET", "POST"}, name="chamilo_core_resource_new_folder")
270
     *
271
     * @param Request $request
272
     *
273
     * @return Response
274
     */
275
    public function newFolderAction(Request $request): Response
276
    {
277
        $this->setBreadCrumb($request);
278
279
        return $this->createResource($request, 'folder');
280
    }
281
282
    /**
283
     * @Route("/{tool}/{type}/{id}/new", methods={"GET", "POST"}, name="chamilo_core_resource_new")
284
     *
285
     * @param Request $request
286
     *
287
     * @return Response
288
     */
289
    public function newAction(Request $request): Response
290
    {
291
        $this->setBreadCrumb($request);
292
293
        return $this->createResource($request, 'file');
294
    }
295
296
    /**
297
     * @Route("/{tool}/{type}/{id}/edit", methods={"GET", "POST"})
298
     *
299
     * @param Request $request
300
     *
301
     * @return Response
302
     */
303
    public function editAction(Request $request): Response
304
    {
305
        $tool = $request->get('tool');
306
        $type = $request->get('type');
307
        $nodeId = $request->get('id');
308
309
        $this->setBreadCrumb($request);
310
311
        $repository = $this->getRepositoryFromRequest($request);
312
        /** @var AbstractResource $resource */
313
        $resource = $repository->getRepository()->findOneBy(['resourceNode' => $nodeId]);
314
        $node = $resource->getResourceNode();
315
        $resourceNodeParentId = $node->getId();
316
317
        $form = $repository->getForm($this->container->get('form.factory'), $resource);
318
319
        if ($node->isEditable()) {
320
            $form->add(
321
                'content',
322
                CKEditorType::class,
323
                [
324
                    'mapped' => false,
325
                    'config' => [
326
                        'filebrowserImageBrowseRoute' => 'editor_filemanager',
327
                        'filebrowserImageBrowseRouteParameters' => array(
328
                            'tool' => $tool,
329
                            'type' => $type,
330
                            'cidReq' => $this->getCourse()->getCode(),
331
                            'id' => $resourceNodeParentId
332
                        )
333
                    ],
334
                ]
335
            );
336
            $content = $repository->getResourceFileContent($resource);
337
            $form->get('content')->setData($content);
338
        }
339
340
        $form->handleRequest($request);
341
342
        if ($form->isSubmitted() && $form->isValid()) {
343
            /** @var CDocument $newResource */
344
            $newResource = $form->getData();
345
346
            if ($form->has('content')) {
347
                $data = $form->get('content')->getData();
348
                $repository->updateResourceFileContent($newResource, $data);
349
            }
350
351
            $newResource->setTitle($form->get('title')->getData());
352
            $repository->updateNodeForResource($newResource);
353
354
            /*$em->persist($newResource);
355
            $em->flush();*/
356
357
            $this->addFlash('success', $this->trans('Updated'));
358
359
            if ($newResource->getResourceNode()->hasResourceFile()) {
360
                $resourceNodeParentId = $newResource->getResourceNode()->getParent()->getId();
361
            }
362
363
            return $this->redirectToRoute(
364
                'chamilo_core_resource_list',
365
                [
366
                    'id' => $resourceNodeParentId,
367
                    'tool' => $tool,
368
                    'type' => $type,
369
                    'cidReq' => $this->getCourse()->getCode(),
370
                ]
371
            );
372
        }
373
374
        return $this->render(
375
            '@ChamiloTheme/Resource/edit.html.twig',
376
            [
377
                'form' => $form->createView(),
378
                'parent' => $resourceNodeParentId,
379
            ]
380
        );
381
    }
382
383
    /**
384
     * Shows a resource.
385
     *
386
     * @Route("/{tool}/{type}/{id}/show", methods={"GET"}, name="chamilo_core_resource_show")
387
     *
388
     * @param Request $request
389
     *
390
     * @return Response
391
     */
392
    public function showAction(Request $request): Response
393
    {
394
        $this->setBreadCrumb($request);
395
        $nodeId = $request->get('id');
396
397
        $repository = $this->getRepositoryFromRequest($request);
398
399
        /** @var AbstractResource $resource */
400
        $resource = $repository->getRepository()->findOneBy(['resourceNode' => $nodeId]);
401
402
        if (null === $resource) {
403
            throw new NotFoundHttpException();
404
        }
405
406
        $resourceNode = $resource->getResourceNode();
407
408
        if (null === $resourceNode) {
409
            throw new NotFoundHttpException();
410
        }
411
412
        $this->denyAccessUnlessGranted(
413
            ResourceNodeVoter::VIEW,
414
            $resourceNode,
415
            'Unauthorised access to resource'
416
        );
417
418
        $tool = $request->get('tool');
419
        $type = $request->get('type');
420
421
        $params = [
422
            'resource' => $resource,
423
            'tool' => $tool,
424
            'type' => $type,
425
        ];
426
427
        return $this->render('@ChamiloTheme/Resource/show.html.twig', $params);
428
    }
429
430
    /**
431
     * @Route("/{tool}/{type}/{id}", name="chamilo_core_resource_delete")
432
     *
433
     * @param Request $request
434
     *
435
     * @return Response
436
     */
437
    public function deleteAction(Request $request): Response
438
    {
439
        $tool = $request->get('tool');
440
        $type = $request->get('type');
441
442
        $em = $this->getDoctrine()->getManager();
443
444
        $id = $request->get('id');
445
        $resourceNode = $this->getDoctrine()->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
446
        $parentId = $resourceNode->getParent()->getId();
447
448
        if (null === $resourceNode) {
449
            throw new NotFoundHttpException();
450
        }
451
452
        $this->denyAccessUnlessGranted(
453
            ResourceNodeVoter::DELETE,
454
            $resourceNode,
455
            'Unauthorised access to resource'
456
        );
457
458
        $em->remove($resourceNode);
459
        $this->addFlash('success', $this->trans('Deleted'));
460
        $em->flush();
461
462
        return $this->redirectToRoute(
463
            'chamilo_core_resource_list',
464
            [
465
                'id' => $parentId,
466
                'tool' => $tool,
467
                'type' => $type,
468
                'cidReq' => $this->getCourse()->getCode(),
469
            ]
470
        );
471
    }
472
473
    /**
474
     * @Route("/{tool}/{type}/{id}", methods={"DELETE"}, name="chamilo_core_resource_delete_mass")
475
     *
476
     * @param Request $request
477
     *
478
     * @return Response
479
     */
480
    public function deleteMassAction($primaryKeys, $allPrimaryKeys, Request $request): Response
481
    {
482
        $tool = $request->get('tool');
483
        $type = $request->get('type');
484
        $em = $this->getDoctrine()->getManager();
485
        $repo = $this->getRepositoryFromRequest($request);
486
487
        $parentId = 0;
488
        foreach ($primaryKeys as $id) {
489
            $resource = $repo->find($id);
490
            $resourceNode = $resource->getResourceNode();
491
492
            if (null === $resourceNode) {
493
                continue;
494
            }
495
496
            $this->denyAccessUnlessGranted(
497
                ResourceNodeVoter::DELETE,
498
                $resourceNode,
499
                'Unauthorised access to resource'
500
            );
501
502
            $parentId = $resourceNode->getParent()->getId();
503
            $em->remove($resource);
504
        }
505
506
        $this->addFlash('success', $this->trans('Deleted'));
507
        $em->flush();
508
509
        return $this->redirectToRoute(
510
            'chamilo_core_resource_list',
511
            [
512
                'id' => $parentId,
513
                'tool' => $tool,
514
                'type' => $type,
515
                'cidReq' => $this->getCourse()->getCode(),
516
            ]
517
        );
518
    }
519
520
    /**
521
     * @Route("/{tool}/{type}/{id}/file", methods={"GET"}, name="chamilo_core_resource_file")
522
     *
523
     * @param Request $request
524
     * @param Glide   $glide
525
     *
526
     * @return Response
527
     */
528
    public function getResourceFileAction(Request $request, Glide $glide): Response
529
    {
530
        $id = $request->get('id');
531
        $filter = $request->get('filter');
532
        $mode = $request->get('mode');
533
        $em = $this->getDoctrine();
534
        $resourceNode = $em->getRepository('ChamiloCoreBundle:Resource\ResourceNode')->find($id);
535
536
        if ($resourceNode === null) {
537
            throw new FileNotFoundException('Resource not found');
538
        }
539
540
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
541
    }
542
543
    /**
544
     * Gets a document when calling route resources_document_get_file.
545
     *
546
     * @param Request             $request
547
     * @param CDocumentRepository $documentRepo
548
     * @param Glide               $glide
549
     *
550
     * @return Response
551
     * @throws \League\Flysystem\FileNotFoundException
552
     */
553
    public function getDocumentAction(Request $request, Glide $glide): Response
554
    {
555
        $file = $request->get('file');
556
        $mode = $request->get('mode');
557
558
        // see list of filters in config/services.yaml
559
        $filter = $request->get('filter');
560
        $mode = !empty($mode) ? $mode : 'show';
561
562
        $repository = $this->getRepository('document', 'files');
563
        $nodeRepository = $repository->getResourceNodeRepository();
564
565
        $title = basename($file);
566
        // @todo improve criteria to avoid giving the wrong file.
567
        $criteria = ['slug' => $title];
568
569
        $resourceNode = $nodeRepository->findOneBy($criteria);
570
571
        if (null === $resourceNode) {
572
            throw new NotFoundHttpException();
573
        }
574
575
        $this->denyAccessUnlessGranted(
576
            ResourceNodeVoter::VIEW,
577
            $resourceNode,
578
            'Unauthorised access to resource'
579
        );
580
581
        return $this->showFile($request, $resourceNode, $glide, $mode, $filter);
582
    }
583
584
    /**
585
     * Downloads a folder.
586
     *
587
     * @param Request             $request
588
     * @param CDocumentRepository $documentRepo
589
     *
590
     * @return Response
591
     */
592
    public function downloadFolderAction(Request $request, CDocumentRepository $documentRepo)
593
    {
594
        $folderId = (int) $request->get('folderId');
595
        $courseNode = $this->getCourse()->getResourceNode();
596
597
        if (empty($folderId)) {
598
            $resourceNode = $courseNode;
599
        } else {
600
            $document = $documentRepo->find($folderId);
601
            $resourceNode = $document->getResourceNode();
602
        }
603
604
        $type = $documentRepo->getResourceType();
605
606
        if (null === $resourceNode || null === $courseNode) {
607
            throw new NotFoundHttpException();
608
        }
609
610
        $this->denyAccessUnlessGranted(
611
            ResourceNodeVoter::VIEW,
612
            $resourceNode,
613
            'Unauthorised access to resource'
614
        );
615
616
        $zipName = $resourceNode->getName().'.zip';
617
        $rootNodePath = $resourceNode->getPathForDisplay();
618
619
        /** @var Filesystem $fileSystem */
620
        $fileSystem = $this->get('oneup_flysystem.resources_filesystem');
621
622
        $resourceNodeRepo = $documentRepo->getResourceNodeRepository();
623
624
        $criteria = Criteria::create()
625
            ->where(Criteria::expr()->neq('resourceFile', null))
626
            ->andWhere(Criteria::expr()->eq('resourceType', $type))
627
        ;
628
629
        /** @var ArrayCollection|ResourceNode[] $children */
630
        /** @var QueryBuilder $children */
631
        $qb = $resourceNodeRepo->getChildrenQueryBuilder($resourceNode);
632
        $qb->addCriteria($criteria);
633
        $children = $qb->getQuery()->getResult();
634
635
        /** @var ResourceNode $node */
636
        foreach ($children as $node) {
637
            /*if ($node->hasResourceFile()) {
638
                $resourceFile = $node->getResourceFile();
639
                $systemName = $resourceFile->getFile()->getPathname();
640
                $stream = $fileSystem->readStream($systemName);
641
                //error_log($node->getPathForDisplay());
642
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
643
                var_dump($fileToDisplay);
644
            }*/
645
            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...
646
            //var_dump($node['path']);
647
        }
648
649
        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...
650
651
652
        $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...
653
        {
654
            // Define suitable options for ZipStream Archive.
655
            $options = new Archive();
656
            $options->setContentType('application/octet-stream');
657
            //initialise zipstream with output zip filename and options.
658
            $zip = new ZipStream($zipName, $options);
659
660
            /** @var ResourceNode $node */
661
            foreach ($children as $node) {
662
                $resourceFile = $node->getResourceFile();
663
                $systemName = $resourceFile->getFile()->getPathname();
664
                $stream = $fileSystem->readStream($systemName);
665
                //error_log($node->getPathForDisplay());
666
                $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
667
                $zip->addFileFromStream($fileToDisplay, $stream);
668
            }
669
            //$data = $repo->getDocumentContent($not_deleted_file['id']);
670
            //$zip->addFile($not_deleted_file['path'], $data);
671
            $zip->finish();
672
        });
673
674
        $disposition = $response->headers->makeDisposition(
675
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
676
            Transliterator::transliterate($zipName)
677
        );
678
        $response->headers->set('Content-Disposition', $disposition);
679
        $response->headers->set('Content-Type', 'application/octet-stream');
680
681
        return $response;
682
    }
683
684
    /**
685
     * Upload form.
686
     *
687
     * @Route("/{tool}/{type}/{id}/upload", name="chamilo_core_resource_upload", methods={"GET", "POST"},
688
     *                                      options={"expose"=true})
689
     */
690
    public function uploadAction(Request $request, $tool, $type, $id): Response
691
    {
692
        $this->setBreadCrumb( $request);
693
        //$helper = $this->container->get('oneup_uploader.templating.uploader_helper');
694
        //$endpoint = $helper->endpoint('courses');
695
        $session = $this->getSession();
696
        $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...
697
698
        return $this->render(
699
            '@ChamiloTheme/Resource/upload.html.twig',
700
            [
701
                'id' => $id,
702
                'type' => $type,
703
                'tool' => $tool,
704
                'cidReq' => $this->getCourse()->getCode(),
705
                'id_session' => $sessionId,
706
            ]
707
        );
708
    }
709
710
    /**
711
     * @param Request      $request
712
     * @param ResourceNode $resourceNode
713
     * @param Glide        $glide
714
     * @param string       $mode show or download
715
     * @param string       $filter
716
     *
717
     * @return mixed|StreamedResponse
718
     */
719
    private function showFile(Request $request, ResourceNode $resourceNode, Glide $glide, $mode = 'show', $filter = '')
720
    {
721
        $this->denyAccessUnlessGranted(
722
            ResourceNodeVoter::VIEW,
723
            $resourceNode,
724
            'Unauthorised access to resource'
725
        );
726
        $resourceFile = $resourceNode->getResourceFile();
727
728
        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...
729
            throw new NotFoundHttpException();
730
        }
731
732
        //$fileName = $resourceFile->getOriginalName();
733
        $fileName = $resourceNode->getSlug();
734
        $filePath = $resourceFile->getFile()->getPathname();
735
        $mimeType = $resourceFile->getMimeType();
736
737
        switch ($mode) {
738
            case 'download':
739
                $forceDownload = true;
740
                break;
741
            case 'show':
742
            default:
743
                $forceDownload = false;
744
                // If it's an image then send it to Glide.
745
                if (strpos($mimeType, 'image') !== false) {
746
                    $server = $glide->getServer();
747
                    $params = $request->query->all();
748
749
                    // The filter overwrites the params from get
750
                    if (!empty($filter)) {
751
                        $params = $glide->getFilters()[$filter] ?? [];
752
                    }
753
754
                    // The image was cropped manually by the user, so we force to render this version,
755
                    // no matter other crop parameters.
756
                    $crop = $resourceFile->getCrop();
757
                    if (!empty($crop)) {
758
                        $params['crop'] = $crop;
759
                    }
760
761
                    return $server->getImageResponse($filePath, $params);
762
                }
763
                break;
764
        }
765
766
        $stream = $this->fs->readStream($filePath);
767
        $response = new StreamedResponse(function () use ($stream): void {
768
            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

768
            stream_copy_to_stream($stream, /** @scrutinizer ignore-type */ fopen('php://output', 'wb'));
Loading history...
769
        });
770
        $disposition = $response->headers->makeDisposition(
771
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
772
            $fileName
773
            //Transliterator::transliterate($fileName)
774
        );
775
        $response->headers->set('Content-Disposition', $disposition);
776
        $response->headers->set('Content-Type', $mimeType ?: 'application/octet-stream');
777
778
        return $response;
779
    }
780
781
    /**
782
     * @param Request $request
783
     * @param string  $fileType
784
     *
785
     * @return RedirectResponse|Response
786
     */
787
    private function createResource(Request $request, $fileType = 'file')
788
    {
789
        $tool = $request->get('tool');
790
        $type = $request->get('type');
791
        $resourceNodeParentId = $request->get('id');
792
793
        $repository = $this->getRepositoryFromRequest($request);
794
795
        $form = $repository->getForm($this->container->get('form.factory'));
796
797
        if ($fileType === 'file') {
798
            $form->add(
799
                'content',
800
                CKEditorType::class,
801
                [
802
                    'mapped' => false,
803
                    'config' => [
804
                        'filebrowserImageBrowseRoute' => 'editor_filemanager',
805
                        'filebrowserImageBrowseRouteParameters' => array(
806
                            'tool' => $tool,
807
                            'type' => $type,
808
                            'cidReq' => $this->getCourse()->getCode(),
809
                            'id' => $resourceNodeParentId
810
                        )
811
                    ],
812
                ]
813
            );
814
        }
815
816
        $course = $this->getCourse();
817
        $session = $this->getSession();
818
        // Default parent node is course.
819
        $parentNode = $course->getResourceNode();
820
        if (!empty($resourceNodeParentId)) {
821
            // Get parent node.
822
            $parentNode = $repository->getResourceNodeRepository()->find($resourceNodeParentId);
823
        }
824
825
        $form->handleRequest($request);
826
        if ($form->isSubmitted() && $form->isValid()) {
827
            $em = $this->getDoctrine()->getManager();
828
829
            /** @var CDocument $newResource */
830
            $newResource = $form->getData();
831
832
            $newResource
833
                ->setCourse($course)
834
                ->setSession($session)
835
                ->setFiletype($fileType)
836
                //->setTitle($title) // already added in $form->getData()
837
                ->setReadonly(false)
838
            ;
839
840
            $file = null;
841
            if ($fileType === 'file') {
842
                $content = $form->get('content')->getViewData();
843
                $newResource->setTitle($newResource->getTitle().'.html');
844
                $fileName = $newResource->getTitle();
845
846
                $handle = tmpfile();
847
                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

847
                fwrite(/** @scrutinizer ignore-type */ $handle, $content);
Loading history...
848
                $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

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