Passed
Push — master ( 619086...47480f )
by Julito
10:49
created

createNodeForResourceWithNoParent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 19
rs 9.7998
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
    /**
251
     * @todo clean path
252
     */
253
    public function addFileFromPath(ResourceInterface $resource, string $fileName, string $path, bool $flush = true)
254
    {
255
        if (!empty($path) && file_exists($path) && !is_dir($path)) {
256
            $mimeType = mime_content_type($path);
257
            $file = new UploadedFile($path, $fileName, $mimeType, null, true);
258
259
            return $this->addFile($resource, $file, '', $flush);
260
        }
261
262
        return null;
263
    }
264
265
    public function addFileFromString(ResourceInterface $resource, string $fileName, string $mimeType, string $content, bool $flush = true): ?ResourceFile
266
    {
267
        $handle = tmpfile();
268
        fwrite($handle, $content);
269
        $meta = stream_get_meta_data($handle);
270
        $file = new UploadedFile($meta['uri'], $fileName, $mimeType, null, true);
271
272
        return $this->addFile($resource, $file, '', $flush);
273
    }
274
275
    public function addFileFromFileRequest(ResourceInterface $resource, string $fileKey, bool $flush = true): ?ResourceFile
276
    {
277
        $request = $this->getRequest();
278
        if ($request->files->has($fileKey)) {
279
            $file = $request->files->get($fileKey);
280
            if (null !== $file) {
281
                $resourceFile = $this->addFile($resource, $file);
282
                if ($flush) {
283
                    $this->getEntityManager()->flush();
284
                }
285
286
                return $resourceFile;
287
            }
288
        }
289
290
        return null;
291
    }
292
293
    public function addFile(ResourceInterface $resource, UploadedFile $file, string $description = '', bool $flush = false): ?ResourceFile
294
    {
295
        $resourceNode = $resource->getResourceNode();
296
297
        if (null === $resourceNode) {
298
            throw new LogicException('Resource node is null');
299
        }
300
301
        $resourceFile = $resourceNode->getResourceFile();
302
        if (null === $resourceFile) {
303
            $resourceFile = new ResourceFile();
304
        }
305
306
        $em = $this->getEntityManager();
307
        $resourceFile
308
            ->setFile($file)
309
            ->setDescription($description)
310
            ->setName($resource->getResourceName())
311
            ->setResourceNode($resourceNode)
312
        ;
313
        $em->persist($resourceFile);
314
        $resourceNode->setResourceFile($resourceFile);
315
        $em->persist($resourceNode);
316
317
        if ($flush) {
318
            $em->flush();
319
        }
320
321
        return $resourceFile;
322
    }
323
324
    public function getResourceType(): ?ResourceType
325
    {
326
        $name = $this->getResourceTypeName();
327
        $repo = $this->getEntityManager()->getRepository(ResourceType::class);
328
        $this->resourceType = $repo->findOneBy([
329
            'name' => $name,
330
        ]);
331
332
        return $this->resourceType;
333
    }
334
335
    public function getResourceTypeName(): string
336
    {
337
        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

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

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

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

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