Passed
Push — master ( 39ba65...4e7d2f )
by Julito
10:09
created

ResourceController::processFile()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 68
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 39
c 0
b 0
f 0
nc 12
nop 4
dl 0
loc 68
rs 7.7404

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
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Controller;
6
7
use Chamilo\CoreBundle\Entity\AbstractResource;
8
use Chamilo\CoreBundle\Entity\ResourceLink;
9
use Chamilo\CoreBundle\Entity\ResourceNode;
10
use Chamilo\CoreBundle\Form\Type\ResourceCommentType;
11
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
12
use Chamilo\CoreBundle\Repository\ResourceWithLinkInterface;
13
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
14
use Chamilo\CoreBundle\Traits\ControllerTrait;
15
use Chamilo\CoreBundle\Traits\CourseControllerTrait;
16
use Chamilo\CoreBundle\Traits\ResourceControllerTrait;
17
use Chamilo\CourseBundle\Controller\CourseControllerInterface;
18
use Doctrine\Common\Collections\ArrayCollection;
19
use Doctrine\Common\Collections\Criteria;
20
use Doctrine\ORM\QueryBuilder;
21
use FOS\CKEditorBundle\Form\Type\CKEditorType;
22
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
23
use Symfony\Component\HttpFoundation\File\UploadedFile;
24
use Symfony\Component\HttpFoundation\JsonResponse;
25
use Symfony\Component\HttpFoundation\RedirectResponse;
26
use Symfony\Component\HttpFoundation\Request;
27
use Symfony\Component\HttpFoundation\Response;
28
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
29
use Symfony\Component\HttpFoundation\StreamedResponse;
30
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
31
use Symfony\Component\Routing\Annotation\Route;
32
use Symfony\Component\Routing\RouterInterface;
33
use ZipStream\Option\Archive;
34
use ZipStream\ZipStream;
35
36
/**
37
 * Class ResourceController.
38
 *
39
 * @Route("/r")
40
 *
41
 * @author Julio Montoya <[email protected]>.
42
 */
43
class ResourceController extends AbstractResourceController implements CourseControllerInterface
44
{
45
    use CourseControllerTrait;
46
    use ResourceControllerTrait;
47
    use ControllerTrait;
48
49
    private $fileContentName = 'file_content';
50
51
    /**
52
     * @deprecated in favor of vue CRUD methods
53
     *
54
     * @Route("/{tool}/{type}", name="chamilo_core_resource_index")
55
     *
56
     * Example: /document/files (See the 'tool' and the 'resource_type' DB tables.)
57
     * For the tool value check the Tool entity.
58
     * For the type value check the ResourceType entity.
59
     */
60
    public function indexAction(Request $request): Response
61
    {
62
        $tool = $request->get('tool');
63
        $type = $request->get('type');
64
65
        $parentResourceNode = $this->getParentResourceNode($request);
66
        $repository = $this->getRepositoryFromRequest($request);
67
        $settings = $repository->getResourceSettings();
68
69
        // The base resource node is the course.
70
        $id = $parentResourceNode->getId();
71
72
        //return $grid->getGridResponse(
73
        return $this->render(
74
            $repository->getTemplates()->getFromAction(__FUNCTION__),
75
            [
76
                'tool' => $tool,
77
                'type' => $type,
78
                'id' => $id,
79
                'parent_resource_node' => $parentResourceNode,
80
                'resource_settings' => $settings,
81
            ]
82
        );
83
    }
84
85
    /**
86
     * @deprecated in favor of vue CRUD methods
87
     * @Route("/{tool}/{type}/{id}/list", name="chamilo_core_resource_list")
88
     *
89
     * If node has children show it
90
     */
91
    public function listAction(Request $request): Response
92
    {
93
        $tool = $request->get('tool');
94
        $type = $request->get('type');
95
        $resourceNodeId = $request->get('id');
96
97
        $repository = $this->getRepositoryFromRequest($request);
98
        $settings = $repository->getResourceSettings();
99
100
        /*$grid = $this->getGrid($request, $repository, $grid, $resourceNodeId, 'chamilo_core_resource_list');
101
        $parentResourceNode = $this->getParentResourceNode($request);
102
        $this->setBreadCrumb($request, $parentResourceNode);*/
103
104
        //return $grid->getGridResponse(
105
        return $this->render(
106
            $repository->getTemplates()->getFromAction(__FUNCTION__),
107
            [
108
                'parent_id' => $resourceNodeId,
109
                'tool' => $tool,
110
                'type' => $type,
111
                'id' => $resourceNodeId,
112
                'parent_resource_node' => $parentResourceNode,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parentResourceNode seems to be never defined.
Loading history...
113
                'resource_settings' => $settings,
114
            ]
115
        );
116
    }
117
118
    /**
119
     * @deprecated in favor of vue CRUD methods
120
     *
121
     * @Route("/{tool}/{type}/{id}/new_folder", methods={"GET", "POST"}, name="chamilo_core_resource_new_folder")
122
     */
123
    public function newFolderAction(Request $request): Response
124
    {
125
        return $this->createResource($request, 'folder');
126
    }
127
128
    /**
129
     * @deprecated in favor of vue CRUD methods
130
     *
131
     * @Route("/{tool}/{type}/{id}/new", methods={"GET", "POST"}, name="chamilo_core_resource_new")
132
     */
133
    public function newAction(Request $request): Response
134
    {
135
        return $this->createResource($request, 'file');
136
    }
137
138
    /**
139
     * @Route("/{tool}/{type}/{id}/disk_space", methods={"GET", "POST"}, name="chamilo_core_resource_disk_space")
140
     */
141
    public function diskSpaceAction(Request $request): Response
142
    {
143
        $nodeId = $request->get('id');
144
        $repository = $this->getRepositoryFromRequest($request);
145
146
        /** @var ResourceNode $resourceNode */
147
        $resourceNode = $repository->getResourceNodeRepository()->find($nodeId);
148
149
        $this->denyAccessUnlessGranted(
150
            ResourceNodeVoter::VIEW,
151
            $resourceNode,
152
            $this->trans('Unauthorised access to resource')
153
        );
154
155
        $this->setBreadCrumb($request, $resourceNode);
156
157
        $course = $this->getCourse();
158
        $totalSize = 0;
159
        if ($course) {
0 ignored issues
show
introduced by
$course is of type Chamilo\CoreBundle\Entity\Course, thus it always evaluated to true.
Loading history...
160
            $totalSize = $course->getDiskQuota();
161
        }
162
163
        $size = $repository->getResourceNodeRepository()->getSize(
164
            $resourceNode,
165
            $repository->getResourceType(),
166
            $course
167
        );
168
169
        $labels[] = $course->getTitle();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$labels was never initialized. Although not strictly required by PHP, it is generally a good practice to add $labels = array(); before regardless.
Loading history...
170
        $data[] = $size;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
171
        $sessions = $course->getSessions();
172
173
        foreach ($sessions as $sessionRelCourse) {
174
            $session = $sessionRelCourse->getSession();
175
176
            $labels[] = $course->getTitle().' - '.$session->getName();
177
            $size = $repository->getResourceNodeRepository()->getSize(
178
                $resourceNode,
179
                $repository->getResourceType(),
180
                $course,
181
                $session
182
            );
183
            $data[] = $size;
184
        }
185
186
        $groups = $course->getGroups();
187
        foreach ($groups as $group) {
188
            $labels[] = $course->getTitle().' - '.$group->getName();
189
            $size = $repository->getResourceNodeRepository()->getSize(
190
                $resourceNode,
191
                $repository->getResourceType(),
192
                $course,
193
                null,
194
                $group
195
            );
196
            $data[] = $size;
197
        }
198
199
        $used = array_sum($data);
200
        $labels[] = $this->trans('Free');
201
        $data[] = $totalSize - $used;
202
203
        return $this->render(
204
            $repository->getTemplates()->getFromAction(__FUNCTION__),
205
            [
206
                'resourceNode' => $resourceNode,
207
                'labels' => $labels,
208
                'data' => $data,
209
            ]
210
        );
211
    }
212
213
    /**
214
     * @deprecated in favor of vue CRUD methods
215
     *
216
     * @Route("/{tool}/{type}/{id}/edit", methods={"GET", "POST"})
217
     */
218
    public function editAction(Request $request, IllustrationRepository $illustrationRepo): Response
219
    {
220
        $resourceNodeId = $request->get('id');
221
222
        $repository = $this->getRepositoryFromRequest($request);
223
        $resource = $repository->getResourceFromResourceNode($resourceNodeId);
224
        $this->denyAccessUnlessValidResource($resource);
225
        $settings = $repository->getResourceSettings();
226
        $resourceNode = $resource->getResourceNode();
227
228
        $this->denyAccessUnlessGranted(
229
            ResourceNodeVoter::EDIT,
230
            $resourceNode,
231
            $this->trans('Unauthorised access to resource')
232
        );
233
234
        $this->setBreadCrumb($request, $resourceNode);
235
        $resourceNodeParentId = $resourceNode->getId();
236
237
        $routeParams = $this->getResourceParams($request);
238
        $routeParams['id'] = $resourceNodeParentId;
239
240
        $form = $repository->getForm($this->container->get('form.factory'), $resource);
241
242
        if ($resourceNode->hasEditableTextContent() && $settings->isAllowToSaveEditorToResourceFile()) {
243
            $form->add(
244
                $this->fileContentName,
245
                CKEditorType::class,
246
                [
247
                    'mapped' => false,
248
                    'config' => [
249
                        'filebrowserImageBrowseRoute' => 'resources_filemanager',
250
                        'filebrowserImageBrowseRouteParameters' => $routeParams,
251
                    ],
252
                ]
253
            );
254
            $content = $repository->getResourceNodeFileContent($resourceNode);
255
            $form->get($this->fileContentName)->setData($content);
256
        }
257
258
        $form->handleRequest($request);
259
260
        if ($form->isSubmitted() && $form->isValid()) {
261
            /** @var AbstractResource $newResource */
262
            $newResource = $form->getData();
263
264
            if ($form->has($this->fileContentName)) {
265
                $data = $form->get($this->fileContentName)->getData();
266
                $repository->updateResourceFileContent($newResource, $data);
267
            }
268
269
            $repository->updateNodeForResource($newResource);
270
271
            if ($form->has('illustration')) {
272
                $illustration = $form->get('illustration')->getData();
273
                if ($illustration) {
274
                    $file = $illustrationRepo->addIllustration($newResource, $this->getUser(), $illustration);
275
                    $illustrationRepo->update($file);
276
                }
277
            }
278
279
            $this->addFlash('success', $this->trans('Updated'));
280
            $resourceNodeParentId = $newResource->getResourceNode()->getParent()->getId();
281
            $routeParams['id'] = $resourceNodeParentId;
282
283
            return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
284
        }
285
286
        return $this->render(
287
            $repository->getTemplates()->getFromAction(__FUNCTION__),
288
            [
289
                'form' => $form->createView(),
290
                'parent' => $resourceNodeParentId,
291
            ]
292
        );
293
    }
294
295
    /**
296
     * Shows a resource information.
297
     *
298
     * @Route("/{tool}/{type}/{id}/info", methods={"GET", "POST"}, name="chamilo_core_resource_info")
299
     */
300
    public function infoAction(Request $request): Response
301
    {
302
        $nodeId = $request->get('id');
303
        $repository = $this->getRepositoryFromRequest($request);
304
305
        /** @var AbstractResource $resource */
306
        $resource = $repository->getResourceFromResourceNode($nodeId);
307
        $this->denyAccessUnlessValidResource($resource);
308
        $resourceNode = $resource->getResourceNode();
309
310
        $this->denyAccessUnlessGranted(
311
            ResourceNodeVoter::VIEW,
312
            $resourceNode,
313
            $this->trans(sprintf('Unauthorised access to resource #%s', $nodeId))
314
        );
315
316
        $this->setBreadCrumb($request, $resourceNode);
317
318
        $tool = $request->get('tool');
319
        $type = $request->get('type');
320
321
        $form = $this->createForm(ResourceCommentType::class, null);
322
323
        $params = [
324
            'resource' => $resource,
325
            'course' => $this->getCourse(),
326
         //   'illustration' => $illustration,
327
            'tool' => $tool,
328
            'type' => $type,
329
            'comment_form' => $form->createView(),
330
        ];
331
332
        return $this->render(
333
            $repository->getTemplates()->getFromAction(__FUNCTION__, $request->isXmlHttpRequest()),
334
            $params
335
        );
336
    }
337
338
    /**
339
     * Preview a file. Mostly used when using a modal.
340
     *
341
     * @Route("/{tool}/{type}/{id}/preview", methods={"GET"}, name="chamilo_core_resource_preview")
342
     */
343
    public function previewAction(Request $request): Response
344
    {
345
        $nodeId = $request->get('id');
346
        $repository = $this->getRepositoryFromRequest($request);
347
348
        /** @var AbstractResource $resource */
349
        $resource = $repository->getResourceFromResourceNode($nodeId);
350
        $this->denyAccessUnlessValidResource($resource);
351
352
        $resourceNode = $resource->getResourceNode();
353
        $this->denyAccessUnlessGranted(
354
            ResourceNodeVoter::VIEW,
355
            $resourceNode,
356
            $this->trans('Unauthorised access to resource')
357
        );
358
359
        $this->setBreadCrumb($request, $resourceNode);
360
361
        $tool = $request->get('tool');
362
        $type = $request->get('type');
363
364
        $params = [
365
            'resource' => $resource,
366
            'tool' => $tool,
367
            'type' => $type,
368
        ];
369
370
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $params);
371
    }
372
373
    /**
374
     * @Route("/{tool}/{type}/{id}/change_visibility", name="chamilo_core_resource_change_visibility")
375
     */
376
    public function changeVisibilityAction(Request $request): Response
377
    {
378
        $id = $request->get('id');
379
380
        $repository = $this->getRepositoryFromRequest($request);
381
382
        /** @var AbstractResource $resource */
383
        $resource = $repository->getResourceFromResourceNode($id);
384
        $this->denyAccessUnlessValidResource($resource);
385
386
        $resourceNode = $resource->getResourceNode();
387
388
        $this->denyAccessUnlessGranted(
389
            ResourceNodeVoter::EDIT,
390
            $resourceNode,
391
            $this->trans('Unauthorised access to resource')
392
        );
393
394
        /** @var ResourceLink $link */
395
        if ($this->hasCourse()) {
396
            $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession());
397
        } else {
398
            $link = $resource->getFirstResourceLink();
399
        }
400
401
        $icon = 'fa-eye';
402
        // Use repository to change settings easily.
403
        if ($link && ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility()) {
404
            $repository->setVisibilityDraft($resource);
405
            $icon = 'fa-eye-slash';
406
        } else {
407
            $repository->setVisibilityPublished($resource);
408
        }
409
410
        $result = ['icon' => $icon];
411
412
        return new JsonResponse($result);
413
    }
414
415
    /**
416
     * @Route("/{tool}/{type}/{id}/delete", name="chamilo_core_resource_delete")
417
     */
418
    public function deleteAction(Request $request): Response
419
    {
420
        $em = $this->getDoctrine()->getManager();
421
422
        $id = $request->get('id');
423
        $resourceNode = $this->getDoctrine()->getRepository(ResourceNode::class)->find($id);
424
        $parentId = $resourceNode->getParent()->getId();
425
426
        $this->denyAccessUnlessGranted(
427
            ResourceNodeVoter::DELETE,
428
            $resourceNode,
429
            $this->trans('Unauthorised access to resource')
430
        );
431
432
        $children = $resourceNode->getChildren();
433
434
        if (!empty($children)) {
435
            /** @var ResourceNode $child */
436
            foreach ($children as $child) {
437
                $em->remove($child);
438
            }
439
        }
440
441
        $em->remove($resourceNode);
442
        $this->addFlash('success', $this->trans('Deleted').': '.$resourceNode->getSlug());
443
        $em->flush();
444
445
        $routeParams = $this->getResourceParams($request);
446
        $routeParams['id'] = $parentId;
447
448
        return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
449
    }
450
451
    /**
452
     * @Route("/{tool}/{type}/{id}/delete_mass", methods={"DELETE"}, name="chamilo_core_resource_delete_mass")
453
     */
454
    public function deleteMassAction($primaryKeys, $allPrimaryKeys, Request $request): Response
455
    {
456
        $em = $this->getDoctrine()->getManager();
457
        $repo = $this->getRepositoryFromRequest($request);
458
459
        $parentId = 0;
460
        foreach ($primaryKeys as $id) {
461
            $resource = $repo->find($id);
462
            $resourceNode = $resource->getResourceNode();
463
464
            if (null === $resourceNode) {
465
                continue;
466
            }
467
468
            $this->denyAccessUnlessGranted(
469
                ResourceNodeVoter::DELETE,
470
                $resourceNode,
471
                $this->trans('Unauthorised access to resource')
472
            );
473
474
            $parentId = $resourceNode->getParent()->getId();
475
            $em->remove($resource);
476
        }
477
478
        $this->addFlash('success', $this->trans('Deleted'));
479
        $em->flush();
480
481
        $routeParams = $this->getResourceParams($request);
482
        $routeParams['id'] = $parentId;
483
484
        return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
485
    }
486
487
    /**
488
     * Shows the associated resource file.
489
     *
490
     * @Route("/{tool}/{type}/{id}/view_resource", methods={"GET"}, name="chamilo_core_resource_view_resource")
491
     */
492
    public function viewResourceAction(Request $request, RouterInterface $router): Response
493
    {
494
        $id = $request->get('id');
495
        $em = $this->getDoctrine();
496
497
        /** @var ResourceNode $resourceNode */
498
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
499
500
        if (null === $resourceNode) {
501
            throw new FileNotFoundException('Resource not found');
502
        }
503
504
        $this->denyAccessUnlessGranted(
505
            ResourceNodeVoter::VIEW,
506
            $resourceNode,
507
            $this->trans('Unauthorised access to resource')
508
        );
509
510
        $repository = $this->getRepositoryFromRequest($request);
511
512
        /** @var AbstractResource $resource */
513
        $resource = $repository->getResourceFromResourceNode($id);
514
515
        $tool = $request->get('tool');
516
        $type = $request->get('type');
517
        $this->setBreadCrumb($request, $resourceNode);
518
519
        $params = [
520
            'resource' => $resource,
521
            'tool' => $tool,
522
            'type' => $type,
523
        ];
524
525
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $params);
526
    }
527
528
    /**
529
     * View file of a resource node.
530
     *
531
     * @Route("/{tool}/{type}/{id}/view", methods={"GET"}, name="chamilo_core_resource_view")
532
     */
533
    public function viewAction(Request $request, RouterInterface $router): Response
534
    {
535
        $id = $request->get('id');
536
        $filter = $request->get('filter'); // See filters definitions in /config/services.yml
537
        $em = $this->getDoctrine();
538
        /** @var ResourceNode $resourceNode */
539
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
540
541
        if (null === $resourceNode) {
542
            throw new FileNotFoundException('Resource not found');
543
        }
544
545
        /*$repo = $this->getRepositoryFromRequest($request);
546
        if ($repo instanceof ResourceWithLinkInterface) {
547
            $resource = $repo->getResourceFromResourceNode($resourceNode->getId());
548
            $url = $repo->getLink($resource, $router, $this->getCourseUrlQueryToArray());
549
550
            return $this->redirect($url);
551
        }*/
552
553
        return $this->processFile($request, $resourceNode, 'show', $filter);
554
    }
555
556
    /**
557
     * Redirect resource to link.
558
     *
559
     * @Route("/{tool}/{type}/{id}/link", methods={"GET"}, name="chamilo_core_resource_link")
560
     */
561
    public function linkAction(Request $request, RouterInterface $router): Response
562
    {
563
        $id = $request->get('id');
564
        $em = $this->getDoctrine();
565
        /** @var ResourceNode $resourceNode */
566
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
567
568
        if (null === $resourceNode) {
569
            throw new FileNotFoundException('Resource not found');
570
        }
571
572
        $repo = $this->getRepositoryFromRequest($request);
573
        if ($repo instanceof ResourceWithLinkInterface) {
574
            $resource = $repo->getResourceFromResourceNode($resourceNode->getId());
575
            $url = $repo->getLink($resource, $router, $this->getCourseUrlQueryToArray());
576
577
            return $this->redirect($url);
578
        }
579
580
        return $this->abort('No redirect');
581
    }
582
583
    /**
584
     * Download file of a resource node.
585
     *
586
     * @Route("/{tool}/{type}/{id}/download", methods={"GET"}, name="chamilo_core_resource_download")
587
     */
588
    public function downloadAction(Request $request)
589
    {
590
        $id = (int) $request->get('id');
591
592
        $em = $this->getDoctrine();
593
        /** @var ResourceNode $resourceNode */
594
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
595
596
        if (null === $resourceNode) {
597
            throw new FileNotFoundException('Resource not found');
598
        }
599
600
        $repo = $this->getRepositoryFromRequest($request);
601
602
        $this->denyAccessUnlessGranted(
603
            ResourceNodeVoter::VIEW,
604
            $resourceNode,
605
            $this->trans('Unauthorised access to resource')
606
        );
607
608
        // If resource node has a file just download it. Don't download the children.
609
        if ($resourceNode->hasResourceFile()) {
610
            // Redirect to download single file.
611
            return $this->processFile($request, $resourceNode, 'download');
612
        }
613
614
        $zipName = $resourceNode->getSlug().'.zip';
615
        $rootNodePath = $resourceNode->getPathForDisplay();
616
        $resourceNodeRepo = $repo->getResourceNodeRepository();
617
618
        $criteria = Criteria::create()
619
            ->where(Criteria::expr()->neq('resourceFile', null)) // must have a file
620
            // ->andWhere(Criteria::expr()->eq('resourceType', $type))
621
        ;
622
623
        /** @var ArrayCollection|ResourceNode[] $children */
624
        /** @var QueryBuilder $children */
625
        $qb = $resourceNodeRepo->getChildrenQueryBuilder($resourceNode);
626
        $qb->addCriteria($criteria);
627
        $children = $qb->getQuery()->getResult();
628
        $count = count($children);
629
        if (0 === $count) {
630
            $params = $this->getResourceParams($request);
631
            $params['id'] = $id;
632
633
            $this->addFlash('warning', $this->trans('No files'));
634
635
            return $this->redirectToRoute('chamilo_core_resource_list', $params);
636
        }
637
638
        $response = new StreamedResponse(
639
            function () use ($rootNodePath, $zipName, $children, $repo) {
640
                // Define suitable options for ZipStream Archive.
641
                $options = new Archive();
642
                $options->setContentType('application/octet-stream');
643
                //initialise zipstream with output zip filename and options.
644
                $zip = new ZipStream($zipName, $options);
645
646
                /** @var ResourceNode $node */
647
                foreach ($children as $node) {
648
                    $stream = $repo->getResourceNodeFileStream($node);
649
                    $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
650
                    $zip->addFileFromStream($fileToDisplay, $stream);
651
                }
652
                $zip->finish();
653
            }
654
        );
655
656
        $disposition = $response->headers->makeDisposition(
657
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
658
            $zipName //Transliterator::transliterate($zipName)
659
        );
660
        $response->headers->set('Content-Disposition', $disposition);
661
        $response->headers->set('Content-Type', 'application/octet-stream');
662
663
        return $response;
664
    }
665
666
    /**
667
     * Upload form.
668
     *
669
     * @Route("/{tool}/{type}/{id}/upload", name="chamilo_core_resource_upload", methods={"GET", "POST"},
670
     *                                      options={"expose"=true})
671
     */
672
    public function uploadAction(Request $request, $tool, $type, $id): Response
673
    {
674
        $repository = $this->getRepositoryFromRequest($request);
675
        $resourceNode = $repository->getResourceNodeRepository()->find($id);
676
677
        $this->denyAccessUnlessGranted(
678
            ResourceNodeVoter::EDIT,
679
            $resourceNode,
680
            $this->trans('Unauthorised access to resource')
681
        );
682
683
        $this->setBreadCrumb($request, $resourceNode);
684
685
        $routeParams = $this->getResourceParams($request);
686
        $routeParams['tool'] = $tool;
687
        $routeParams['type'] = $type;
688
        $routeParams['id'] = $id;
689
690
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $routeParams);
691
    }
692
693
    /**
694
     * @return mixed|StreamedResponse
695
     */
696
    private function processFile(Request $request, ResourceNode $resourceNode, $mode = 'show', $filter = '')
697
    {
698
        $this->denyAccessUnlessGranted(
699
            ResourceNodeVoter::VIEW,
700
            $resourceNode,
701
            $this->trans('Unauthorised view access to resource')
702
        );
703
704
        $repo = $this->getRepositoryFromRequest($request);
705
        $resourceFile = $resourceNode->getResourceFile();
706
707
        if (!$resourceFile) {
0 ignored issues
show
introduced by
$resourceFile is of type Chamilo\CoreBundle\Entity\ResourceFile, thus it always evaluated to true.
Loading history...
708
            throw new NotFoundHttpException($this->trans('File not found for resource'));
709
        }
710
711
        $fileName = $resourceNode->getResourceFile()->getOriginalName();
712
        $mimeType = $resourceFile->getMimeType();
713
714
        switch ($mode) {
715
            case 'download':
716
                $forceDownload = true;
717
718
                break;
719
            case 'show':
720
            default:
721
                $forceDownload = false;
722
                // If it's an image then send it to Glide.
723
                if (false !== strpos($mimeType, 'image')) {
724
                    $glide = $this->getGlide();
725
                    $server = $glide->getServer();
726
                    $params = $request->query->all();
727
728
                    // The filter overwrites the params from GET.
729
                    if (!empty($filter)) {
730
                        $params = $glide->getFilters()[$filter] ?? [];
731
                    }
732
733
                    // The image was cropped manually by the user, so we force to render this version,
734
                    // no matter other crop parameters.
735
                    $crop = $resourceFile->getCrop();
736
                    if (!empty($crop)) {
737
                        $params['crop'] = $crop;
738
                    }
739
740
                    $fileName = $repo->getResourceNodeRepository()->getFilename($resourceFile);
741
742
                    return $server->getImageResponse($fileName, $params);
743
                }
744
745
                break;
746
        }
747
748
        $stream = $repo->getResourceNodeFileStream($resourceNode);
749
750
        $response = new StreamedResponse(
751
            function () use ($stream): void {
752
                stream_copy_to_stream($stream, fopen('php://output', 'wb'));
753
            }
754
        );
755
        $disposition = $response->headers->makeDisposition(
756
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
757
            $fileName
758
        //Transliterator::transliterate($fileName)
759
        );
760
        $response->headers->set('Content-Disposition', $disposition);
761
        $response->headers->set('Content-Type', $mimeType ?: 'application/octet-stream');
762
763
        return $response;
764
    }
765
766
    /**
767
     * @param string $fileType
768
     *
769
     * @return RedirectResponse|Response
770
     */
771
    private function createResource(Request $request, $fileType = 'file')
772
    {
773
        $resourceNodeParentId = $request->get('id');
774
        $repository = $this->getRepositoryFromRequest($request);
775
776
        // Default parent node is course.
777
        $parentNode = $this->getParentResourceNode($request);
778
779
        $this->setBreadCrumb($request, $parentNode);
780
781
        $this->denyAccessUnlessGranted(
782
            ResourceNodeVoter::CREATE,
783
            $parentNode,
784
            $this->trans('Unauthorised access to resource')
785
        );
786
787
        $form = $repository->getForm($this->container->get('form.factory'), null);
788
        $settings = $repository->getResourceSettings();
789
790
        if ('file' === $fileType && $settings->isAllowToSaveEditorToResourceFile()) {
791
            $resourceParams = $this->getResourceParams($request);
792
            $form->add(
793
                $this->fileContentName,
794
                CKEditorType::class,
795
                [
796
                    'mapped' => false,
797
                    'config' => [
798
                        'filebrowserImageBrowseRoute' => 'resources_filemanager',
799
                        'filebrowserImageBrowseRouteParameters' => $resourceParams,
800
                        'fullPage' => true,
801
                    ],
802
                ]
803
            );
804
        }
805
806
        $form->handleRequest($request);
807
        if ($form->isSubmitted() && $form->isValid()) {
808
            $em = $this->getDoctrine()->getManager();
809
            $course = $this->getCourse()->getId();
810
            $course = $this->getDoctrine()->getRepository('ChamiloCoreBundle:Course')->find($course);
811
            $session = $this->getSession();
812
813
            /** @var AbstractResource $newResource */
814
            $newResource = $repository->setResourceProperties($form, $course, $session, $fileType);
815
816
            $file = null;
817
            if ('file' === $fileType && $settings->isAllowToSaveEditorToResourceFile()) {
818
                $content = $form->get($this->fileContentName)->getViewData();
819
                $newResource->setTitle($newResource->getTitle().'.html');
0 ignored issues
show
Bug introduced by
The method getTitle() does not exist on Chamilo\CoreBundle\Entity\AbstractResource. It seems like you code against a sub-type of Chamilo\CoreBundle\Entity\AbstractResource such as Chamilo\CoreBundle\Entity\Course or Chamilo\CourseBundle\Entity\CLink or Chamilo\CourseBundle\Entity\CNotebook or Chamilo\CourseBundle\Entity\CAnnouncement or Chamilo\CourseBundle\Entity\CWiki or Chamilo\CourseBundle\Entity\CSurvey or Chamilo\CourseBundle\Entity\CQuiz or Chamilo\CourseBundle\Ent...ntPublicationCorrection or Chamilo\CourseBundle\Entity\CCourseDescription or Chamilo\CourseBundle\Entity\CGroupCategory or Chamilo\CourseBundle\Entity\CDocument or Chamilo\CourseBundle\Entity\CThematic or Chamilo\CourseBundle\Entity\CQuizQuestionCategory or Chamilo\CourseBundle\Entity\CStudentPublication or Chamilo\CourseBundle\Entity\CCalendarEvent. ( Ignorable by Annotation )

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

819
                $newResource->setTitle($newResource->/** @scrutinizer ignore-call */ getTitle().'.html');
Loading history...
Bug introduced by
The method setTitle() does not exist on Chamilo\CoreBundle\Entity\AbstractResource. It seems like you code against a sub-type of Chamilo\CoreBundle\Entity\AbstractResource such as Chamilo\CoreBundle\Entity\Course or Chamilo\CourseBundle\Entity\CLink or Chamilo\CourseBundle\Entity\CNotebook or Chamilo\CourseBundle\Entity\CAnnouncement or Chamilo\CourseBundle\Entity\CWiki or Chamilo\CourseBundle\Entity\CSurvey or Chamilo\CourseBundle\Entity\CQuiz or Chamilo\CourseBundle\Ent...ntPublicationCorrection or Chamilo\CourseBundle\Entity\CCourseDescription or Chamilo\CourseBundle\Entity\CGroupCategory or Chamilo\CourseBundle\Entity\CDocument or Chamilo\CourseBundle\Entity\CThematic or Chamilo\CourseBundle\Entity\CQuizQuestionCategory or Chamilo\CourseBundle\Entity\CStudentPublication or Chamilo\CourseBundle\Entity\CCalendarEvent. ( Ignorable by Annotation )

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

819
                $newResource->/** @scrutinizer ignore-call */ 
820
                              setTitle($newResource->getTitle().'.html');
Loading history...
820
                $fileName = $newResource->getTitle();
821
822
                $handle = tmpfile();
823
                fwrite($handle, $content);
824
                $meta = stream_get_meta_data($handle);
825
                $file = new UploadedFile($meta['uri'], $fileName, 'text/html', null, true);
826
            }
827
828
            //$parent = $repository->getResourceNodeRepository()->getResourceByNode($parentNode);
829
            // @todo fix correct parent
830
            $newResource->setParent($parent);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parent does not exist. Did you maybe mean $parentNode?
Loading history...
831
            $newResource->addCourseLink(
832
                $course,
833
                $session
834
            );
835
            $em->persist($newResource);
836
            $em->flush();
837
838
            $repository->addFile($newResource, $file);
839
            $em->flush();
840
841
            // Loops all sharing options
842
            /*foreach ($shareList as $share) {
843
                $idList = [];
844
                if (isset($share['search'])) {
845
                    $idList = explode(',', $share['search']);
846
                }
847
848
                $resourceRight = null;
849
                if (isset($share['mask'])) {
850
                    $resourceRight = new ResourceRight();
851
                    $resourceRight
852
                        ->setMask($share['mask'])
853
                        ->setRole($share['role'])
854
                    ;
855
                }
856
857
                // Build links
858
                switch ($share['sharing']) {
859
                    case 'everyone':
860
                        $repository->addResourceToEveryone(
861
                            $resourceNode,
862
                            $resourceRight
863
                        );
864
                        break;
865
                    case 'course':
866
                        $repository->addResourceToCourse(
867
                            $resourceNode,
868
                            $course,
869
                            $resourceRight
870
                        );
871
                        break;
872
                    case 'session':
873
                        $repository->addResourceToSession(
874
                            $resourceNode,
875
                            $course,
876
                            $session,
877
                            $resourceRight
878
                        );
879
                        break;
880
                    case 'user':
881
                        // Only for me
882
                        if (isset($share['only_me'])) {
883
                            $repository->addResourceOnlyToMe($resourceNode);
884
                        } else {
885
                            // To other users
886
                            $repository->addResourceToUserList($resourceNode, $idList);
887
                        }
888
                        break;
889
                    case 'group':
890
                        // @todo
891
                        break;
892
                }*/
893
            //}
894
            $em->flush();
895
            $this->addFlash('success', $this->trans('Saved'));
896
897
            $params = $this->getResourceParams($request);
898
            $params['id'] = $resourceNodeParentId;
899
900
            return $this->redirectToRoute(
901
                'chamilo_core_resource_list',
902
                $params
903
            );
904
        }
905
906
        switch ($fileType) {
907
            case 'folder':
908
                $template = $repository->getTemplates()->getFromAction('newFolderAction');
909
910
                break;
911
            case 'file':
912
                $template = $repository->getTemplates()->getFromAction('newAction');
913
914
                break;
915
        }
916
917
        $routeParams = $this->getResourceParams($request);
918
        $routeParams['form'] = $form->createView();
919
        $routeParams['parent'] = $resourceNodeParentId;
920
        $routeParams['file_type'] = $fileType;
921
922
        return $this->render($template, $routeParams);
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...
923
    }
924
}
925