Completed
Push — master ( 13dd2e...a1a590 )
by Julito
20:58
created

ResourceNode::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
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
     * @var UuidInterface|null
62
     *
63
     * @ORM\Column(type="uuid", unique=true)
64
     */
65
    protected $uuid;
66
67
    /**
68
     * @Assert\NotBlank()
69
     * @Groups({"resource_node:read", "resource_node:write", "document:read", "document:write"})
70
     * @Gedmo\TreePathSource
71
     *
72
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
73
     */
74
    protected $title;
75
76
    /**
77
     * @Assert\NotBlank()
78
     *
79
     * @Gedmo\Slug(fields={"title"})
80
     * @ORM\Column(name="slug", type="string", length=255, nullable=false)
81
     */
82
    protected $slug;
83
84
    /**
85
     * @ORM\ManyToOne(targetEntity="ResourceType")
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(
114
     *     targetEntity="Chamilo\CoreBundle\Entity\User", inversedBy="resourceNodes"
115
     * )
116
     * @ORM\JoinColumn(name="creator_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
117
     */
118
    protected $creator;
119
120
    /**
121
     * @ApiSubresource()
122
     *
123
     * @Gedmo\TreeParent
124
     * @ORM\ManyToOne(
125
     *     targetEntity="ResourceNode",
126
     *     inversedBy="children"
127
     * )
128
     * @ORM\JoinColumns({@ORM\JoinColumn(onDelete="CASCADE")})
129
     */
130
    protected $parent;
131
132
    /**
133
     * @Gedmo\TreeLevel
134
     *
135
     * @ORM\Column(name="level", type="integer", nullable=true)
136
     */
137
    protected $level;
138
139
    /**
140
     * @var ResourceNode[]
141
     *
142
     * @ORM\OneToMany(
143
     *     targetEntity="ResourceNode",
144
     *     mappedBy="parent"
145
     * )
146
     * @ORM\OrderBy({"id" = "ASC"})
147
     */
148
    protected $children;
149
150
    /**
151
     * @Groups({"resource_node:read", "document:read"})
152
     * @Gedmo\TreePath(appendId=true,separator="`")
153
     *
154
     * @ORM\Column(name="path", type="text", nullable=true)
155
     */
156
    protected $path;
157
158
    /**
159
     * Shortcut to access Course resource from ResourceNode.
160
     *
161
     * ORM\OneToOne(targetEntity="Chamilo\CoreBundle\Entity\Illustration", mappedBy="resourceNode")
162
     */
163
    //protected $illustration;
164
165
    /**
166
     * @var ResourceComment[]|ArrayCollection
167
     *
168
     * @ORM\OneToMany(targetEntity="ResourceComment", mappedBy="resourceNode", cascade={"persist", "remove"})
169
     */
170
    protected $comments;
171
172
    /**
173
     * @var \DateTime
174
     *
175
     * @Groups({"resource_node:read", "document:read"})
176
     * @Gedmo\Timestampable(on="create")
177
     * @ORM\Column(type="datetime")
178
     */
179
    protected $createdAt;
180
181
    /**
182
     * @var \DateTime
183
     *
184
     * @Groups({"resource_node:read", "document:read"})
185
     * @Gedmo\Timestampable(on="update")
186
     * @ORM\Column(type="datetime")
187
     */
188
    protected $updatedAt;
189
190
    /**
191
     * @var bool
192
     *
193
     * @Groups({"resource_node:read", "document:read"})
194
     */
195
    protected $fileEditableText;
196
197
    protected $content;
198
199
    /**
200
     * Constructor.
201
     */
202
    public function __construct()
203
    {
204
        $this->uuid = Uuid::uuid4()->toString();
205
        $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...
206
        $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...
207
        $this->comments = new ArrayCollection();
208
        $this->createdAt = new \DateTime();
209
        $this->editableContent = false;
210
    }
211
212
    /**
213
     * @return string
214
     */
215
    public function __toString()
216
    {
217
        return (string) $this->getPathForDisplay();
218
    }
219
220
    /**
221
     * Returns the resource id.
222
     *
223
     * @return int
224
     */
225
    public function getId()
226
    {
227
        return $this->id;
228
    }
229
230
    /**
231
     * @param int $id
232
     *
233
     * @return $this
234
     */
235
    public function setId($id)
236
    {
237
        $this->id = $id;
238
239
        return $this;
240
    }
241
242
    /**
243
     * Returns the resource creator.
244
     *
245
     * @return User
246
     */
247
    public function getCreator(): ?User
248
    {
249
        return $this->creator;
250
    }
251
252
    public function setCreator(User $creator = null)
253
    {
254
        $this->creator = $creator;
255
256
        return $this;
257
    }
258
259
    /**
260
     * Returns the children resource instances.
261
     *
262
     * @return ResourceNode[]|ArrayCollection
263
     */
264
    public function getChildren()
265
    {
266
        return $this->children;
267
    }
268
269
    /**
270
     * Sets the parent resource.
271
     *
272
     * @param ResourceNode $parent
273
     *
274
     * @return $this
275
     */
276
    public function setParent(self $parent = null)
277
    {
278
        $this->parent = $parent;
279
280
        return $this;
281
    }
282
283
    /**
284
     * Returns the parent resource.
285
     *
286
     * @return ResourceNode
287
     */
288
    public function getParent()
289
    {
290
        return $this->parent;
291
    }
292
293
    /**
294
     * Return the lvl value of the resource in the tree.
295
     *
296
     * @return int
297
     */
298
    public function getLevel()
299
    {
300
        return $this->level;
301
    }
302
303
    /**
304
     * Returns the "raw" path of the resource
305
     * (the path merge names and ids of all items).
306
     * Eg.: "Root-1/subdir-2/file.txt-3/".
307
     *
308
     * @return string
309
     */
310
    public function getPath()
311
    {
312
        return $this->path;
313
    }
314
315
    /**
316
     * @return ResourceComment[]|ArrayCollection
317
     */
318
    public function getComments()
319
    {
320
        return $this->comments;
321
    }
322
323
    public function addComment(ResourceComment $comment)
324
    {
325
        $comment->setResourceNode($this);
326
327
        return $this->comments->add($comment);
328
    }
329
330
    /**
331
     * Returns the path cleaned from its ids.
332
     * Eg.: "Root/subdir/file.txt".
333
     *
334
     * @return string
335
     */
336
    public function getPathForDisplay()
337
    {
338
        return self::convertPathForDisplay($this->path);
339
    }
340
341
    public function getPathForDisplayToArray($baseRoot = null)
342
    {
343
        $parts = explode(self::PATH_SEPARATOR, $this->path);
344
        $list = [];
345
        foreach ($parts as $part) {
346
            $parts = explode('-', $part);
347
            if (empty($parts[1])) {
348
                continue;
349
            }
350
351
            $value = $parts[0];
352
            $id = $parts[1];
353
354
            if (!empty($baseRoot)) {
355
                if ($id < $baseRoot) {
356
                    continue;
357
                }
358
            }
359
            $list[$id] = $value;
360
        }
361
362
        return $list;
363
    }
364
365
    /**
366
     * @return string
367
     */
368
    public function getPathForDisplayRemoveBase(string $base)
369
    {
370
        $path = str_replace($base, '', $this->path);
371
372
        return self::convertPathForDisplay($path);
373
    }
374
375
    public function getSlug()
376
    {
377
        return $this->slug;
378
    }
379
380
    public function getTitle()
381
    {
382
        return $this->title;
383
    }
384
385
    public function setTitle(string $title)
386
    {
387
        $this->title = $title;
388
389
        return $this;
390
    }
391
392
    /**
393
     * @return ResourceNode
394
     */
395
    public function setSlug(string $slug)
396
    {
397
        if (false !== strpos(self::PATH_SEPARATOR, $slug)) {
398
            throw new \InvalidArgumentException('Invalid character "'.self::PATH_SEPARATOR.'" in resource name.');
399
        }
400
401
        $this->slug = $slug;
402
403
        return $this;
404
    }
405
406
    /**
407
     * Convert a path for display: remove ids.
408
     *
409
     * @param string $path
410
     *
411
     * @return string
412
     */
413
    public static function convertPathForDisplay($path)
414
    {
415
        /*$pathForDisplay = preg_replace(
416
            '/-\d+'.self::PATH_SEPARATOR.'/',
417
            ' / ',
418
            $path
419
        );
420
        if ($pathForDisplay !== null && strlen($pathForDisplay) > 0) {
421
            $pathForDisplay = substr_replace($pathForDisplay, '', -3);
422
        }
423
        */
424
        $pathForDisplay = preg_replace(
425
            '/-\d+'.self::PATH_SEPARATOR.'/',
426
            '/',
427
            $path
428
        );
429
430
        if (null !== $pathForDisplay && strlen($pathForDisplay) > 0) {
431
            $pathForDisplay = substr_replace($pathForDisplay, '', -1);
432
        }
433
434
        return $pathForDisplay;
435
    }
436
437
    /**
438
     * @return ResourceType
439
     */
440
    public function getResourceType()
441
    {
442
        return $this->resourceType;
443
    }
444
445
    /**
446
     * @param ResourceType $resourceType
447
     *
448
     * @return ResourceNode
449
     */
450
    public function setResourceType($resourceType)
451
    {
452
        $this->resourceType = $resourceType;
453
454
        return $this;
455
    }
456
457
    /**
458
     * @return ArrayCollection|ResourceLink[]
459
     */
460
    public function getResourceLinks()
461
    {
462
        return $this->resourceLinks;
463
    }
464
465
    /**
466
     * @return ResourceNode
467
     */
468
    public function setResourceLinks($resourceLinks)
469
    {
470
        $this->resourceLinks = $resourceLinks;
471
472
        return $this;
473
    }
474
475
    /**
476
     * @param Session $session
477
     *
478
     * @return ArrayCollection
479
     */
480
    public function hasSession(Session $session = null)
481
    {
482
        $links = $this->getResourceLinks();
483
        $criteria = Criteria::create();
484
485
        $criteria->andWhere(
486
            Criteria::expr()->eq('session', $session)
487
        );
488
489
        return $links->matching($criteria);
490
    }
491
492
    public function hasResourceFile(): bool
493
    {
494
        return null !== $this->resourceFile;
495
    }
496
497
    public function getResourceFile(): ?ResourceFile
498
    {
499
        return $this->resourceFile;
500
    }
501
502
    public function hasEditableContent(): bool
503
    {
504
        if ($this->hasResourceFile()) {
505
            $mimeType = $this->getResourceFile()->getMimeType();
506
            if (false !== strpos($mimeType, 'text')) {
507
                return true;
508
            }
509
        }
510
511
        return false;
512
    }
513
514
    public function isFileEditableText(): bool
515
    {
516
        return $this->hasEditableContent();
517
    }
518
519
    public function isResourceFileAnImage(): bool
520
    {
521
        if ($this->hasResourceFile()) {
522
            $mimeType = $this->getResourceFile()->getMimeType();
523
            if (false !== strpos($mimeType, 'image')) {
524
                return true;
525
            }
526
        }
527
528
        return false;
529
    }
530
531
    public function isResourceFileAVideo(): bool
532
    {
533
        if ($this->hasResourceFile()) {
534
            $mimeType = $this->getResourceFile()->getMimeType();
535
            if (false !== strpos($mimeType, 'video')) {
536
                return true;
537
            }
538
        }
539
540
        return false;
541
    }
542
543
    public function setResourceFile(ResourceFile $resourceFile = null): self
544
    {
545
        $this->resourceFile = $resourceFile;
546
547
        return $this;
548
    }
549
550
    public function getIcon(): string
551
    {
552
        $class = 'fa fa-folder';
553
        if ($this->hasResourceFile()) {
554
            $class = 'far fa-file';
555
556
            if ($this->isResourceFileAnImage()) {
557
                $class = 'far fa-file-image';
558
            }
559
            if ($this->isResourceFileAVideo()) {
560
                $class = 'far fa-file-video';
561
            }
562
        }
563
564
        return '<i class="'.$class.'"></i>';
565
    }
566
567
    public function getThumbnail(RouterInterface $router): string
568
    {
569
        $size = 'fa-3x';
570
        $class = "fa fa-folder $size";
571
        if ($this->hasResourceFile()) {
572
            $class = "far fa-file $size";
573
574
            if ($this->isResourceFileAnImage()) {
575
                $class = "far fa-file-image $size";
576
577
                $params = [
578
                    'id' => $this->getId(),
579
                    'tool' => $this->getResourceType()->getTool(),
580
                    'type' => $this->getResourceType()->getName(),
581
                    'filter' => 'editor_thumbnail',
582
                ];
583
                $url = $router->generate(
584
                    'chamilo_core_resource_view_file',
585
                    $params
586
                );
587
588
                return "<img src='$url'/>";
589
            }
590
            if ($this->isResourceFileAVideo()) {
591
                $class = "far fa-file-video $size";
592
            }
593
        }
594
595
        return '<i class="'.$class.'"></i>';
596
    }
597
598
    public function getContent()
599
    {
600
        return $this->content;
601
    }
602
603
    public function setContent(string $content): self
604
    {
605
        $this->content = $content;
606
607
        return $this;
608
    }
609
}
610