Passed
Push — master ( 55e34c...7d0dcf )
by Julito
09:50
created

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