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