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