Passed
Push — master ( 7c4243...e861e2 )
by Julito
10:46
created

ResourceRepository::getResourceFileUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Repository;
8
9
use Chamilo\CoreBundle\Component\Resource\Settings;
10
use Chamilo\CoreBundle\Component\Resource\Template;
11
use Chamilo\CoreBundle\Entity\AbstractResource;
12
use Chamilo\CoreBundle\Entity\Course;
13
use Chamilo\CoreBundle\Entity\ResourceFile;
14
use Chamilo\CoreBundle\Entity\ResourceInterface;
15
use Chamilo\CoreBundle\Entity\ResourceLink;
16
use Chamilo\CoreBundle\Entity\ResourceNode;
17
use Chamilo\CoreBundle\Entity\ResourceRight;
18
use Chamilo\CoreBundle\Entity\ResourceType;
19
use Chamilo\CoreBundle\Entity\Session;
20
use Chamilo\CoreBundle\Entity\User;
21
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
22
use Chamilo\CourseBundle\Entity\CGroup;
23
use Chamilo\CourseBundle\Traits\NonResourceRepository;
24
use DateTime;
25
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
26
use Doctrine\Common\Collections\ArrayCollection;
27
use Doctrine\DBAL\Types\Types;
28
use Doctrine\ORM\EntityRepository;
29
use Doctrine\ORM\QueryBuilder;
30
use Exception;
31
use LogicException;
32
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
33
use Symfony\Component\Form\FormFactory;
34
use Symfony\Component\Form\FormInterface;
35
use Symfony\Component\HttpFoundation\File\UploadedFile;
36
use Throwable;
37
38
/**
39
 * Extends EntityRepository is needed to process settings.
40
 */
41
abstract class ResourceRepository extends ServiceEntityRepository
42
{
43
    use NonResourceRepository;
44
45
    protected Settings $settings;
46
    protected Template $templates;
47
    protected ?ResourceType $resourceType = null;
48
49
    public function setSettings(Settings $settings): self
50
    {
51
        $this->settings = $settings;
52
53
        return $this;
54
    }
55
56
    public function setTemplates(Template $templates): self
57
    {
58
        $this->templates = $templates;
59
60
        return $this;
61
    }
62
63
    public function getResourceSettings(): Settings
64
    {
65
        return $this->settings;
66
    }
67
68
    public function getTemplates(): Template
69
    {
70
        return $this->templates;
71
    }
72
73
    public function getClassName(): string
74
    {
75
        $class = static::class;
76
        //Chamilo\CoreBundle\Repository\Node\IllustrationRepository
77
        $class = str_replace('\\Repository\\', '\\Entity\\', $class);
78
        $class = str_replace('Repository', '', $class);
79
        if (!class_exists($class)) {
80
            throw new Exception(sprintf('Repo: %s not found ', $class));
81
        }
82
83
        return $class;
84
    }
85
86
    public function getCount(QueryBuilder $qb): int
87
    {
88
        $qb->select('count(resource)');
89
        $qb->setMaxResults(1);
90
91
        return (int) $qb->getQuery()->getSingleScalarResult();
92
    }
93
94
    /**
95
     * @return FormInterface
96
     */
97
    public function getForm(FormFactory $formFactory, ResourceInterface $resource = null, array $options = [])
98
    {
99
        $formType = $this->getResourceFormType();
100
101
        if (null === $resource) {
102
            $className = $this->repository->getClassName();
103
            $resource = new $className();
104
        }
105
106
        return $formFactory->create($formType, $resource, $options);
107
    }
108
109
    public function getResourceByResourceNode(ResourceNode $resourceNode): ?ResourceInterface
110
    {
111
        return $this->findOneBy([
112
            'resourceNode' => $resourceNode,
113
        ]);
114
    }
115
116
    /*public function findOneBy(array $criteria, array $orderBy = null)
117
    {
118
        return $this->findOneBy($criteria, $orderBy);
119
    }*/
120
121
    /*public function updateResource(AbstractResource $resource)
122
    {
123
        $em = $this->getEntityManager();
124
125
        $resourceNode = $resource->getResourceNode();
126
        $resourceNode->setTitle($resource->getResourceName());
127
128
        $links = $resource->getResourceLinkEntityList();
129
        if ($links) {
130
            foreach ($links as $link) {
131
                $link->setResourceNode($resourceNode);
132
133
                $rights = [];
134
                switch ($link->getVisibility()) {
135
                    case ResourceLink::VISIBILITY_PENDING:
136
                    case ResourceLink::VISIBILITY_DRAFT:
137
                        $editorMask = ResourceNodeVoter::getEditorMask();
138
                        $resourceRight = new ResourceRight();
139
                        $resourceRight
140
                            ->setMask($editorMask)
141
                            ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
142
                        ;
143
                        $rights[] = $resourceRight;
144
145
                        break;
146
                }
147
148
                if (!empty($rights)) {
149
                    foreach ($rights as $right) {
150
                        $link->addResourceRight($right);
151
                    }
152
                }
153
                $em->persist($link);
154
            }
155
        }
156
157
        $em->persist($resourceNode);
158
        $em->persist($resource);
159
        $em->flush();
160
    }*/
161
162
    public function create(AbstractResource $resource): void
163
    {
164
        $this->getEntityManager()->persist($resource);
165
        $this->getEntityManager()->flush();
166
    }
167
168
    public function update(AbstractResource $resource, bool $andFlush = true): void
169
    {
170
        if (!$resource->hasResourceNode()) {
171
            throw new Exception('Resource needs a resource node');
172
        }
173
174
        $resource->getResourceNode()->setUpdatedAt(new DateTime());
175
        $resource->getResourceNode()->setTitle($resource->getResourceName());
176
        $this->getEntityManager()->persist($resource);
177
178
        if ($andFlush) {
179
            $this->getEntityManager()->flush();
180
        }
181
    }
182
183
    public function updateNodeForResource(ResourceInterface $resource): ResourceNode
184
    {
185
        $em = $this->getEntityManager();
186
187
        $resourceNode = $resource->getResourceNode();
188
        $resourceName = $resource->getResourceName();
189
190
        if ($resourceNode->hasResourceFile()) {
191
            $resourceFile = $resourceNode->getResourceFile();
192
            if (null !== $resourceFile) {
193
                $originalName = $resourceFile->getOriginalName();
194
                $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
195
196
                //$originalBasename = \basename($resourceName, $originalExtension);
197
                /*$slug = sprintf(
198
                    '%s.%s',
199
                    $this->slugify->slugify($originalBasename),
200
                    $this->slugify->slugify($originalExtension)
201
                );*/
202
203
                $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
204
                $resourceFile->setOriginalName($newOriginalName);
205
206
                $em->persist($resourceFile);
207
            }
208
        }
209
        //$slug = $this->slugify->slugify($resourceName);
210
211
        $resourceNode->setTitle($resourceName);
212
        //$resourceNode->setSlug($slug);
213
214
        $em->persist($resourceNode);
215
        $em->persist($resource);
216
217
        $em->flush();
218
219
        return $resourceNode;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $resourceNode could return the type null which is incompatible with the type-hinted return Chamilo\CoreBundle\Entity\ResourceNode. Consider adding an additional type-check to rule them out.
Loading history...
220
    }
221
222
    public function findCourseResourceByTitle(
223
        string $title,
224
        ResourceNode $parentNode,
225
        Course $course,
226
        Session $session = null,
227
        CGroup $group = null
228
    ): ?ResourceInterface {
229
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
230
        $this->addTitleQueryBuilder($title, $qb);
231
        $qb->setMaxResults(1);
232
233
        return $qb->getQuery()->getOneOrNullResult();
234
    }
235
236
    public function findCourseResourcesByTitle(
237
        string $title,
238
        ResourceNode $parentNode,
239
        Course $course,
240
        Session $session = null,
241
        CGroup $group = null
242
    ) {
243
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
244
        $this->addTitleQueryBuilder($title, $qb);
245
246
        return $qb->getQuery()->getResult();
247
    }
248
249
    /**
250
     * @todo clean path
251
     */
252
    public function addFileFromPath(ResourceInterface $resource, string $fileName, string $path, bool $flush = true)
253
    {
254
        if (!empty($path) && file_exists($path) && !is_dir($path)) {
255
            $mimeType = mime_content_type($path);
256
            $file = new UploadedFile($path, $fileName, $mimeType, null, true);
257
258
            return $this->addFile($resource, $file, '', $flush);
259
        }
260
261
        return null;
262
    }
263
264
    public function addFileFromString(ResourceInterface $resource, string $fileName, string $mimeType, string $content, bool $flush = true): ?ResourceFile
265
    {
266
        $handle = tmpfile();
267
        fwrite($handle, $content);
268
        $meta = stream_get_meta_data($handle);
269
        $file = new UploadedFile($meta['uri'], $fileName, $mimeType, null, true);
270
271
        return $this->addFile($resource, $file, '', $flush);
272
    }
273
274
    public function addFileFromFileRequest(ResourceInterface $resource, string $fileKey, bool $flush = true): ?ResourceFile
275
    {
276
        $request = $this->getRequest();
277
        if ($request->files->has($fileKey)) {
278
            $file = $request->files->get($fileKey);
279
            if (null !== $file) {
280
                $resourceFile = $this->addFile($resource, $file);
281
                if ($flush) {
282
                    $this->getEntityManager()->flush();
283
                }
284
285
                return $resourceFile;
286
            }
287
        }
288
289
        return null;
290
    }
291
292
    public function addFile(ResourceInterface $resource, UploadedFile $file, string $description = '', bool $flush = false): ?ResourceFile
293
    {
294
        $resourceNode = $resource->getResourceNode();
295
296
        if (null === $resourceNode) {
297
            throw new LogicException('Resource node is null');
298
        }
299
300
        $resourceFile = $resourceNode->getResourceFile();
301
        if (null === $resourceFile) {
302
            $resourceFile = new ResourceFile();
303
        }
304
305
        $em = $this->getEntityManager();
306
        $resourceFile
307
            ->setFile($file)
308
            ->setDescription($description)
309
            ->setName($resource->getResourceName())
310
            ->setResourceNode($resourceNode)
311
        ;
312
        $em->persist($resourceFile);
313
        $resourceNode->setResourceFile($resourceFile);
314
        $em->persist($resourceNode);
315
316
        if ($flush) {
317
            $em->flush();
318
        }
319
320
        return $resourceFile;
321
    }
322
323
    public function getResourceType(): ?ResourceType
324
    {
325
        $name = $this->getResourceTypeName();
326
        $repo = $this->getEntityManager()->getRepository(ResourceType::class);
327
        $this->resourceType = $repo->findOneBy([
328
            'name' => $name,
329
        ]);
330
331
        return $this->resourceType;
332
    }
333
334
    public function getResourceTypeName(): string
335
    {
336
        return $this->toolChain->getResourceTypeNameFromRepository(static::class);
0 ignored issues
show
Bug introduced by
The method getResourceTypeNameFromRepository() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

336
        return $this->toolChain->/** @scrutinizer ignore-call */ getResourceTypeNameFromRepository(static::class);

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...
337
    }
338
339
    public function getResourcesByCourse(Course $course, Session $session = null, CGroup $group = null, ResourceNode $parentNode = null): QueryBuilder
340
    {
341
        $checker = $this->getAuthorizationChecker();
342
        $reflectionClass = $this->getClassMetadata()->getReflectionClass();
343
344
        // Check if this resource type requires to load the base course resources when using a session
345
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
346
347
        $resourceTypeName = $this->getResourceTypeName();
348
        $qb = $this->createQueryBuilder('resource')
349
            ->select('resource')
350
            //->from($className, 'resource')
351
            ->innerJoin('resource.resourceNode', 'node')
352
            ->innerJoin('node.resourceLinks', 'links')
353
            ->innerJoin('node.resourceType', 'type')
354
            ->leftJoin('node.resourceFile', 'file')
355
356
            ->where('type.name = :type')
357
            ->setParameter('type', $resourceTypeName, Types::STRING)
358
            ->andWhere('links.course = :course')
359
            ->setParameter('course', $course)
360
            ->addSelect('node')
361
            ->addSelect('links')
362
            //->addSelect('course')
363
            ->addSelect('type')
364
            ->addSelect('file')
365
        ;
366
367
        $isAdmin =
368
            $checker->isGranted('ROLE_ADMIN') ||
369
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
370
371
        // Do not show deleted resources.
372
        $qb
373
            ->andWhere('links.visibility != :visibilityDeleted')
374
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED, Types::INTEGER)
375
        ;
376
377
        if (!$isAdmin) {
378
            $qb
379
                ->andWhere('links.visibility = :visibility')
380
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED, Types::INTEGER)
381
            ;
382
            // @todo Add start/end visibility restrictions.
383
        }
384
385
        if (null === $session) {
386
            $qb->andWhere(
387
                $qb->expr()->orX(
388
                    $qb->expr()->isNull('links.session'),
389
                    $qb->expr()->eq('links.session', 0)
390
                )
391
            );
392
        } elseif ($loadBaseSessionContent) {
393
            // Load course base content.
394
            $qb->andWhere('links.session = :session OR links.session IS NULL');
395
            $qb->setParameter('session', $session);
396
        } else {
397
            // Load only session resources.
398
            $qb->andWhere('links.session = :session');
399
            $qb->setParameter('session', $session);
400
        }
401
402
        if (null !== $parentNode) {
403
            $qb->andWhere('node.parent = :parentNode');
404
            $qb->setParameter('parentNode', $parentNode);
405
        }
406
407
        if (null === $group) {
408
            $qb->andWhere(
409
                $qb->expr()->orX(
410
                    $qb->expr()->isNull('links.group'),
411
                    $qb->expr()->eq('links.group', 0)
412
                )
413
            );
414
        } else {
415
            $qb->andWhere('links.group = :group');
416
            $qb->setParameter('group', $group);
417
        }
418
419
        return $qb;
420
    }
421
422
    /**
423
     * Get resources only from the base course.
424
     */
425
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null): QueryBuilder
426
    {
427
        $checker = $this->getAuthorizationChecker();
428
        $resourceTypeName = $this->getResourceTypeName();
429
430
        $qb = $this->createQueryBuilder('resource')
431
            ->select('resource')
432
            ->innerJoin('resource.resourceNode', 'node')
433
            ->innerJoin('node.resourceLinks', 'links')
434
            ->innerJoin('node.resourceType', 'type')
435
            ->where('type.name = :type')
436
            ->setParameter('type', $resourceTypeName, Types::STRING)
437
            ->andWhere('links.course = :course')
438
            ->setParameter('course', $course)
439
        ;
440
441
        $isAdmin = $checker->isGranted('ROLE_ADMIN') || $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
442
443
        // Do not show deleted resources
444
        $qb
445
            ->andWhere('links.visibility != :visibilityDeleted')
446
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED, Types::INTEGER)
447
        ;
448
449
        if (!$isAdmin) {
450
            $qb
451
                ->andWhere('links.visibility = :visibility')
452
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED, Types::INTEGER)
453
            ;
454
            // @todo Add start/end visibility restrictions
455
        }
456
457
        if (null !== $parentNode) {
458
            $qb->andWhere('node.parent = :parentNode');
459
            $qb->setParameter('parentNode', $parentNode);
460
        }
461
462
        return $qb;
463
    }
464
465
    public function getResourceByCreatorFromTitle(
466
        string $title,
467
        User $user,
468
        ResourceNode $parentNode
469
    ): ?ResourceInterface {
470
        $qb = $this->getResourcesByCreator($user, $parentNode);
471
        $this->addTitleQueryBuilder($title, $qb);
472
        $qb->setMaxResults(1);
473
474
        return $qb->getQuery()->getOneOrNullResult();
475
    }
476
477
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null): QueryBuilder
478
    {
479
        $qb = $this->createQueryBuilder('resource')
480
            ->select('resource')
481
            ->innerJoin('resource.resourceNode', 'node')
482
            //->innerJoin('node.resourceLinks', 'links')
483
            //->where('node.resourceType = :type')
484
            //->setParameter('type',$type)
485
            ;
486
        /*$qb
487
            ->andWhere('links.visibility = :visibility')
488
            ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
489
        ;*/
490
491
        if (null !== $parentNode) {
492
            $qb->andWhere('node.parent = :parentNode');
493
            $qb->setParameter('parentNode', $parentNode);
494
        }
495
496
        $this->addCreatorQueryBuilder($user, $qb);
497
498
        return $qb;
499
    }
500
501
    public function getResourcesByCourseLinkedToUser(
502
        User $user,
503
        Course $course,
504
        Session $session = null,
505
        CGroup $group = null,
506
        ResourceNode $parentNode = null
507
    ): QueryBuilder {
508
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
509
        $qb->andWhere('node.creator = :user OR (links.user = :user OR links.user IS NULL)');
510
        $qb->setParameter('user', $user);
511
512
        return $qb;
513
    }
514
515
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
516
    {
517
        $checker = $this->getAuthorizationChecker();
518
        $resourceTypeName = $this->getResourceTypeName();
519
520
        $qb = $this->createQueryBuilder('resource')
521
            ->select('resource')
522
            ->innerJoin('resource.resourceNode', 'node')
523
            ->innerJoin('node.resourceLinks', 'links')
524
            ->innerJoin('node.resourceType', 'type')
525
            ->where('type.name = :type')
526
            ->setParameter('type', $resourceTypeName, Types::STRING)
527
            ->andWhere('links.user = :user')
528
            ->setParameter('user', $user)
529
        ;
530
531
        $isAdmin = $checker->isGranted('ROLE_ADMIN') ||
532
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
533
534
        // Do not show deleted resources
535
        $qb
536
            ->andWhere('links.visibility != :visibilityDeleted')
537
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED)
538
        ;
539
540
        if (!$isAdmin) {
541
            $qb
542
                ->andWhere('links.visibility = :visibility')
543
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED)
544
            ;
545
            // @todo Add start/end visibility restrictrions
546
        }
547
548
        if (null !== $parentNode) {
549
            $qb->andWhere('node.parent = :parentNode');
550
            $qb->setParameter('parentNode', $parentNode);
551
        }
552
553
        return $qb;
554
    }
555
556
    public function getResourceFromResourceNode(int $resourceNodeId): ?ResourceInterface
557
    {
558
        $qb = $this->createQueryBuilder('resource')
559
            ->select('resource')
560
            ->addSelect('node')
561
            ->addSelect('links')
562
            ->innerJoin('resource.resourceNode', 'node')
563
        //    ->innerJoin('node.creator', 'userCreator')
564
            ->innerJoin('node.resourceLinks', 'links')
565
//            ->leftJoin('node.resourceFile', 'file')
566
            ->where('node.id = :id')
567
            ->setParameters([
568
                'id' => $resourceNodeId,
569
            ])
570
            //->addSelect('node')
571
        ;
572
573
        return $qb->getQuery()->getOneOrNullResult();
574
    }
575
576
    public function delete(ResourceInterface $resource): void
577
    {
578
        $children = $resource->getResourceNode()->getChildren();
579
        foreach ($children as $child) {
580
            if ($child->hasResourceFile()) {
581
                $this->getEntityManager()->remove($child->getResourceFile());
582
            }
583
            $resourceNode = $this->getResourceFromResourceNode($child->getId());
584
            if (null !== $resourceNode) {
585
                $this->delete($resourceNode);
586
            }
587
        }
588
        $this->getEntityManager()->remove($resource);
589
        $this->getEntityManager()->flush();
590
    }
591
592
    /**
593
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
594
     * ResourceLinks and ResourceFile (including files via Flysystem).
595
     */
596
    public function hardDelete(AbstractResource $resource): void
597
    {
598
        $em = $this->getEntityManager();
599
        $em->remove($resource);
600
        $em->flush();
601
    }
602
603
    public function getResourceFileContent(AbstractResource $resource): string
604
    {
605
        try {
606
            $resourceNode = $resource->getResourceNode();
607
608
            return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
0 ignored issues
show
Bug introduced by
The method getResourceNodeFileContent() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

608
            return $this->resourceNodeRepository->/** @scrutinizer ignore-call */ getResourceNodeFileContent($resourceNode);

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...
609
        } catch (Throwable $throwable) {
610
            throw new FileNotFoundException($resource->getResourceName());
611
        }
612
    }
613
614
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
615
    {
616
        return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
617
    }
618
619
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
620
    {
621
        return $this->resourceNodeRepository->getResourceNodeFileStream($resourceNode);
622
    }
623
624
    public function getResourceFileDownloadUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
625
    {
626
        $extraParams['mode'] = 'download';
627
628
        return $this->getResourceFileUrl($resource, $extraParams, $referenceType);
629
    }
630
631
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
632
    {
633
        return $this->getResourceNodeRepository()->getResourceFileUrl(
634
            $resource->getResourceNode(),
635
            $extraParams,
636
            $referenceType
637
        );
638
    }
639
640
    /**
641
     * @return bool
642
     */
643
    public function updateResourceFileContent(AbstractResource $resource, string $content)
644
    {
645
        error_log('updateResourceFileContent');
646
647
        $resourceNode = $resource->getResourceNode();
648
        if ($resourceNode->hasResourceFile()) {
649
            $resourceNode->setContent($content);
650
            error_log('updated');
651
            $resourceNode->getResourceFile()->setSize(\strlen($content));
652
            /*
653
            error_log('has file');
654
            $resourceFile = $resourceNode->getResourceFile();
655
            if ($resourceFile) {
656
                error_log('$resourceFile');
657
                $title = $resource->getResourceName();
658
                $handle = tmpfile();
659
                fwrite($handle, $content);
660
                error_log($title);
661
                error_log($content);
662
                $meta = stream_get_meta_data($handle);
663
                $file = new UploadedFile($meta['uri'], $title, 'text/html', null, true);
664
                $resource->setUploadFile($file);
665
666
                return true;
667
            }*/
668
        }
669
        error_log('false');
670
671
        return false;
672
    }
673
674
    public function setResourceName(AbstractResource $resource, $title): void
675
    {
676
        $resource->setResourceName($title);
677
        $resourceNode = $resource->getResourceNode();
678
        $resourceNode->setTitle($title);
679
        if ($resourceNode->hasResourceFile()) {
680
            //$resourceNode->getResourceFile()->getFile()->
681
            //$resourceNode->getResourceFile()->setName($title);
682
            //$resourceFile->setName($title);
683
684
            /*$fileName = $this->getResourceNodeRepository()->getFilename($resourceFile);
685
            error_log('$fileName');
686
            error_log($fileName);
687
            error_log($title);
688
            $this->getResourceNodeRepository()->getFileSystem()->rename($fileName, $title);
689
            $resourceFile->setName($title);
690
            $resourceFile->setOriginalName($title);*/
691
        }
692
    }
693
694
    /**
695
     * Change all links visibility to DELETED.
696
     */
697
    public function softDelete(AbstractResource $resource): void
698
    {
699
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
700
    }
701
702
    public function setVisibilityPublished(AbstractResource $resource): void
703
    {
704
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
705
    }
706
707
    public function setVisibilityDeleted(AbstractResource $resource): void
708
    {
709
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
710
    }
711
712
    public function setVisibilityDraft(AbstractResource $resource): void
713
    {
714
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
715
    }
716
717
    public function setVisibilityPending(AbstractResource $resource): void
718
    {
719
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
720
    }
721
722
    public function addResourceNode(ResourceInterface $resource, User $creator, ResourceInterface $parentResource): ResourceNode
723
    {
724
        $parentResourceNode = $parentResource->getResourceNode();
725
726
        return $this->createNodeForResource($resource, $creator, $parentResourceNode);
727
    }
728
729
    /**
730
     * @todo remove this function and merge it with addResourceNode()
731
     */
732
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode, UploadedFile $file = null): ResourceNode
733
    {
734
        $em = $this->getEntityManager();
735
736
        $resourceType = $this->getResourceType();
737
        $resourceName = $resource->getResourceName();
738
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));
0 ignored issues
show
Bug introduced by
The method slugify() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

738
        /** @scrutinizer ignore-call */ 
739
        $extension = $this->slugify->slugify(pathinfo($resourceName, PATHINFO_EXTENSION));

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...
739
740
        if (empty($extension)) {
741
            $slug = $this->slugify->slugify($resourceName);
742
        } else {
743
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
744
            $originalBasename = basename($resourceName, $originalExtension);
745
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
746
        }
747
748
        $resourceNode = new ResourceNode();
749
        $resourceNode
750
            ->setTitle($resourceName)
751
            ->setSlug($slug)
752
            ->setCreator($creator)
753
            ->setResourceType($resourceType)
754
        ;
755
756
        if (null !== $parentNode) {
757
            $resourceNode->setParent($parentNode);
758
        }
759
760
        $resource->setResourceNode($resourceNode);
761
        $em->persist($resourceNode);
762
        $em->persist($resource);
763
764
        if (null !== $file) {
765
            $this->addFile($resource, $file);
766
        }
767
768
        return $resourceNode;
769
    }
770
771
    /**
772
     * This is only used during installation for the special nodes (admin and AccessUrl).
773
     */
774
    public function createNodeForResourceWithNoParent(ResourceInterface $resource, User $creator): ResourceNode
775
    {
776
        $em = $this->getEntityManager();
777
778
        $resourceType = $this->getResourceType();
779
        $resourceName = $resource->getResourceName();
780
        $slug = $this->slugify->slugify($resourceName);
781
        $resourceNode = new ResourceNode();
782
        $resourceNode
783
            ->setTitle($resourceName)
784
            ->setSlug($slug)
785
            ->setCreator($creator)
786
            ->setResourceType($resourceType)
787
        ;
788
        $resource->setResourceNode($resourceNode);
789
        $em->persist($resourceNode);
790
        $em->persist($resource);
791
792
        return $resourceNode;
793
    }
794
795
    public function getTotalSpaceByCourse(Course $course, CGroup $group = null, Session $session = null): int
796
    {
797
        $qb = $this->createQueryBuilder('resource');
798
        $qb
799
            ->select('SUM(file.size) as total')
800
            ->innerJoin('resource.resourceNode', 'node')
801
            ->innerJoin('node.resourceLinks', 'l')
802
            ->innerJoin('node.resourceFile', 'file')
803
            ->where('l.course = :course')
804
            ->andWhere('l.visibility <> :visibility')
805
            ->andWhere('file IS NOT NULL')
806
            ->setParameters(
807
                [
808
                    'course' => $course,
809
                    'visibility' => ResourceLink::VISIBILITY_DELETED,
810
                ]
811
            )
812
        ;
813
814
        if (null === $group) {
815
            $qb->andWhere('l.group IS NULL');
816
        } else {
817
            $qb
818
                ->andWhere('l.group = :group')
819
                ->setParameter('group', $group)
820
            ;
821
        }
822
823
        if (null === $session) {
824
            $qb->andWhere('l.session IS NULL');
825
        } else {
826
            $qb
827
                ->andWhere('l.session = :session')
828
                ->setParameter('session', $session)
829
            ;
830
        }
831
832
        $query = $qb->getQuery();
833
834
        return (int) $query->getSingleScalarResult();
835
    }
836
837
    public function addTitleDecoration(AbstractResource $resource, Course $course, Session $session = null): string
838
    {
839
        if (null === $session) {
840
            return '';
841
        }
842
843
        $link = $resource->getFirstResourceLinkFromCourseSession($course, $session);
844
        if (null === $link) {
845
            return '';
846
        }
847
848
        return '<img title="'.$session->getName().'" src="/img/icons/22/star.png" />';
849
    }
850
851
    public function isGranted(string $subject, AbstractResource $resource): bool
852
    {
853
        return $this->getAuthorizationChecker()->isGranted($subject, $resource->getResourceNode());
854
    }
855
856
    /**
857
     * Changes the visibility of the children that matches the exact same link.
858
     */
859
    public function copyVisibilityToChildren(ResourceNode $resourceNode, ResourceLink $link): bool
860
    {
861
        $children = $resourceNode->getChildren();
862
863
        if (0 === $children->count()) {
864
            return false;
865
        }
866
867
        $em = $this->getEntityManager();
868
869
        /** @var ResourceNode $child */
870
        foreach ($children as $child) {
871
            if ($child->getChildren()->count() > 0) {
872
                $this->copyVisibilityToChildren($child, $link);
873
            }
874
875
            $links = $child->getResourceLinks();
876
            foreach ($links as $linkItem) {
877
                if ($linkItem->getUser() === $link->getUser() &&
878
                    $linkItem->getSession() === $link->getSession() &&
879
                    $linkItem->getCourse() === $link->getCourse() &&
880
                    $linkItem->getUserGroup() === $link->getUserGroup()
881
                ) {
882
                    $linkItem->setVisibility($link->getVisibility());
883
                    $em->persist($linkItem);
884
                }
885
            }
886
        }
887
888
        $em->flush();
889
890
        return true;
891
    }
892
893
    public function saveUpload(UploadedFile $file): ResourceInterface
894
    {
895
        throw new Exception('Implement saveUpload');
896
    }
897
898
    public function getResourceFormType(): string
899
    {
900
        throw new Exception('Implement getResourceFormType');
901
    }
902
903
    protected function getOrCreateQueryBuilder(QueryBuilder $qb = null, string $alias = 'resource'): QueryBuilder
904
    {
905
        return $qb ?: $this->createQueryBuilder($alias);
906
    }
907
908
    protected function addTitleQueryBuilder(?string $title, QueryBuilder $qb = null): QueryBuilder
909
    {
910
        $qb = $this->getOrCreateQueryBuilder($qb);
911
        if (null === $title) {
912
            return $qb;
913
        }
914
915
        $qb
916
            ->andWhere('node.title = :title')
917
            ->setParameter('title', $title)
918
        ;
919
920
        return $qb;
921
    }
922
923
    protected function addCreatorQueryBuilder(?User $user, QueryBuilder $qb = null): QueryBuilder
924
    {
925
        $qb = $this->getOrCreateQueryBuilder($qb);
926
        if (null === $user) {
927
            return $qb;
928
        }
929
930
        $qb
931
            ->andWhere('node.creator = :creator')
932
            ->setParameter('creator', $user)
933
        ;
934
935
        return $qb;
936
    }
937
938
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
939
    {
940
        $resourceNode = $resource->getResourceNode();
941
942
        if (null === $resourceNode) {
943
            return false;
944
        }
945
946
        $em = $this->getEntityManager();
947
        if ($recursive) {
948
            $children = $resourceNode->getChildren();
949
            if (!empty($children)) {
950
                /** @var ResourceNode $child */
951
                foreach ($children as $child) {
952
                    $criteria = [
953
                        'resourceNode' => $child,
954
                    ];
955
                    $childDocument = $this->findOneBy($criteria);
956
                    if ($childDocument) {
957
                        $this->setLinkVisibility($childDocument, $visibility);
958
                    }
959
                }
960
            }
961
        }
962
963
        $links = $resourceNode->getResourceLinks();
964
965
        if (!empty($links)) {
966
            /** @var ResourceLink $link */
967
            foreach ($links as $link) {
968
                $link->setVisibility($visibility);
969
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
970
                    $editorMask = ResourceNodeVoter::getEditorMask();
971
                    //$rights = [];
972
                    $resourceRight = new ResourceRight();
973
                    $resourceRight
974
                        ->setMask($editorMask)
975
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
976
                        ->setResourceLink($link)
977
                    ;
978
                    $link->addResourceRight($resourceRight);
979
                } else {
980
                    $link->setResourceRights(new ArrayCollection());
981
                }
982
                $em->persist($link);
983
            }
984
        }
985
        $em->flush();
986
987
        return true;
988
    }
989
}
990