Passed
Push — master ( 2266b9...0bc43f )
by Julito
17:49
created

getResourceByCreatorFromTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 10
rs 10
c 0
b 0
f 0
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\Utils\CreateUploadedFile;
10
use Chamilo\CoreBundle\Entity\AbstractResource;
11
use Chamilo\CoreBundle\Entity\Course;
12
use Chamilo\CoreBundle\Entity\ResourceFile;
13
use Chamilo\CoreBundle\Entity\ResourceInterface;
14
use Chamilo\CoreBundle\Entity\ResourceLink;
15
use Chamilo\CoreBundle\Entity\ResourceNode;
16
use Chamilo\CoreBundle\Entity\ResourceRight;
17
use Chamilo\CoreBundle\Entity\ResourceType;
18
use Chamilo\CoreBundle\Entity\Session;
19
use Chamilo\CoreBundle\Entity\User;
20
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
21
use Chamilo\CoreBundle\Traits\NonResourceRepository;
22
use Chamilo\CoreBundle\Traits\Repository\RepositoryQueryBuilderTrait;
23
use Chamilo\CourseBundle\Entity\CGroup;
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\HttpFoundation\File\UploadedFile;
34
use Throwable;
35
36
/**
37
 * Extends Resource EntityRepository.
38
 */
39
abstract class ResourceRepository extends ServiceEntityRepository
40
{
41
    use NonResourceRepository;
42
    use RepositoryQueryBuilderTrait;
43
44
    protected ?ResourceType $resourceType = null;
45
46
    public function getCount(QueryBuilder $qb): int
47
    {
48
        $qb
49
            ->select('count(resource)')
50
            ->setMaxResults(1)
51
            ->setFirstResult(null)
52
        ;
53
54
        return (int) $qb->getQuery()->getSingleScalarResult();
55
    }
56
57
    public function getResourceByResourceNode(ResourceNode $resourceNode): ?ResourceInterface
58
    {
59
        return $this->findOneBy([
60
            'resourceNode' => $resourceNode,
61
        ]);
62
    }
63
64
    public function create(AbstractResource $resource): void
65
    {
66
        $this->getEntityManager()->persist($resource);
67
        $this->getEntityManager()->flush();
68
    }
69
70
    public function update(AbstractResource | User $resource, bool $andFlush = true): void
71
    {
72
        if (!$resource->hasResourceNode()) {
73
            throw new Exception('Resource needs a resource node');
74
        }
75
76
        $em = $this->getEntityManager();
77
78
        $resource->getResourceNode()->setUpdatedAt(new DateTime());
79
        $resource->getResourceNode()->setTitle($resource->getResourceName());
80
        $em->persist($resource);
81
82
        if ($andFlush) {
83
            $em->flush();
84
        }
85
    }
86
87
    public function updateNodeForResource(ResourceInterface $resource): ResourceNode
88
    {
89
        $em = $this->getEntityManager();
90
91
        $resourceNode = $resource->getResourceNode();
92
        $resourceName = $resource->getResourceName();
93
94
        if ($resourceNode->hasResourceFile()) {
95
            $resourceFile = $resourceNode->getResourceFile();
96
            if (null !== $resourceFile) {
97
                $originalName = $resourceFile->getOriginalName();
98
                $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
99
100
                //$originalBasename = \basename($resourceName, $originalExtension);
101
                /*$slug = sprintf(
102
                    '%s.%s',
103
                    $this->slugify->slugify($originalBasename),
104
                    $this->slugify->slugify($originalExtension)
105
                );*/
106
107
                $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
108
                $resourceFile->setOriginalName($newOriginalName);
109
110
                $em->persist($resourceFile);
111
            }
112
        }
113
        //$slug = $this->slugify->slugify($resourceName);
114
115
        $resourceNode->setTitle($resourceName);
116
        //$resourceNode->setSlug($slug);
117
118
        $em->persist($resourceNode);
119
        $em->persist($resource);
120
121
        $em->flush();
122
123
        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...
124
    }
125
126
    public function findCourseResourceByTitle(
127
        string $title,
128
        ResourceNode $parentNode,
129
        Course $course,
130
        Session $session = null,
131
        CGroup $group = null
132
    ): ?ResourceInterface {
133
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
134
        $this->addTitleQueryBuilder($title, $qb);
135
        $qb->setMaxResults(1);
136
137
        return $qb->getQuery()->getOneOrNullResult();
138
    }
139
140
    public function findCourseResourceBySlug(
141
        string $title,
142
        ResourceNode $parentNode,
143
        Course $course,
144
        Session $session = null,
145
        CGroup $group = null
146
    ): ?ResourceInterface {
147
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
148
        $this->addSlugQueryBuilder($title, $qb);
149
        $qb->setMaxResults(1);
150
151
        return $qb->getQuery()->getOneOrNullResult();
152
    }
153
154
    /**
155
     * @return ResourceInterface[]
156
     */
157
    public function findCourseResourcesByTitle(
158
        string $title,
159
        ResourceNode $parentNode,
160
        Course $course,
161
        Session $session = null,
162
        CGroup $group = null
163
    ) {
164
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
165
        $this->addTitleQueryBuilder($title, $qb);
166
167
        return $qb->getQuery()->getResult();
168
    }
169
170
    /**
171
     * @todo clean path
172
     */
173
    public function addFileFromPath(ResourceInterface $resource, string $fileName, string $path, bool $flush = true): ?ResourceFile
174
    {
175
        if (!empty($path) && file_exists($path) && !is_dir($path)) {
176
            $mimeType = mime_content_type($path);
177
            $file = new UploadedFile($path, $fileName, $mimeType, null, true);
178
179
            return $this->addFile($resource, $file, '', $flush);
180
        }
181
182
        return null;
183
    }
184
185
    public function addFileFromString(ResourceInterface $resource, string $fileName, string $mimeType, string $content, bool $flush = true): ?ResourceFile
186
    {
187
        $file = CreateUploadedFile::fromString($fileName, $mimeType, $content);
188
189
        return $this->addFile($resource, $file, '', $flush);
190
    }
191
192
    public function addFileFromFileRequest(ResourceInterface $resource, string $fileKey, bool $flush = true): ?ResourceFile
193
    {
194
        $request = $this->getRequest();
195
        if ($request->files->has($fileKey)) {
196
            $file = $request->files->get($fileKey);
197
            if (null !== $file) {
198
                $resourceFile = $this->addFile($resource, $file);
199
                if ($flush) {
200
                    $this->getEntityManager()->flush();
201
                }
202
203
                return $resourceFile;
204
            }
205
        }
206
207
        return null;
208
    }
209
210
    public function addFile(ResourceInterface $resource, UploadedFile $file, string $description = '', bool $flush = false): ?ResourceFile
211
    {
212
        $resourceNode = $resource->getResourceNode();
213
214
        if (null === $resourceNode) {
215
            throw new LogicException('Resource node is null');
216
        }
217
218
        $resourceFile = $resourceNode->getResourceFile();
219
        if (null === $resourceFile) {
220
            $resourceFile = new ResourceFile();
221
        }
222
223
        $em = $this->getEntityManager();
224
        $resourceFile
225
            ->setFile($file)
226
            ->setDescription($description)
227
            ->setName($resource->getResourceName())
228
            ->setResourceNode($resourceNode)
229
        ;
230
        $em->persist($resourceFile);
231
        $resourceNode->setResourceFile($resourceFile);
232
        $em->persist($resourceNode);
233
234
        if ($flush) {
235
            $em->flush();
236
        }
237
238
        return $resourceFile;
239
    }
240
241
    public function getResourceType(): ResourceType
242
    {
243
        $resourceTypeName = $this->toolChain->getResourceTypeNameByEntity($this->getClassName());
0 ignored issues
show
Bug introduced by
The method getResourceTypeNameByEntity() 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

243
        /** @scrutinizer ignore-call */ 
244
        $resourceTypeName = $this->toolChain->getResourceTypeNameByEntity($this->getClassName());

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...
244
        $repo = $this->getEntityManager()->getRepository(ResourceType::class);
245
246
        return $repo->findOneBy([
247
            'name' => $resourceTypeName,
248
        ]);
249
    }
250
251
    public function addVisibilityQueryBuilder(QueryBuilder $qb = null): QueryBuilder
252
    {
253
        $qb = $this->getOrCreateQueryBuilder($qb);
254
255
        $checker = $this->getAuthorizationChecker();
256
        $isAdmin =
257
            $checker->isGranted('ROLE_ADMIN') ||
258
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
259
260
        // Do not show deleted resources.
261
        $qb
262
            ->andWhere('links.visibility != :visibilityDeleted')
263
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED, Types::INTEGER)
264
        ;
265
266
        if (!$isAdmin) {
267
            $qb
268
                ->andWhere('links.visibility = :visibility')
269
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED, Types::INTEGER)
270
            ;
271
            // @todo Add start/end visibility restrictions.
272
        }
273
274
        return $qb;
275
    }
276
277
    public function addCourseQueryBuilder(Course $course, QueryBuilder $qb): QueryBuilder
278
    {
279
        $qb
280
            ->andWhere('links.course = :course')
281
            ->setParameter('course', $course)
282
        ;
283
284
        return $qb;
285
    }
286
287
    public function addCourseSessionGroupQueryBuilder(Course $course, Session $session = null, CGroup $group = null, QueryBuilder $qb = null): QueryBuilder
288
    {
289
        $reflectionClass = $this->getClassMetadata()->getReflectionClass();
290
291
        // Check if this resource type requires to load the base course resources when using a session
292
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
293
294
        $this->addCourseQueryBuilder($course, $qb);
295
296
        if (null === $session) {
297
            $qb->andWhere(
298
                $qb->expr()->orX(
0 ignored issues
show
Bug introduced by
The method expr() 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

298
                $qb->/** @scrutinizer ignore-call */ 
299
                     expr()->orX(

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...
299
                    $qb->expr()->isNull('links.session'),
300
                    $qb->expr()->eq('links.session', 0)
301
                )
302
            );
303
        } elseif ($loadBaseSessionContent) {
304
            // Load course base content.
305
            $qb->andWhere('links.session = :session OR links.session IS NULL');
306
            $qb->setParameter('session', $session);
307
        } else {
308
            // Load only session resources.
309
            $qb->andWhere('links.session = :session');
310
            $qb->setParameter('session', $session);
311
        }
312
313
        if (null === $group) {
314
            $qb->andWhere(
315
                $qb->expr()->orX(
316
                    $qb->expr()->isNull('links.group'),
317
                    $qb->expr()->eq('links.group', 0)
318
                )
319
            );
320
        } else {
321
            $qb->andWhere('links.group = :group');
322
            $qb->setParameter('group', $group);
323
        }
324
325
        return $qb;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb could return the type null which is incompatible with the type-hinted return Doctrine\ORM\QueryBuilder. Consider adding an additional type-check to rule them out.
Loading history...
326
    }
327
328
    public function getResourceTypeName(): string
329
    {
330
        return $this->toolChain->getResourceTypeNameByEntity($this->getClassName());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->toolChain-...($this->getClassName()) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
331
    }
332
333
    public function getResources(ResourceNode $parentNode = null): QueryBuilder
334
    {
335
        $resourceTypeName = $this->getResourceTypeName();
336
337
        $qb = $this->createQueryBuilder('resource')
338
            ->select('resource')
339
            ->innerJoin('resource.resourceNode', 'node')
340
            ->innerJoin('node.resourceLinks', 'links')
341
            ->innerJoin('node.resourceType', 'type')
342
            ->leftJoin('node.resourceFile', 'file')
343
            ->where('type.name = :type')
344
            ->setParameter('type', $resourceTypeName, Types::STRING)
345
            ->addSelect('node')
346
            ->addSelect('links')
347
            ->addSelect('type')
348
            ->addSelect('file')
349
        ;
350
351
        if (null !== $parentNode) {
352
            $qb->andWhere('node.parent = :parentNode');
353
            $qb->setParameter('parentNode', $parentNode);
354
        }
355
356
        return $qb;
357
    }
358
359
    public function getResourcesByCourse(Course $course, Session $session = null, CGroup $group = null, ResourceNode $parentNode = null): QueryBuilder
360
    {
361
        $qb = $this->getResources($parentNode);
362
        $this->addVisibilityQueryBuilder($qb);
363
        $this->addCourseSessionGroupQueryBuilder($course, $session, $group, $qb);
364
365
        return $qb;
366
    }
367
368
    /**
369
     * Get resources only from the base course.
370
     */
371
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null): QueryBuilder
372
    {
373
        $qb = $this->getResources($parentNode);
374
        $this->addCourseQueryBuilder($course, $qb);
375
        $this->addVisibilityQueryBuilder($qb);
376
377
        return $qb;
378
    }
379
380
    public function getResourceByCreatorFromTitle(
381
        string $title,
382
        User $user,
383
        ResourceNode $parentNode
384
    ): ?ResourceInterface {
385
        $qb = $this->getResourcesByCreator($user, $parentNode);
386
        $this->addTitleQueryBuilder($title, $qb);
387
        $qb->setMaxResults(1);
388
389
        return $qb->getQuery()->getOneOrNullResult();
390
    }
391
392
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null): QueryBuilder
393
    {
394
        $qb = $this->createQueryBuilder('resource')
395
            ->select('resource')
396
            ->innerJoin('resource.resourceNode', 'node')
397
        ;
398
399
        if (null !== $parentNode) {
400
            $qb->andWhere('node.parent = :parentNode');
401
            $qb->setParameter('parentNode', $parentNode);
402
        }
403
404
        $this->addCreatorQueryBuilder($user, $qb);
405
406
        return $qb;
407
    }
408
409
    public function getResourcesByCourseLinkedToUser(
410
        User $user,
411
        Course $course,
412
        Session $session = null,
413
        CGroup $group = null,
414
        ResourceNode $parentNode = null
415
    ): QueryBuilder {
416
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
417
        $qb->andWhere('node.creator = :user OR (links.user = :user OR links.user IS NULL)');
418
        $qb->setParameter('user', $user);
419
420
        return $qb;
421
    }
422
423
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
424
    {
425
        $qb = $this->getResources($parentNode);
426
        $qb
427
            ->andWhere('links.user = :user')
428
            ->setParameter('user', $user)
429
        ;
430
431
        $this->addVisibilityQueryBuilder($qb);
432
433
        return $qb;
434
    }
435
436
    public function getResourceFromResourceNode(int $resourceNodeId): ?ResourceInterface
437
    {
438
        $qb = $this->createQueryBuilder('resource')
439
            ->select('resource')
440
            ->addSelect('node')
441
            ->addSelect('links')
442
            ->innerJoin('resource.resourceNode', 'node')
443
        //    ->innerJoin('node.creator', 'userCreator')
444
            ->leftJoin('node.resourceLinks', 'links')
445
//            ->leftJoin('node.resourceFile', 'file')
446
            ->where('node.id = :id')
447
            ->setParameters([
448
                'id' => $resourceNodeId,
449
            ])
450
        ;
451
452
        return $qb->getQuery()->getOneOrNullResult();
453
    }
454
455
    public function delete(ResourceInterface $resource): void
456
    {
457
        $em = $this->getEntityManager();
458
        $children = $resource->getResourceNode()->getChildren();
459
        foreach ($children as $child) {
460
            if ($child->hasResourceFile()) {
461
                $em->remove($child->getResourceFile());
462
            }
463
            $resourceNode = $this->getResourceFromResourceNode($child->getId());
464
            if (null !== $resourceNode) {
465
                $this->delete($resourceNode);
466
            }
467
        }
468
469
        $em->remove($resource);
470
        $em->flush();
471
    }
472
473
    /**
474
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
475
     * ResourceLinks and ResourceFile (including files via Flysystem).
476
     */
477
    public function hardDelete(AbstractResource $resource): void
478
    {
479
        $em = $this->getEntityManager();
480
        $em->remove($resource);
481
        $em->flush();
482
    }
483
484
    public function getResourceFileContent(AbstractResource $resource): string
485
    {
486
        try {
487
            $resourceNode = $resource->getResourceNode();
488
489
            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

489
            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...
490
        } catch (Throwable $throwable) {
491
            throw new FileNotFoundException($resource->getResourceName());
492
        }
493
    }
494
495
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
496
    {
497
        return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
498
    }
499
500
    /**
501
     * @return false|resource
502
     */
503
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
504
    {
505
        return $this->resourceNodeRepository->getResourceNodeFileStream($resourceNode);
506
    }
507
508
    public function getResourceFileDownloadUrl(AbstractResource $resource, array $extraParams = [], ?int $referenceType = null): string
509
    {
510
        $extraParams['mode'] = 'download';
511
512
        return $this->getResourceFileUrl($resource, $extraParams, $referenceType);
513
    }
514
515
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], ?int $referenceType = null): string
516
    {
517
        return $this->getResourceNodeRepository()->getResourceFileUrl(
518
            $resource->getResourceNode(),
519
            $extraParams,
520
            $referenceType
521
        );
522
    }
523
524
    public function updateResourceFileContent(AbstractResource $resource, string $content): bool
525
    {
526
        $resourceNode = $resource->getResourceNode();
527
        if ($resourceNode->hasResourceFile()) {
528
            $resourceNode->setContent($content);
529
            $resourceNode->getResourceFile()->setSize(\strlen($content));
530
531
            return true;
532
        }
533
534
        return false;
535
    }
536
537
    public function setResourceName(AbstractResource $resource, $title): void
538
    {
539
        if (!empty($title)) {
540
            $resource->setResourceName($title);
541
            $resourceNode = $resource->getResourceNode();
542
            $resourceNode->setTitle($title);
543
        }
544
545
        //if ($resourceNode->hasResourceFile()) {
546
            //$resourceNode->getResourceFile()->getFile()->
547
            //$resourceNode->getResourceFile()->setName($title);
548
            //$resourceFile->setName($title);
549
550
            /*$fileName = $this->getResourceNodeRepository()->getFilename($resourceFile);
551
            error_log('$fileName');
552
            error_log($fileName);
553
            error_log($title);
554
            $this->getResourceNodeRepository()->getFileSystem()->rename($fileName, $title);
555
            $resourceFile->setName($title);
556
            $resourceFile->setOriginalName($title);*/
557
        //}
558
    }
559
560
    /**
561
     * Change all links visibility to DELETED.
562
     */
563
    public function softDelete(AbstractResource $resource): void
564
    {
565
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
566
    }
567
568
    public function toggleVisibilityPublishedDraft(AbstractResource $resource): void
569
    {
570
        $firstLink = $resource->getFirstResourceLink();
571
572
        if (ResourceLink::VISIBILITY_PUBLISHED === $firstLink->getVisibility()) {
573
            $this->setVisibilityDraft($resource);
574
575
            return;
576
        }
577
578
        if (ResourceLink::VISIBILITY_DRAFT === $firstLink->getVisibility()) {
579
            $this->setVisibilityPublished($resource);
580
        }
581
    }
582
583
    public function setVisibilityPublished(AbstractResource $resource): void
584
    {
585
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
586
    }
587
588
    public function setVisibilityDraft(AbstractResource $resource): void
589
    {
590
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
591
    }
592
593
    public function setVisibilityDeleted(AbstractResource $resource): void
594
    {
595
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
596
    }
597
598
    public function setVisibilityPending(AbstractResource $resource): void
599
    {
600
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
601
    }
602
603
    public function addResourceNode(ResourceInterface $resource, User $creator, ResourceInterface $parentResource): ResourceNode
604
    {
605
        $parentResourceNode = $parentResource->getResourceNode();
606
607
        return $this->createNodeForResource($resource, $creator, $parentResourceNode);
608
    }
609
610
    /**
611
     * @todo remove this function and merge it with addResourceNode()
612
     */
613
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode, UploadedFile $file = null): ResourceNode
614
    {
615
        $em = $this->getEntityManager();
616
617
        $resourceType = $this->getResourceType();
618
        $resourceName = $resource->getResourceName();
619
        $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

619
        /** @scrutinizer ignore-call */ 
620
        $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...
620
621
        if (empty($extension)) {
622
            $slug = $this->slugify->slugify($resourceName);
623
        } else {
624
            $originalExtension = pathinfo($resourceName, PATHINFO_EXTENSION);
625
            $originalBasename = basename($resourceName, $originalExtension);
626
            $slug = sprintf('%s.%s', $this->slugify->slugify($originalBasename), $originalExtension);
627
        }
628
629
        $resourceNode = new ResourceNode();
630
        $resourceNode
631
            ->setTitle($resourceName)
632
            ->setSlug($slug)
633
            ->setCreator($creator)
634
            ->setResourceType($resourceType)
635
        ;
636
637
        if (null !== $parentNode) {
638
            $resourceNode->setParent($parentNode);
639
        }
640
641
        $resource->setResourceNode($resourceNode);
642
        $em->persist($resourceNode);
643
        $em->persist($resource);
644
645
        if (null !== $file) {
646
            $this->addFile($resource, $file);
647
        }
648
649
        return $resourceNode;
650
    }
651
652
    /**
653
     * This is only used during installation for the special nodes (admin and AccessUrl).
654
     */
655
    public function createNodeForResourceWithNoParent(ResourceInterface $resource, User $creator): ResourceNode
656
    {
657
        $em = $this->getEntityManager();
658
659
        $resourceType = $this->getResourceType();
660
        $resourceName = $resource->getResourceName();
661
        $slug = $this->slugify->slugify($resourceName);
662
        $resourceNode = new ResourceNode();
663
        $resourceNode
664
            ->setTitle($resourceName)
665
            ->setSlug($slug)
666
            ->setCreator($creator)
667
            ->setResourceType($resourceType)
668
        ;
669
        $resource->setResourceNode($resourceNode);
670
        $em->persist($resourceNode);
671
        $em->persist($resource);
672
673
        return $resourceNode;
674
    }
675
676
    public function getTotalSpaceByCourse(Course $course, CGroup $group = null, Session $session = null): int
677
    {
678
        $qb = $this->createQueryBuilder('resource');
679
        $qb
680
            ->select('SUM(file.size) as total')
681
            ->innerJoin('resource.resourceNode', 'node')
682
            ->innerJoin('node.resourceLinks', 'l')
683
            ->innerJoin('node.resourceFile', 'file')
684
            ->where('l.course = :course')
685
            ->andWhere('l.visibility <> :visibility')
686
            ->andWhere('file IS NOT NULL')
687
            ->setParameters(
688
                [
689
                    'course' => $course,
690
                    'visibility' => ResourceLink::VISIBILITY_DELETED,
691
                ]
692
            )
693
        ;
694
695
        if (null === $group) {
696
            $qb->andWhere('l.group IS NULL');
697
        } else {
698
            $qb
699
                ->andWhere('l.group = :group')
700
                ->setParameter('group', $group)
701
            ;
702
        }
703
704
        if (null === $session) {
705
            $qb->andWhere('l.session IS NULL');
706
        } else {
707
            $qb
708
                ->andWhere('l.session = :session')
709
                ->setParameter('session', $session)
710
            ;
711
        }
712
713
        $query = $qb->getQuery();
714
715
        return (int) $query->getSingleScalarResult();
716
    }
717
718
    public function addTitleDecoration(AbstractResource $resource, Course $course, Session $session = null): string
719
    {
720
        if (null === $session) {
721
            return '';
722
        }
723
724
        $link = $resource->getFirstResourceLinkFromCourseSession($course, $session);
725
        if (null === $link) {
726
            return '';
727
        }
728
729
        return '<img title="'.$session->getName().'" src="/img/icons/22/star.png" />';
730
    }
731
732
    public function isGranted(string $subject, AbstractResource $resource): bool
733
    {
734
        return $this->getAuthorizationChecker()->isGranted($subject, $resource->getResourceNode());
735
    }
736
737
    /**
738
     * Changes the visibility of the children that matches the exact same link.
739
     */
740
    public function copyVisibilityToChildren(ResourceNode $resourceNode, ResourceLink $link): bool
741
    {
742
        $children = $resourceNode->getChildren();
743
744
        if (0 === $children->count()) {
745
            return false;
746
        }
747
748
        $em = $this->getEntityManager();
749
750
        /** @var ResourceNode $child */
751
        foreach ($children as $child) {
752
            if ($child->getChildren()->count() > 0) {
753
                $this->copyVisibilityToChildren($child, $link);
754
            }
755
756
            $links = $child->getResourceLinks();
757
            foreach ($links as $linkItem) {
758
                if ($linkItem->getUser() === $link->getUser() &&
759
                    $linkItem->getSession() === $link->getSession() &&
760
                    $linkItem->getCourse() === $link->getCourse() &&
761
                    $linkItem->getUserGroup() === $link->getUserGroup()
762
                ) {
763
                    $linkItem->setVisibility($link->getVisibility());
764
                    $em->persist($linkItem);
765
                }
766
            }
767
        }
768
769
        $em->flush();
770
771
        return true;
772
    }
773
774
    protected function addSlugQueryBuilder(?string $slug, QueryBuilder $qb = null): QueryBuilder
775
    {
776
        $qb = $this->getOrCreateQueryBuilder($qb);
777
        if (null === $slug) {
778
            return $qb;
779
        }
780
781
        $qb
782
            ->andWhere('node.slug = :slug')
783
            ->setParameter('slug', $slug)
784
        ;
785
786
        return $qb;
787
    }
788
789
    protected function addTitleQueryBuilder(?string $title, QueryBuilder $qb = null): QueryBuilder
790
    {
791
        $qb = $this->getOrCreateQueryBuilder($qb);
792
        if (null === $title) {
793
            return $qb;
794
        }
795
796
        $qb
797
            ->andWhere('node.title = :title')
798
            ->setParameter('title', $title)
799
        ;
800
801
        return $qb;
802
    }
803
804
    protected function addCreatorQueryBuilder(?User $user, QueryBuilder $qb = null): QueryBuilder
805
    {
806
        $qb = $this->getOrCreateQueryBuilder($qb);
807
        if (null === $user) {
808
            return $qb;
809
        }
810
811
        $qb
812
            ->andWhere('node.creator = :creator')
813
            ->setParameter('creator', $user)
814
        ;
815
816
        return $qb;
817
    }
818
819
    private function setLinkVisibility(AbstractResource $resource, int $visibility, bool $recursive = true): bool
820
    {
821
        $resourceNode = $resource->getResourceNode();
822
823
        if (null === $resourceNode) {
824
            return false;
825
        }
826
827
        $em = $this->getEntityManager();
828
        if ($recursive) {
829
            $children = $resourceNode->getChildren();
830
            if (!empty($children)) {
831
                /** @var ResourceNode $child */
832
                foreach ($children as $child) {
833
                    $criteria = [
834
                        'resourceNode' => $child,
835
                    ];
836
                    $childDocument = $this->findOneBy($criteria);
837
                    if ($childDocument) {
838
                        $this->setLinkVisibility($childDocument, $visibility);
839
                    }
840
                }
841
            }
842
        }
843
844
        $links = $resourceNode->getResourceLinks();
845
846
        if (!empty($links)) {
847
            /** @var ResourceLink $link */
848
            foreach ($links as $link) {
849
                $link->setVisibility($visibility);
850
                if (ResourceLink::VISIBILITY_DRAFT === $visibility) {
851
                    $editorMask = ResourceNodeVoter::getEditorMask();
852
                    $resourceRight = (new ResourceRight())
853
                        ->setMask($editorMask)
854
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
855
                        ->setResourceLink($link)
856
                    ;
857
                    $link->addResourceRight($resourceRight);
858
                } else {
859
                    $link->setResourceRights(new ArrayCollection());
860
                }
861
                $em->persist($link);
862
            }
863
        }
864
        $em->flush();
865
866
        return true;
867
    }
868
}
869