Passed
Push — master ( 1f4f67...9a61c2 )
by Julito
11:21
created

ResourceRepository::addResourceNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 3
dl 0
loc 7
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 Chamilo\CoreBundle\Component\Resource\Settings;
8
use Chamilo\CoreBundle\Component\Resource\Template;
9
use Chamilo\CoreBundle\Entity\AbstractResource;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\ResourceFile;
12
use Chamilo\CoreBundle\Entity\ResourceInterface;
13
use Chamilo\CoreBundle\Entity\ResourceLink;
14
use Chamilo\CoreBundle\Entity\ResourceNode;
15
use Chamilo\CoreBundle\Entity\ResourceRight;
16
use Chamilo\CoreBundle\Entity\ResourceType;
17
use Chamilo\CoreBundle\Entity\Session;
18
use Chamilo\CoreBundle\Entity\User;
19
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
20
use Chamilo\CoreBundle\ToolChain;
21
use Chamilo\CourseBundle\Entity\CGroup;
22
use Cocur\Slugify\SlugifyInterface;
23
use Doctrine\ORM\EntityManager;
24
use Doctrine\ORM\EntityRepository;
25
use Doctrine\ORM\QueryBuilder;
26
use League\Flysystem\FilesystemInterface;
27
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
28
use Symfony\Component\Form\FormFactory;
29
use Symfony\Component\Form\FormInterface;
30
use Symfony\Component\HttpFoundation\File\UploadedFile;
31
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
32
use Symfony\Component\Routing\RouterInterface;
33
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
34
35
/**
36
 * Class ResourceRepository.
37
 * Extends EntityRepository is needed to process settings.
38
 */
39
class ResourceRepository extends EntityRepository
40
{
41
    /**
42
     * @var EntityRepository
43
     */
44
    protected $repository;
45
46
    /**
47
     * @var FilesystemInterface
48
     */
49
    protected $fs;
50
51
    /**
52
     * @var EntityManager
53
     */
54
    protected $entityManager;
55
56
    /**
57
     * The entity class FQN.
58
     *
59
     * @var string
60
     */
61
    protected $className;
62
63
    /** @var RouterInterface */
64
    protected $router;
65
66
    /** @var ResourceNodeRepository */
67
    protected $resourceNodeRepository;
68
69
    /**
70
     * @var AuthorizationCheckerInterface
71
     */
72
    protected $authorizationChecker;
73
74
    /** @var SlugifyInterface */
75
    protected $slugify;
76
77
    /** @var ToolChain */
78
    protected $toolChain;
79
    protected $settings;
80
    protected $templates;
81
    protected $resourceType;
82
83
    /**
84
     * ResourceRepository constructor.
85
     */
86
    public function __construct(
87
        AuthorizationCheckerInterface $authorizationChecker,
88
        EntityManager $entityManager,
89
        RouterInterface $router,
90
        SlugifyInterface $slugify,
91
        ToolChain $toolChain,
92
        ResourceNodeRepository $resourceNodeRepository
93
    ) {
94
        $className = $this->getClassName();
95
        $this->repository = $entityManager->getRepository($className);
96
        $this->authorizationChecker = $authorizationChecker;
97
        $this->router = $router;
98
        $this->resourceNodeRepository = $resourceNodeRepository;
99
        $this->slugify = $slugify;
100
        $this->toolChain = $toolChain;
101
        $this->settings = new Settings();
102
        $this->templates = new Template();
103
    }
104
105
    public function getClassName()
106
    {
107
        $class = get_class($this);
108
        //Chamilo\CoreBundle\Repository\IllustrationRepository
109
        $class = str_replace('\\Repository\\', '\\Entity\\', $class);
110
        $class = str_replace('Repository', '', $class);
111
        if (false === class_exists($class)) {
112
            throw new \Exception("Repo: $class not found ");
113
        }
114
115
        return $class;
116
    }
117
118
    public function getAuthorizationChecker(): AuthorizationCheckerInterface
119
    {
120
        return $this->authorizationChecker;
121
    }
122
123
    /**
124
     * @return AbstractResource
125
     */
126
    public function create()
127
    {
128
        $class = $this->repository->getClassName();
129
130
        return new $class();
131
    }
132
133
    public function getRouter(): RouterInterface
134
    {
135
        return $this->router;
136
    }
137
138
    /**
139
     * @return ResourceNodeRepository
140
     */
141
    public function getResourceNodeRepository()
142
    {
143
        return $this->resourceNodeRepository;
144
    }
145
146
    public function getEntityManager(): EntityManager
147
    {
148
        return $this->getRepository()->getEntityManager();
149
    }
150
151
    /**
152
     * @return EntityRepository
153
     */
154
    public function getRepository()
155
    {
156
        return $this->repository;
157
    }
158
159
    /**
160
     * @return FormInterface
161
     */
162
    public function getForm(FormFactory $formFactory, AbstractResource $resource = null, $options = [])
163
    {
164
        $formType = $this->getResourceFormType();
165
166
        if (null === $resource) {
167
            $className = $this->repository->getClassName();
168
            $resource = new $className();
169
        }
170
171
        return $formFactory->create($formType, $resource, $options);
172
    }
173
174
    /**
175
     * @param null $lockMode
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $lockMode is correct as it would always require null to be passed?
Loading history...
176
     * @param null $lockVersion
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $lockVersion is correct as it would always require null to be passed?
Loading history...
177
     *
178
     * @return ResourceInterface
179
     */
180
    public function find($id, $lockMode = null, $lockVersion = null)
181
    {
182
        return $this->getRepository()->find($id, $lockMode, $lockVersion);
183
    }
184
185
    public function getResourceByResourceNode(ResourceNode $resourceNode)
186
    {
187
        return $this->getRepository()->findOneBy(['resourceNode' => $resourceNode]);
188
    }
189
190
    public function findOneBy(array $criteria, array $orderBy = null)
191
    {
192
        return $this->getRepository()->findOneBy($criteria, $orderBy);
193
    }
194
195
    /*public function updateResource(AbstractResource $resource)
196
    {
197
        $em = $this->getEntityManager();
198
199
        $resourceNode = $resource->getResourceNode();
200
        $resourceNode->setTitle($resource->getResourceName());
201
202
        $links = $resource->getResourceLinkEntityList();
203
        if ($links) {
204
            foreach ($links as $link) {
205
                $link->setResourceNode($resourceNode);
206
207
                $rights = [];
208
                switch ($link->getVisibility()) {
209
                    case ResourceLink::VISIBILITY_PENDING:
210
                    case ResourceLink::VISIBILITY_DRAFT:
211
                        $editorMask = ResourceNodeVoter::getEditorMask();
212
                        $resourceRight = new ResourceRight();
213
                        $resourceRight
214
                            ->setMask($editorMask)
215
                            ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
216
                        ;
217
                        $rights[] = $resourceRight;
218
219
                        break;
220
                }
221
222
                if (!empty($rights)) {
223
                    foreach ($rights as $right) {
224
                        $link->addResourceRight($right);
225
                    }
226
                }
227
                $em->persist($link);
228
            }
229
        }
230
231
        $em->persist($resourceNode);
232
        $em->persist($resource);
233
        $em->flush();
234
    }*/
235
236
    public function update(AbstractResource $resource): void
237
    {
238
        $resource->getResourceNode()->setTitle($resource->getResourceName());
239
240
        $this->getEntityManager()->persist($resource);
241
        $this->getEntityManager()->flush();
242
    }
243
244
    public function updateNodeForResource(ResourceInterface $resource): ResourceNode
245
    {
246
        $em = $this->getEntityManager();
247
248
        $resourceNode = $resource->getResourceNode();
249
        $resourceName = $resource->getResourceName();
250
251
        if ($resourceNode->hasResourceFile()) {
252
            $resourceFile = $resourceNode->getResourceFile();
253
            if ($resourceFile) {
0 ignored issues
show
introduced by
$resourceFile is of type Chamilo\CoreBundle\Entity\ResourceFile, thus it always evaluated to true.
Loading history...
254
                $originalName = $resourceFile->getOriginalName();
255
                $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
256
257
                //$originalBasename = \basename($resourceName, $originalExtension);
258
                /*$slug = sprintf(
259
                    '%s.%s',
260
                    $this->slugify->slugify($originalBasename),
261
                    $this->slugify->slugify($originalExtension)
262
                );*/
263
264
                $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
265
                $resourceFile->setOriginalName($newOriginalName);
266
267
                $em->persist($resourceFile);
268
            }
269
        } else {
270
            //$slug = $this->slugify->slugify($resourceName);
271
        }
272
273
        $resourceNode->setTitle($resourceName);
274
        //$resourceNode->setSlug($slug);
275
276
        $em->persist($resourceNode);
277
        $em->persist($resource);
278
279
        $em->flush();
280
281
        return $resourceNode;
282
    }
283
284
    public function addFile(ResourceInterface $resource, UploadedFile $file): ?ResourceFile
285
    {
286
        $resourceNode = $resource->getResourceNode();
287
288
        if (null === $resourceNode) {
289
            throw new \LogicException('Resource node is null');
290
        }
291
292
        $resourceFile = $resourceNode->getResourceFile();
293
        if (null === $resourceFile) {
294
            $resourceFile = new ResourceFile();
295
        }
296
297
        $em = $this->getEntityManager();
298
        $resourceFile->setFile($file);
299
        $resourceFile->setName($resource->getResourceName());
300
        $em->persist($resourceFile);
301
302
        $resourceNode->setResourceFile($resourceFile);
303
        $em->persist($resourceNode);
304
305
        return $resourceFile;
306
    }
307
308
    public function addResourceNode(AbstractResource $resource, User $creator, AbstractResource $parent = null): ResourceNode
309
    {
310
        if (null !== $parent) {
311
            $parent = $parent->getResourceNode();
312
        }
313
314
        return $this->createNodeForResource($resource, $creator, $parent);
315
    }
316
317
    /**
318
     * @return ResourceType
319
     */
320
    public function getResourceType()
321
    {
322
        $name = $this->getResourceTypeName();
323
        $repo = $this->getEntityManager()->getRepository(ResourceType::class);
324
        $this->resourceType = $repo->findOneBy(['name' => $name]);
325
326
        return $this->resourceType;
327
    }
328
329
    public function getResourceTypeName(): string
330
    {
331
        return $this->toolChain->getResourceTypeNameFromRepository(get_class($this));
332
    }
333
334
    public function getResourcesByCourse(Course $course, Session $session = null, CGroup $group = null, ResourceNode $parentNode = null): QueryBuilder
335
    {
336
        $repo = $this->getRepository();
337
        $className = $repo->getClassName();
338
        $checker = $this->getAuthorizationChecker();
339
        $reflectionClass = $repo->getClassMetadata()->getReflectionClass();
340
341
        // Check if this resource type requires to load the base course resources when using a session
342
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
343
        $resourceTypeName = $this->getResourceTypeName();
344
345
        $qb = $repo->getEntityManager()->createQueryBuilder()
346
            ->select('resource')
347
            ->from($className, 'resource')
348
            ->innerJoin('resource.resourceNode', 'node')
349
            ->innerJoin('node.resourceLinks', 'links')
350
            ->innerJoin('node.resourceType', 'type')
351
            ->leftJoin('node.resourceFile', 'file')
352
353
            ->where('type.name = :type')
354
            ->setParameter('type', $resourceTypeName)
355
            ->andWhere('links.course = :course')
356
            ->setParameter('course', $course)
357
            ->addSelect('node')
358
            ->addSelect('links')
359
            //->addSelect('course')
360
            ->addSelect('type')
361
            ->addSelect('file')
362
        ;
363
364
        $isAdmin =
365
            $checker->isGranted('ROLE_ADMIN') ||
366
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
367
368
        // Do not show deleted resources.
369
        $qb
370
            ->andWhere('links.visibility != :visibilityDeleted')
371
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
372
        ;
373
374
        if (false === $isAdmin) {
375
            $qb
376
                ->andWhere('links.visibility = :visibility')
377
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
378
            ;
379
            // @todo Add start/end visibility restrictions.
380
        }
381
382
        if (null === $session) {
383
            $qb->andWhere(
384
                $qb->expr()->orX(
385
                    $qb->expr()->isNull('links.session'),
386
                    $qb->expr()->eq('links.session', 0)
387
                )
388
            );
389
        } else {
390
            if ($loadBaseSessionContent) {
391
                // Load course base content.
392
                $qb->andWhere('links.session = :session OR links.session IS NULL');
393
                $qb->setParameter('session', $session);
394
            } else {
395
                // Load only session resources.
396
                $qb->andWhere('links.session = :session');
397
                $qb->setParameter('session', $session);
398
            }
399
        }
400
401
        if (null !== $parentNode) {
402
            $qb->andWhere('node.parent = :parentNode');
403
            $qb->setParameter('parentNode', $parentNode);
404
        }
405
406
        if (null === $group) {
407
            $qb->andWhere(
408
                $qb->expr()->orX(
409
                    $qb->expr()->isNull('links.group'),
410
                    $qb->expr()->eq('links.group', 0)
411
                )
412
            );
413
        } else {
414
            $qb->andWhere('links.group = :group');
415
            $qb->setParameter('group', $group);
416
        }
417
418
        return $qb;
419
    }
420
421
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null)
422
    {
423
        $repo = $this->getRepository();
424
        $className = $repo->getClassName();
425
        $checker = $this->getAuthorizationChecker();
426
        $resourceTypeName = $this->getResourceTypeName();
427
428
        $qb = $repo->getEntityManager()->createQueryBuilder()
429
            ->select('resource')
430
            ->from($className, 'resource')
431
            ->innerJoin(
432
                'resource.resourceNode',
433
                'node'
434
            )
435
            ->innerJoin('node.resourceLinks', 'links')
436
            ->innerJoin('node.resourceType', 'type')
437
            ->where('type.name = :type')
438
            ->setParameter('type', $resourceTypeName)
439
            ->andWhere('links.course = :course')
440
            ->setParameter('course', $course)
441
        ;
442
443
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
444
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
445
446
        // Do not show deleted resources
447
        $qb
448
            ->andWhere('links.visibility != :visibilityDeleted')
449
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
450
        ;
451
452
        if (false === $isAdmin) {
453
            $qb
454
                ->andWhere('links.visibility = :visibility')
455
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
456
            ;
457
            // @todo Add start/end visibility restrictions
458
        }
459
460
        if (null !== $parentNode) {
461
            $qb->andWhere('node.parent = :parentNode');
462
            $qb->setParameter('parentNode', $parentNode);
463
        }
464
465
        return $qb;
466
    }
467
468
    /**
469
     * @return QueryBuilder
470
     */
471
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null)
472
    {
473
        $repo = $this->getRepository();
474
        $className = $repo->getClassName();
475
476
        $qb = $repo->getEntityManager()->createQueryBuilder()
477
            ->select('resource')
478
            ->from($className, 'resource')
479
            ->innerJoin(
480
                'resource.resourceNode',
481
                'node'
482
            )
483
            //->innerJoin('node.resourceLinks', 'links')
484
            //->where('node.resourceType = :type')
485
            //->setParameter('type',$type)
486
            ;
487
        /*$qb
488
            ->andWhere('links.visibility = :visibility')
489
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
490
        ;*/
491
492
        if (null !== $parentNode) {
493
            $qb->andWhere('node.parent = :parentNode');
494
            $qb->setParameter('parentNode', $parentNode);
495
        }
496
497
        $qb->andWhere('node.creator = :creator');
498
        $qb->setParameter('creator', $user);
499
500
        return $qb;
501
    }
502
503
    public function getResourcesByCourseLinkedToUser(
504
        User $user,
505
        Course $course,
506
        Session $session = null,
507
        CGroup $group = null,
508
        ResourceNode $parentNode = null
509
    ): QueryBuilder {
510
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
511
512
        $qb->andWhere('links.user = :user OR links.user IS NULL');
513
        $qb->setParameter('user', $user);
514
515
        return $qb;
516
    }
517
518
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
519
    {
520
        $repo = $this->getRepository();
521
        $className = $repo->getClassName();
522
        $checker = $this->getAuthorizationChecker();
523
        $resourceTypeName = $this->getResourceTypeName();
524
525
        $qb = $repo->getEntityManager()->createQueryBuilder()
526
            ->select('resource')
527
            ->from($className, 'resource')
528
            ->innerJoin(
529
                'resource.resourceNode',
530
                'node'
531
            )
532
            ->innerJoin('node.resourceLinks', 'links')
533
            ->innerJoin('node.resourceType', 'type')
534
            ->where('type.name = :type')
535
            ->setParameter('type', $resourceTypeName)
536
            ->andWhere('links.user = :user')
537
            ->setParameter('user', $user)
538
        ;
539
540
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
541
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
542
543
        // Do not show deleted resources
544
        $qb
545
            ->andWhere('links.visibility != :visibilityDeleted')
546
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
547
        ;
548
549
        if (false === $isAdmin) {
550
            $qb
551
                ->andWhere('links.visibility = :visibility')
552
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
553
            ;
554
            // @todo Add start/end visibility restrictrions
555
        }
556
557
        if (null !== $parentNode) {
558
            $qb->andWhere('node.parent = :parentNode');
559
            $qb->setParameter('parentNode', $parentNode);
560
        }
561
562
        return $qb;
563
    }
564
565
    public function getResourceFromResourceNode(int $resourceNodeId): ?AbstractResource
566
    {
567
        // Include links
568
        $qb = $this->getRepository()->createQueryBuilder('resource')
569
            ->select('resource')
570
            ->addSelect('node')
571
            ->addSelect('links')
572
            ->innerJoin('resource.resourceNode', 'node')
573
        //    ->innerJoin('node.creator', 'userCreator')
574
            ->innerJoin('node.resourceLinks', 'links')
575
//            ->leftJoin('node.resourceFile', 'file')
576
            ->where('node.id = :id')
577
            ->setParameters(['id' => $resourceNodeId])
578
            //->addSelect('node')
579
        ;
580
581
        return $qb->getQuery()->getOneOrNullResult();
582
    }
583
584
    public function delete(AbstractResource $resource)
585
    {
586
        $children = $resource->getResourceNode()->getChildren();
587
        foreach ($children as $child) {
588
            if ($child->hasResourceFile()) {
589
                $this->getEntityManager()->remove($child->getResourceFile());
590
            }
591
            $resourceNode = $this->getResourceFromResourceNode($child->getId());
592
            if ($resourceNode) {
593
                $this->delete($resourceNode);
594
            }
595
        }
596
        $this->getEntityManager()->remove($resource);
597
        $this->getEntityManager()->flush();
598
    }
599
600
    /**
601
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
602
     * ResourceLinks and ResourceFile (including files via Flysystem).
603
     */
604
    public function hardDelete(AbstractResource $resource)
605
    {
606
        $em = $this->getEntityManager();
607
        $em->remove($resource);
608
        $em->flush();
609
    }
610
611
    public function getResourceFileContent(AbstractResource $resource): string
612
    {
613
        try {
614
            $resourceNode = $resource->getResourceNode();
615
616
            return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
617
        } catch (\Throwable $exception) {
618
            throw new FileNotFoundException($resource);
619
        }
620
    }
621
622
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
623
    {
624
        return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
625
    }
626
627
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
628
    {
629
        return $this->resourceNodeRepository->getResourceNodeFileStream($resourceNode);
630
    }
631
632
    public function getResourceFileDownloadUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
633
    {
634
        $extraParams['mode'] = 'download';
635
636
        return $this->getResourceFileUrl($resource, $extraParams, $referenceType);
637
    }
638
639
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
640
    {
641
        try {
642
            $resourceNode = $resource->getResourceNode();
643
            if ($resourceNode->hasResourceFile()) {
644
                $params = [
645
                    'tool' => $resourceNode->getResourceType()->getTool(),
646
                    'type' => $resourceNode->getResourceType(),
647
                    'id' => $resourceNode->getId(),
648
                ];
649
650
                if (!empty($extraParams)) {
651
                    $params = array_merge($params, $extraParams);
652
                }
653
654
                $referenceType = $referenceType ?? UrlGeneratorInterface::ABSOLUTE_PATH;
655
656
                $mode = $params['mode'] ?? 'view';
657
                // Remove mode from params and sent directly to the controller.
658
                unset($params['mode']);
659
660
                switch ($mode) {
661
                    case 'download':
662
                        return $this->router->generate('chamilo_core_resource_download', $params, $referenceType);
663
                    case 'view':
664
                        return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
665
                }
666
            }
667
668
            return '';
669
        } catch (\Throwable $exception) {
670
            throw new FileNotFoundException($resource);
671
        }
672
    }
673
674
    public function getResourceSettings(): Settings
675
    {
676
        return $this->settings;
677
    }
678
679
    public function getTemplates(): Template
680
    {
681
        return $this->templates;
682
    }
683
684
    /**
685
     * @param string $content
686
     *
687
     * @return bool
688
     */
689
    public function updateResourceFileContent(AbstractResource $resource, $content)
690
    {
691
        error_log('updateResourceFileContent');
692
693
        $resourceNode = $resource->getResourceNode();
694
        if ($resourceNode->hasResourceFile()) {
695
            error_log('has file');
696
            $resourceFile = $resourceNode->getResourceFile();
697
            if ($resourceFile) {
0 ignored issues
show
introduced by
$resourceFile is of type Chamilo\CoreBundle\Entity\ResourceFile, thus it always evaluated to true.
Loading history...
698
                error_log('$resourceFile');
699
                $title = $resource->getResourceName();
700
                $handle = tmpfile();
701
                fwrite($handle, $content);
702
                error_log($title);
703
                error_log($content);
704
                $meta = stream_get_meta_data($handle);
705
                $file = new UploadedFile($meta['uri'], $title, 'text/html', null, true);
706
                $resource->setUploadFile($file);
707
708
                return true;
709
            }
710
        }
711
        error_log('false');
712
713
        return false;
714
    }
715
716
    public function setResourceName(AbstractResource $resource, $title)
717
    {
718
        $resource->setResourceName($title);
719
        $resourceNode = $resource->getResourceNode();
720
        $resourceNode->setTitle($title);
721
        if ($resourceNode->hasResourceFile()) {
722
            //$resourceNode->getResourceFile()->getFile()->
723
            //$resourceNode->getResourceFile()->setName($title);
724
            //$resourceFile->setName($title);
725
726
            /*$fileName = $this->getResourceNodeRepository()->getFilename($resourceFile);
727
            error_log('$fileName');
728
            error_log($fileName);
729
            error_log($title);
730
            $this->getResourceNodeRepository()->getFileSystem()->rename($fileName, $title);
731
            $resourceFile->setName($title);
732
            $resourceFile->setOriginalName($title);*/
733
        }
734
    }
735
736
    /**
737
     * Change all links visibility to DELETED.
738
     */
739
    public function softDelete(AbstractResource $resource)
740
    {
741
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
742
    }
743
744
    public function setVisibilityPublished(AbstractResource $resource)
745
    {
746
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
747
    }
748
749
    public function setVisibilityDeleted(AbstractResource $resource)
750
    {
751
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
752
    }
753
754
    public function setVisibilityDraft(AbstractResource $resource)
755
    {
756
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
757
    }
758
759
    public function setVisibilityPending(AbstractResource $resource)
760
    {
761
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
762
    }
763
764
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode = null, UploadedFile $file = null): ResourceNode
765
    {
766
        $em = $this->getEntityManager();
767
768
        $resourceType = $this->getResourceType();
769
        $resourceName = $resource->getResourceName();
770
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
771
772
        if (empty($extension)) {
773
            $slug = $this->slugify->slugify($resourceName);
774
        } else {
775
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
776
            $originalBasename = \basename($resourceName, $originalExtension);
777
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
778
        }
779
780
        $resourceNode = new ResourceNode();
781
        $resourceNode
782
            ->setTitle($resourceName)
783
            ->setSlug($slug)
784
            ->setCreator($creator)
785
            ->setResourceType($resourceType)
786
        ;
787
788
        if (null !== $parentNode) {
789
            $resourceNode->setParent($parentNode);
790
        }
791
792
        $resource->setResourceNode($resourceNode);
793
        $em->persist($resourceNode);
794
        $em->persist($resource);
795
796
        if (null !== $file) {
797
            $this->addFile($resource, $file);
798
        }
799
800
        return $resourceNode;
801
    }
802
803
    public function getTotalSpaceByCourse(Course $course, CGroup $group = null, Session $session = null): int
804
    {
805
        $repo = $this->getRepository();
806
807
        $qb = $repo->createQueryBuilder('resource');
808
        $qb
809
            ->select('SUM(file.size) as total')
810
            ->innerJoin('resource.resourceNode', 'node')
811
            ->innerJoin('node.resourceLinks', 'l')
812
            ->innerJoin('node.resourceFile', 'file')
813
            ->where('l.course = :course')
814
            ->andWhere('l.visibility <> :visibility')
815
            ->andWhere('file IS NOT NULL')
816
            ->setParameters(
817
                [
818
                    'course' => $course,
819
                    'visibility' => ResourceLink::VISIBILITY_DELETED,
820
                ]
821
            );
822
823
        if (null === $group) {
824
            $qb->andWhere('l.group IS NULL');
825
        } else {
826
            $qb
827
                ->andWhere('l.group = :group')
828
                ->setParameter('group', $group);
829
        }
830
831
        if (null === $session) {
832
            $qb->andWhere('l.session IS NULL');
833
        } else {
834
            $qb
835
                ->andWhere('l.session = :session')
836
                ->setParameter('session', $session);
837
        }
838
839
        $query = $qb->getQuery();
840
841
        return (int) $query->getSingleScalarResult();
842
    }
843
844
    public function isGranted(string $subject, AbstractResource $resource): bool
845
    {
846
        return $this->getAuthorizationChecker()->isGranted($subject, $resource->getResourceNode());
847
    }
848
849
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
850
    {
851
        $resourceNode = $resource->getResourceNode();
852
853
        if (null === $resourceNode) {
854
            return false;
855
        }
856
857
        $em = $this->getEntityManager();
858
        if ($recursive) {
859
            $children = $resourceNode->getChildren();
860
            if (!empty($children)) {
861
                /** @var ResourceNode $child */
862
                foreach ($children as $child) {
863
                    $criteria = ['resourceNode' => $child];
864
                    $childDocument = $this->getRepository()->findOneBy($criteria);
865
                    if ($childDocument) {
866
                        $this->setLinkVisibility($childDocument, $visibility);
867
                    }
868
                }
869
            }
870
        }
871
872
        $links = $resourceNode->getResourceLinks();
873
874
        if (!empty($links)) {
875
            /** @var ResourceLink $link */
876
            foreach ($links as $link) {
877
                $link->setVisibility($visibility);
878
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
879
                    $editorMask = ResourceNodeVoter::getEditorMask();
880
                    $rights = [];
881
                    $resourceRight = new ResourceRight();
882
                    $resourceRight
883
                        ->setMask($editorMask)
884
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
885
                        ->setResourceLink($link)
886
                    ;
887
                    $rights[] = $resourceRight;
888
889
                    if (!empty($rights)) {
890
                        $link->setResourceRight($rights);
891
                    }
892
                } else {
893
                    $link->setResourceRight([]);
894
                }
895
                $em->persist($link);
896
            }
897
        }
898
        $em->flush();
899
900
        return true;
901
    }
902
}
903