Passed
Push — master ( fe6195...c1edf4 )
by Julito
09:22
created

ResourceRepository::getTemplates()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
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