Passed
Push — master ( 45d699...d5e463 )
by Julito
12:21
created

ResourceRepository::getForm()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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