Completed
Push — master ( 38accd...2bf9cf )
by Julito
10:36
created

ResourceRepository::getTool()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 6
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\ResourceLink;
14
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
15
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
16
use Chamilo\CoreBundle\Entity\Resource\ResourceType;
17
use Chamilo\CoreBundle\Entity\Session;
18
use Chamilo\CoreBundle\Entity\Usergroup;
19
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
20
use Chamilo\CourseBundle\Entity\CGroupInfo;
21
use Chamilo\UserBundle\Entity\User;
22
use Cocur\Slugify\SlugifyInterface;
23
use Doctrine\ORM\EntityManager;
24
use Doctrine\ORM\EntityRepository as BaseEntityRepository;
25
use Doctrine\ORM\Query\Expr\Join;
26
use Doctrine\ORM\QueryBuilder;
27
use League\Flysystem\FilesystemInterface;
28
//use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
29
use League\Flysystem\MountManager;
30
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
31
use Symfony\Component\Form\FormFactory;
32
use Symfony\Component\Form\FormInterface;
33
use Symfony\Component\HttpFoundation\File\UploadedFile;
34
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
35
use Symfony\Component\Routing\RouterInterface;
36
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
37
38
/**
39
 * Class ResourceRepository.
40
 * Extends EntityRepository is needed to process settings.
41
 */
42
class ResourceRepository extends BaseEntityRepository
43
{
44
    /**
45
     * @var EntityRepository
46
     */
47
    protected $repository;
48
49
    /**
50
     * @var FilesystemInterface
51
     */
52
    protected $fs;
53
54
    /**
55
     * @var EntityManager
56
     */
57
    protected $entityManager;
58
59
    /**
60
     * The entity class FQN.
61
     *
62
     * @var string
63
     */
64
    protected $className;
65
66
    /** @var RouterInterface */
67
    protected $router;
68
69
    protected $resourceNodeRepository;
70
71
    /**
72
     * @var AuthorizationCheckerInterface
73
     */
74
    protected $authorizationChecker;
75
76
    /** @var MountManager */
77
    protected $mountManager;
78
79
    /** @var SlugifyInterface */
80
    protected $slugify;
81
82
    /**
83
     * ResourceRepository constructor.
84
     */
85
    public function __construct(
86
        AuthorizationCheckerInterface $authorizationChecker,
87
        EntityManager $entityManager,
88
        MountManager $mountManager,
89
        RouterInterface $router,
90
        SlugifyInterface $slugify,
91
        string $className
92
    ) {
93
        $this->authorizationChecker = $authorizationChecker;
94
        $this->repository = $entityManager->getRepository($className);
95
        // Flysystem mount name is saved in config/packages/oneup_flysystem.yaml @todo add it as a service.
96
        $this->fs = $mountManager->getFilesystem('resources_fs');
97
        $this->mountManager = $mountManager;
98
        $this->router = $router;
99
        $this->resourceNodeRepository = $entityManager->getRepository('ChamiloCoreBundle:Resource\ResourceNode');
100
        $this->slugify = $slugify;
101
    }
102
103
    public function getAuthorizationChecker(): AuthorizationCheckerInterface
104
    {
105
        return $this->authorizationChecker;
106
    }
107
108
    /**
109
     * @return mixed
110
     */
111
    public function create()
112
    {
113
        return new $this->className();
114
    }
115
116
    public function getRouter(): RouterInterface
117
    {
118
        return $this->router;
119
    }
120
121
    /**
122
     * @return ResourceNodeRepository
123
     */
124
    public function getResourceNodeRepository()
125
    {
126
        return $this->resourceNodeRepository;
127
    }
128
129
    /**
130
     * @return FilesystemInterface
131
     */
132
    public function getFileSystem()
133
    {
134
        return $this->fs;
135
    }
136
137
    public function getEntityManager(): EntityManager
138
    {
139
        return $this->getRepository()->getEntityManager();
140
    }
141
142
    /**
143
     * @return EntityRepository
144
     */
145
    public function getRepository()
146
    {
147
        return $this->repository;
148
    }
149
150
    /**
151
     * @return FormInterface
152
     */
153
    public function getForm(FormFactory $formFactory, AbstractResource $resource = null, $options = [])
154
    {
155
        $className = $this->repository->getClassName();
156
        $shortName = (new \ReflectionClass($className))->getShortName();
157
158
        // @todo remove hardcode class loading
159
        $formType = 'Chamilo\CoreBundle\Form\Resource\\'.$shortName.'Type';
160
        if (null === $resource) {
161
            $resource = new $className();
162
        }
163
164
        return $formFactory->create($formType, $resource, $options);
165
    }
166
167
    /**
168
     * @param mixed $id
169
     * @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...
170
     * @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...
171
     */
172
    public function find($id, $lockMode = null, $lockVersion = null) //: ?AbstractResource
173
    {
174
        return $this->getRepository()->find($id);
175
    }
176
177
    public function findOneBy(array $criteria, array $orderBy = null): ?AbstractResource
178
    {
179
        return $this->getRepository()->findOneBy($criteria, $orderBy);
180
    }
181
182
    public function createNodeForResource(AbstractResource $resource, User $creator, ResourceNode $parent = null, UploadedFile $file = null): ResourceNode
183
    {
184
        $em = $this->getEntityManager();
185
186
        $resourceType = $this->getResourceType();
187
        $resourceNode = new ResourceNode();
188
        $resourceName = $resource->getResourceName();
0 ignored issues
show
Bug introduced by
The method getResourceName() does not exist on Chamilo\CoreBundle\Entit...source\AbstractResource. Did you maybe mean getResourceNode()? ( Ignorable by Annotation )

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

188
        /** @scrutinizer ignore-call */ 
189
        $resourceName = $resource->getResourceName();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
189
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
190
191
        if (empty($extension)) {
192
            $slug = $this->slugify->slugify($resourceName);
193
        } else {
194
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
195
            $originalBasename = \basename($resourceName, $originalExtension);
196
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
197
        }
198
199
        $resourceNode
200
            ->setSlug($slug)
201
            ->setCreator($creator)
202
            ->setResourceType($resourceType)
203
        ;
204
205
        if (null !== $parent) {
206
            $resourceNode->setParent($parent);
207
        }
208
209
        $resource->setResourceNode($resourceNode);
210
        $em->persist($resourceNode);
211
        $em->persist($resource);
212
213
        if (null !== $file) {
214
            $this->addFile($resource, $file);
215
        }
216
217
        return $resourceNode;
218
    }
219
220
    public function updateNodeForResource(AbstractResource $resource): ResourceNode
221
    {
222
        $em = $this->getEntityManager();
223
224
        $resourceNode = $resource->getResourceNode();
225
        $resourceName = $resource->getResourceName();
226
227
        if ($resourceNode->hasResourceFile()) {
228
            $resourceFile = $resourceNode->getResourceFile();
229
            $originalName = $resourceFile->getOriginalName();
230
            $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
231
232
            $originalBasename = \basename($resourceName, $originalExtension);
233
            $slug = sprintf(
234
                '%s.%s',
235
                $this->slugify->slugify($originalBasename),
236
                $this->slugify->slugify($originalExtension)
237
            );
238
239
            $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
240
            $resourceFile->setOriginalName($newOriginalName);
241
242
            $em->persist($resourceFile);
243
        } else {
244
            $slug = $this->slugify->slugify($resourceName);
245
        }
246
247
        $resourceNode->setSlug($slug);
248
249
        $em->persist($resourceNode);
250
        $em->persist($resource);
251
252
        $em->flush();
253
254
        return $resourceNode;
255
    }
256
257
    public function addFile(AbstractResource $resource, UploadedFile $file): ?ResourceFile
258
    {
259
        $resourceNode = $resource->getResourceNode();
260
261
        if (null === $resourceNode) {
262
            throw new \LogicException('Resource node is null');
263
        }
264
265
        $resourceFile = $resourceNode->getResourceFile();
266
        if (null === $resourceFile) {
267
            $resourceFile = new ResourceFile();
268
        }
269
270
        $em = $this->getEntityManager();
271
        //$resourceFile->setMimeType($file->getMimeType());
272
        $resourceFile->setFile($file);
273
        $resourceFile->setName($resource->getResourceName());
274
        $em->persist($resourceFile);
275
276
        $resourceNode->setResourceFile($resourceFile);
277
        $em->persist($resourceNode);
278
279
        return $resourceFile;
280
    }
281
282
    public function addResourceNode(AbstractResource $resource, User $creator, AbstractResource $parent = null): ResourceNode
283
    {
284
        if (null !== $parent) {
285
            $parent = $parent->getResourceNode();
286
        }
287
288
        return $this->createNodeForResource($resource, $creator, $parent);
289
    }
290
291
    public function addResourceToCourse(AbstractResource $resource, int $visibility, User $creator, Course $course, Session $session = null, CGroupInfo $group = null)
292
    {
293
        $node = $this->createNodeForResource($resource, $creator, $course->getResourceNode());
294
295
        $this->addResourceNodeToCourse($node, $visibility, $course, $session, $group);
296
    }
297
298
    /**
299
     * @param $visibility
300
     * @param $course
301
     * @param $session
302
     * @param $group
303
     */
304
    public function addResourceNodeToCourse(ResourceNode $resourceNode, $visibility, $course, $session, $group): void
305
    {
306
        $visibility = (int) $visibility;
307
        if (empty($visibility)) {
308
            $visibility = ResourceLink::VISIBILITY_PUBLISHED;
309
        }
310
311
        $link = new ResourceLink();
312
        $link
313
            ->setCourse($course)
314
            ->setSession($session)
315
            ->setGroup($group)
316
            //->setUser($toUser)
317
            ->setResourceNode($resourceNode)
318
            ->setVisibility($visibility)
319
        ;
320
321
        $rights = [];
322
        switch ($visibility) {
323
            case ResourceLink::VISIBILITY_PENDING:
324
            case ResourceLink::VISIBILITY_DRAFT:
325
                $editorMask = ResourceNodeVoter::getEditorMask();
326
                $resourceRight = new ResourceRight();
327
                $resourceRight
328
                    ->setMask($editorMask)
329
                    ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
330
                ;
331
                $rights[] = $resourceRight;
332
333
                break;
334
        }
335
336
        if (!empty($rights)) {
337
            foreach ($rights as $right) {
338
                $link->addResourceRight($right);
339
            }
340
        }
341
342
        $em = $this->getEntityManager();
343
        $em->persist($link);
344
    }
345
346
    /**
347
     * @return ResourceType
348
     */
349
    public function getResourceType()
350
    {
351
        $em = $this->getEntityManager();
352
        $service = get_class($this);
353
354
        return $em->getRepository('ChamiloCoreBundle:Resource\ResourceType')->findOneBy(
355
            ['service' => $service]
356
        );
357
    }
358
359
    public function addResourceToMe(ResourceNode $resourceNode): ResourceLink
360
    {
361
        $resourceLink = new ResourceLink();
362
        $resourceLink
363
            ->setResourceNode($resourceNode)
364
            ->setPrivate(true);
0 ignored issues
show
Bug introduced by
The method setPrivate() does not exist on Chamilo\CoreBundle\Entity\Resource\ResourceLink. ( Ignorable by Annotation )

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

364
            ->/** @scrutinizer ignore-call */ setPrivate(true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
365
366
        $this->getEntityManager()->persist($resourceLink);
367
        $this->getEntityManager()->flush();
368
369
        return $resourceLink;
370
    }
371
372
    public function addResourceToEveryone(ResourceNode $resourceNode, ResourceRight $right): ResourceLink
373
    {
374
        $resourceLink = new ResourceLink();
375
        $resourceLink
376
            ->setResourceNode($resourceNode)
377
            ->addResourceRight($right)
378
        ;
379
380
        $this->getEntityManager()->persist($resourceLink);
381
        $this->getEntityManager()->flush();
382
383
        return $resourceLink;
384
    }
385
386
    public function addResourceToCourse2(ResourceNode $resourceNode, Course $course, ResourceRight $right): ResourceLink
387
    {
388
        $resourceLink = new ResourceLink();
389
        $resourceLink
390
            ->setResourceNode($resourceNode)
391
            ->setCourse($course)
392
            ->addResourceRight($right);
393
        $this->getEntityManager()->persist($resourceLink);
394
        $this->getEntityManager()->flush();
395
396
        return $resourceLink;
397
    }
398
399
    public function addResourceToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
400
    {
401
        $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
402
        $this->getEntityManager()->persist($resourceLink);
403
404
        return $resourceLink;
405
    }
406
407
    public function addResourceNodeToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
408
    {
409
        $resourceLink = new ResourceLink();
410
        $resourceLink
411
            ->setResourceNode($resourceNode)
412
            ->setUser($toUser);
413
414
        return $resourceLink;
415
    }
416
417
    public function addResourceToSession(
418
        ResourceNode $resourceNode,
419
        Course $course,
420
        Session $session,
421
        ResourceRight $right
422
    ) {
423
        $resourceLink = $this->addResourceToCourse(
0 ignored issues
show
Bug introduced by
The call to Chamilo\CoreBundle\Repos...::addResourceToCourse() has too few arguments starting with course. ( Ignorable by Annotation )

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

423
        /** @scrutinizer ignore-call */ 
424
        $resourceLink = $this->addResourceToCourse(

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
Are you sure the assignment to $resourceLink is correct as $this->addResourceToCour...eNode, $course, $right) targeting Chamilo\CoreBundle\Repos...::addResourceToCourse() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
424
            $resourceNode,
425
            $course,
426
            $right
427
        );
428
        $resourceLink->setSession($session);
429
        $this->getEntityManager()->persist($resourceLink);
430
431
        return $resourceLink;
432
    }
433
434
    /**
435
     * @return ResourceLink
436
     */
437
    public function addResourceToCourseGroup(
438
        ResourceNode $resourceNode,
439
        Course $course,
440
        CGroupInfo $group,
441
        ResourceRight $right
442
    ) {
443
        $resourceLink = $this->addResourceToCourse(
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $resourceLink is correct as $this->addResourceToCour...eNode, $course, $right) targeting Chamilo\CoreBundle\Repos...::addResourceToCourse() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
The call to Chamilo\CoreBundle\Repos...::addResourceToCourse() has too few arguments starting with course. ( Ignorable by Annotation )

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

443
        /** @scrutinizer ignore-call */ 
444
        $resourceLink = $this->addResourceToCourse(

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
444
            $resourceNode,
445
            $course,
446
            $right
447
        );
448
        $resourceLink->setGroup($group);
449
        $this->getEntityManager()->persist($resourceLink);
450
451
        return $resourceLink;
452
    }
453
454
    /**
455
     * @return ResourceLink
456
     */
457
    public function addResourceToGroup(
458
        ResourceNode $resourceNode,
459
        Usergroup $group,
460
        ResourceRight $right
461
    ) {
462
        $resourceLink = new ResourceLink();
463
        $resourceLink
464
            ->setResourceNode($resourceNode)
465
            ->setUserGroup($group)
466
            ->addResourceRight($right);
467
468
        return $resourceLink;
469
    }
470
471
    /**
472
     * @param array $userList User id list
473
     */
474
    public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
475
    {
476
        $em = $this->getEntityManager();
477
478
        if (!empty($userList)) {
479
            foreach ($userList as $userId) {
480
                $toUser = $em->getRepository('ChamiloUserBundle:User')->find($userId);
481
482
                $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
483
                $em->persist($resourceLink);
484
            }
485
        }
486
    }
487
488
    /**
489
     * @return QueryBuilder
490
     */
491
    public function getResourcesByCourse(Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null)
492
    {
493
        $repo = $this->getRepository();
494
        $className = $repo->getClassName();
495
        $checker = $this->getAuthorizationChecker();
496
497
        $reflectionClass = $repo->getClassMetadata()->getReflectionClass();
498
499
        // Check if this resource type requires to load the base course resources when using a session
500
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
501
502
        $type = $this->getResourceType();
503
504
        $qb = $repo->getEntityManager()->createQueryBuilder()
505
            ->select('resource')
506
            ->from($className, 'resource')
507
            ->innerJoin(
508
                ResourceNode::class,
509
                'node',
510
                Join::WITH,
511
                'resource.resourceNode = node.id'
512
            )
513
            ->innerJoin('node.resourceLinks', 'links')
514
            ->where('node.resourceType = :type')
515
            ->setParameter('type', $type);
516
        $qb
517
            ->andWhere('links.course = :course')
518
            ->setParameter('course', $course)
519
        ;
520
521
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
522
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
523
524
        // Do not show deleted resources
525
526
        $qb
527
            ->andWhere('links.visibility != :visibilityDeleted')
528
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
529
        ;
530
531
        if (false === $isAdmin) {
532
            $qb
533
                ->andWhere('links.visibility = :visibility')
534
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
535
            ;
536
            // @todo Add start/end visibility restrictrions
537
        }
538
539
        if (null === $session) {
540
            $qb->andWhere('links.session IS NULL');
541
        } else {
542
            if ($loadBaseSessionContent) {
543
                // Load course base content.
544
                $qb->andWhere('links.session = :session OR links.session IS NULL');
545
                $qb->setParameter('session', $session);
546
            } else {
547
                // Load only session resources.
548
                $qb->andWhere('links.session = :session');
549
                $qb->setParameter('session', $session);
550
            }
551
        }
552
553
        if (null !== $parentNode) {
554
            $qb->andWhere('node.parent = :parentNode');
555
            $qb->setParameter('parentNode', $parentNode);
556
        }
557
558
        if (null === $group) {
559
            $qb->andWhere('links.group IS NULL');
560
        }
561
562
        ///var_dump($qb->getQuery()->getSQL(), $type->getId(), $parentNode->getId());exit;
563
564
        return $qb;
565
    }
566
567
    /**
568
     * @return QueryBuilder
569
     */
570
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null)
571
    {
572
        $repo = $this->getRepository();
573
        $className = $repo->getClassName();
574
        $checker = $this->getAuthorizationChecker();
575
        $reflectionClass = $repo->getClassMetadata()->getReflectionClass();
576
        //$isPersonalResource = $reflectionClass->hasProperty('loadPersonalResources');
577
578
        $type = $this->getResourceType();
579
580
        $qb = $repo->getEntityManager()->createQueryBuilder()
581
            ->select('resource')
582
            ->from($className, 'resource')
583
            ->innerJoin(
584
                ResourceNode::class,
585
                'node',
586
                Join::WITH,
587
                'resource.resourceNode = node.id'
588
            )
589
            //->innerJoin('node.resourceLinks', 'links')
590
            //->where('node.resourceType = :type')
591
            //->setParameter('type',$type)
592
            ;
593
        /*$qb
594
            ->andWhere('links.visibility = :visibility')
595
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
596
        ;*/
597
598
        if (null !== $parentNode) {
599
            $qb->andWhere('node.parent = :parentNode');
600
            $qb->setParameter('parentNode', $parentNode);
601
        }
602
603
        $qb->andWhere('node.creator = :creator');
604
        $qb->setParameter('creator', $user);
605
        //var_dump($qb->getQuery()->getSQL(), $parentNode->getId());exit;
606
607
        return $qb;
608
    }
609
610
    public function getResourceFromResourceNode($resourceNodeId): ?AbstractResource
611
    {
612
        return $this->getRepository()->findOneBy(['resourceNode' => $resourceNodeId]);
613
    }
614
615
    /**
616
     * @param Session $session
617
     */
618
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
619
    {
620
        if (null !== $session) {
621
            /** @var AbstractResource $entity */
622
            $entity = $row->getEntity();
623
            $hasSession = $entity->getResourceNode()->hasSession($session);
624
            if ($hasSession->count() > 0) {
625
                return $action;
626
            }
627
628
            return null;
629
        }
630
631
        return $action;
632
    }
633
634
    /**
635
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
636
     * ResourceLinks and ResourceFile (including files via Flysystem).
637
     */
638
    public function hardDelete(AbstractResource $resource)
639
    {
640
        $em = $this->getEntityManager();
641
        $em->remove($resource);
642
        $em->flush();
643
    }
644
645
    /**
646
     * Change all links visibility to DELETED.
647
     */
648
    public function softDelete(AbstractResource $resource)
649
    {
650
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
651
    }
652
653
    public function setVisibilityPublished(AbstractResource $resource)
654
    {
655
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
656
    }
657
658
    public function setVisibilityDraft(AbstractResource $resource)
659
    {
660
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
661
    }
662
663
    public function setVisibilityPending(AbstractResource $resource)
664
    {
665
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
666
    }
667
668
    public function getResourceFileContent(AbstractResource $resource): string
669
    {
670
        try {
671
            $resourceNode = $resource->getResourceNode();
672
            if ($resourceNode->hasResourceFile()) {
673
                $resourceFile = $resourceNode->getResourceFile();
674
                $fileName = $resourceFile->getFile()->getPathname();
675
676
                return $this->fs->read($fileName);
677
            }
678
679
            return '';
680
        } catch (\Throwable $exception) {
681
            throw new FileNotFoundException($resource);
682
        }
683
    }
684
685
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
686
    {
687
        try {
688
            if ($resourceNode->hasResourceFile()) {
689
                $resourceFile = $resourceNode->getResourceFile();
690
                $fileName = $resourceFile->getFile()->getPathname();
691
692
                return $this->fs->read($fileName);
693
            }
694
695
            return '';
696
        } catch (\Throwable $exception) {
697
            throw new FileNotFoundException($resourceNode);
698
        }
699
    }
700
701
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
702
    {
703
        try {
704
            if ($resourceNode->hasResourceFile()) {
705
                $resourceFile = $resourceNode->getResourceFile();
706
                $fileName = $resourceFile->getFile()->getPathname();
707
708
                return $this->fs->readStream($fileName);
709
            }
710
711
            return '';
712
        } catch (\Throwable $exception) {
713
            throw new FileNotFoundException($resourceNode);
714
        }
715
    }
716
717
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
718
    {
719
        try {
720
            $resourceNode = $resource->getResourceNode();
721
            if ($resourceNode->hasResourceFile()) {
722
                $params = [
723
                    'tool' => $resourceNode->getResourceType()->getTool(),
724
                    'type' => $resourceNode->getResourceType(),
725
                    'id' => $resourceNode->getId(),
726
                ];
727
728
                if (!empty($extraParams)) {
729
                    $params = array_merge($params, $extraParams);
730
                }
731
732
                $referenceType = $referenceType ?? UrlGeneratorInterface::ABSOLUTE_PATH;
733
734
                return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
735
            }
736
737
            return '';
738
        } catch (\Throwable $exception) {
739
            throw new FileNotFoundException($resource);
740
        }
741
    }
742
743
    /**
744
     * @param string $content
745
     *
746
     * @return bool
747
     */
748
    public function updateResourceFileContent(AbstractResource $resource, $content)
749
    {
750
        try {
751
            $resourceNode = $resource->getResourceNode();
752
            if ($resourceNode->hasResourceFile()) {
753
                $resourceFile = $resourceNode->getResourceFile();
754
                $fileName = $resourceFile->getFile()->getPathname();
755
756
                $this->fs->update($fileName, $content);
757
                $size = $this->fs->getSize($fileName);
758
                $resource->setSize($size);
0 ignored issues
show
Bug introduced by
The method setSize() does not exist on Chamilo\CoreBundle\Entit...source\AbstractResource. It seems like you code against a sub-type of Chamilo\CoreBundle\Entit...source\AbstractResource such as Chamilo\CourseBundle\Entity\CDocument. ( Ignorable by Annotation )

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

758
                $resource->/** @scrutinizer ignore-call */ 
759
                           setSize($size);
Loading history...
759
                $this->entityManager->persist($resource);
760
761
                return true;
762
            }
763
764
            return false;
765
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
766
        }
767
    }
768
769
    public function getResourceSettings(): ResourceSettings
770
    {
771
        $settings = new ResourceSettings();
772
        $settings
773
            ->setAllowNodeCreation(false)
774
            ->setAllowResourceCreation(false)
775
            ->setAllowResourceUpload(false)
776
        ;
777
778
        return $settings;
779
    }
780
781
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
782
    {
783
        $resourceNode = $resource->getResourceNode();
784
785
        if (null === $resourceNode) {
786
            return false;
787
        }
788
789
        $em = $this->getEntityManager();
790
        if ($recursive) {
791
            $children = $resourceNode->getChildren();
792
            if (!empty($children)) {
793
                /** @var ResourceNode $child */
794
                foreach ($children as $child) {
795
                    $criteria = ['resourceNode' => $child];
796
                    $childDocument = $this->getRepository()->findOneBy($criteria);
797
                    if ($childDocument) {
798
                        $this->setLinkVisibility($childDocument, $visibility);
799
                    }
800
                }
801
            }
802
        }
803
804
        $links = $resourceNode->getResourceLinks();
805
806
        if (!empty($links)) {
807
            /** @var ResourceLink $link */
808
            foreach ($links as $link) {
809
                $link->setVisibility($visibility);
810
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
811
                    $editorMask = ResourceNodeVoter::getEditorMask();
812
                    $rights = [];
813
                    $resourceRight = new ResourceRight();
814
                    $resourceRight
815
                        ->setMask($editorMask)
816
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
817
                        ->setResourceLink($link)
818
                    ;
819
                    $rights[] = $resourceRight;
820
821
                    if (!empty($rights)) {
822
                        $link->setResourceRight($rights);
823
                    }
824
                } else {
825
                    $link->setResourceRight([]);
826
                }
827
                $em->persist($link);
828
            }
829
        }
830
        $em->flush();
831
832
        return true;
833
    }
834
}
835