Completed
Push — master ( 98c696...006e96 )
by Julito
11:19
created

ResourceRepository::getFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Repository;
6
7
use APY\DataGridBundle\Grid\Action\RowAction;
8
use APY\DataGridBundle\Grid\Row;
9
use Chamilo\CoreBundle\Component\Utils\ResourceSettings;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
12
use Chamilo\CoreBundle\Entity\Resource\ResourceFile;
13
use Chamilo\CoreBundle\Entity\Resource\ResourceInterface;
14
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
15
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
16
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
17
use Chamilo\CoreBundle\Entity\Resource\ResourceType;
18
use Chamilo\CoreBundle\Entity\Session;
19
use Chamilo\CoreBundle\Entity\Usergroup;
20
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
21
use Chamilo\CoreBundle\ToolChain;
22
use Chamilo\CourseBundle\Entity\CDocument;
23
use Chamilo\CourseBundle\Entity\CGroupInfo;
24
use Chamilo\UserBundle\Entity\User;
25
use Cocur\Slugify\SlugifyInterface;
26
use Doctrine\ORM\EntityManager;
27
use Doctrine\ORM\EntityRepository;
28
use Doctrine\ORM\EntityRepository as BaseEntityRepository;
29
use Doctrine\ORM\Query\Expr\Join;
30
use Doctrine\ORM\QueryBuilder;
31
use League\Flysystem\FilesystemInterface;
32
use League\Flysystem\MountManager;
33
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
34
use Symfony\Component\Form\FormFactory;
35
use Symfony\Component\Form\FormInterface;
36
use Symfony\Component\HttpFoundation\File\UploadedFile;
37
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
38
use Symfony\Component\Routing\RouterInterface;
39
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
40
use Vich\UploaderBundle\Storage\FlysystemStorage;
41
42
/**
43
 * Class ResourceRepository.
44
 * Extends EntityRepository is needed to process settings.
45
 */
46
class ResourceRepository extends BaseEntityRepository
47
{
48
    /**
49
     * @var EntityRepository
50
     */
51
    protected $repository;
52
53
    /**
54
     * @var FilesystemInterface
55
     */
56
    protected $fs;
57
58
    /**
59
     * @var EntityManager
60
     */
61
    protected $entityManager;
62
63
    /**
64
     * The entity class FQN.
65
     *
66
     * @var string
67
     */
68
    protected $className;
69
70
    /** @var RouterInterface */
71
    protected $router;
72
73
    /** @var ResourceNodeRepository */
74
    protected $resourceNodeRepository;
75
76
    /**
77
     * @var AuthorizationCheckerInterface
78
     */
79
    protected $authorizationChecker;
80
81
    /** @var MountManager */
82
    protected $mountManager;
83
84
    /** @var SlugifyInterface */
85
    protected $slugify;
86
87
    /** @var ToolChain */
88
    protected $toolChain;
89
90
    /** @var FlysystemStorage */
91
    protected $storage;
92
93
    /**
94
     * ResourceRepository constructor.
95
     */
96
    public function __construct(
97
        AuthorizationCheckerInterface $authorizationChecker,
98
        EntityManager $entityManager,
99
        MountManager $mountManager,
100
        RouterInterface $router,
101
        SlugifyInterface $slugify,
102
        ToolChain $toolChain,
103
        FlysystemStorage $storage,
104
        string $className
105
    ) {
106
        $this->authorizationChecker = $authorizationChecker;
107
        $this->repository = $entityManager->getRepository($className);
108
109
        // Flysystem mount name is saved in config/packages/oneup_flysystem.yaml @todo add it as a service.
110
        $this->fs = $mountManager->getFilesystem('resources_fs');
111
        $this->storage = $storage;
112
        $this->mountManager = $mountManager;
113
        $this->router = $router;
114
        $this->resourceNodeRepository = $entityManager->getRepository('ChamiloCoreBundle:Resource\ResourceNode');
115
        $this->slugify = $slugify;
116
        $this->toolChain = $toolChain;
117
    }
118
119
    public function getAuthorizationChecker(): AuthorizationCheckerInterface
120
    {
121
        return $this->authorizationChecker;
122
    }
123
124
    public function create()
125
    {
126
        return new $this->className();
127
    }
128
129
    public function getRouter(): RouterInterface
130
    {
131
        return $this->router;
132
    }
133
134
    /**
135
     * @return ResourceNodeRepository
136
     */
137
    public function getResourceNodeRepository()
138
    {
139
        return $this->resourceNodeRepository;
140
    }
141
142
    /**
143
     * @return FilesystemInterface
144
     */
145
    public function getFileSystem()
146
    {
147
        return $this->fs;
148
    }
149
150
    public function getEntityManager(): EntityManager
151
    {
152
        return $this->getRepository()->getEntityManager();
153
    }
154
155
    /**
156
     * @return EntityRepository
157
     */
158
    public function getRepository()
159
    {
160
        return $this->repository;
161
    }
162
163
    /**
164
     * @return FormInterface
165
     */
166
    public function getForm(FormFactory $formFactory, AbstractResource $resource = null, $options = [])
167
    {
168
        $className = $this->repository->getClassName();
169
        $shortName = (new \ReflectionClass($className))->getShortName();
170
171
        // @todo remove hardcode class loading
172
        $formType = 'Chamilo\CoreBundle\Form\Resource\\'.$shortName.'Type';
173
        if (null === $resource) {
174
            $resource = new $className();
175
        }
176
177
        return $formFactory->create($formType, $resource, $options);
178
    }
179
180
    /**
181
     * @param null $lockMode
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $lockMode is correct as it would always require null to be passed?
Loading history...
182
     * @param null $lockVersion
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $lockVersion is correct as it would always require null to be passed?
Loading history...
183
     *
184
     * @return ResourceInterface
185
     */
186
    public function find($id, $lockMode = null, $lockVersion = null)
187
    {
188
        return $this->getRepository()->find($id);
189
    }
190
191
    public function findOneBy(array $criteria, array $orderBy = null)
192
    {
193
        return $this->getRepository()->findOneBy($criteria, $orderBy);
194
    }
195
196
    public function updateNodeForResource(ResourceInterface $resource): ResourceNode
197
    {
198
        $em = $this->getEntityManager();
199
200
        $resourceNode = $resource->getResourceNode();
201
        $resourceName = $resource->getResourceName();
202
203
        if ($resourceNode->hasResourceFile()) {
204
            $resourceFile = $resourceNode->getResourceFile();
205
            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...
206
                $originalName = $resourceFile->getOriginalName();
207
                $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
208
209
                $originalBasename = \basename($resourceName, $originalExtension);
210
                $slug = sprintf(
211
                    '%s.%s',
212
                    $this->slugify->slugify($originalBasename),
213
                    $this->slugify->slugify($originalExtension)
214
                );
215
216
                $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
217
                $resourceFile->setOriginalName($newOriginalName);
218
219
                $em->persist($resourceFile);
220
            }
221
        } else {
222
            $slug = $this->slugify->slugify($resourceName);
223
        }
224
225
        $resourceNode->setSlug($slug);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $slug does not seem to be defined for all execution paths leading up to this point.
Loading history...
226
227
        $em->persist($resourceNode);
228
        $em->persist($resource);
229
230
        $em->flush();
231
232
        return $resourceNode;
233
    }
234
235
    public function addFile(ResourceInterface $resource, UploadedFile $file): ?ResourceFile
236
    {
237
        $resourceNode = $resource->getResourceNode();
238
239
        if (null === $resourceNode) {
240
            throw new \LogicException('Resource node is null');
241
        }
242
243
        $resourceFile = $resourceNode->getResourceFile();
244
        if (null === $resourceFile) {
245
            $resourceFile = new ResourceFile();
246
        }
247
248
        $em = $this->getEntityManager();
249
        $resourceFile->setFile($file);
250
        $resourceFile->setName($resource->getResourceName());
251
        $em->persist($resourceFile);
252
253
        $resourceNode->setResourceFile($resourceFile);
254
        $em->persist($resourceNode);
255
256
        return $resourceFile;
257
    }
258
259
    public function addResourceNode(AbstractResource $resource, User $creator, AbstractResource $parent = null): ResourceNode
260
    {
261
        if (null !== $parent) {
262
            $parent = $parent->getResourceNode();
263
        }
264
265
        return $this->createNodeForResource($resource, $creator, $parent);
266
    }
267
268
    public function addResourceToCourse(AbstractResource $resource, int $visibility, User $creator, Course $course, Session $session = null, CGroupInfo $group = null, UploadedFile $file = null)
269
    {
270
        $node = $this->createNodeForResource($resource, $creator, $course->getResourceNode(), $file);
271
272
        $this->addResourceNodeToCourse($node, $visibility, $course, $session, $group);
273
    }
274
275
    public function addResourceToCourseWithParent(AbstractResource $resource, ResourceNode $parentNode, int $visibility, User $creator, Course $course, Session $session = null, CGroupInfo $group = null, UploadedFile $file = null)
276
    {
277
        $node = $this->createNodeForResource($resource, $creator, $parentNode, $file);
278
279
        $this->addResourceNodeToCourse($node, $visibility, $course, $session, $group);
280
    }
281
282
    public function addResourceNodeToCourse(ResourceNode $resourceNode, int $visibility, Course $course, Session $session = null, CGroupInfo $group = null, User $toUser = null): void
283
    {
284
        if (empty($visibility)) {
285
            $visibility = ResourceLink::VISIBILITY_PUBLISHED;
286
        }
287
288
        $link = new ResourceLink();
289
        $link
290
            ->setCourse($course)
291
            ->setSession($session)
292
            ->setGroup($group)
293
            ->setUser($toUser)
294
            ->setResourceNode($resourceNode)
295
            ->setVisibility($visibility)
296
        ;
297
298
        $rights = [];
299
        switch ($visibility) {
300
            case ResourceLink::VISIBILITY_PENDING:
301
            case ResourceLink::VISIBILITY_DRAFT:
302
                $editorMask = ResourceNodeVoter::getEditorMask();
303
                $resourceRight = new ResourceRight();
304
                $resourceRight
305
                    ->setMask($editorMask)
306
                    ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
307
                ;
308
                $rights[] = $resourceRight;
309
310
                break;
311
        }
312
313
        if (!empty($rights)) {
314
            foreach ($rights as $right) {
315
                $link->addResourceRight($right);
316
            }
317
        }
318
319
        $em = $this->getEntityManager();
320
        $em->persist($link);
321
    }
322
323
    public function addResourceToMe(ResourceNode $resourceNode): ResourceLink
324
    {
325
        $resourceLink = new ResourceLink();
326
        $resourceLink
327
            ->setResourceNode($resourceNode)
328
        ;
329
330
        $this->getEntityManager()->persist($resourceLink);
331
        $this->getEntityManager()->flush();
332
333
        return $resourceLink;
334
    }
335
336
    public function addResourceToEveryone(ResourceNode $resourceNode, ResourceRight $right): ResourceLink
337
    {
338
        $resourceLink = new ResourceLink();
339
        $resourceLink
340
            ->setResourceNode($resourceNode)
341
            ->addResourceRight($right)
342
        ;
343
344
        $this->getEntityManager()->persist($resourceLink);
345
        $this->getEntityManager()->flush();
346
347
        return $resourceLink;
348
    }
349
350
    public function addResourceToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
351
    {
352
        $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
353
        $this->getEntityManager()->persist($resourceLink);
354
355
        return $resourceLink;
356
    }
357
358
    public function addResourceNodeToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
359
    {
360
        $resourceLink = new ResourceLink();
361
        $resourceLink
362
            ->setResourceNode($resourceNode)
363
            ->setUser($toUser);
364
365
        return $resourceLink;
366
    }
367
368
    public function addResourceToCourseGroup(
369
        ResourceNode $resourceNode,
370
        CGroupInfo $group
371
    ) {
372
        $exists = $resourceNode->getResourceLinks()->exists(function ($key, $element) use ($group) {
373
            if ($element->getGroup()) {
374
                return $group->getIid() == $element->getGroup()->getIid();
375
            }
376
        });
377
378
        if (false === $exists) {
379
            $resourceLink = new ResourceLink();
380
            $resourceLink
381
                ->setResourceNode($resourceNode)
382
                ->setGroup($group)
383
                ->setVisibility(ResourceLink::VISIBILITY_PUBLISHED);
384
            $this->getEntityManager()->persist($resourceLink);
385
386
            return $resourceLink;
387
        }
388
    }
389
390
    /*public function addResourceToSession(
391
        ResourceNode $resourceNode,
392
        Course $course,
393
        Session $session,
394
        ResourceRight $right
395
    ) {
396
        $resourceLink = $this->addResourceToCourse(
397
            $resourceNode,
398
            $course,
399
            $right
400
        );
401
        $resourceLink->setSession($session);
402
        $this->getEntityManager()->persist($resourceLink);
403
404
        return $resourceLink;
405
    }*/
406
407
    /**
408
     * @return ResourceLink
409
     */
410
    public function addResourceToGroup(
411
        ResourceNode $resourceNode,
412
        Usergroup $group,
413
        ResourceRight $right
414
    ) {
415
        $resourceLink = new ResourceLink();
416
        $resourceLink
417
            ->setResourceNode($resourceNode)
418
            ->setUserGroup($group)
419
            ->addResourceRight($right);
420
421
        return $resourceLink;
422
    }
423
424
    /**
425
     * @param array $userList User id list
426
     */
427
    public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
428
    {
429
        $em = $this->getEntityManager();
430
431
        if (!empty($userList)) {
432
            $userRepo = $em->getRepository('ChamiloUserBundle:User');
433
            foreach ($userList as $userId) {
434
                $toUser = $userRepo->find($userId);
435
                $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
436
                $em->persist($resourceLink);
437
            }
438
        }
439
    }
440
441
    /**
442
     * @return ResourceType
443
     */
444
    public function getResourceType()
445
    {
446
        $em = $this->getEntityManager();
447
        $service = get_class($this);
448
        $name = $this->toolChain->getResourceTypeNameFromRepository($service);
449
        $repo = $em->getRepository('ChamiloCoreBundle:Resource\ResourceType');
450
451
        return $repo->findOneBy(['name' => $name]);
452
    }
453
454
    /**
455
     * @return QueryBuilder
456
     */
457
    public function getResourcesByCourse(Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null)
458
    {
459
        $repo = $this->getRepository();
460
        $className = $repo->getClassName();
461
        $checker = $this->getAuthorizationChecker();
462
        $reflectionClass = $repo->getClassMetadata()->getReflectionClass();
463
464
        // Check if this resource type requires to load the base course resources when using a session
465
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
466
467
        $type = $this->getResourceType();
468
469
        $qb = $repo->getEntityManager()->createQueryBuilder()
470
            ->select('resource')
471
            ->from($className, 'resource')
472
            ->innerJoin(
473
                ResourceNode::class,
474
                'node',
475
                Join::WITH,
476
                'resource.resourceNode = node.id'
477
            )
478
            ->innerJoin('node.resourceLinks', 'links')
479
            ->where('node.resourceType = :type')
480
            ->setParameter('type', $type);
481
        $qb
482
            ->andWhere('links.course = :course')
483
            ->setParameter('course', $course)
484
        ;
485
486
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
487
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
488
489
        // Do not show deleted resources
490
        $qb
491
            ->andWhere('links.visibility != :visibilityDeleted')
492
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
493
        ;
494
495
        if (false === $isAdmin) {
496
            $qb
497
                ->andWhere('links.visibility = :visibility')
498
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
499
            ;
500
            // @todo Add start/end visibility restrictrions
501
        }
502
503
        if (null === $session) {
504
            $qb->andWhere('links.session IS NULL');
505
        } else {
506
            if ($loadBaseSessionContent) {
507
                // Load course base content.
508
                $qb->andWhere('links.session = :session OR links.session IS NULL');
509
                $qb->setParameter('session', $session);
510
            } else {
511
                // Load only session resources.
512
                $qb->andWhere('links.session = :session');
513
                $qb->setParameter('session', $session);
514
            }
515
        }
516
517
        if (null !== $parentNode) {
518
            $qb->andWhere('node.parent = :parentNode');
519
            $qb->setParameter('parentNode', $parentNode);
520
        }
521
522
        if (null === $group) {
523
            $qb->andWhere('links.group IS NULL');
524
        }
525
526
        return $qb;
527
    }
528
529
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null)
530
    {
531
        $repo = $this->getRepository();
532
        $className = $repo->getClassName();
533
        $checker = $this->getAuthorizationChecker();
534
        $type = $this->getResourceType();
535
536
        $qb = $repo->getEntityManager()->createQueryBuilder()
537
            ->select('resource')
538
            ->from($className, 'resource')
539
            ->innerJoin(
540
                ResourceNode::class,
541
                'node',
542
                Join::WITH,
543
                'resource.resourceNode = node.id'
544
            )
545
            ->innerJoin('node.resourceLinks', 'links')
546
            ->where('node.resourceType = :type')
547
            ->setParameter('type', $type);
548
        $qb
549
            ->andWhere('links.course = :course')
550
            ->setParameter('course', $course)
551
        ;
552
553
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
554
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
555
556
        // Do not show deleted resources
557
        $qb
558
            ->andWhere('links.visibility != :visibilityDeleted')
559
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
560
        ;
561
562
        if (false === $isAdmin) {
563
            $qb
564
                ->andWhere('links.visibility = :visibility')
565
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
566
            ;
567
            // @todo Add start/end visibility restrictrions
568
        }
569
570
        if (null !== $parentNode) {
571
            $qb->andWhere('node.parent = :parentNode');
572
            $qb->setParameter('parentNode', $parentNode);
573
        }
574
575
        return $qb;
576
    }
577
578
    /**
579
     * @return QueryBuilder
580
     */
581
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null)
582
    {
583
        $repo = $this->getRepository();
584
        $className = $repo->getClassName();
585
586
        $qb = $repo->getEntityManager()->createQueryBuilder()
587
            ->select('resource')
588
            ->from($className, 'resource')
589
            ->innerJoin(
590
                ResourceNode::class,
591
                'node',
592
                Join::WITH,
593
                'resource.resourceNode = node.id'
594
            )
595
            //->innerJoin('node.resourceLinks', 'links')
596
            //->where('node.resourceType = :type')
597
            //->setParameter('type',$type)
598
            ;
599
        /*$qb
600
            ->andWhere('links.visibility = :visibility')
601
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
602
        ;*/
603
604
        if (null !== $parentNode) {
605
            $qb->andWhere('node.parent = :parentNode');
606
            $qb->setParameter('parentNode', $parentNode);
607
        }
608
609
        $qb->andWhere('node.creator = :creator');
610
        $qb->setParameter('creator', $user);
611
        //var_dump($qb->getQuery()->getSQL(), $parentNode->getId());exit;
612
613
        return $qb;
614
    }
615
616
    public function getResourceFromResourceNode(int $resourceNodeId): ?AbstractResource
617
    {
618
        return $this->getRepository()->findOneBy(['resourceNode' => $resourceNodeId]);
619
    }
620
621
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
622
    {
623
        if (null !== $session) {
624
            /** @var AbstractResource $entity */
625
            $entity = $row->getEntity();
626
            $hasSession = $entity->getResourceNode()->hasSession($session);
627
            if ($hasSession->count() > 0) {
628
                return $action;
629
            }
630
631
            return null;
632
        }
633
634
        return $action;
635
    }
636
637
    /**
638
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
639
     * ResourceLinks and ResourceFile (including files via Flysystem).
640
     */
641
    public function hardDelete(AbstractResource $resource)
642
    {
643
        $em = $this->getEntityManager();
644
        $em->remove($resource);
645
        $em->flush();
646
    }
647
648
    public function getResourceFileContent(AbstractResource $resource): string
649
    {
650
        try {
651
            $resourceNode = $resource->getResourceNode();
652
            if ($resourceNode->hasResourceFile()) {
653
                $resourceFile = $resourceNode->getResourceFile();
654
                $fileName = $this->getFilename($resourceFile);
655
656
                return $this->getFileSystem()->read($fileName);
657
            }
658
659
            return '';
660
        } catch (\Throwable $exception) {
661
            throw new FileNotFoundException($resource);
662
        }
663
    }
664
665
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
666
    {
667
        try {
668
            if ($resourceNode->hasResourceFile()) {
669
                $resourceFile = $resourceNode->getResourceFile();
670
                $fileName = $this->getFilename($resourceFile);
671
672
                return $this->getFileSystem()->read($fileName);
673
            }
674
675
            return '';
676
        } catch (\Throwable $exception) {
677
            throw new FileNotFoundException($resourceNode);
678
        }
679
    }
680
681
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
682
    {
683
        try {
684
            if ($resourceNode->hasResourceFile()) {
685
                $resourceFile = $resourceNode->getResourceFile();
686
                $fileName = $this->getFilename($resourceFile);
687
688
                return $this->getFileSystem()->readStream($fileName);
689
            }
690
691
            return '';
692
        } catch (\Throwable $exception) {
693
            throw new FileNotFoundException($resourceNode);
694
        }
695
    }
696
697
    public function getFilename(ResourceFile $resourceFile)
698
    {
699
        //$fileName = $resourceFile->getFile()->getPathname();
700
        return $this->storage->resolveUri($resourceFile);
701
    }
702
703
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
704
    {
705
        try {
706
            $resourceNode = $resource->getResourceNode();
707
            if ($resourceNode->hasResourceFile()) {
708
                $params = [
709
                    'tool' => $resourceNode->getResourceType()->getTool(),
710
                    'type' => $resourceNode->getResourceType(),
711
                    'id' => $resourceNode->getId(),
712
                ];
713
714
                if (!empty($extraParams)) {
715
                    $params = array_merge($params, $extraParams);
716
                }
717
718
                $referenceType = $referenceType ?? UrlGeneratorInterface::ABSOLUTE_PATH;
719
720
                return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
721
            }
722
723
            return '';
724
        } catch (\Throwable $exception) {
725
            throw new FileNotFoundException($resource);
726
        }
727
    }
728
729
    public function getResourceSettings(): ResourceSettings
730
    {
731
        $settings = new ResourceSettings();
732
        $settings
733
            ->setAllowNodeCreation(false)
734
            ->setAllowResourceCreation(false)
735
            ->setAllowResourceUpload(false)
736
        ;
737
738
        return $settings;
739
    }
740
741
    /**
742
     * @param string $content
743
     *
744
     * @return bool
745
     */
746
    public function updateResourceFileContent(AbstractResource $resource, $content)
747
    {
748
        try {
749
            $resourceNode = $resource->getResourceNode();
750
            if ($resourceNode->hasResourceFile()) {
751
                $resourceFile = $resourceNode->getResourceFile();
752
                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...
753
                    $fileName = $resourceFile->getFile()->getPathname();
754
                    $this->getFileSystem()->update($fileName, $content);
755
                    $size = $this->getFileSystem()->getSize($fileName);
756
                    if ($resource instanceof CDocument) {
757
                        $resource->setSize($size);
758
                    }
759
                    $this->entityManager->persist($resource);
760
761
                    return true;
762
                }
763
            }
764
765
            return false;
766
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
767
        }
768
    }
769
770
    /**
771
     * Change all links visibility to DELETED.
772
     */
773
    public function softDelete(AbstractResource $resource)
774
    {
775
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
776
    }
777
778
    public function setVisibilityPublished(AbstractResource $resource)
779
    {
780
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
781
    }
782
783
    public function setVisibilityDraft(AbstractResource $resource)
784
    {
785
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
786
    }
787
788
    public function setVisibilityPending(AbstractResource $resource)
789
    {
790
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
791
    }
792
793
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode = null, UploadedFile $file = null): ResourceNode
794
    {
795
        $em = $this->getEntityManager();
796
797
        $resourceType = $this->getResourceType();
798
        $resourceNode = new ResourceNode();
799
        $resourceName = $resource->getResourceName();
800
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
801
802
        if (empty($extension)) {
803
            $slug = $this->slugify->slugify($resourceName);
804
        } else {
805
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
806
            $originalBasename = \basename($resourceName, $originalExtension);
807
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
808
        }
809
810
        $resourceNode
811
            ->setSlug($slug)
812
            ->setCreator($creator)
813
            ->setResourceType($resourceType)
814
        ;
815
816
        if (null !== $parentNode) {
817
            $resourceNode->setParent($parentNode);
818
        }
819
820
        $resource->setResourceNode($resourceNode);
821
        $em->persist($resourceNode);
822
        $em->persist($resource);
823
824
        if (null !== $file) {
825
            $this->addFile($resource, $file);
826
        }
827
828
        return $resourceNode;
829
    }
830
831
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
832
    {
833
        $resourceNode = $resource->getResourceNode();
834
835
        if (null === $resourceNode) {
836
            return false;
837
        }
838
839
        $em = $this->getEntityManager();
840
        if ($recursive) {
841
            $children = $resourceNode->getChildren();
842
            if (!empty($children)) {
843
                /** @var ResourceNode $child */
844
                foreach ($children as $child) {
845
                    $criteria = ['resourceNode' => $child];
846
                    $childDocument = $this->getRepository()->findOneBy($criteria);
847
                    if ($childDocument) {
848
                        $this->setLinkVisibility($childDocument, $visibility);
849
                    }
850
                }
851
            }
852
        }
853
854
        $links = $resourceNode->getResourceLinks();
855
856
        if (!empty($links)) {
857
            /** @var ResourceLink $link */
858
            foreach ($links as $link) {
859
                $link->setVisibility($visibility);
860
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
861
                    $editorMask = ResourceNodeVoter::getEditorMask();
862
                    $rights = [];
863
                    $resourceRight = new ResourceRight();
864
                    $resourceRight
865
                        ->setMask($editorMask)
866
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
867
                        ->setResourceLink($link)
868
                    ;
869
                    $rights[] = $resourceRight;
870
871
                    if (!empty($rights)) {
872
                        $link->setResourceRight($rights);
873
                    }
874
                } else {
875
                    $link->setResourceRight([]);
876
                }
877
                $em->persist($link);
878
            }
879
        }
880
        $em->flush();
881
882
        return true;
883
    }
884
}
885