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

ResourceRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 2
b 0
f 0
nc 1
nop 8
dl 0
loc 21
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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