Completed
Push — master ( c58ed8...556108 )
by Julito
10:31
created

ResourceNode::getChildren()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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