Completed
Push — master ( 6033c5...af0fd1 )
by Julito
10:22
created

ResourceRepository::getResourcesByCourse()   B

Complexity

Conditions 7
Paths 48

Size

Total Lines 68
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 41
nc 48
nop 4
dl 0
loc 68
rs 8.3306
c 3
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Repository;
5
6
use APY\DataGridBundle\Grid\Action\RowAction;
7
use APY\DataGridBundle\Grid\Row;
8
use Chamilo\CoreBundle\Entity\Course;
9
use Chamilo\CoreBundle\Entity\Resource\AbstractResource;
10
use Chamilo\CoreBundle\Entity\Resource\ResourceFile;
11
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
12
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
13
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
14
use Chamilo\CoreBundle\Entity\Resource\ResourceType;
15
use Chamilo\CoreBundle\Entity\Session;
16
use Chamilo\CoreBundle\Entity\Tool;
17
use Chamilo\CoreBundle\Entity\Usergroup;
18
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
19
use Chamilo\CourseBundle\Entity\CGroupInfo;
20
use Chamilo\UserBundle\Entity\User;
21
use Cocur\Slugify\SlugifyInterface;
22
use Doctrine\ORM\EntityManager;
23
use Doctrine\ORM\Query\Expr\Join;
24
use Doctrine\ORM\QueryBuilder;
25
use League\Flysystem\FilesystemInterface;
26
use League\Flysystem\MountManager;
27
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
28
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
29
use Symfony\Component\Form\FormFactory;
30
use Symfony\Component\Form\FormInterface;
31
use Symfony\Component\HttpFoundation\File\UploadedFile;
32
use Symfony\Component\Routing\RouterInterface;
33
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
34
35
/**
36
 * Class ResourceRepository.
37
 */
38
class ResourceRepository extends EntityRepository
39
{
40
    /**
41
     * @var EntityRepository
42
     */
43
    protected $repository;
44
45
    /**
46
     * @var FilesystemInterface
47
     */
48
    protected $fs;
49
50
    /**
51
     * @var EntityManager
52
     */
53
    protected $entityManager;
54
55
    /**
56
     * The entity class FQN.
57
     *
58
     * @var string
59
     */
60
    protected $className;
61
62
    /** @var RouterInterface */
63
    protected $router;
64
65
    protected $resourceNodeRepository;
66
67
    /**
68
     * @var AuthorizationCheckerInterface
69
     */
70
    protected $authorizationChecker;
71
72
    /**
73
     * @var MountManager
74
     */
75
    protected $mountManager;
76
    protected $slugify;
77
78
    /**
79
     * ResourceRepository constructor.
80
     *
81
     * @param AuthorizationCheckerInterface $authorizationChecker
82
     * @param EntityManager                 $entityManager
83
     * @param MountManager                  $mountManager
84
     * @param RouterInterface               $router
85
     * @param string                        $className
86
     */
87
    public function __construct(
88
        AuthorizationCheckerInterface $authorizationChecker,
89
        EntityManager $entityManager,
90
        MountManager $mountManager,
91
        RouterInterface $router,
92
        SlugifyInterface $slugify,
93
        string $className
94
    ) {
95
        $this->repository = $entityManager->getRepository($className);
96
        // Flysystem mount name is saved in config/packages/oneup_flysystem.yaml @todo add it as a service.
97
        $this->fs = $mountManager->getFilesystem('resources_fs');
98
        $this->mountManager = $mountManager;
99
        $this->router = $router;
100
        $this->resourceNodeRepository = $entityManager->getRepository('ChamiloCoreBundle:Resource\ResourceNode');
101
        $this->authorizationChecker = $authorizationChecker;
102
        $this->slugify = $slugify;
103
    }
104
105
    /**
106
     * @return AuthorizationCheckerInterface
107
     */
108
    public function getAuthorizationChecker(): AuthorizationCheckerInterface
109
    {
110
        return $this->authorizationChecker;
111
    }
112
113
    /**
114
     * @return mixed
115
     */
116
    public function create()
117
    {
118
        return new $this->className();
119
    }
120
121
    /**
122
     * @return RouterInterface
123
     */
124
    public function getRouter(): RouterInterface
125
    {
126
        return $this->router;
127
    }
128
129
    /**
130
     * @return ResourceNodeRepository
131
     */
132
    public function getResourceNodeRepository()
133
    {
134
        return $this->resourceNodeRepository;
135
    }
136
137
    /**
138
     * @return FilesystemInterface
139
     */
140
    public function getFileSystem()
141
    {
142
        return $this->fs;
143
    }
144
145
    /**
146
     * @return EntityManager
147
     */
148
    public function getEntityManager(): EntityManager
149
    {
150
        return $this->getRepository()->getEntityManager();
151
    }
152
153
    /**
154
     * @return EntityRepository
155
     */
156
    public function getRepository()
157
    {
158
        return $this->repository;
159
    }
160
161
    /**
162
     * @param FormFactory $formFactory
163
     *
164
     * @return FormInterface
165
     */
166
    public function getForm(FormFactory $formFactory, AbstractResource $resource = null, $options = [])
167
    {
168
        $className = $this->repository->getClassName();
169
        $shortName = (new \ReflectionClass($className))->getShortName();
170
171
        $formType = str_replace('Entity\CDocument', 'Form\\Type', $className).'\\'.$shortName.'Type';
172
173
        if ($resource === null){
174
            $resource = new $className;
175
        }
176
177
        return $formFactory->create($formType, $resource, $options);
178
    }
179
180
    /**
181
     * @param mixed $id
182
     * @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...
183
     * @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...
184
     *
185
     * @return AbstractResource|null
186
     */
187
    public function find($id, $lockMode = null, $lockVersion = null): ?AbstractResource
188
    {
189
        return $this->getRepository()->find($id);
190
    }
191
192
    /**
193
     * @return AbstractResource|null
194
     */
195
    public function findOneBy(array $criteria, array $orderBy = null): ?AbstractResource
196
    {
197
        return $this->getRepository()->findOneBy($criteria, $orderBy);
198
    }
199
200
    /**
201
     * @param AbstractResource  $resource
202
     * @param User              $creator
203
     * @param ResourceNode|null $parent
204
     *
205
     * @return ResourceNode
206
     */
207
    public function createNodeForResource(AbstractResource $resource, User $creator, ResourceNode $parent = null, UploadedFile $file = null): ResourceNode
208
    {
209
        $em = $this->getEntityManager();
210
211
        $resourceType = $this->getResourceType();
212
213
        $resourceNode = new ResourceNode();
214
        $resourceName = $resource->getResourceName();
215
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
216
217
        if (empty($extension)) {
218
            $slug = $this->slugify->slugify($resourceName);
219
        } else {
220
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
221
            $originalBasename = \basename($resourceName, $originalExtension);
222
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
223
        }
224
225
        $resourceNode
226
            ->setSlug($slug)
227
            ->setCreator($creator)
228
            ->setResourceType($resourceType)
229
        ;
230
231
        if (null !== $parent) {
232
            $resourceNode->setParent($parent);
233
        }
234
235
        $resource->setResourceNode($resourceNode);
236
        $em->persist($resourceNode);
237
        $em->persist($resource);
238
239
        if (null !== $file) {
240
            $this->addFile($resource, $file);
241
        }
242
243
        return $resourceNode;
244
    }
245
246
    /**
247
     * @param AbstractResource $resource
248
     *
249
     * @return ResourceNode
250
     */
251
    public function updateNodeForResource(AbstractResource $resource): ResourceNode
252
    {
253
        $em = $this->getEntityManager();
254
255
        $resourceNode = $resource->getResourceNode();
256
        $resourceName = $resource->getResourceName();
257
258
        if ($resourceNode->hasResourceFile()) {
259
            $resourceFile = $resourceNode->getResourceFile();
260
            $originalName = $resourceFile->getOriginalName();
261
            $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
262
263
            $originalBasename = \basename($resourceName, $originalExtension);
264
            $slug = sprintf(
265
                '%s.%s',
266
                $this->slugify->slugify($originalBasename),
267
                $this->slugify->slugify($originalExtension)
268
            );
269
270
            $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
271
            $resourceFile->setOriginalName($newOriginalName);
272
273
            $em->persist($resourceFile);
274
        } else {
275
            $slug = $this->slugify->slugify($resourceName);
276
        }
277
278
        $resourceNode->setSlug($slug);
279
280
        $em->persist($resourceNode);
281
        $em->persist($resource);
282
283
        $em->flush();
284
285
        return $resourceNode;
286
    }
287
288
    /**
289
     * @return ResourceFile|null
290
     */
291
    public function addFile(AbstractResource $resource, UploadedFile $file): ?ResourceFile
292
    {
293
        $resourceNode = $resource->getResourceNode();
294
295
        if (null === $resourceNode) {
296
            throw new \LogicException('Resource node is null');
297
        }
298
299
        $resourceFile = $resourceNode->getResourceFile();
300
        if (null === $resourceFile) {
301
            $resourceFile = new ResourceFile();
302
        }
303
304
        $em = $this->getEntityManager();
305
306
        $resourceFile->setFile($file);
307
        $resourceFile->setName($resource->getResourceName());
308
        $em->persist($resourceFile);
309
310
        $resourceNode->setResourceFile($resourceFile);
311
        $em->persist($resourceNode);
312
313
        return $resourceFile;
314
    }
315
316
    /**
317
     * @param AbstractResource      $resource
318
     * @param User                  $creator
319
     * @param AbstractResource|null $parent
320
     *
321
     * @return ResourceNode
322
     */
323
    public function addResourceNode(AbstractResource $resource, User $creator, AbstractResource $parent = null): ResourceNode
324
    {
325
        if (null !== $parent) {
326
            $parent = $parent->getResourceNode();
327
        }
328
329
        return $this->createNodeForResource($resource, $creator, $parent);
330
    }
331
332
    /**
333
     * @param AbstractResource $resource
334
     * @param int              $visibility
335
     * @param User             $creator
336
     * @param Course           $course
337
     * @param Session|null     $session
338
     * @param CGroupInfo|null  $group
339
     */
340
    public function addResourceToCourse(AbstractResource $resource, int $visibility, User $creator, Course $course, Session $session = null, CGroupInfo $group = null)
341
    {
342
        $node = $this->createNodeForResource($resource, $creator, $course->getResourceNode());
343
344
        $this->addResourceNodeToCourse($node, $visibility, $course, $session, $group);
345
    }
346
347
    /**
348
     * @param ResourceNode $resourceNode
349
     * @param int          $visibility
350
     * @param Course       $course
351
     * @param Session      $session
352
     * @param CGroupInfo   $group
353
     */
354
    public function addResourceNodeToCourse(ResourceNode $resourceNode, $visibility, $course, $session, $group): void
355
    {
356
        $visibility = (int) $visibility;
357
        if (empty($visibility)) {
358
            $visibility = ResourceLink::VISIBILITY_PUBLISHED;
359
        }
360
361
        $link = new ResourceLink();
362
        $link
363
            ->setCourse($course)
364
            ->setSession($session)
365
            ->setGroup($group)
366
            //->setUser($toUser)
367
            ->setResourceNode($resourceNode)
368
            ->setVisibility($visibility)
369
        ;
370
371
        $rights = [];
372
        switch ($visibility) {
373
            case ResourceLink::VISIBILITY_PENDING:
374
            case ResourceLink::VISIBILITY_DRAFT:
375
                $editorMask = ResourceNodeVoter::getEditorMask();
376
                $resourceRight = new ResourceRight();
377
                $resourceRight
378
                    ->setMask($editorMask)
379
                    ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
380
                ;
381
                $rights[] = $resourceRight;
382
                break;
383
        }
384
385
        if (!empty($rights)) {
386
            foreach ($rights as $right) {
387
                $link->addResourceRight($right);
388
            }
389
        }
390
391
        $em = $this->getEntityManager();
392
        $em->persist($link);
393
    }
394
395
    /**
396
     * @return ResourceType
397
     */
398
    public function getResourceType()
399
    {
400
        $em = $this->getEntityManager();
401
        $entityName = $this->getRepository()->getClassName();
402
403
        return $em->getRepository('ChamiloCoreBundle:Resource\ResourceType')->findOneBy(
404
            ['entityName' => $entityName]
405
        );
406
    }
407
408
    public function addResourceToMe(ResourceNode $resourceNode): ResourceLink
409
    {
410
        $resourceLink = new ResourceLink();
411
        $resourceLink
412
            ->setResourceNode($resourceNode)
413
            ->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

413
            ->/** @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...
414
415
        $this->getEntityManager()->persist($resourceLink);
416
        $this->getEntityManager()->flush();
417
418
        return $resourceLink;
419
    }
420
421
    public function addResourceToEveryone(ResourceNode $resourceNode, ResourceRight $right): ResourceLink
422
    {
423
        $resourceLink = new ResourceLink();
424
        $resourceLink
425
            ->setResourceNode($resourceNode)
426
            ->addResourceRight($right)
427
        ;
428
429
        $this->getEntityManager()->persist($resourceLink);
430
        $this->getEntityManager()->flush();
431
432
        return $resourceLink;
433
    }
434
435
    public function addResourceToCourse2(ResourceNode $resourceNode, Course $course, ResourceRight $right): ResourceLink
436
    {
437
        $resourceLink = new ResourceLink();
438
        $resourceLink
439
            ->setResourceNode($resourceNode)
440
            ->setCourse($course)
441
            ->addResourceRight($right);
442
        $this->getEntityManager()->persist($resourceLink);
443
        $this->getEntityManager()->flush();
444
445
        return $resourceLink;
446
    }
447
448
    public function addResourceToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
449
    {
450
        $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
451
        $this->getEntityManager()->persist($resourceLink);
452
453
        return $resourceLink;
454
    }
455
456
    public function addResourceNodeToUser(ResourceNode $resourceNode, User $toUser): ResourceLink
457
    {
458
        $resourceLink = new ResourceLink();
459
        $resourceLink
460
            ->setResourceNode($resourceNode)
461
            ->setUser($toUser);
462
463
        return $resourceLink;
464
    }
465
466
    public function addResourceToSession(
467
        ResourceNode $resourceNode,
468
        Course $course,
469
        Session $session,
470
        ResourceRight $right
471
    ) {
472
        $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

472
        /** @scrutinizer ignore-call */ 
473
        $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...
473
            $resourceNode,
474
            $course,
475
            $right
476
        );
477
        $resourceLink->setSession($session);
478
        $this->getEntityManager()->persist($resourceLink);
479
480
        return $resourceLink;
481
    }
482
483
    /**
484
     * @return ResourceLink
485
     */
486
    public function addResourceToCourseGroup(
487
        ResourceNode $resourceNode,
488
        Course $course,
489
        CGroupInfo $group,
490
        ResourceRight $right
491
    ) {
492
        $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

492
        /** @scrutinizer ignore-call */ 
493
        $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...
493
            $resourceNode,
494
            $course,
495
            $right
496
        );
497
        $resourceLink->setGroup($group);
498
        $this->getEntityManager()->persist($resourceLink);
499
500
        return $resourceLink;
501
    }
502
503
    /**
504
     * @return ResourceLink
505
     */
506
    public function addResourceToGroup(
507
        ResourceNode $resourceNode,
508
        Usergroup $group,
509
        ResourceRight $right
510
    ) {
511
        $resourceLink = new ResourceLink();
512
        $resourceLink
513
            ->setResourceNode($resourceNode)
514
            ->setUserGroup($group)
515
            ->addResourceRight($right);
516
517
        return $resourceLink;
518
    }
519
520
    /**
521
     * @param array $userList User id list
522
     */
523
    public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
524
    {
525
        $em = $this->getEntityManager();
526
527
        if (!empty($userList)) {
528
            foreach ($userList as $userId) {
529
                $toUser = $em->getRepository('ChamiloUserBundle:User')->find($userId);
530
531
                $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
532
                $em->persist($resourceLink);
533
            }
534
        }
535
    }
536
537
    /**
538
     * @param Course          $course
539
     * @param Session|null    $session
540
     * @param CGroupInfo|null $group
541
     *
542
     * @return QueryBuilder
543
     */
544
    public function getResourcesByCourse(Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null)
545
    {
546
        $repo = $this->getRepository();
547
        $className = $repo->getClassName();
548
        $checker = $this->getAuthorizationChecker();
549
550
        // Check if this resource type requires to load the base course resources when using a session
551
        $loadBaseSessionContent = $repo->getClassMetadata()->getReflectionClass()->hasProperty(
552
            'loadCourseResourcesInSession'
553
        );
554
        $type = $this->getResourceType();
555
556
        $qb = $repo->getEntityManager()->createQueryBuilder()
557
            ->select('resource')
558
            ->from($className, 'resource')
559
            ->innerJoin(
560
                ResourceNode::class,
561
                'node',
562
                Join::WITH,
563
                'resource.resourceNode = node.id'
564
            )
565
            ->innerJoin('node.resourceLinks', 'links')
566
            ->where('node.resourceType = :type')
567
            ->andWhere('links.course = :course')
568
            ->setParameters(
569
                [
570
                    'type' => $type,
571
                    'course' => $course,
572
                ]
573
            );
574
575
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
576
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
577
578
        if (false === $isAdmin) {
579
            $qb
580
                ->andWhere('links.visibility = :visibility')
581
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
582
            ;
583
            // @todo Add start/end visibility restrictrions
584
        }
585
586
        if (null === $session) {
587
            $qb->andWhere('links.session IS NULL');
588
        } else {
589
            if ($loadBaseSessionContent) {
590
                // Load course base content.
591
                $qb->andWhere('links.session = :session OR links.session IS NULL');
592
                $qb->setParameter('session', $session);
593
            } else {
594
                // Load only session resources.
595
                $qb->andWhere('links.session = :session');
596
                $qb->setParameter('session', $session);
597
            }
598
        }
599
600
        if (null !== $parentNode) {
601
            $qb->andWhere('node.parent = :parentNode');
602
            $qb->setParameter('parentNode', $parentNode);
603
        }
604
605
        if (null === $group) {
606
            $qb->andWhere('links.group IS NULL');
607
        }
608
609
        //echo ($qb->getQuery()->getSQL());exit;
610
611
        return $qb;
612
    }
613
614
    /**
615
     * @param RowAction $action
616
     * @param Row       $row
617
     * @param Session   $session
618
     *
619
     * @return RowAction|null
620
     */
621
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
622
    {
623
        if (null !== $session) {
624
            /** @var AbstractResource $entity */
625
            $entity = $row->getEntity();
626
            $hasSession = $entity->getResourceNode()->hasSession($session);
627
            if ($hasSession->count() > 0) {
628
                return $action;
629
            }
630
631
            return null;
632
        }
633
634
        return $action;
635
    }
636
637
    /**
638
     * @param string $tool
639
     *
640
     * @return Tool|null
641
     */
642
    private function getTool($tool)
643
    {
644
        return $this
645
            ->getEntityManager()
646
            ->getRepository('ChamiloCoreBundle:Tool')
647
            ->findOneBy(['name' => $tool]);
648
    }
649
650
    /**
651
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
652
     * ResourceLinks and ResourceFile (including files via Flysystem).
653
     */
654
    public function hardDelete(AbstractResource $resource)
655
    {
656
        $em = $this->getEntityManager();
657
        $em->remove($resource);
658
        $em->flush();
659
    }
660
661
    /**
662
     * Change all links visibility to DELETED.
663
     */
664
    public function softDelete(AbstractResource $resource)
665
    {
666
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
667
    }
668
669
    /**
670
     * @param AbstractResource $resource
671
     */
672
    public function setVisibilityPublished(AbstractResource $resource)
673
    {
674
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
675
    }
676
677
    /**
678
     * @param AbstractResource $resource
679
     */
680
    public function setVisibilityDraft(AbstractResource $resource)
681
    {
682
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
683
    }
684
685
    /**
686
     * @param AbstractResource $resource
687
     */
688
    public function setVisibilityPending(AbstractResource $resource)
689
    {
690
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
691
    }
692
693
    /**
694
     * @param AbstractResource $resource
695
     * @param int              $visibility
696
     * @param bool             $recursive
697
     *
698
     * @return bool
699
     */
700
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
701
    {
702
        $resourceNode = $resource->getResourceNode();
703
704
        if (null === $resourceNode) {
705
            return false;
706
        }
707
708
        $em = $this->getEntityManager();
709
        if ($recursive) {
710
            $children = $resourceNode->getChildren();
711
            if (!empty($children)) {
712
                /** @var ResourceNode $child */
713
                foreach ($children as $child) {
714
                    $criteria = ['resourceNode' => $child];
715
                    $childDocument = $this->getRepository()->findOneBy($criteria);
716
                    if ($childDocument) {
717
                        $this->setLinkVisibility($childDocument, $visibility);
718
                    }
719
                }
720
            }
721
        }
722
723
        $links = $resourceNode->getResourceLinks();
724
725
        if (!empty($links)) {
726
            /** @var ResourceLink $link */
727
            foreach ($links as $link) {
728
                $link->setVisibility($visibility);
729
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
730
                    $editorMask = ResourceNodeVoter::getEditorMask();
731
                    $rights = [];
732
                    $resourceRight = new ResourceRight();
733
                    $resourceRight
734
                        ->setMask($editorMask)
735
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
736
                        ->setResourceLink($link)
737
                    ;
738
                    $rights[] = $resourceRight;
739
740
                    if (!empty($rights)) {
741
                        $link->setResourceRight($rights);
742
                    }
743
                } else {
744
                    $link->setResourceRight([]);
745
                }
746
                $em->persist($link);
747
            }
748
        }
749
        $em->flush();
750
751
        return true;
752
    }
753
754
    /**
755
     * @param AbstractResource $resource
756
     *
757
     * @return string
758
     */
759
    public function getResourceFileContent(AbstractResource $resource): string
760
    {
761
        try {
762
            $resourceNode = $resource->getResourceNode();
763
            if ($resourceNode->hasResourceFile()) {
764
                $resourceFile = $resourceNode->getResourceFile();
765
                $fileName = $resourceFile->getFile()->getPathname();
766
767
                return $this->fs->read($fileName);
768
            }
769
770
            return '';
771
        } catch (\Throwable $exception) {
772
            throw new FileNotFoundException($resource);
773
        }
774
    }
775
776
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = []): string
777
    {
778
        try {
779
            $resourceNode = $resource->getResourceNode();
780
            if ($resourceNode->hasResourceFile()) {
781
                $params = [
782
                    'tool' => $resourceNode->getResourceType()->getTool(),
783
                    'type' => $resourceNode->getResourceType(),
784
                    'id' => $resourceNode->getId(),
785
                ];
786
787
                if (!empty($extraParams)) {
788
                    $params = array_merge($params, $extraParams);
789
                }
790
791
                return $this->router->generate('chamilo_core_resource_file', $params);
792
            }
793
794
            return '';
795
        } catch (\Throwable $exception) {
796
            throw new FileNotFoundException($resource);
797
        }
798
    }
799
800
    /**
801
     * @param AbstractResource $resource
802
     * @param string $content
803
     *
804
     * @return bool
805
     */
806
    public function updateResourceFileContent(AbstractResource $resource, $content)
807
    {
808
        try {
809
            $resourceNode = $resource->getResourceNode();
810
            if ($resourceNode->hasResourceFile()) {
811
                $resourceFile = $resourceNode->getResourceFile();
812
                $fileName = $resourceFile->getFile()->getPathname();
813
814
                $this->fs->update($fileName, $content);
815
                $size = $this->fs->getSize($fileName);
816
                $resource->setSize($size);
817
                $this->entityManager->persist($resource);
818
819
                return true;
820
            }
821
822
            return false;
823
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
824
        }
825
    }
826
827
}
828