Passed
Push — master ( a7a364...7ade69 )
by Julito
09:22
created

ResourceController::previewAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 1
dl 0
loc 28
rs 9.7
c 0
b 0
f 0
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\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 $illustrationRepository): 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 = $illustrationRepository->addIllustration($newResource, $this->getUser(), $illustration);
275
                    $em = $illustrationRepository->getEntityManager();
276
                    $em->persist($file);
277
                    $em->flush();
278
                }
279
            }
280
281
            $this->addFlash('success', $this->trans('Updated'));
282
283
            $resourceNodeParentId = $newResource->getResourceNode()->getParent()->getId();
284
            $routeParams['id'] = $resourceNodeParentId;
285
286
            return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
287
        }
288
289
        return $this->render(
290
            $repository->getTemplates()->getFromAction(__FUNCTION__),
291
            [
292
                'form' => $form->createView(),
293
                'parent' => $resourceNodeParentId,
294
            ]
295
        );
296
    }
297
298
    /**
299
     * Shows a resource information.
300
     *
301
     * @Route("/{tool}/{type}/{id}/info", methods={"GET", "POST"}, name="chamilo_core_resource_info")
302
     */
303
    public function infoAction(Request $request): Response
304
    {
305
        $nodeId = $request->get('id');
306
        $repository = $this->getRepositoryFromRequest($request);
307
308
        /** @var AbstractResource $resource */
309
        $resource = $repository->getResourceFromResourceNode($nodeId);
310
        $this->denyAccessUnlessValidResource($resource);
311
        $resourceNode = $resource->getResourceNode();
312
313
        $this->denyAccessUnlessGranted(
314
            ResourceNodeVoter::VIEW,
315
            $resourceNode,
316
            $this->trans(sprintf('Unauthorised access to resource #%s', $nodeId))
317
        );
318
319
        $this->setBreadCrumb($request, $resourceNode);
320
321
        $tool = $request->get('tool');
322
        $type = $request->get('type');
323
324
        $form = $this->createForm(ResourceCommentType::class, null);
325
326
        $params = [
327
            'resource' => $resource,
328
            'course' => $this->getCourse(),
329
         //   'illustration' => $illustration,
330
            'tool' => $tool,
331
            'type' => $type,
332
            'comment_form' => $form->createView(),
333
        ];
334
335
        return $this->render(
336
            $repository->getTemplates()->getFromAction(__FUNCTION__, $request->isXmlHttpRequest()),
337
            $params
338
        );
339
    }
340
341
    /**
342
     * Preview a file. Mostly used when using a modal.
343
     *
344
     * @Route("/{tool}/{type}/{id}/preview", methods={"GET"}, name="chamilo_core_resource_preview")
345
     */
346
    public function previewAction(Request $request): Response
347
    {
348
        $nodeId = $request->get('id');
349
        $repository = $this->getRepositoryFromRequest($request);
350
351
        /** @var AbstractResource $resource */
352
        $resource = $repository->getResourceFromResourceNode($nodeId);
353
        $this->denyAccessUnlessValidResource($resource);
354
355
        $resourceNode = $resource->getResourceNode();
356
        $this->denyAccessUnlessGranted(
357
            ResourceNodeVoter::VIEW,
358
            $resourceNode,
359
            $this->trans('Unauthorised access to resource')
360
        );
361
362
        $this->setBreadCrumb($request, $resourceNode);
363
364
        $tool = $request->get('tool');
365
        $type = $request->get('type');
366
367
        $params = [
368
            'resource' => $resource,
369
            'tool' => $tool,
370
            'type' => $type,
371
        ];
372
373
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $params);
374
    }
375
376
    /**
377
     * @Route("/{tool}/{type}/{id}/change_visibility", name="chamilo_core_resource_change_visibility")
378
     */
379
    public function changeVisibilityAction(Request $request): Response
380
    {
381
        $id = $request->get('id');
382
383
        $repository = $this->getRepositoryFromRequest($request);
384
385
        /** @var AbstractResource $resource */
386
        $resource = $repository->getResourceFromResourceNode($id);
387
        $this->denyAccessUnlessValidResource($resource);
388
389
        $resourceNode = $resource->getResourceNode();
390
391
        $this->denyAccessUnlessGranted(
392
            ResourceNodeVoter::EDIT,
393
            $resourceNode,
394
            $this->trans('Unauthorised access to resource')
395
        );
396
397
        /** @var ResourceLink $link */
398
        if ($this->hasCourse()) {
399
            $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession());
400
        } else {
401
            $link = $resource->getFirstResourceLink();
402
        }
403
404
        $icon = 'fa-eye';
405
        // Use repository to change settings easily.
406
        if ($link && ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility()) {
407
            $repository->setVisibilityDraft($resource);
408
            $icon = 'fa-eye-slash';
409
        } else {
410
            $repository->setVisibilityPublished($resource);
411
        }
412
413
        $result = ['icon' => $icon];
414
415
        return new JsonResponse($result);
416
    }
417
418
    /**
419
     * @Route("/{tool}/{type}/{id}/delete", name="chamilo_core_resource_delete")
420
     */
421
    public function deleteAction(Request $request): Response
422
    {
423
        $em = $this->getDoctrine()->getManager();
424
425
        $id = $request->get('id');
426
        $resourceNode = $this->getDoctrine()->getRepository(ResourceNode::class)->find($id);
427
        $parentId = $resourceNode->getParent()->getId();
428
429
        $this->denyAccessUnlessGranted(
430
            ResourceNodeVoter::DELETE,
431
            $resourceNode,
432
            $this->trans('Unauthorised access to resource')
433
        );
434
435
        $children = $resourceNode->getChildren();
436
437
        if (!empty($children)) {
438
            /** @var ResourceNode $child */
439
            foreach ($children as $child) {
440
                $em->remove($child);
441
            }
442
        }
443
444
        $em->remove($resourceNode);
445
        $this->addFlash('success', $this->trans('Deleted').': '.$resourceNode->getSlug());
446
        $em->flush();
447
448
        $routeParams = $this->getResourceParams($request);
449
        $routeParams['id'] = $parentId;
450
451
        return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
452
    }
453
454
    /**
455
     * @Route("/{tool}/{type}/{id}/delete_mass", methods={"DELETE"}, name="chamilo_core_resource_delete_mass")
456
     */
457
    public function deleteMassAction($primaryKeys, $allPrimaryKeys, Request $request): Response
458
    {
459
        $em = $this->getDoctrine()->getManager();
460
        $repo = $this->getRepositoryFromRequest($request);
461
462
        $parentId = 0;
463
        foreach ($primaryKeys as $id) {
464
            $resource = $repo->find($id);
465
            $resourceNode = $resource->getResourceNode();
466
467
            if (null === $resourceNode) {
468
                continue;
469
            }
470
471
            $this->denyAccessUnlessGranted(
472
                ResourceNodeVoter::DELETE,
473
                $resourceNode,
474
                $this->trans('Unauthorised access to resource')
475
            );
476
477
            $parentId = $resourceNode->getParent()->getId();
478
            $em->remove($resource);
479
        }
480
481
        $this->addFlash('success', $this->trans('Deleted'));
482
        $em->flush();
483
484
        $routeParams = $this->getResourceParams($request);
485
        $routeParams['id'] = $parentId;
486
487
        return $this->redirectToRoute('chamilo_core_resource_list', $routeParams);
488
    }
489
490
    /**
491
     * Shows the associated resource file.
492
     *
493
     * @Route("/{tool}/{type}/{id}/view_resource", methods={"GET"}, name="chamilo_core_resource_view_resource")
494
     */
495
    public function viewResourceAction(Request $request, RouterInterface $router): Response
496
    {
497
        $id = $request->get('id');
498
        $em = $this->getDoctrine();
499
500
        /** @var ResourceNode $resourceNode */
501
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
502
503
        if (null === $resourceNode) {
504
            throw new FileNotFoundException('Resource not found');
505
        }
506
507
        $this->denyAccessUnlessGranted(
508
            ResourceNodeVoter::VIEW,
509
            $resourceNode,
510
            $this->trans('Unauthorised access to resource')
511
        );
512
513
        $repository = $this->getRepositoryFromRequest($request);
514
515
        /** @var AbstractResource $resource */
516
        $resource = $repository->getResourceFromResourceNode($id);
517
518
        $tool = $request->get('tool');
519
        $type = $request->get('type');
520
        $this->setBreadCrumb($request, $resourceNode);
521
522
        $params = [
523
            'resource' => $resource,
524
            'tool' => $tool,
525
            'type' => $type,
526
        ];
527
528
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $params);
529
    }
530
531
    /**
532
     * View file of a resource node.
533
     *
534
     * @Route("/{tool}/{type}/{id}/view", methods={"GET"}, name="chamilo_core_resource_view")
535
     */
536
    public function viewAction(Request $request, RouterInterface $router): Response
537
    {
538
        $id = $request->get('id');
539
        $filter = $request->get('filter'); // See filters definitions in /config/services.yml
540
        $em = $this->getDoctrine();
541
        /** @var ResourceNode $resourceNode */
542
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
543
544
        if (null === $resourceNode) {
545
            throw new FileNotFoundException('Resource not found');
546
        }
547
548
        $repo = $this->getRepositoryFromRequest($request);
549
550
        if ($repo instanceof ResourceWithLinkInterface) {
551
            $resource = $repo->getResourceFromResourceNode($resourceNode->getId());
552
            $url = $repo->getLink($resource, $router, $this->getCourseUrlQueryToArray());
553
554
            return $this->redirect($url);
555
        }
556
557
        return $this->processFile($request, $resourceNode, 'show', $filter);
558
    }
559
560
    /**
561
     * Download file of a resource node.
562
     *
563
     * @Route("/{tool}/{type}/{id}/download", methods={"GET"}, name="chamilo_core_resource_download")
564
     */
565
    public function downloadAction(Request $request)
566
    {
567
        $id = (int) $request->get('id');
568
569
        $em = $this->getDoctrine();
570
        /** @var ResourceNode $resourceNode */
571
        $resourceNode = $em->getRepository(ResourceNode::class)->find($id);
572
573
        if (null === $resourceNode) {
574
            throw new FileNotFoundException('Resource not found');
575
        }
576
577
        $repo = $this->getRepositoryFromRequest($request);
578
579
        $this->denyAccessUnlessGranted(
580
            ResourceNodeVoter::VIEW,
581
            $resourceNode,
582
            $this->trans('Unauthorised access to resource')
583
        );
584
585
        // If resource node has a file just download it. Don't download the children.
586
        if ($resourceNode->hasResourceFile()) {
587
            // Redirect to download single file.
588
            return $this->processFile($request, $resourceNode, 'download');
589
        }
590
591
        $zipName = $resourceNode->getSlug().'.zip';
592
        $rootNodePath = $resourceNode->getPathForDisplay();
593
        $resourceNodeRepo = $repo->getResourceNodeRepository();
594
595
        $criteria = Criteria::create()
596
            ->where(Criteria::expr()->neq('resourceFile', null)) // must have a file
597
            // ->andWhere(Criteria::expr()->eq('resourceType', $type))
598
        ;
599
600
        /** @var ArrayCollection|ResourceNode[] $children */
601
        /** @var QueryBuilder $children */
602
        $qb = $resourceNodeRepo->getChildrenQueryBuilder($resourceNode);
603
        $qb->addCriteria($criteria);
604
        $children = $qb->getQuery()->getResult();
605
        $count = count($children);
606
        if (0 === $count) {
607
            $params = $this->getResourceParams($request);
608
            $params['id'] = $id;
609
610
            $this->addFlash('warning', $this->trans('No files'));
611
612
            return $this->redirectToRoute('chamilo_core_resource_list', $params);
613
        }
614
615
        $response = new StreamedResponse(
616
            function () use ($rootNodePath, $zipName, $children, $repo) {
617
                // Define suitable options for ZipStream Archive.
618
                $options = new Archive();
619
                $options->setContentType('application/octet-stream');
620
                //initialise zipstream with output zip filename and options.
621
                $zip = new ZipStream($zipName, $options);
622
623
                /** @var ResourceNode $node */
624
                foreach ($children as $node) {
625
                    $stream = $repo->getResourceNodeFileStream($node);
626
                    $fileToDisplay = str_replace($rootNodePath, '', $node->getPathForDisplay());
627
                    $zip->addFileFromStream($fileToDisplay, $stream);
628
                }
629
                $zip->finish();
630
            }
631
        );
632
633
        $disposition = $response->headers->makeDisposition(
634
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
635
            $zipName //Transliterator::transliterate($zipName)
636
        );
637
        $response->headers->set('Content-Disposition', $disposition);
638
        $response->headers->set('Content-Type', 'application/octet-stream');
639
640
        return $response;
641
    }
642
643
    /**
644
     * Upload form.
645
     *
646
     * @Route("/{tool}/{type}/{id}/upload", name="chamilo_core_resource_upload", methods={"GET", "POST"},
647
     *                                      options={"expose"=true})
648
     */
649
    public function uploadAction(Request $request, $tool, $type, $id): Response
650
    {
651
        $repository = $this->getRepositoryFromRequest($request);
652
        $resourceNode = $repository->getResourceNodeRepository()->find($id);
653
654
        $this->denyAccessUnlessGranted(
655
            ResourceNodeVoter::EDIT,
656
            $resourceNode,
657
            $this->trans('Unauthorised access to resource')
658
        );
659
660
        $this->setBreadCrumb($request, $resourceNode);
661
662
        $routeParams = $this->getResourceParams($request);
663
        $routeParams['tool'] = $tool;
664
        $routeParams['type'] = $type;
665
        $routeParams['id'] = $id;
666
667
        return $this->render($repository->getTemplates()->getFromAction(__FUNCTION__), $routeParams);
668
    }
669
670
    /**
671
     * @return mixed|StreamedResponse
672
     */
673
    private function processFile(Request $request, ResourceNode $resourceNode, $mode = 'show', $filter = '')
674
    {
675
        $this->denyAccessUnlessGranted(
676
            ResourceNodeVoter::VIEW,
677
            $resourceNode,
678
            $this->trans('Unauthorised view access to resource')
679
        );
680
681
        $repo = $this->getRepositoryFromRequest($request);
682
        $resourceFile = $resourceNode->getResourceFile();
683
684
        if (!$resourceFile) {
0 ignored issues
show
introduced by
$resourceFile is of type Chamilo\CoreBundle\Entity\ResourceFile, thus it always evaluated to true.
Loading history...
685
            throw new NotFoundHttpException($this->trans('File not found for resource'));
686
        }
687
688
        $fileName = $resourceNode->getResourceFile()->getOriginalName();
689
        $mimeType = $resourceFile->getMimeType();
690
691
        switch ($mode) {
692
            case 'download':
693
                $forceDownload = true;
694
695
                break;
696
            case 'show':
697
            default:
698
                $forceDownload = false;
699
                // If it's an image then send it to Glide.
700
                if (false !== strpos($mimeType, 'image')) {
701
                    $glide = $this->getGlide();
702
                    $server = $glide->getServer();
703
                    $params = $request->query->all();
704
705
                    // The filter overwrites the params from GET.
706
                    if (!empty($filter)) {
707
                        $params = $glide->getFilters()[$filter] ?? [];
708
                    }
709
710
                    // The image was cropped manually by the user, so we force to render this version,
711
                    // no matter other crop parameters.
712
                    $crop = $resourceFile->getCrop();
713
                    if (!empty($crop)) {
714
                        $params['crop'] = $crop;
715
                    }
716
717
                    $fileName = $repo->getResourceNodeRepository()->getFilename($resourceFile);
718
719
                    return $server->getImageResponse($fileName, $params);
720
                }
721
722
                break;
723
        }
724
725
        $stream = $repo->getResourceNodeFileStream($resourceNode);
726
727
        $response = new StreamedResponse(
728
            function () use ($stream): void {
729
                stream_copy_to_stream($stream, fopen('php://output', 'wb'));
730
            }
731
        );
732
        $disposition = $response->headers->makeDisposition(
733
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
734
            $fileName
735
        //Transliterator::transliterate($fileName)
736
        );
737
        $response->headers->set('Content-Disposition', $disposition);
738
        $response->headers->set('Content-Type', $mimeType ?: 'application/octet-stream');
739
740
        return $response;
741
    }
742
743
    /**
744
     * @param string $fileType
745
     *
746
     * @return RedirectResponse|Response
747
     */
748
    private function createResource(Request $request, $fileType = 'file')
749
    {
750
        $resourceNodeParentId = $request->get('id');
751
        $repository = $this->getRepositoryFromRequest($request);
752
753
        // Default parent node is course.
754
        $parentNode = $this->getParentResourceNode($request);
755
756
        $this->setBreadCrumb($request, $parentNode);
757
758
        $this->denyAccessUnlessGranted(
759
            ResourceNodeVoter::CREATE,
760
            $parentNode,
761
            $this->trans('Unauthorised access to resource')
762
        );
763
764
        $form = $repository->getForm($this->container->get('form.factory'), null);
765
        $settings = $repository->getResourceSettings();
766
767
        if ('file' === $fileType && $settings->isAllowToSaveEditorToResourceFile()) {
768
            $resourceParams = $this->getResourceParams($request);
769
            $form->add(
770
                $this->fileContentName,
771
                CKEditorType::class,
772
                [
773
                    'mapped' => false,
774
                    'config' => [
775
                        'filebrowserImageBrowseRoute' => 'resources_filemanager',
776
                        'filebrowserImageBrowseRouteParameters' => $resourceParams,
777
                        'fullPage' => true,
778
                    ],
779
                ]
780
            );
781
        }
782
783
        $form->handleRequest($request);
784
        if ($form->isSubmitted() && $form->isValid()) {
785
            $em = $this->getDoctrine()->getManager();
786
            $course = $this->getCourse()->getId();
787
            $course = $this->getDoctrine()->getRepository('ChamiloCoreBundle:Course')->find($course);
788
            $session = $this->getSession();
789
790
            /** @var AbstractResource $newResource */
791
            $newResource = $repository->setResourceProperties($form, $course, $session, $fileType);
792
793
            $file = null;
794
            if ('file' === $fileType && $settings->isAllowToSaveEditorToResourceFile()) {
795
                $content = $form->get($this->fileContentName)->getViewData();
796
                $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\CThematicPlan or Chamilo\CourseBundle\Entity\CQuiz 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

796
                $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\CThematicPlan or Chamilo\CourseBundle\Entity\CQuiz 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

796
                $newResource->/** @scrutinizer ignore-call */ 
797
                              setTitle($newResource->getTitle().'.html');
Loading history...
797
                $fileName = $newResource->getTitle();
798
799
                $handle = tmpfile();
800
                fwrite($handle, $content);
801
                $meta = stream_get_meta_data($handle);
802
                $file = new UploadedFile($meta['uri'], $fileName, 'text/html', null, true);
803
            }
804
805
            //$parent = $repository->getResourceNodeRepository()->getResourceByNode($parentNode);
806
            // @todo fix correct parent
807
            $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...
808
            $newResource->addCourseLink(
809
                $course,
810
                $session
811
            );
812
            $em->persist($newResource);
813
            $em->flush();
814
815
            $repository->addFile($newResource, $file);
816
            $em->flush();
817
818
            // Loops all sharing options
819
            /*foreach ($shareList as $share) {
820
                $idList = [];
821
                if (isset($share['search'])) {
822
                    $idList = explode(',', $share['search']);
823
                }
824
825
                $resourceRight = null;
826
                if (isset($share['mask'])) {
827
                    $resourceRight = new ResourceRight();
828
                    $resourceRight
829
                        ->setMask($share['mask'])
830
                        ->setRole($share['role'])
831
                    ;
832
                }
833
834
                // Build links
835
                switch ($share['sharing']) {
836
                    case 'everyone':
837
                        $repository->addResourceToEveryone(
838
                            $resourceNode,
839
                            $resourceRight
840
                        );
841
                        break;
842
                    case 'course':
843
                        $repository->addResourceToCourse(
844
                            $resourceNode,
845
                            $course,
846
                            $resourceRight
847
                        );
848
                        break;
849
                    case 'session':
850
                        $repository->addResourceToSession(
851
                            $resourceNode,
852
                            $course,
853
                            $session,
854
                            $resourceRight
855
                        );
856
                        break;
857
                    case 'user':
858
                        // Only for me
859
                        if (isset($share['only_me'])) {
860
                            $repository->addResourceOnlyToMe($resourceNode);
861
                        } else {
862
                            // To other users
863
                            $repository->addResourceToUserList($resourceNode, $idList);
864
                        }
865
                        break;
866
                    case 'group':
867
                        // @todo
868
                        break;
869
                }*/
870
            //}
871
            $em->flush();
872
            $this->addFlash('success', $this->trans('Saved'));
873
874
            $params = $this->getResourceParams($request);
875
            $params['id'] = $resourceNodeParentId;
876
877
            return $this->redirectToRoute(
878
                'chamilo_core_resource_list',
879
                $params
880
            );
881
        }
882
883
        switch ($fileType) {
884
            case 'folder':
885
                $template = $repository->getTemplates()->getFromAction('newFolderAction');
886
887
                break;
888
            case 'file':
889
                $template = $repository->getTemplates()->getFromAction('newAction');
890
891
                break;
892
        }
893
894
        $routeParams = $this->getResourceParams($request);
895
        $routeParams['form'] = $form->createView();
896
        $routeParams['parent'] = $resourceNodeParentId;
897
        $routeParams['file_type'] = $fileType;
898
899
        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...
900
    }
901
}
902