Passed
Push — master ( ad6737...b4c9af )
by Julito
10:24
created

ResourceRepository::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

809
        $resource->/** @scrutinizer ignore-call */ 
810
                   setResourceNode($resourceNode);
Loading history...
810
        $em->persist($resourceNode);
811
        $em->persist($resource);
812
813
        if (null !== $file) {
814
            $this->addFile($resource, $file);
815
        }
816
817
        return $resourceNode;
818
    }
819
820
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
821
    {
822
        $resourceNode = $resource->getResourceNode();
823
824
        if (null === $resourceNode) {
825
            return false;
826
        }
827
828
        $em = $this->getEntityManager();
829
        if ($recursive) {
830
            $children = $resourceNode->getChildren();
831
            if (!empty($children)) {
832
                /** @var ResourceNode $child */
833
                foreach ($children as $child) {
834
                    $criteria = ['resourceNode' => $child];
835
                    $childDocument = $this->getRepository()->findOneBy($criteria);
836
                    if ($childDocument) {
837
                        $this->setLinkVisibility($childDocument, $visibility);
838
                    }
839
                }
840
            }
841
        }
842
843
        $links = $resourceNode->getResourceLinks();
844
845
        if (!empty($links)) {
846
            /** @var ResourceLink $link */
847
            foreach ($links as $link) {
848
                $link->setVisibility($visibility);
849
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
850
                    $editorMask = ResourceNodeVoter::getEditorMask();
851
                    $rights = [];
852
                    $resourceRight = new ResourceRight();
853
                    $resourceRight
854
                        ->setMask($editorMask)
855
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
856
                        ->setResourceLink($link)
857
                    ;
858
                    $rights[] = $resourceRight;
859
860
                    if (!empty($rights)) {
861
                        $link->setResourceRight($rights);
862
                    }
863
                } else {
864
                    $link->setResourceRight([]);
865
                }
866
                $em->persist($link);
867
            }
868
        }
869
        $em->flush();
870
871
        return true;
872
    }
873
}
874