Passed
Push — master ( b1e54d...4a0c08 )
by Julito
07:58
created

ResourceRepository::findCourseResourcesByTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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

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

603
            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...
604
        } catch (Throwable $throwable) {
605
            throw new FileNotFoundException($resource->getResourceName());
606
        }
607
    }
608
609
    public function getResourceNodeFileContent(ResourceNode $resourceNode): string
610
    {
611
        return $this->resourceNodeRepository->getResourceNodeFileContent($resourceNode);
612
    }
613
614
    public function getResourceNodeFileStream(ResourceNode $resourceNode)
615
    {
616
        return $this->resourceNodeRepository->getResourceNodeFileStream($resourceNode);
617
    }
618
619
    public function getResourceFileDownloadUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
620
    {
621
        $extraParams['mode'] = 'download';
622
623
        return $this->getResourceFileUrl($resource, $extraParams, $referenceType);
624
    }
625
626
    public function getResourceFileUrl(AbstractResource $resource, array $extraParams = [], $referenceType = null): string
627
    {
628
        try {
629
            $resourceNode = $resource->getResourceNode();
630
            if ($resourceNode->hasResourceFile()) {
631
                $params = [
632
                    'tool' => $resourceNode->getResourceType()->getTool(),
633
                    'type' => $resourceNode->getResourceType(),
634
                    'id' => $resourceNode->getId(),
635
                ];
636
637
                if (!empty($extraParams)) {
638
                    $params = array_merge($params, $extraParams);
639
                }
640
641
                $referenceType ??= UrlGeneratorInterface::ABSOLUTE_PATH;
642
643
                $mode = $params['mode'] ?? 'view';
644
                // Remove mode from params and sent directly to the controller.
645
                unset($params['mode']);
646
647
                switch ($mode) {
648
                    case 'download':
649
                        return $this->router->generate('chamilo_core_resource_download', $params, $referenceType);
0 ignored issues
show
Bug introduced by
The method generate() 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

649
                        return $this->router->/** @scrutinizer ignore-call */ generate('chamilo_core_resource_download', $params, $referenceType);

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...
650
                    case 'view':
651
                        return $this->router->generate('chamilo_core_resource_view', $params, $referenceType);
652
                }
653
            }
654
655
            return '';
656
        } catch (Throwable $exception) {
657
            throw new FileNotFoundException($resource->getResourceName());
658
        }
659
    }
660
661
    /**
662
     * @return bool
663
     */
664
    public function updateResourceFileContent(AbstractResource $resource, string $content)
665
    {
666
        error_log('updateResourceFileContent');
667
668
        $resourceNode = $resource->getResourceNode();
669
        if ($resourceNode->hasResourceFile()) {
670
            $resourceNode->setContent($content);
671
            error_log('updated');
672
            $resourceNode->getResourceFile()->setSize(\strlen($content));
673
            /*
674
            error_log('has file');
675
            $resourceFile = $resourceNode->getResourceFile();
676
            if ($resourceFile) {
677
                error_log('$resourceFile');
678
                $title = $resource->getResourceName();
679
                $handle = tmpfile();
680
                fwrite($handle, $content);
681
                error_log($title);
682
                error_log($content);
683
                $meta = stream_get_meta_data($handle);
684
                $file = new UploadedFile($meta['uri'], $title, 'text/html', null, true);
685
                $resource->setUploadFile($file);
686
687
                return true;
688
            }*/
689
        }
690
        error_log('false');
691
692
        return false;
693
    }
694
695
    public function setResourceName(AbstractResource $resource, $title): void
696
    {
697
        $resource->setResourceName($title);
698
        $resourceNode = $resource->getResourceNode();
699
        $resourceNode->setTitle($title);
700
        if ($resourceNode->hasResourceFile()) {
701
            //$resourceNode->getResourceFile()->getFile()->
702
            //$resourceNode->getResourceFile()->setName($title);
703
            //$resourceFile->setName($title);
704
705
            /*$fileName = $this->getResourceNodeRepository()->getFilename($resourceFile);
706
            error_log('$fileName');
707
            error_log($fileName);
708
            error_log($title);
709
            $this->getResourceNodeRepository()->getFileSystem()->rename($fileName, $title);
710
            $resourceFile->setName($title);
711
            $resourceFile->setOriginalName($title);*/
712
        }
713
    }
714
715
    /**
716
     * Change all links visibility to DELETED.
717
     */
718
    public function softDelete(AbstractResource $resource): void
719
    {
720
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
721
    }
722
723
    public function setVisibilityPublished(AbstractResource $resource): void
724
    {
725
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PUBLISHED);
726
    }
727
728
    public function setVisibilityDeleted(AbstractResource $resource): void
729
    {
730
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DELETED);
731
    }
732
733
    public function setVisibilityDraft(AbstractResource $resource): void
734
    {
735
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_DRAFT);
736
    }
737
738
    public function setVisibilityPending(AbstractResource $resource): void
739
    {
740
        $this->setLinkVisibility($resource, ResourceLink::VISIBILITY_PENDING);
741
    }
742
743
    public function createNodeForResource(ResourceInterface $resource, User $creator, ResourceNode $parentNode = null, UploadedFile $file = null): ResourceNode
744
    {
745
        $em = $this->getEntityManager();
746
747
        $resourceType = $this->getResourceType();
748
        $resourceName = $resource->getResourceName();
749
        $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

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