Completed
Push — master ( 3de9bb...339b13 )
by Julito
09:11
created

ResourceNode::setResourceLinks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Entity;
6
7
use ApiPlatform\Core\Annotation\ApiFilter;
8
use ApiPlatform\Core\Annotation\ApiResource;
9
use ApiPlatform\Core\Annotation\ApiSubresource;
10
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
11
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
12
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
13
use Chamilo\CoreBundle\Traits\TimestampableAgoTrait;
14
use Doctrine\Common\Collections\ArrayCollection;
15
use Doctrine\Common\Collections\Criteria;
16
use Doctrine\ORM\Mapping as ORM;
17
use Gedmo\Mapping\Annotation as Gedmo;
18
use Gedmo\Timestampable\Traits\TimestampableEntity;
19
use Ramsey\Uuid\Uuid;
20
use Ramsey\Uuid\UuidInterface;
21
use Symfony\Component\Routing\RouterInterface;
22
use Symfony\Component\Serializer\Annotation\Groups;
23
use Symfony\Component\Validator\Constraints as Assert;
24
25
//*     attributes={"security"="is_granted('ROLE_ADMIN')"},
26
/**
27
 * Base entity for all resources.
28
 *
29
 * @ApiResource(
30
 *     collectionOperations={"get"},
31
 *     normalizationContext={"groups"={"resource_node:read", "document:read"}},
32
 *     denormalizationContext={"groups"={"resource_node:write", "document:write"}}
33
 * )
34
 * @ApiFilter(SearchFilter::class, properties={"title": "partial"})
35
 * @ApiFilter(PropertyFilter::class)
36
 * @ApiFilter(OrderFilter::class, properties={"id", "title", "resourceFile", "createdAt", "updatedAt"})
37
 * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Repository\ResourceNodeRepository")
38
 *
39
 * @ORM\HasLifecycleCallbacks
40
 * @ORM\Table(name="resource_node")
41
 * @ORM\EntityListeners({"Chamilo\CoreBundle\Entity\Listener\ResourceNodeListener"})
42
 *
43
 * @Gedmo\Tree(type="materializedPath")
44
 */
45
class ResourceNode
46
{
47
    use TimestampableEntity;
48
    use TimestampableAgoTrait;
49
50
    public const PATH_SEPARATOR = '/';
51
52
    /**
53
     * @Groups({"resource_node:read", "document:read"})
54
     * @ORM\Id
55
     * @ORM\Column(type="integer")
56
     * @ORM\GeneratedValue(strategy="AUTO")
57
     */
58
    protected $id;
59
60
    /**
61
     * @Assert\NotBlank()
62
     * @Groups({"resource_node:read", "resource_node:write", "document:read", "document:write"})
63
     * @Gedmo\TreePathSource
64
     *
65
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
66
     */
67
    protected $title;
68
69
    /**
70
     * @Assert\NotBlank()
71
     *
72
     * @Gedmo\Slug(fields={"title"})
73
     * @ORM\Column(name="slug", type="string", length=255, nullable=false)
74
     */
75
    protected $slug;
76
77
    /**
78
     * @var UuidInterface|null
79
     *
80
     * @ORM\Column(type="uuid", unique=true)
81
     */
82
    protected $uuid;
83
84
    /**
85
     * @ORM\ManyToOne(targetEntity="ResourceType", inversedBy="resourceNodes")
86
     * @ORM\JoinColumn(name="resource_type_id", referencedColumnName="id", nullable=false)
87
     */
88
    protected $resourceType;
89
90
    /**
91
     * @ApiSubresource()
92
     *
93
     * @var ResourceLink[]
94
     *
95
     * @ORM\OneToMany(targetEntity="ResourceLink", mappedBy="resourceNode", cascade={"persist", "remove"})
96
     */
97
    protected $resourceLinks;
98
99
    /**
100
     * @var ResourceFile available file for this node
101
     *
102
     * @Groups({"resource_node:read", "resource_node:write", "document:read", "document:write"})
103
     *
104
     * @ORM\OneToOne(targetEntity="ResourceFile", inversedBy="resourceNode", orphanRemoval=true)
105
     * @ORM\JoinColumn(name="resource_file_id", referencedColumnName="id", onDelete="CASCADE")
106
     */
107
    protected $resourceFile;
108
109
    /**
110
     * @var User the creator of this node
111
     * @Assert\Valid()
112
     * @Groups({"resource_node:read", "resource_node:write", "document:write"})
113
     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\User", inversedBy="resourceNodes")
114
     * @ORM\JoinColumn(name="creator_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
115
     */
116
    protected $creator;
117
118
    /**
119
     * @ApiSubresource()
120
     *
121
     * @Gedmo\TreeParent
122
     * @ORM\ManyToOne(
123
     *     targetEntity="ResourceNode",
124
     *     inversedBy="children"
125
     * )
126
     * @ORM\JoinColumns({@ORM\JoinColumn(onDelete="CASCADE")})
127
     */
128
    protected $parent;
129
130
    /**
131
     * @Gedmo\TreeLevel
132
     *
133
     * @ORM\Column(name="level", type="integer", nullable=true)
134
     */
135
    protected $level;
136
137
    /**
138
     * @var ResourceNode[]
139
     *
140
     * @ORM\OneToMany(
141
     *     targetEntity="ResourceNode",
142
     *     mappedBy="parent"
143
     * )
144
     * @ORM\OrderBy({"id" = "ASC"})
145
     */
146
    protected $children;
147
148
    /**
149
     * @Groups({"resource_node:read", "document:read"})
150
     * @Gedmo\TreePath(appendId=true,separator="/")
151
     *
152
     * @ORM\Column(name="path", type="text", nullable=true)
153
     */
154
    protected $path;
155
156
    /**
157
     * Shortcut to access Course resource from ResourceNode.
158
     *
159
     * ORM\OneToOne(targetEntity="Chamilo\CoreBundle\Entity\Illustration", mappedBy="resourceNode")
160
     */
161
    //protected $illustration;
162
163
    /**
164
     * @var ResourceComment[]|ArrayCollection
165
     *
166
     * @ORM\OneToMany(targetEntity="ResourceComment", mappedBy="resourceNode", cascade={"persist", "remove"})
167
     */
168
    protected $comments;
169
170
    /**
171
     * @var \DateTime
172
     *
173
     * @Groups({"resource_node:read", "document:read"})
174
     * @Gedmo\Timestampable(on="create")
175
     * @ORM\Column(type="datetime")
176
     */
177
    protected $createdAt;
178
179
    /**
180
     * @var \DateTime
181
     *
182
     * @Groups({"resource_node:read", "document:read"})
183
     * @Gedmo\Timestampable(on="update")
184
     * @ORM\Column(type="datetime")
185
     */
186
    protected $updatedAt;
187
188
    /**
189
     * @var bool
190
     *
191
     * @Groups({"resource_node:read", "document:read"})
192
     */
193
    protected $fileEditableText;
194
195
    protected $content;
196
197
    /**
198
     * Constructor.
199
     */
200
    public function __construct()
201
    {
202
        $this->uuid = Uuid::uuid4()->toString();
203
        $this->children = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\Common\Collections\ArrayCollection() of type Doctrine\Common\Collections\ArrayCollection is incompatible with the declared type Chamilo\CoreBundle\Entity\ResourceNode[] of property $children.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
204
        $this->resourceLinks = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\Common\Collections\ArrayCollection() of type Doctrine\Common\Collections\ArrayCollection is incompatible with the declared type Chamilo\CoreBundle\Entity\ResourceLink[] of property $resourceLinks.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
205
        $this->comments = new ArrayCollection();
206
        $this->createdAt = new \DateTime();
207
        $this->editableContent = false;
208
    }
209
210
    /**
211
     * @return string
212
     */
213
    public function __toString()
214
    {
215
        return (string) $this->getPathForDisplay();
216
    }
217
218
    /**
219
     * Returns the resource id.
220
     *
221
     * @return int
222
     */
223
    public function getId()
224
    {
225
        return $this->id;
226
    }
227
228
    /**
229
     * Returns the resource creator.
230
     *
231
     * @return User
232
     */
233
    public function getCreator(): ?User
234
    {
235
        return $this->creator;
236
    }
237
238
    public function setCreator(User $creator = null): self
239
    {
240
        $this->creator = $creator;
241
242
        return $this;
243
    }
244
245
    /**
246
     * Returns the children resource instances.
247
     *
248
     * @return ResourceNode[]|ArrayCollection
249
     */
250
    public function getChildren()
251
    {
252
        return $this->children;
253
    }
254
255
    /**
256
     * Sets the parent resource.
257
     */
258
    public function setParent(self $parent = null): self
259
    {
260
        $this->parent = $parent;
261
262
        return $this;
263
    }
264
265
    /**
266
     * Returns the parent resource.
267
     *
268
     * @return ResourceNode
269
     */
270
    public function getParent()
271
    {
272
        return $this->parent;
273
    }
274
275
    /**
276
     * Return the lvl value of the resource in the tree.
277
     *
278
     * @return int
279
     */
280
    public function getLevel()
281
    {
282
        return $this->level;
283
    }
284
285
    /**
286
     * Returns the "raw" path of the resource
287
     * (the path merge names and ids of all items).
288
     * Eg.: "Root-1/subdir-2/file.txt-3/".
289
     *
290
     * @return string
291
     */
292
    public function getPath()
293
    {
294
        return $this->path;
295
    }
296
297
    /**
298
     * @return ResourceComment[]|ArrayCollection
299
     */
300
    public function getComments()
301
    {
302
        return $this->comments;
303
    }
304
305
    public function addComment(ResourceComment $comment)
306
    {
307
        $comment->setResourceNode($this);
308
309
        return $this->comments->add($comment);
310
    }
311
312
    /**
313
     * Returns the path cleaned from its ids.
314
     * Eg.: "Root/subdir/file.txt".
315
     *
316
     * @return string
317
     */
318
    public function getPathForDisplay()
319
    {
320
        return self::convertPathForDisplay($this->path);
321
    }
322
323
    public function getPathForDisplayToArray($baseRoot = null)
324
    {
325
        $parts = explode(self::PATH_SEPARATOR, $this->path);
326
        $list = [];
327
        foreach ($parts as $part) {
328
            $parts = explode('-', $part);
329
            if (empty($parts[1])) {
330
                continue;
331
            }
332
333
            $value = $parts[0];
334
            $id = $parts[1];
335
336
            if (!empty($baseRoot)) {
337
                if ($id < $baseRoot) {
338
                    continue;
339
                }
340
            }
341
            $list[$id] = $value;
342
        }
343
344
        return $list;
345
    }
346
347
    public function getPathForDisplayRemoveBase(string $base): string
348
    {
349
        $path = str_replace($base, '', $this->path);
350
351
        return self::convertPathForDisplay($path);
352
    }
353
354
    public function getSlug()
355
    {
356
        return $this->slug;
357
    }
358
359
    public function getTitle()
360
    {
361
        return $this->title;
362
    }
363
364
    public function setTitle(string $title)
365
    {
366
        $this->title = $title;
367
368
        return $this;
369
    }
370
371
    public function setSlug(string $slug): self
372
    {
373
        if (false !== strpos(self::PATH_SEPARATOR, $slug)) {
374
            throw new \InvalidArgumentException('Invalid character "'.self::PATH_SEPARATOR.'" in resource name.');
375
        }
376
377
        $this->slug = $slug;
378
379
        return $this;
380
    }
381
382
    /**
383
     * Convert a path for display: remove ids.
384
     *
385
     * @param string $path
386
     *
387
     * @return string
388
     */
389
    public static function convertPathForDisplay($path)
390
    {
391
        /*$pathForDisplay = preg_replace(
392
            '/-\d+'.self::PATH_SEPARATOR.'/',
393
            ' / ',
394
            $path
395
        );
396
        if ($pathForDisplay !== null && strlen($pathForDisplay) > 0) {
397
            $pathForDisplay = substr_replace($pathForDisplay, '', -3);
398
        }
399
        */
400
        $pathForDisplay = preg_replace(
401
            '/-\d+'.self::PATH_SEPARATOR.'/',
402
            '/',
403
            $path
404
        );
405
406
        if (null !== $pathForDisplay && strlen($pathForDisplay) > 0) {
407
            $pathForDisplay = substr_replace($pathForDisplay, '', -1);
408
        }
409
410
        return $pathForDisplay;
411
    }
412
413
    /**
414
     * @return ResourceType
415
     */
416
    public function getResourceType()
417
    {
418
        return $this->resourceType;
419
    }
420
421
    public function setResourceType(ResourceType $resourceType): self
422
    {
423
        $this->resourceType = $resourceType;
424
425
        return $this;
426
    }
427
428
    /**
429
     * @return ArrayCollection|ResourceLink[]
430
     */
431
    public function getResourceLinks()
432
    {
433
        return $this->resourceLinks;
434
    }
435
436
    /**
437
     * @return ResourceNode
438
     */
439
    public function setResourceLinks($resourceLinks)
440
    {
441
        $this->resourceLinks = $resourceLinks;
442
443
        return $this;
444
    }
445
446
    /**
447
     * @param Session $session
448
     *
449
     * @return ArrayCollection
450
     */
451
    public function hasSession(Session $session = null)
452
    {
453
        $links = $this->getResourceLinks();
454
        $criteria = Criteria::create();
455
456
        $criteria->andWhere(
457
            Criteria::expr()->eq('session', $session)
458
        );
459
460
        return $links->matching($criteria);
461
    }
462
463
    public function hasResourceFile(): bool
464
    {
465
        return null !== $this->resourceFile;
466
    }
467
468
    public function getResourceFile(): ?ResourceFile
469
    {
470
        return $this->resourceFile;
471
    }
472
473
    public function hasEditableTextContent(): bool
474
    {
475
        if ($this->hasResourceFile()) {
476
            $mimeType = $this->getResourceFile()->getMimeType();
477
            if (false !== strpos($mimeType, 'text')) {
478
                return true;
479
            }
480
        }
481
482
        return false;
483
    }
484
485
    public function isFileEditableText(): bool
486
    {
487
        return $this->hasEditableTextContent();
488
    }
489
490
    public function isResourceFileAnImage(): bool
491
    {
492
        if ($this->hasResourceFile()) {
493
            $mimeType = $this->getResourceFile()->getMimeType();
494
            if (false !== strpos($mimeType, 'image')) {
495
                return true;
496
            }
497
        }
498
499
        return false;
500
    }
501
502
    public function isResourceFileAVideo(): bool
503
    {
504
        if ($this->hasResourceFile()) {
505
            $mimeType = $this->getResourceFile()->getMimeType();
506
            if (false !== strpos($mimeType, 'video')) {
507
                return true;
508
            }
509
        }
510
511
        return false;
512
    }
513
514
    public function setResourceFile(ResourceFile $resourceFile = null): self
515
    {
516
        $this->resourceFile = $resourceFile;
517
518
        return $this;
519
    }
520
521
    public function getIcon(): string
522
    {
523
        $class = 'fa fa-folder';
524
        if ($this->hasResourceFile()) {
525
            $class = 'far fa-file';
526
527
            if ($this->isResourceFileAnImage()) {
528
                $class = 'far fa-file-image';
529
            }
530
            if ($this->isResourceFileAVideo()) {
531
                $class = 'far fa-file-video';
532
            }
533
        }
534
535
        return '<i class="'.$class.'"></i>';
536
    }
537
538
    public function getThumbnail(RouterInterface $router): string
539
    {
540
        $size = 'fa-3x';
541
        $class = "fa fa-folder $size";
542
        if ($this->hasResourceFile()) {
543
            $class = "far fa-file $size";
544
545
            if ($this->isResourceFileAnImage()) {
546
                $class = "far fa-file-image $size";
547
548
                $params = [
549
                    'id' => $this->getId(),
550
                    'tool' => $this->getResourceType()->getTool(),
551
                    'type' => $this->getResourceType()->getName(),
552
                    'filter' => 'editor_thumbnail',
553
                ];
554
                $url = $router->generate(
555
                    'chamilo_core_resource_view',
556
                    $params
557
                );
558
559
                return "<img src='$url'/>";
560
            }
561
            if ($this->isResourceFileAVideo()) {
562
                $class = "far fa-file-video $size";
563
            }
564
        }
565
566
        return '<i class="'.$class.'"></i>';
567
    }
568
569
    public function getContent()
570
    {
571
        return $this->content;
572
    }
573
574
    public function setContent(string $content): self
575
    {
576
        $this->content = $content;
577
578
        return $this;
579
    }
580
}
581