Passed
Push — master ( 4f3b5b...268dc8 )
by Julito
10:04
created

addResourceToCourseWithParent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 8
dl 0
loc 5
rs 10
c 0
b 0
f 0

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
            $qb->andWhere(
505
                $qb->expr()->orX(
506
                    $qb->expr()->isNull('links.session'),
507
                    $qb->expr()->eq('links.session', 0)
508
                )
509
            );
510
        } else {
511
            if ($loadBaseSessionContent) {
512
                // Load course base content.
513
                $qb->andWhere('links.session = :session OR links.session IS NULL');
514
                $qb->setParameter('session', $session);
515
            } else {
516
                // Load only session resources.
517
                $qb->andWhere('links.session = :session');
518
                $qb->setParameter('session', $session);
519
            }
520
        }
521
522
        if (null !== $parentNode) {
523
            $qb->andWhere('node.parent = :parentNode');
524
            $qb->setParameter('parentNode', $parentNode);
525
        }
526
527
        if (null === $group) {
528
            $qb->andWhere(
529
                $qb->expr()->orX(
530
                    $qb->expr()->isNull('links.group'),
531
                    $qb->expr()->eq('links.group', 0)
532
                )
533
            );
534
        } else {
535
            $qb->andWhere('links.group = :group');
536
            $qb->setParameter('group', $group);
537
        }
538
539
        return $qb;
540
    }
541
542
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null)
543
    {
544
        $repo = $this->getRepository();
545
        $className = $repo->getClassName();
546
        $checker = $this->getAuthorizationChecker();
547
        $type = $this->getResourceType();
548
549
        $qb = $repo->getEntityManager()->createQueryBuilder()
550
            ->select('resource')
551
            ->from($className, 'resource')
552
            ->innerJoin(
553
                ResourceNode::class,
554
                'node',
555
                Join::WITH,
556
                'resource.resourceNode = node.id'
557
            )
558
            ->innerJoin('node.resourceLinks', 'links')
559
            ->where('node.resourceType = :type')
560
            ->setParameter('type', $type);
561
        $qb
562
            ->andWhere('links.course = :course')
563
            ->setParameter('course', $course)
564
        ;
565
566
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
567
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
568
569
        // Do not show deleted resources
570
        $qb
571
            ->andWhere('links.visibility != :visibilityDeleted')
572
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
573
        ;
574
575
        if (false === $isAdmin) {
576
            $qb
577
                ->andWhere('links.visibility = :visibility')
578
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
579
            ;
580
            // @todo Add start/end visibility restrictrions
581
        }
582
583
        if (null !== $parentNode) {
584
            $qb->andWhere('node.parent = :parentNode');
585
            $qb->setParameter('parentNode', $parentNode);
586
        }
587
588
        return $qb;
589
    }
590
591
    /**
592
     * @return QueryBuilder
593
     */
594
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null)
595
    {
596
        $repo = $this->getRepository();
597
        $className = $repo->getClassName();
598
599
        $qb = $repo->getEntityManager()->createQueryBuilder()
600
            ->select('resource')
601
            ->from($className, 'resource')
602
            ->innerJoin(
603
                ResourceNode::class,
604
                'node',
605
                Join::WITH,
606
                'resource.resourceNode = node.id'
607
            )
608
            //->innerJoin('node.resourceLinks', 'links')
609
            //->where('node.resourceType = :type')
610
            //->setParameter('type',$type)
611
            ;
612
        /*$qb
613
            ->andWhere('links.visibility = :visibility')
614
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
615
        ;*/
616
617
        if (null !== $parentNode) {
618
            $qb->andWhere('node.parent = :parentNode');
619
            $qb->setParameter('parentNode', $parentNode);
620
        }
621
622
        $qb->andWhere('node.creator = :creator');
623
        $qb->setParameter('creator', $user);
624
        //var_dump($qb->getQuery()->getSQL(), $parentNode->getId());exit;
625
626
        return $qb;
627
    }
628
629
    public function getResourcesByCourseLinkedToUser(User $user, Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null): QueryBuilder
630
    {
631
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
632
633
        $qb
634
            ->andWhere('links.user = :user')
635
            ->setParameter('user', $user);
636
637
        return $qb;
638
    }
639
640
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
641
    {
642
        $repo = $this->getRepository();
643
        $className = $repo->getClassName();
644
        $checker = $this->getAuthorizationChecker();
645
        $type = $this->getResourceType();
646
647
        $qb = $repo->getEntityManager()->createQueryBuilder()
648
            ->select('resource')
649
            ->from($className, 'resource')
650
            ->innerJoin(
651
                ResourceNode::class,
652
                'node',
653
                Join::WITH,
654
                'resource.resourceNode = node.id'
655
            )
656
            ->innerJoin('node.resourceLinks', 'links')
657
            ->where('node.resourceType = :type')
658
            ->setParameter('type', $type);
659
        $qb
660
            ->andWhere('links.user = :user')
661
            ->setParameter('user', $user)
662
        ;
663
664
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
665
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
666
667
        // Do not show deleted resources
668
        $qb
669
            ->andWhere('links.visibility != :visibilityDeleted')
670
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
671
        ;
672
673
        if (false === $isAdmin) {
674
            $qb
675
                ->andWhere('links.visibility = :visibility')
676
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
677
            ;
678
            // @todo Add start/end visibility restrictrions
679
        }
680
681
        if (null !== $parentNode) {
682
            $qb->andWhere('node.parent = :parentNode');
683
            $qb->setParameter('parentNode', $parentNode);
684
        }
685
686
        return $qb;
687
    }
688
689
    public function getResourceFromResourceNode(int $resourceNodeId): ?AbstractResource
690
    {
691
        return $this->getRepository()->findOneBy(['resourceNode' => $resourceNodeId]);
692
    }
693
694
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
695
    {
696
        if (null !== $session) {
697
            /** @var AbstractResource $entity */
698
            $entity = $row->getEntity();
699
            $hasSession = $entity->getResourceNode()->hasSession($session);
700
            if ($hasSession->count() > 0) {
701
                return $action;
702
            }
703
704
            return null;
705
        }
706
707
        return $action;
708
    }
709
710
    public function delete(AbstractResource $resource)
711
    {
712
        $children = $resource->getResourceNode()->getChildren();
713
        foreach ($children as $child) {
714
            $this->getEntityManager()->remove($child);
715
        }
716
        $this->getEntityManager()->remove($resource->getResourceNode());
717
        $this->getEntityManager()->flush();
718
    }
719
720
    /**
721
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
722
     * ResourceLinks and ResourceFile (including files via Flysystem).
723
     */
724
    public function hardDelete(AbstractResource $resource)
725
    {
726
        $em = $this->getEntityManager();
727
        $em->remove($resource);
728
        $em->flush();
729
    }
730
731
    public function getResourceFileContent(AbstractResource $resource): string
732
    {
733
        try {
734
            $resourceNode = $resource->getResourceNode();
735
            if ($resourceNode->hasResourceFile()) {
736
                $resourceFile = $resourceNode->getResourceFile();
737
                $fileName = $this->getFilename($resourceFile);
738
739
                return $this->getFileSystem()->read($fileName);
740
            }
741
742
            return '';
743
        } catch (\Throwable $exception) {
744
            throw new FileNotFoundException($resource);
745
        }
746
    }
747
748
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
749
    {
750
        try {
751
            if ($resourceNode->hasResourceFile()) {
752
                $resourceFile = $resourceNode->getResourceFile();
753
                $fileName = $this->getFilename($resourceFile);
754
755
                return $this->getFileSystem()->read($fileName);
756
            }
757
758
            return '';
759
        } catch (\Throwable $exception) {
760
            throw new FileNotFoundException($resourceNode);
761
        }
762
    }
763
764
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
765
    {
766
        try {
767
            if ($resourceNode->hasResourceFile()) {
768
                $resourceFile = $resourceNode->getResourceFile();
769
                $fileName = $this->getFilename($resourceFile);
770
771
                return $this->getFileSystem()->readStream($fileName);
772
            }
773
774
            return '';
775
        } catch (\Throwable $exception) {
776
            throw new FileNotFoundException($resourceNode);
777
        }
778
    }
779
780
    public function getFilename(ResourceFile $resourceFile)
781
    {
782
        return $this->storage->resolveUri($resourceFile);
783
    }
784
785
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
786
    {
787
        try {
788
            $resourceNode = $resource->getResourceNode();
789
            if ($resourceNode->hasResourceFile()) {
790
                $params = [
791
                    'tool' => $resourceNode->getResourceType()->getTool(),
792
                    'type' => $resourceNode->getResourceType(),
793
                    'id' => $resourceNode->getId(),
794
                ];
795
796
                if (!empty($extraParams)) {
797
                    $params = array_merge($params, $extraParams);
798
                }
799
800
                $referenceType = $referenceType ?? UrlGeneratorInterface::ABSOLUTE_PATH;
801
802
                return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
803
            }
804
805
            return '';
806
        } catch (\Throwable $exception) {
807
            throw new FileNotFoundException($resource);
808
        }
809
    }
810
811
    public function getResourceSettings(): ResourceSettings
812
    {
813
        $settings = new ResourceSettings();
814
        $settings
815
            ->setAllowNodeCreation(false)
816
            ->setAllowResourceCreation(false)
817
            ->setAllowResourceUpload(false)
818
        ;
819
820
        return $settings;
821
    }
822
823
    /**
824
     * @param string $content
825
     *
826
     * @return bool
827
     */
828
    public function updateResourceFileContent(AbstractResource $resource, $content)
829
    {
830
        try {
831
            $resourceNode = $resource->getResourceNode();
832
            if ($resourceNode->hasResourceFile()) {
833
                $resourceFile = $resourceNode->getResourceFile();
834
                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...
835
                    $fileName = $this->getFilename($resourceFile);
836
                    $this->getFileSystem()->update($fileName, $content);
837
                    $size = $this->getFileSystem()->getSize($fileName);
838
839
                    if ($resource instanceof CDocument) {
840
                        $resource->setSize($size);
841
                    }
842
                    $this->entityManager->persist($resource);
843
844
                    return true;
845
                }
846
            }
847
848
            return false;
849
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
850
        }
851
    }
852
853
    /**
854
     * Change all links visibility to DELETED.
855
     */
856
    public function softDelete(AbstractResource $resource)
857
    {
858
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
859
    }
860
861
    public function setVisibilityPublished(AbstractResource $resource)
862
    {
863
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
864
    }
865
866
    public function setVisibilityDraft(AbstractResource $resource)
867
    {
868
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
869
    }
870
871
    public function setVisibilityPending(AbstractResource $resource)
872
    {
873
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
874
    }
875
876
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode = null, UploadedFile $file = null): ResourceNode
877
    {
878
        $em = $this->getEntityManager();
879
880
        $resourceType = $this->getResourceType();
881
        $resourceNode = new ResourceNode();
882
        $resourceName = $resource->getResourceName();
883
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
884
885
        if (empty($extension)) {
886
            $slug = $this->slugify->slugify($resourceName);
887
        } else {
888
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
889
            $originalBasename = \basename($resourceName, $originalExtension);
890
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
891
        }
892
893
        $resourceNode
894
            ->setSlug($slug)
895
            ->setCreator($creator)
896
            ->setResourceType($resourceType)
897
        ;
898
899
        if (null !== $parentNode) {
900
            $resourceNode->setParent($parentNode);
901
        }
902
903
        $resource->setResourceNode($resourceNode);
904
        $em->persist($resourceNode);
905
        $em->persist($resource);
906
907
        if (null !== $file) {
908
            $this->addFile($resource, $file);
909
        }
910
911
        return $resourceNode;
912
    }
913
914
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
915
    {
916
        $resourceNode = $resource->getResourceNode();
917
918
        if (null === $resourceNode) {
919
            return false;
920
        }
921
922
        $em = $this->getEntityManager();
923
        if ($recursive) {
924
            $children = $resourceNode->getChildren();
925
            if (!empty($children)) {
926
                /** @var ResourceNode $child */
927
                foreach ($children as $child) {
928
                    $criteria = ['resourceNode' => $child];
929
                    $childDocument = $this->getRepository()->findOneBy($criteria);
930
                    if ($childDocument) {
931
                        $this->setLinkVisibility($childDocument, $visibility);
932
                    }
933
                }
934
            }
935
        }
936
937
        $links = $resourceNode->getResourceLinks();
938
939
        if (!empty($links)) {
940
            /** @var ResourceLink $link */
941
            foreach ($links as $link) {
942
                $link->setVisibility($visibility);
943
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
944
                    $editorMask = ResourceNodeVoter::getEditorMask();
945
                    $rights = [];
946
                    $resourceRight = new ResourceRight();
947
                    $resourceRight
948
                        ->setMask($editorMask)
949
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
950
                        ->setResourceLink($link)
951
                    ;
952
                    $rights[] = $resourceRight;
953
954
                    if (!empty($rights)) {
955
                        $link->setResourceRight($rights);
956
                    }
957
                } else {
958
                    $link->setResourceRight([]);
959
                }
960
                $em->persist($link);
961
            }
962
        }
963
        $em->flush();
964
965
        return true;
966
    }
967
}
968