Passed
Push — master ( dfb4c6...e2c783 )
by Julito
09:23
created

ResourceRepository::getResourcesByLinkedUser()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 47
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 31
nc 8
nop 2
dl 0
loc 47
rs 9.424
c 1
b 0
f 0
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
            ->setVisibility(ResourceLink::VISIBILITY_PUBLISHED)
364
            ->setUser($toUser);
365
366
        return $resourceLink;
367
    }
368
369
    public function addResourceToCourseGroup(
370
        ResourceNode $resourceNode,
371
        CGroupInfo $group
372
    ) {
373
        $exists = $resourceNode->getResourceLinks()->exists(function ($key, $element) use ($group) {
374
            if ($element->getGroup()) {
375
                return $group->getIid() == $element->getGroup()->getIid();
376
            }
377
        });
378
379
        if (false === $exists) {
380
            $resourceLink = new ResourceLink();
381
            $resourceLink
382
                ->setResourceNode($resourceNode)
383
                ->setGroup($group)
384
                ->setVisibility(ResourceLink::VISIBILITY_PUBLISHED)
385
            ;
386
            $this->getEntityManager()->persist($resourceLink);
387
388
            return $resourceLink;
389
        }
390
    }
391
392
    /*public function addResourceToSession(
393
        ResourceNode $resourceNode,
394
        Course $course,
395
        Session $session,
396
        ResourceRight $right
397
    ) {
398
        $resourceLink = $this->addResourceToCourse(
399
            $resourceNode,
400
            $course,
401
            $right
402
        );
403
        $resourceLink->setSession($session);
404
        $this->getEntityManager()->persist($resourceLink);
405
406
        return $resourceLink;
407
    }*/
408
409
    /**
410
     * @return ResourceLink
411
     */
412
    public function addResourceToGroup(
413
        ResourceNode $resourceNode,
414
        Usergroup $group,
415
        ResourceRight $right
416
    ) {
417
        $resourceLink = new ResourceLink();
418
        $resourceLink
419
            ->setResourceNode($resourceNode)
420
            ->setUserGroup($group)
421
            ->addResourceRight($right);
422
423
        return $resourceLink;
424
    }
425
426
    /**
427
     * @param array $userList User id list
428
     */
429
    public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
430
    {
431
        $em = $this->getEntityManager();
432
433
        if (!empty($userList)) {
434
            $userRepo = $em->getRepository('ChamiloUserBundle:User');
435
            foreach ($userList as $userId) {
436
                $toUser = $userRepo->find($userId);
437
                $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
438
                $em->persist($resourceLink);
439
            }
440
        }
441
    }
442
443
    /**
444
     * @return ResourceType
445
     */
446
    public function getResourceType()
447
    {
448
        $em = $this->getEntityManager();
449
        $service = get_class($this);
450
        $name = $this->toolChain->getResourceTypeNameFromRepository($service);
451
        $repo = $em->getRepository('ChamiloCoreBundle:Resource\ResourceType');
452
453
        return $repo->findOneBy(['name' => $name]);
454
    }
455
456
    public function getResourcesByCourse(Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null): QueryBuilder
457
    {
458
        $repo = $this->getRepository();
459
        $className = $repo->getClassName();
460
        $checker = $this->getAuthorizationChecker();
461
        $reflectionClass = $repo->getClassMetadata()->getReflectionClass();
462
463
        // Check if this resource type requires to load the base course resources when using a session
464
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
465
466
        $type = $this->getResourceType();
467
468
        $qb = $repo->getEntityManager()->createQueryBuilder()
469
            ->select('resource')
470
            ->from($className, 'resource')
471
            ->innerJoin(
472
                ResourceNode::class,
473
                'node',
474
                Join::WITH,
475
                'resource.resourceNode = node.id'
476
            )
477
            ->innerJoin('node.resourceLinks', 'links')
478
            ->where('node.resourceType = :type')
479
            ->setParameter('type', $type);
480
        $qb
481
            ->andWhere('links.course = :course')
482
            ->setParameter('course', $course)
483
        ;
484
485
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
486
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
487
488
        // Do not show deleted resources
489
        $qb
490
            ->andWhere('links.visibility != :visibilityDeleted')
491
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
492
        ;
493
494
        if (false === $isAdmin) {
495
            $qb
496
                ->andWhere('links.visibility = :visibility')
497
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
498
            ;
499
            // @todo Add start/end visibility restrictrions
500
        }
501
502
        if (null === $session) {
503
            $qb->andWhere('links.session IS NULL');
504
        } else {
505
            if ($loadBaseSessionContent) {
506
                // Load course base content.
507
                $qb->andWhere('links.session = :session OR links.session IS NULL');
508
                $qb->setParameter('session', $session);
509
            } else {
510
                // Load only session resources.
511
                $qb->andWhere('links.session = :session');
512
                $qb->setParameter('session', $session);
513
            }
514
        }
515
516
        if (null !== $parentNode) {
517
            $qb->andWhere('node.parent = :parentNode');
518
            $qb->setParameter('parentNode', $parentNode);
519
        }
520
521
        if (null === $group) {
522
            $qb->andWhere('links.group IS NULL');
523
        }
524
525
        return $qb;
526
    }
527
528
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null)
529
    {
530
        $repo = $this->getRepository();
531
        $className = $repo->getClassName();
532
        $checker = $this->getAuthorizationChecker();
533
        $type = $this->getResourceType();
534
535
        $qb = $repo->getEntityManager()->createQueryBuilder()
536
            ->select('resource')
537
            ->from($className, 'resource')
538
            ->innerJoin(
539
                ResourceNode::class,
540
                'node',
541
                Join::WITH,
542
                'resource.resourceNode = node.id'
543
            )
544
            ->innerJoin('node.resourceLinks', 'links')
545
            ->where('node.resourceType = :type')
546
            ->setParameter('type', $type);
547
        $qb
548
            ->andWhere('links.course = :course')
549
            ->setParameter('course', $course)
550
        ;
551
552
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
553
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
554
555
        // Do not show deleted resources
556
        $qb
557
            ->andWhere('links.visibility != :visibilityDeleted')
558
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
559
        ;
560
561
        if (false === $isAdmin) {
562
            $qb
563
                ->andWhere('links.visibility = :visibility')
564
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
565
            ;
566
            // @todo Add start/end visibility restrictrions
567
        }
568
569
        if (null !== $parentNode) {
570
            $qb->andWhere('node.parent = :parentNode');
571
            $qb->setParameter('parentNode', $parentNode);
572
        }
573
574
        return $qb;
575
    }
576
577
    /**
578
     * @return QueryBuilder
579
     */
580
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null)
581
    {
582
        $repo = $this->getRepository();
583
        $className = $repo->getClassName();
584
585
        $qb = $repo->getEntityManager()->createQueryBuilder()
586
            ->select('resource')
587
            ->from($className, 'resource')
588
            ->innerJoin(
589
                ResourceNode::class,
590
                'node',
591
                Join::WITH,
592
                'resource.resourceNode = node.id'
593
            )
594
            //->innerJoin('node.resourceLinks', 'links')
595
            //->where('node.resourceType = :type')
596
            //->setParameter('type',$type)
597
            ;
598
        /*$qb
599
            ->andWhere('links.visibility = :visibility')
600
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
601
        ;*/
602
603
        if (null !== $parentNode) {
604
            $qb->andWhere('node.parent = :parentNode');
605
            $qb->setParameter('parentNode', $parentNode);
606
        }
607
608
        $qb->andWhere('node.creator = :creator');
609
        $qb->setParameter('creator', $user);
610
        //var_dump($qb->getQuery()->getSQL(), $parentNode->getId());exit;
611
612
        return $qb;
613
    }
614
615
    public function getResourcesByCourseLinkedToUser(User $user, Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null): QueryBuilder
616
    {
617
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
618
619
        $qb
620
            ->andWhere('links.user = :user')
621
            ->setParameter('user', $user)
622
        ;
623
624
        return $qb;
625
    }
626
627
628
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
629
    {
630
        $repo = $this->getRepository();
631
        $className = $repo->getClassName();
632
        $checker = $this->getAuthorizationChecker();
633
        $type = $this->getResourceType();
634
635
        $qb = $repo->getEntityManager()->createQueryBuilder()
636
            ->select('resource')
637
            ->from($className, 'resource')
638
            ->innerJoin(
639
                ResourceNode::class,
640
                'node',
641
                Join::WITH,
642
                'resource.resourceNode = node.id'
643
            )
644
            ->innerJoin('node.resourceLinks', 'links')
645
            ->where('node.resourceType = :type')
646
            ->setParameter('type', $type);
647
        $qb
648
            ->andWhere('links.user = :user')
649
            ->setParameter('user', $user)
650
        ;
651
652
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
653
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
654
655
        // Do not show deleted resources
656
        $qb
657
            ->andWhere('links.visibility != :visibilityDeleted')
658
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
659
        ;
660
661
        if (false === $isAdmin) {
662
            $qb
663
                ->andWhere('links.visibility = :visibility')
664
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
665
            ;
666
            // @todo Add start/end visibility restrictrions
667
        }
668
669
        if (null !== $parentNode) {
670
            $qb->andWhere('node.parent = :parentNode');
671
            $qb->setParameter('parentNode', $parentNode);
672
        }
673
674
        return $qb;
675
    }
676
677
    public function getResourceFromResourceNode(int $resourceNodeId): ?AbstractResource
678
    {
679
        return $this->getRepository()->findOneBy(['resourceNode' => $resourceNodeId]);
680
    }
681
682
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
683
    {
684
        if (null !== $session) {
685
            /** @var AbstractResource $entity */
686
            $entity = $row->getEntity();
687
            $hasSession = $entity->getResourceNode()->hasSession($session);
688
            if ($hasSession->count() > 0) {
689
                return $action;
690
            }
691
692
            return null;
693
        }
694
695
        return $action;
696
    }
697
698
    /**
699
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
700
     * ResourceLinks and ResourceFile (including files via Flysystem).
701
     */
702
    public function hardDelete(AbstractResource $resource)
703
    {
704
        $em = $this->getEntityManager();
705
        $em->remove($resource);
706
        $em->flush();
707
    }
708
709
    public function getResourceFileContent(AbstractResource $resource): string
710
    {
711
        try {
712
            $resourceNode = $resource->getResourceNode();
713
            if ($resourceNode->hasResourceFile()) {
714
                $resourceFile = $resourceNode->getResourceFile();
715
                $fileName = $this->getFilename($resourceFile);
716
717
                return $this->getFileSystem()->read($fileName);
718
            }
719
720
            return '';
721
        } catch (\Throwable $exception) {
722
            throw new FileNotFoundException($resource);
723
        }
724
    }
725
726
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
727
    {
728
        try {
729
            if ($resourceNode->hasResourceFile()) {
730
                $resourceFile = $resourceNode->getResourceFile();
731
                $fileName = $this->getFilename($resourceFile);
732
733
                return $this->getFileSystem()->read($fileName);
734
            }
735
736
            return '';
737
        } catch (\Throwable $exception) {
738
            throw new FileNotFoundException($resourceNode);
739
        }
740
    }
741
742
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
743
    {
744
        try {
745
            if ($resourceNode->hasResourceFile()) {
746
                $resourceFile = $resourceNode->getResourceFile();
747
                $fileName = $this->getFilename($resourceFile);
748
749
                return $this->getFileSystem()->readStream($fileName);
750
            }
751
752
            return '';
753
        } catch (\Throwable $exception) {
754
            throw new FileNotFoundException($resourceNode);
755
        }
756
    }
757
758
    public function getFilename(ResourceFile $resourceFile)
759
    {
760
        //$fileName = $resourceFile->getFile()->getPathname();
761
        return $this->storage->resolveUri($resourceFile);
762
    }
763
764
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
765
    {
766
        try {
767
            $resourceNode = $resource->getResourceNode();
768
            if ($resourceNode->hasResourceFile()) {
769
                $params = [
770
                    'tool' => $resourceNode->getResourceType()->getTool(),
771
                    'type' => $resourceNode->getResourceType(),
772
                    'id' => $resourceNode->getId(),
773
                ];
774
775
                if (!empty($extraParams)) {
776
                    $params = array_merge($params, $extraParams);
777
                }
778
779
                $referenceType = $referenceType ?? UrlGeneratorInterface::ABSOLUTE_PATH;
780
781
                return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
782
            }
783
784
            return '';
785
        } catch (\Throwable $exception) {
786
            throw new FileNotFoundException($resource);
787
        }
788
    }
789
790
    public function getResourceSettings(): ResourceSettings
791
    {
792
        $settings = new ResourceSettings();
793
        $settings
794
            ->setAllowNodeCreation(false)
795
            ->setAllowResourceCreation(false)
796
            ->setAllowResourceUpload(false)
797
        ;
798
799
        return $settings;
800
    }
801
802
    /**
803
     * @param string $content
804
     *
805
     * @return bool
806
     */
807
    public function updateResourceFileContent(AbstractResource $resource, $content)
808
    {
809
        try {
810
            $resourceNode = $resource->getResourceNode();
811
            if ($resourceNode->hasResourceFile()) {
812
                $resourceFile = $resourceNode->getResourceFile();
813
                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...
814
                    $fileName = $resourceFile->getFile()->getPathname();
815
                    $this->getFileSystem()->update($fileName, $content);
816
                    $size = $this->getFileSystem()->getSize($fileName);
817
                    if ($resource instanceof CDocument) {
818
                        $resource->setSize($size);
819
                    }
820
                    $this->entityManager->persist($resource);
821
822
                    return true;
823
                }
824
            }
825
826
            return false;
827
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
828
        }
829
    }
830
831
    /**
832
     * Change all links visibility to DELETED.
833
     */
834
    public function softDelete(AbstractResource $resource)
835
    {
836
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
837
    }
838
839
    public function setVisibilityPublished(AbstractResource $resource)
840
    {
841
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
842
    }
843
844
    public function setVisibilityDraft(AbstractResource $resource)
845
    {
846
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
847
    }
848
849
    public function setVisibilityPending(AbstractResource $resource)
850
    {
851
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
852
    }
853
854
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode = null, UploadedFile $file = null): ResourceNode
855
    {
856
        $em = $this->getEntityManager();
857
858
        $resourceType = $this->getResourceType();
859
        $resourceNode = new ResourceNode();
860
        $resourceName = $resource->getResourceName();
861
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
862
863
        if (empty($extension)) {
864
            $slug = $this->slugify->slugify($resourceName);
865
        } else {
866
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
867
            $originalBasename = \basename($resourceName, $originalExtension);
868
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
869
        }
870
871
        $resourceNode
872
            ->setSlug($slug)
873
            ->setCreator($creator)
874
            ->setResourceType($resourceType)
875
        ;
876
877
        if (null !== $parentNode) {
878
            $resourceNode->setParent($parentNode);
879
        }
880
881
        $resource->setResourceNode($resourceNode);
882
        $em->persist($resourceNode);
883
        $em->persist($resource);
884
885
        if (null !== $file) {
886
            $this->addFile($resource, $file);
887
        }
888
889
        return $resourceNode;
890
    }
891
892
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
893
    {
894
        $resourceNode = $resource->getResourceNode();
895
896
        if (null === $resourceNode) {
897
            return false;
898
        }
899
900
        $em = $this->getEntityManager();
901
        if ($recursive) {
902
            $children = $resourceNode->getChildren();
903
            if (!empty($children)) {
904
                /** @var ResourceNode $child */
905
                foreach ($children as $child) {
906
                    $criteria = ['resourceNode' => $child];
907
                    $childDocument = $this->getRepository()->findOneBy($criteria);
908
                    if ($childDocument) {
909
                        $this->setLinkVisibility($childDocument, $visibility);
910
                    }
911
                }
912
            }
913
        }
914
915
        $links = $resourceNode->getResourceLinks();
916
917
        if (!empty($links)) {
918
            /** @var ResourceLink $link */
919
            foreach ($links as $link) {
920
                $link->setVisibility($visibility);
921
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
922
                    $editorMask = ResourceNodeVoter::getEditorMask();
923
                    $rights = [];
924
                    $resourceRight = new ResourceRight();
925
                    $resourceRight
926
                        ->setMask($editorMask)
927
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
928
                        ->setResourceLink($link)
929
                    ;
930
                    $rights[] = $resourceRight;
931
932
                    if (!empty($rights)) {
933
                        $link->setResourceRight($rights);
934
                    }
935
                } else {
936
                    $link->setResourceRight([]);
937
                }
938
                $em->persist($link);
939
            }
940
        }
941
        $em->flush();
942
943
        return true;
944
    }
945
}
946