Passed
Push — master ( 9ac6fa...c6fd81 )
by Julito
10:12
created

ResourceRepository::updateNodeForResource()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 37
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 16
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 37
rs 9.7333
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\Component\Utils\CreateUploadedFile;
12
use Chamilo\CoreBundle\Entity\AbstractResource;
13
use Chamilo\CoreBundle\Entity\Course;
14
use Chamilo\CoreBundle\Entity\ResourceFile;
15
use Chamilo\CoreBundle\Entity\ResourceInterface;
16
use Chamilo\CoreBundle\Entity\ResourceLink;
17
use Chamilo\CoreBundle\Entity\ResourceNode;
18
use Chamilo\CoreBundle\Entity\ResourceRight;
19
use Chamilo\CoreBundle\Entity\ResourceType;
20
use Chamilo\CoreBundle\Entity\Session;
21
use Chamilo\CoreBundle\Entity\User;
22
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
23
use Chamilo\CoreBundle\Traits\NonResourceRepository;
24
use Chamilo\CoreBundle\Traits\Repository\RepositoryQueryBuilderTrait;
25
use Chamilo\CourseBundle\Entity\CGroup;
26
use DateTime;
27
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
28
use Doctrine\Common\Collections\ArrayCollection;
29
use Doctrine\DBAL\Types\Types;
30
use Doctrine\ORM\EntityRepository;
31
use Doctrine\ORM\QueryBuilder;
32
use Exception;
33
use LogicException;
34
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
35
use Symfony\Component\Form\FormFactory;
36
use Symfony\Component\Form\FormInterface;
37
use Symfony\Component\HttpFoundation\File\UploadedFile;
38
use Throwable;
39
40
/**
41
 * Extends EntityRepository is needed to process settings.
42
 */
43
abstract class ResourceRepository extends ServiceEntityRepository
44
{
45
    use NonResourceRepository;
46
    use RepositoryQueryBuilderTrait;
47
48
    protected Settings $settings;
49
    protected Template $templates;
50
    protected ?ResourceType $resourceType = null;
51
52
    public function setSettings(Settings $settings): self
53
    {
54
        $this->settings = $settings;
55
56
        return $this;
57
    }
58
59
    public function setTemplates(Template $templates): self
60
    {
61
        $this->templates = $templates;
62
63
        return $this;
64
    }
65
66
    public function getResourceSettings(): Settings
67
    {
68
        return $this->settings;
69
    }
70
71
    public function getTemplates(): Template
72
    {
73
        return $this->templates;
74
    }
75
76
    public function getClassName(): string
77
    {
78
        $class = static::class;
79
        //Chamilo\CoreBundle\Repository\Node\IllustrationRepository
80
        $class = str_replace('\\Repository\\', '\\Entity\\', $class);
81
        $class = str_replace('Repository', '', $class);
82
        if (!class_exists($class)) {
83
            throw new Exception(sprintf('Repo: %s not found ', $class));
84
        }
85
86
        return $class;
87
    }
88
89
    public function getCount(QueryBuilder $qb): int
90
    {
91
        $qb->select('count(resource)');
92
        $qb->setMaxResults(1);
93
94
        return (int) $qb->getQuery()->getSingleScalarResult();
95
    }
96
97
    /**
98
     * @return FormInterface
99
     */
100
    public function getForm(FormFactory $formFactory, ResourceInterface $resource = null, array $options = [])
101
    {
102
        $formType = $this->getResourceFormType();
103
104
        if (null === $resource) {
105
            $className = $this->repository->getClassName();
106
            $resource = new $className();
107
        }
108
109
        return $formFactory->create($formType, $resource, $options);
110
    }
111
112
    public function getResourceByResourceNode(ResourceNode $resourceNode): ?ResourceInterface
113
    {
114
        return $this->findOneBy([
115
            'resourceNode' => $resourceNode,
116
        ]);
117
    }
118
119
    public function create(AbstractResource $resource): void
120
    {
121
        $this->getEntityManager()->persist($resource);
122
        $this->getEntityManager()->flush();
123
    }
124
125
    public function update(AbstractResource | User $resource, bool $andFlush = true): void
126
    {
127
        if (!$resource->hasResourceNode()) {
128
            throw new Exception('Resource needs a resource node');
129
        }
130
131
        $resource->getResourceNode()->setUpdatedAt(new DateTime());
132
        $resource->getResourceNode()->setTitle($resource->getResourceName());
133
        $this->getEntityManager()->persist($resource);
134
135
        if ($andFlush) {
136
            $this->getEntityManager()->flush();
137
        }
138
    }
139
140
    public function updateNodeForResource(ResourceInterface $resource): ResourceNode
141
    {
142
        $em = $this->getEntityManager();
143
144
        $resourceNode = $resource->getResourceNode();
145
        $resourceName = $resource->getResourceName();
146
147
        if ($resourceNode->hasResourceFile()) {
148
            $resourceFile = $resourceNode->getResourceFile();
149
            if (null !== $resourceFile) {
150
                $originalName = $resourceFile->getOriginalName();
151
                $originalExtension = pathinfo($originalName, PATHINFO_EXTENSION);
152
153
                //$originalBasename = \basename($resourceName, $originalExtension);
154
                /*$slug = sprintf(
155
                    '%s.%s',
156
                    $this->slugify->slugify($originalBasename),
157
                    $this->slugify->slugify($originalExtension)
158
                );*/
159
160
                $newOriginalName = sprintf('%s.%s', $resourceName, $originalExtension);
161
                $resourceFile->setOriginalName($newOriginalName);
162
163
                $em->persist($resourceFile);
164
            }
165
        }
166
        //$slug = $this->slugify->slugify($resourceName);
167
168
        $resourceNode->setTitle($resourceName);
169
        //$resourceNode->setSlug($slug);
170
171
        $em->persist($resourceNode);
172
        $em->persist($resource);
173
174
        $em->flush();
175
176
        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...
177
    }
178
179
    public function findCourseResourceByTitle(
180
        string $title,
181
        ResourceNode $parentNode,
182
        Course $course,
183
        Session $session = null,
184
        CGroup $group = null
185
    ): ?ResourceInterface {
186
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
187
        $this->addTitleQueryBuilder($title, $qb);
188
        $qb->setMaxResults(1);
189
190
        return $qb->getQuery()->getOneOrNullResult();
191
    }
192
193
    /**
194
     * @return ResourceInterface[]
195
     */
196
    public function findCourseResourcesByTitle(
197
        string $title,
198
        ResourceNode $parentNode,
199
        Course $course,
200
        Session $session = null,
201
        CGroup $group = null
202
    ) {
203
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
204
        $this->addTitleQueryBuilder($title, $qb);
205
206
        return $qb->getQuery()->getResult();
207
    }
208
209
    /**
210
     * @todo clean path
211
     */
212
    public function addFileFromPath(ResourceInterface $resource, string $fileName, string $path, bool $flush = true): ?ResourceFile
213
    {
214
        if (!empty($path) && file_exists($path) && !is_dir($path)) {
215
            $mimeType = mime_content_type($path);
216
            $file = new UploadedFile($path, $fileName, $mimeType, null, true);
217
218
            return $this->addFile($resource, $file, '', $flush);
219
        }
220
221
        return null;
222
    }
223
224
    public function addFileFromString(ResourceInterface $resource, string $fileName, string $mimeType, string $content, bool $flush = true): ?ResourceFile
225
    {
226
        $file = CreateUploadedFile::fromString($fileName, $mimeType, $content);
227
228
        return $this->addFile($resource, $file, '', $flush);
229
    }
230
231
    public function addFileFromFileRequest(ResourceInterface $resource, string $fileKey, bool $flush = true): ?ResourceFile
232
    {
233
        $request = $this->getRequest();
234
        if ($request->files->has($fileKey)) {
235
            $file = $request->files->get($fileKey);
236
            if (null !== $file) {
237
                $resourceFile = $this->addFile($resource, $file);
238
                if ($flush) {
239
                    $this->getEntityManager()->flush();
240
                }
241
242
                return $resourceFile;
243
            }
244
        }
245
246
        return null;
247
    }
248
249
    public function addFile(ResourceInterface $resource, UploadedFile $file, string $description = '', bool $flush = false): ?ResourceFile
250
    {
251
        $resourceNode = $resource->getResourceNode();
252
253
        if (null === $resourceNode) {
254
            throw new LogicException('Resource node is null');
255
        }
256
257
        $resourceFile = $resourceNode->getResourceFile();
258
        if (null === $resourceFile) {
259
            $resourceFile = new ResourceFile();
260
        }
261
262
        $em = $this->getEntityManager();
263
        $resourceFile
264
            ->setFile($file)
265
            ->setDescription($description)
266
            ->setName($resource->getResourceName())
267
            ->setResourceNode($resourceNode)
268
        ;
269
        $em->persist($resourceFile);
270
        $resourceNode->setResourceFile($resourceFile);
271
        $em->persist($resourceNode);
272
273
        if ($flush) {
274
            $em->flush();
275
        }
276
277
        return $resourceFile;
278
    }
279
280
    public function getResourceType(): ?ResourceType
281
    {
282
        $name = $this->getResourceTypeName();
283
        $repo = $this->getEntityManager()->getRepository(ResourceType::class);
284
        $this->resourceType = $repo->findOneBy([
285
            'name' => $name,
286
        ]);
287
288
        return $this->resourceType;
289
    }
290
291
    public function getResourceTypeName(): string
292
    {
293
        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

293
        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...
294
    }
295
296
    public function addVisibilityQueryBuilder(QueryBuilder $qb = null): QueryBuilder
297
    {
298
        $qb = $this->getOrCreateQueryBuilder($qb);
299
300
        $checker = $this->getAuthorizationChecker();
301
        $isAdmin =
302
            $checker->isGranted('ROLE_ADMIN') ||
303
            $checker->isGranted('ROLE_CURRENT_COURSE_TEACHER');
304
305
        // Do not show deleted resources.
306
        $qb
307
            ->andWhere('links.visibility != :visibilityDeleted')
308
            ->setParameter('visibilityDeleted', ResourceLink::VISIBILITY_DELETED, Types::INTEGER)
309
        ;
310
311
        if (!$isAdmin) {
312
            $qb
313
                ->andWhere('links.visibility = :visibility')
314
                ->setParameter('visibility', ResourceLink::VISIBILITY_PUBLISHED, Types::INTEGER)
315
            ;
316
            // @todo Add start/end visibility restrictions.
317
        }
318
319
        return $qb;
320
    }
321
322
    public function addCourseQueryBuilder(Course $course, QueryBuilder $qb): QueryBuilder
323
    {
324
        $qb
325
            ->andWhere('links.course = :course')
326
            ->setParameter('course', $course)
327
        ;
328
329
        return $qb;
330
    }
331
332
    public function addCourseSessionGroupQueryBuilder(Course $course, Session $session = null, CGroup $group = null, QueryBuilder $qb = null): QueryBuilder
333
    {
334
        $reflectionClass = $this->getClassMetadata()->getReflectionClass();
335
336
        // Check if this resource type requires to load the base course resources when using a session
337
        $loadBaseSessionContent = $reflectionClass->hasProperty('loadCourseResourcesInSession');
338
339
        $this->addCourseQueryBuilder($course, $qb);
340
341
        if (null === $session) {
342
            $qb->andWhere(
343
                $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

343
                $qb->/** @scrutinizer ignore-call */ 
344
                     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...
344
                    $qb->expr()->isNull('links.session'),
345
                    $qb->expr()->eq('links.session', 0)
346
                )
347
            );
348
        } elseif ($loadBaseSessionContent) {
349
            // Load course base content.
350
            $qb->andWhere('links.session = :session OR links.session IS NULL');
351
            $qb->setParameter('session', $session);
352
        } else {
353
            // Load only session resources.
354
            $qb->andWhere('links.session = :session');
355
            $qb->setParameter('session', $session);
356
        }
357
358
        if (null === $group) {
359
            $qb->andWhere(
360
                $qb->expr()->orX(
361
                    $qb->expr()->isNull('links.group'),
362
                    $qb->expr()->eq('links.group', 0)
363
                )
364
            );
365
        } else {
366
            $qb->andWhere('links.group = :group');
367
            $qb->setParameter('group', $group);
368
        }
369
370
        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...
371
    }
372
373
    public function getResources(ResourceNode $parentNode = null): QueryBuilder
374
    {
375
        $resourceTypeName = $this->getResourceTypeName();
376
377
        $qb = $this->createQueryBuilder('resource')
378
            ->select('resource')
379
            ->innerJoin('resource.resourceNode', 'node')
380
            ->innerJoin('node.resourceLinks', 'links')
381
            ->innerJoin('node.resourceType', 'type')
382
            ->leftJoin('node.resourceFile', 'file')
383
            ->where('type.name = :type')
384
            ->setParameter('type', $resourceTypeName, Types::STRING)
385
            ->addSelect('node')
386
            ->addSelect('links')
387
            ->addSelect('type')
388
            ->addSelect('file')
389
        ;
390
391
        if (null !== $parentNode) {
392
            $qb->andWhere('node.parent = :parentNode');
393
            $qb->setParameter('parentNode', $parentNode);
394
        }
395
396
        return $qb;
397
    }
398
399
    public function getResourcesByCourse(Course $course, Session $session = null, CGroup $group = null, ResourceNode $parentNode = null): QueryBuilder
400
    {
401
        $qb = $this->getResources($parentNode);
402
        $this->addVisibilityQueryBuilder($qb);
403
        $this->addCourseSessionGroupQueryBuilder($course, $session, $group, $qb);
404
405
        return $qb;
406
    }
407
408
    /**
409
     * Get resources only from the base course.
410
     */
411
    public function getResourcesByCourseOnly(Course $course, ResourceNode $parentNode = null): QueryBuilder
412
    {
413
        $qb = $this->getResources($parentNode);
414
        $this->addCourseQueryBuilder($course, $qb);
415
        $this->addVisibilityQueryBuilder($qb);
416
417
        return $qb;
418
    }
419
420
    public function getResourceByCreatorFromTitle(
421
        string $title,
422
        User $user,
423
        ResourceNode $parentNode
424
    ): ?ResourceInterface {
425
        $qb = $this->getResourcesByCreator($user, $parentNode);
426
        $this->addTitleQueryBuilder($title, $qb);
427
        $qb->setMaxResults(1);
428
429
        return $qb->getQuery()->getOneOrNullResult();
430
    }
431
432
    public function getResourcesByCreator(User $user, ResourceNode $parentNode = null): QueryBuilder
433
    {
434
        $qb = $this->createQueryBuilder('resource')
435
            ->select('resource')
436
            ->innerJoin('resource.resourceNode', 'node')
437
        ;
438
439
        if (null !== $parentNode) {
440
            $qb->andWhere('node.parent = :parentNode');
441
            $qb->setParameter('parentNode', $parentNode);
442
        }
443
444
        $this->addCreatorQueryBuilder($user, $qb);
445
446
        return $qb;
447
    }
448
449
    public function getResourcesByCourseLinkedToUser(
450
        User $user,
451
        Course $course,
452
        Session $session = null,
453
        CGroup $group = null,
454
        ResourceNode $parentNode = null
455
    ): QueryBuilder {
456
        $qb = $this->getResourcesByCourse($course, $session, $group, $parentNode);
457
        $qb->andWhere('node.creator = :user OR (links.user = :user OR links.user IS NULL)');
458
        $qb->setParameter('user', $user);
459
460
        return $qb;
461
    }
462
463
    public function getResourcesByLinkedUser(User $user, ResourceNode $parentNode = null): QueryBuilder
464
    {
465
        $qb = $this->getResources($parentNode);
466
        $qb
467
            ->andWhere('links.user = :user')
468
            ->setParameter('user', $user)
469
        ;
470
471
        $this->addVisibilityQueryBuilder($qb);
472
473
        return $qb;
474
    }
475
476
    public function getResourceFromResourceNode(int $resourceNodeId): ?ResourceInterface
477
    {
478
        $qb = $this->createQueryBuilder('resource')
479
            ->select('resource')
480
            ->addSelect('node')
481
            ->addSelect('links')
482
            ->innerJoin('resource.resourceNode', 'node')
483
        //    ->innerJoin('node.creator', 'userCreator')
484
            ->innerJoin('node.resourceLinks', 'links')
485
//            ->leftJoin('node.resourceFile', 'file')
486
            ->where('node.id = :id')
487
            ->setParameters([
488
                'id' => $resourceNodeId,
489
            ])
490
            //->addSelect('node')
491
        ;
492
493
        return $qb->getQuery()->getOneOrNullResult();
494
    }
495
496
    public function delete(ResourceInterface $resource): void
497
    {
498
        $children = $resource->getResourceNode()->getChildren();
499
        foreach ($children as $child) {
500
            if ($child->hasResourceFile()) {
501
                $this->getEntityManager()->remove($child->getResourceFile());
502
            }
503
            $resourceNode = $this->getResourceFromResourceNode($child->getId());
504
            if (null !== $resourceNode) {
505
                $this->delete($resourceNode);
506
            }
507
        }
508
        $this->getEntityManager()->remove($resource);
509
        $this->getEntityManager()->flush();
510
    }
511
512
    /**
513
     * Deletes several entities: AbstractResource (Ex: CDocument, CQuiz), ResourceNode,
514
     * ResourceLinks and ResourceFile (including files via Flysystem).
515
     */
516
    public function hardDelete(AbstractResource $resource): void
517
    {
518
        $em = $this->getEntityManager();
519
        $em->remove($resource);
520
        $em->flush();
521
    }
522
523
    public function getResourceFileContent(AbstractResource $resource): string
524
    {
525
        try {
526
            $resourceNode = $resource->getResourceNode();
527
528
            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

528
            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...
529
        } catch (Throwable $throwable) {
530
            throw new FileNotFoundException($resource->getResourceName());
531
        }
532
    }
533
534
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
535
    {
536
        return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
537
    }
538
539
    /**
540
     * @return false|resource
541
     */
542
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
543
    {
544
        return $this->resourceNodeRepository->getResourceNodeFileStream($resourceNode);
545
    }
546
547
    public function getResourceFileDownloadUrl(AbstractResource $resource, array $extraParams = [], ?int $referenceType = null): string
548
    {
549
        $extraParams['mode'] = 'download';
550
551
        return $this->getResourceFileUrl($resource, $extraParams, $referenceType);
552
    }
553
554
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], ?int $referenceType = null): string
555
    {
556
        return $this->getResourceNodeRepository()->getResourceFileUrl(
557
            $resource->getResourceNode(),
558
            $extraParams,
559
            $referenceType
560
        );
561
    }
562
563
    /**
564
     * @return bool
565
     */
566
    public function updateResourceFileContent(AbstractResource $resource, string $content)
567
    {
568
        error_log('updateResourceFileContent');
569
570
        $resourceNode = $resource->getResourceNode();
571
        if ($resourceNode->hasResourceFile()) {
572
            $resourceNode->setContent($content);
573
            $resourceNode->getResourceFile()->setSize(\strlen($content));
574
        }
575
576
        return false;
577
    }
578
579
    public function setResourceName(AbstractResource $resource, $title): void
580
    {
581
        if (!empty($title)) {
582
            $resource->setResourceName($title);
583
            $resourceNode = $resource->getResourceNode();
584
            $resourceNode->setTitle($title);
585
        }
586
587
        //if ($resourceNode->hasResourceFile()) {
588
            //$resourceNode->getResourceFile()->getFile()->
589
            //$resourceNode->getResourceFile()->setName($title);
590
            //$resourceFile->setName($title);
591
592
            /*$fileName = $this->getResourceNodeRepository()->getFilename($resourceFile);
593
            error_log('$fileName');
594
            error_log($fileName);
595
            error_log($title);
596
            $this->getResourceNodeRepository()->getFileSystem()->rename($fileName, $title);
597
            $resourceFile->setName($title);
598
            $resourceFile->setOriginalName($title);*/
599
        //}
600
    }
601
602
    /**
603
     * Change all links visibility to DELETED.
604
     */
605
    public function softDelete(AbstractResource $resource): void
606
    {
607
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
608
    }
609
610
    public function setVisibilityPublished(AbstractResource $resource): void
611
    {
612
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
613
    }
614
615
    public function setVisibilityDeleted(AbstractResource $resource): void
616
    {
617
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
618
    }
619
620
    public function setVisibilityDraft(AbstractResource $resource): void
621
    {
622
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
623
    }
624
625
    public function setVisibilityPending(AbstractResource $resource): void
626
    {
627
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
628
    }
629
630
    public function addResourceNode(ResourceInterface $resource, User $creator, ResourceInterface $parentResource): ResourceNode
631
    {
632
        $parentResourceNode = $parentResource->getResourceNode();
633
634
        return $this->createNodeForResource($resource, $creator, $parentResourceNode);
635
    }
636
637
    /**
638
     * @todo remove this function and merge it with addResourceNode()
639
     */
640
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode, UploadedFile $file = null): ResourceNode
641
    {
642
        $em = $this->getEntityManager();
643
644
        $resourceType = $this->getResourceType();
645
        $resourceName = $resource->getResourceName();
646
        $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

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