Completed
Push — master ( 0c649e...1ec116 )
by Julito
08:09
created

ResourceRepository::addResourceNodeParent()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 21
nc 4
nop 3
dl 0
loc 33
rs 9.584
c 0
b 0
f 0
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
        /*$em->persist($resourceNode);
314
        $em->flush();*/
315
316
        return $resourceFile;
317
    }
318
319
    /**
320
     * @param AbstractResource      $resource
321
     * @param User                  $creator
322
     * @param AbstractResource|null $parent
323
     *
324
     * @return ResourceNode
325
     */
326
    public function addResourceNode(AbstractResource $resource, User $creator, AbstractResource $parent = null): ResourceNode
327
    {
328
        if (null !== $parent) {
329
            $parent = $parent->getResourceNode();
330
        }
331
332
        return $this->createNodeForResource($resource, $creator, $parent);
333
    }
334
335
    /**
336
     * @param AbstractResource $resource
337
     * @param int              $visibility
338
     * @param User             $creator
339
     * @param Course           $course
340
     * @param Session|null     $session
341
     * @param CGroupInfo|null  $group
342
     */
343
    public function addResourceToCourse(AbstractResource $resource, int $visibility, User $creator, Course $course, Session $session = null, CGroupInfo $group = null)
344
    {
345
        $node = $this->addResourceNode($resource, $creator, $course);
346
        $this->addResourceNodeToCourse($node, $visibility, $course, $session, $group);
347
    }
348
349
    /**
350
     * @param ResourceNode $resourceNode
351
     * @param int          $visibility
352
     * @param Course       $course
353
     * @param Session      $session
354
     * @param CGroupInfo   $group
355
     */
356
    public function addResourceNodeToCourse(ResourceNode $resourceNode, $visibility, $course, $session, $group): void
357
    {
358
        $visibility = (int) $visibility;
359
        if (empty($visibility)) {
360
            $visibility = ResourceLink::VISIBILITY_PUBLISHED;
361
        }
362
363
        $link = new ResourceLink();
364
        $link
365
            ->setCourse($course)
366
            ->setSession($session)
367
            ->setGroup($group)
368
            //->setUser($toUser)
369
            ->setResourceNode($resourceNode)
370
            ->setVisibility($visibility)
371
        ;
372
373
        $rights = [];
374
        switch ($visibility) {
375
            case ResourceLink::VISIBILITY_PENDING:
376
            case ResourceLink::VISIBILITY_DRAFT:
377
                $editorMask = ResourceNodeVoter::getEditorMask();
378
                $resourceRight = new ResourceRight();
379
                $resourceRight
380
                    ->setMask($editorMask)
381
                    ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
382
                ;
383
                $rights[] = $resourceRight;
384
                break;
385
        }
386
387
        if (!empty($rights)) {
388
            foreach ($rights as $right) {
389
                $link->addResourceRight($right);
390
            }
391
        }
392
393
        $em = $this->getEntityManager();
394
        $em->persist($link);
395
    }
396
397
    /**
398
     * @return ResourceType
399
     */
400
    public function getResourceType()
401
    {
402
        $em = $this->getEntityManager();
403
        $entityName = $this->getRepository()->getClassName();
404
405
        return $em->getRepository('ChamiloCoreBundle:Resource\ResourceType')->findOneBy(
406
            ['entityName' => $entityName]
407
        );
408
    }
409
410
    public function addResourceToMe(ResourceNode $resourceNode): ResourceLink
411
    {
412
        $resourceLink = new ResourceLink();
413
        $resourceLink
414
            ->setResourceNode($resourceNode)
415
            ->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

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

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

494
        /** @scrutinizer ignore-call */ 
495
        $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...
495
            $resourceNode,
496
            $course,
497
            $right
498
        );
499
        $resourceLink->setGroup($group);
500
        $this->getEntityManager()->persist($resourceLink);
501
502
        return $resourceLink;
503
    }
504
505
    /**
506
     * @return ResourceLink
507
     */
508
    public function addResourceToGroup(
509
        ResourceNode $resourceNode,
510
        Usergroup $group,
511
        ResourceRight $right
512
    ) {
513
        $resourceLink = new ResourceLink();
514
        $resourceLink
515
            ->setResourceNode($resourceNode)
516
            ->setUserGroup($group)
517
            ->addResourceRight($right);
518
519
        return $resourceLink;
520
    }
521
522
    /**
523
     * @param array $userList User id list
524
     */
525
    public function addResourceToUserList(ResourceNode $resourceNode, array $userList)
526
    {
527
        $em = $this->getEntityManager();
528
529
        if (!empty($userList)) {
530
            foreach ($userList as $userId) {
531
                $toUser = $em->getRepository('ChamiloUserBundle:User')->find($userId);
532
533
                $resourceLink = $this->addResourceNodeToUser($resourceNode, $toUser);
534
                $em->persist($resourceLink);
535
            }
536
        }
537
    }
538
539
    /**
540
     * @param Course          $course
541
     * @param Session|null    $session
542
     * @param CGroupInfo|null $group
543
     *
544
     * @return QueryBuilder
545
     */
546
    public function getResourcesByCourse(Course $course, Session $session = null, CGroupInfo $group = null, ResourceNode $parentNode = null)
547
    {
548
        $repo = $this->getRepository();
549
        $className = $repo->getClassName();
550
        $checker = $this->getAuthorizationChecker();
551
552
        // Check if this resource type requires to load the base course resources when using a session
553
        $loadBaseSessionContent = $repo->getClassMetadata()->getReflectionClass()->hasProperty(
554
            'loadCourseResourcesInSession'
555
        );
556
        $type = $this->getResourceType();
557
558
        $qb = $repo->getEntityManager()->createQueryBuilder()
559
            ->select('resource')
560
            ->from($className, 'resource')
561
            ->innerJoin(
562
                ResourceNode::class,
563
                'node',
564
                Join::WITH,
565
                'resource.resourceNode = node.id'
566
            )
567
            ->innerJoin('node.resourceLinks', 'links')
568
            ->where('node.resourceType = :type')
569
            ->andWhere('links.course = :course')
570
            ->setParameters(
571
                [
572
                    'type' => $type,
573
                    'course' => $course,
574
                ]
575
            );
576
577
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
578
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
579
580
        if (false === $isAdmin) {
581
            $qb
582
                ->andWhere('links.visibility = :visibility')
583
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
584
            ;
585
            // @todo Add start/end visibility restrictrions
586
        }
587
588
        if (null === $session) {
589
            $qb->andWhere('links.session IS NULL');
590
        } else {
591
            if ($loadBaseSessionContent) {
592
                // Load course base content.
593
                $qb->andWhere('links.session = :session OR links.session IS NULL');
594
                $qb->setParameter('session', $session);
595
            } else {
596
                // Load only session resources.
597
                $qb->andWhere('links.session = :session');
598
                $qb->setParameter('session', $session);
599
            }
600
        }
601
602
        if (null !== $parentNode) {
603
            $qb->andWhere('node.parent = :parentNode');
604
            $qb->setParameter('parentNode', $parentNode);
605
        }
606
607
        if (null === $group) {
608
            $qb->andWhere('links.group IS NULL');
609
        }
610
611
        //echo ($qb->getQuery()->getSQL());exit;
612
613
        return $qb;
614
    }
615
616
    /**
617
     * @param RowAction $action
618
     * @param Row       $row
619
     * @param Session   $session
620
     *
621
     * @return RowAction|null
622
     */
623
    public function rowCanBeEdited(RowAction $action, Row $row, Session $session = null): ?RowAction
624
    {
625
        if (null !== $session) {
626
            /** @var AbstractResource $entity */
627
            $entity = $row->getEntity();
628
            $hasSession = $entity->getResourceNode()->hasSession($session);
629
            if ($hasSession->count() > 0) {
630
                return $action;
631
            }
632
633
            return null;
634
        }
635
636
        return $action;
637
    }
638
639
    /**
640
     * @param string $tool
641
     *
642
     * @return Tool|null
643
     */
644
    private function getTool($tool)
0 ignored issues
show
Unused Code introduced by
The method getTool() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
645
    {
646
        return $this
647
            ->getEntityManager()
648
            ->getRepository('ChamiloCoreBundle:Tool')
649
            ->findOneBy(['name' => $tool]);
650
    }
651
652
    /**
653
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
654
     * ResourceLinks and ResourceFile (including files via Flysystem).
655
     */
656
    public function hardDelete(AbstractResource $resource)
657
    {
658
        $em = $this->getEntityManager();
659
        $em->remove($resource);
660
        $em->flush();
661
    }
662
663
    /**
664
     * Change all links visibility to DELETED.
665
     */
666
    public function softDelete(AbstractResource $resource)
667
    {
668
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
669
    }
670
671
    /**
672
     * @param AbstractResource $resource
673
     */
674
    public function setVisibilityPublished(AbstractResource $resource)
675
    {
676
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
677
    }
678
679
    /**
680
     * @param AbstractResource $resource
681
     */
682
    public function setVisibilityDraft(AbstractResource $resource)
683
    {
684
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
685
    }
686
687
    /**
688
     * @param AbstractResource $resource
689
     */
690
    public function setVisibilityPending(AbstractResource $resource)
691
    {
692
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
693
    }
694
695
    /**
696
     * @param AbstractResource $resource
697
     * @param                  $visibility
698
     * @param bool             $recursive
699
     *
700
     * @return bool
701
     */
702
    private function setLinkVisibility(AbstractResource $resource, $visibility, $recursive = true)
703
    {
704
        $resourceNode = $resource->getResourceNode();
705
706
        if (null === $resourceNode) {
707
            return false;
708
        }
709
710
        $em = $this->getEntityManager();
711
        if ($recursive) {
712
            $children = $resourceNode->getChildren();
713
            if (!empty($children)) {
714
                /** @var ResourceNode $child */
715
                foreach ($children as $child) {
716
                    $criteria = ['resourceNode' => $child];
717
                    $childDocument = $this->getRepository()->findOneBy($criteria);
718
                    if ($childDocument) {
719
                        $this->setLinkVisibility($childDocument, $visibility);
720
                    }
721
                }
722
            }
723
        }
724
725
        $links = $resourceNode->getResourceLinks();
726
727
        if (!empty($links)) {
728
            /** @var ResourceLink $link */
729
            foreach ($links as $link) {
730
                $link->setVisibility($visibility);
731
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
732
                    $editorMask = ResourceNodeVoter::getEditorMask();
733
                    $rights = [];
734
                    $resourceRight = new ResourceRight();
735
                    $resourceRight
736
                        ->setMask($editorMask)
737
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
738
                        ->setResourceLink($link)
739
                    ;
740
                    $rights[] = $resourceRight;
741
742
                    if (!empty($rights)) {
743
                        $link->setResourceRight($rights);
744
                    }
745
                } else {
746
                    $link->setResourceRight([]);
747
                }
748
                $em->persist($link);
749
            }
750
        }
751
        $em->flush();
752
753
        return true;
754
    }
755
756
    /**
757
     * @param AbstractResource $resource
758
     *
759
     * @return string
760
     */
761
    public function getResourceFileContent(AbstractResource $resource): string
762
    {
763
        try {
764
            $resourceNode = $resource->getResourceNode();
765
            if ($resourceNode->hasResourceFile()) {
766
                $resourceFile = $resourceNode->getResourceFile();
767
                $fileName = $resourceFile->getFile()->getPathname();
768
769
                return $this->fs->read($fileName);
770
            }
771
772
            return '';
773
        } catch (\Throwable $exception) {
774
            throw new FileNotFoundException($id);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $id seems to be never defined.
Loading history...
775
        }
776
    }
777
778
    /**
779
     * @param AbstractResource $resource
780
     * @param string $content
781
     *
782
     * @return bool
783
     */
784
    public function updateResourceFileContent(AbstractResource $resource, $content)
785
    {
786
        try {
787
            $resourceNode = $resource->getResourceNode();
788
            if ($resourceNode->hasResourceFile()) {
789
                $resourceFile = $resourceNode->getResourceFile();
790
                $fileName = $resourceFile->getFile()->getPathname();
791
792
                $this->fs->update($fileName, $content);
793
                $size = $this->fs->getSize($fileName);
794
                $resource->setSize($size);
795
                $this->entityManager->persist($resource);
796
797
                return true;
798
            }
799
800
            return false;
801
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
802
        }
803
    }
804
805
}
806