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