Passed
Push — master ( 0b60a0...db12d9 )
by Julito
12:26
created

ResourceRepository::getResourceFileUrl()   B

Complexity

Conditions 6
Paths 19

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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