Passed
Push — master ( 8f17a5...faab0f )
by Julito
09:35
created

ResourceRepository::addResourceNodeToUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

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

359
            ->/** @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...
360
361
        $this->getEntityManager()->persist($resourceLink);
362
        $this->getEntityManager()->flush();
363
364
        return $resourceLink;
365
    }
366
367
    public function addResourceToEveryone(ResourceNode $resourceNode, ResourceRight $right): ResourceLink
368
    {
369
        $resourceLink = new ResourceLink();
370
        $resourceLink
371
            ->setResourceNode($resourceNode)
372
            ->addResourceRight($right)
373
        ;
374
375
        $this->getEntityManager()->persist($resourceLink);
376
        $this->getEntityManager()->flush();
377
378
        return $resourceLink;
379
    }
380
381
    public function addResourceToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
382
    {
383
        $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
384
        $this->getEntityManager()->persist($resourceLink);
385
386
        return $resourceLink;
387
    }
388
389
    public function addResourceNodeToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
390
    {
391
        $resourceLink = new ResourceLink();
392
        $resourceLink
393
            ->setResourceNode($resourceNode)
394
            ->setUser($toUser);
395
396
        return $resourceLink;
397
    }
398
399
    public function addResourceToSession(
400
        ResourceNode $resourceNode,
401
        Course $course,
402
        Session $session,
403
        ResourceRight $right
404
    ) {
405
        $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

405
        /** @scrutinizer ignore-call */ 
406
        $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...
406
            $resourceNode,
407
            $course,
408
            $right
409
        );
410
        $resourceLink->setSession($session);
411
        $this->getEntityManager()->persist($resourceLink);
412
413
        return $resourceLink;
414
    }
415
416
    /**
417
     * @return ResourceLink
418
     */
419
    public function addResourceToCourseGroup(
420
        ResourceNode $resourceNode,
421
        Course $course,
422
        CGroupInfo $group,
423
        ResourceRight $right
424
    ) {
425
        $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

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

733
                $resource->/** @scrutinizer ignore-call */ 
734
                           setSize($size);
Loading history...
734
                $this->entityManager->persist($resource);
735
736
                return true;
737
            }
738
739
            return false;
740
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
741
        }
742
    }
743
744
    /**
745
     * Change all links visibility to DELETED.
746
     */
747
    public function softDelete(AbstractResource $resource)
748
    {
749
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
750
    }
751
752
    public function setVisibilityPublished(AbstractResource $resource)
753
    {
754
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
755
    }
756
757
    public function setVisibilityDraft(AbstractResource $resource)
758
    {
759
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
760
    }
761
762
    public function setVisibilityPending(AbstractResource $resource)
763
    {
764
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
765
    }
766
767
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
768
    {
769
        $resourceNode = $resource->getResourceNode();
770
771
        if (null === $resourceNode) {
772
            return false;
773
        }
774
775
        $em = $this->getEntityManager();
776
        if ($recursive) {
777
            $children = $resourceNode->getChildren();
778
            if (!empty($children)) {
779
                /** @var ResourceNode $child */
780
                foreach ($children as $child) {
781
                    $criteria = ['resourceNode' => $child];
782
                    $childDocument = $this->getRepository()->findOneBy($criteria);
783
                    if ($childDocument) {
784
                        $this->setLinkVisibility($childDocument, $visibility);
785
                    }
786
                }
787
            }
788
        }
789
790
        $links = $resourceNode->getResourceLinks();
791
792
        if (!empty($links)) {
793
            /** @var ResourceLink $link */
794
            foreach ($links as $link) {
795
                $link->setVisibility($visibility);
796
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
797
                    $editorMask = ResourceNodeVoter::getEditorMask();
798
                    $rights = [];
799
                    $resourceRight = new ResourceRight();
800
                    $resourceRight
801
                        ->setMask($editorMask)
802
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
803
                        ->setResourceLink($link)
804
                    ;
805
                    $rights[] = $resourceRight;
806
807
                    if (!empty($rights)) {
808
                        $link->setResourceRight($rights);
809
                    }
810
                } else {
811
                    $link->setResourceRight([]);
812
                }
813
                $em->persist($link);
814
            }
815
        }
816
        $em->flush();
817
818
        return true;
819
    }
820
}
821