Completed
Push — master ( 67834e...72c918 )
by Julito
08:46 queued 11s
created

ResourceNode   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 560
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 128
dl 0
loc 560
rs 6
c 1
b 0
f 0
wmc 55

36 Methods

Rating   Name   Duplication   Size   Complexity  
A hasResourceFile() 0 3 1
A setResourceType() 0 5 1
A getResourceLinks() 0 3 1
A isCourseNode() 0 3 1
A isIllustrationNode() 0 3 1
A getResourceFile() 0 3 1
A getCourse() 0 3 1
A isResourceFileAVideo() 0 10 3
A addComment() 0 5 1
A getResourceType() 0 3 1
A getPathForDisplay() 0 3 1
A getChildren() 0 3 1
A getParent() 0 3 1
A getPathForDisplayToArray() 0 22 5
A convertPathForDisplay() 0 22 3
A isResourceFileAnImage() 0 10 3
A getCreator() 0 3 1
A getThumbnail() 0 29 4
A getId() 0 3 1
A setCreator() 0 5 1
A hasEditableContent() 0 10 3
A getPath() 0 3 1
A setParent() 0 5 1
A hasSession() 0 10 1
A setSlug() 0 9 2
A setResourceLinks() 0 5 1
A __construct() 0 6 1
A getSlug() 0 3 1
A getLevel() 0 3 1
A getComments() 0 3 1
A setId() 0 5 1
A getPathForDisplayRemoveBase() 0 5 1
A getIcon() 0 15 4
A setTitle() 0 5 1
A __toString() 0 3 1
A setResourceFile() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like ResourceNode often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ResourceNode, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Entity\Resource;
6
7
use Chamilo\CoreBundle\Entity\Course;
8
use Chamilo\CoreBundle\Entity\Session;
9
use Chamilo\UserBundle\Entity\User;
10
use Doctrine\Common\Collections\ArrayCollection;
11
use Doctrine\Common\Collections\Criteria;
12
use Doctrine\ORM\Mapping as ORM;
13
use Gedmo\Mapping\Annotation as Gedmo;
14
use Gedmo\Timestampable\Traits\TimestampableEntity;
15
use JMS\Serializer\Annotation as JMS;
16
use JMS\Serializer\Annotation\Groups;
17
use Symfony\Component\Routing\RouterInterface;
18
use Symfony\Component\Validator\Constraints as Assert;
19
20
/**
21
 * Base entity for all resources.
22
 *
23
 * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Repository\ResourceNodeRepository")
24
 *
25
 * @ORM\Table(name="resource_node")
26
 *
27
 * @Gedmo\Tree(type="materializedPath")
28
 */
29
class ResourceNode
30
{
31
    public const PATH_SEPARATOR = '`';
32
    use TimestampableEntity;
33
34
    /**
35
     * @ORM\Id
36
     * @ORM\Column(type="integer")
37
     * @ORM\GeneratedValue(strategy="AUTO")
38
     */
39
    protected $id;
40
41
    /**
42
     * @Assert\NotBlank()
43
     *
44
     * @Gedmo\TreePathSource
45
     *
46
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
47
     */
48
    protected $title;
49
50
    /**
51
     * @Assert\NotBlank()
52
     *
53
     * @Gedmo\Slug(fields={"title"})
54
     * @ORM\Column(name="slug", type="string", length=255, nullable=false)
55
     */
56
    protected $slug;
57
58
    /**
59
     * @ORM\ManyToOne(targetEntity="ResourceType", inversedBy="resourceNodes")
60
     * @ORM\JoinColumn(name="resource_type_id", referencedColumnName="id", nullable=false)
61
     */
62
    protected $resourceType;
63
64
    /**
65
     * @var ResourceLink[]
66
     *
67
     * @ORM\OneToMany(targetEntity="ResourceLink", mappedBy="resourceNode", cascade={"remove"})
68
     */
69
    protected $resourceLinks;
70
71
    /**
72
     * @var ResourceFile
73
     * @Groups({"list"})
74
     *
75
     * @ORM\OneToOne(targetEntity="ResourceFile", inversedBy="resourceNode", orphanRemoval=true, fetch="EAGER")
76
     * @ORM\JoinColumn(name="resource_file_id", referencedColumnName="id", onDelete="CASCADE")
77
     */
78
    protected $resourceFile;
79
80
    /**
81
     * @ORM\ManyToOne(
82
     *     targetEntity="Chamilo\UserBundle\Entity\User", inversedBy="resourceNodes"
83
     * )
84
     * @ORM\JoinColumn(name="creator_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
85
     */
86
    protected $creator;
87
88
    /**
89
     * @Gedmo\TreeParent
90
     *
91
     * @ORM\ManyToOne(
92
     *     targetEntity="ResourceNode",
93
     *     inversedBy="children"
94
     * )
95
     * @ORM\JoinColumns({@ORM\JoinColumn(onDelete="CASCADE")})
96
     */
97
    protected $parent;
98
99
    /**
100
     * @Gedmo\TreeLevel
101
     *
102
     * @ORM\Column(name="level", type="integer", nullable=true)
103
     */
104
    protected $level;
105
106
    /**
107
     * @var ResourceNode[]
108
     *
109
     * @ORM\OneToMany(
110
     *     targetEntity="ResourceNode",
111
     *     mappedBy="parent"
112
     * )
113
     * @ORM\OrderBy({"id" = "ASC"})
114
     */
115
    protected $children;
116
117
    /**
118
     * @Gedmo\TreePath(appendId=true,separator="`")
119
     *
120
     * @ORM\Column(name="path", type="text", nullable=true)
121
     */
122
    protected $path;
123
124
    /**
125
     * Shortcut to access Course resource from ResourceNode.
126
     *
127
     * @ORM\OneToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", mappedBy="resourceNode")
128
     */
129
    protected $course;
130
131
    /**
132
     * Shortcut to access Course resource from ResourceNode.
133
     *
134
     * @ORM\OneToOne(targetEntity="Chamilo\CoreBundle\Entity\Illustration", mappedBy="resourceNode")
135
     */
136
    protected $illustration;
137
138
    /**
139
     * @var ResourceComment[]|ArrayCollection
140
     *
141
     * @ORM\OneToMany(targetEntity="ResourceComment", mappedBy="resourceNode", cascade={"persist", "remove"})
142
     */
143
    protected $comments;
144
145
    /**
146
     * @var \DateTime
147
     *
148
     * @Groups({"list"})
149
     * @Gedmo\Timestampable(on="create")
150
     * @ORM\Column(type="datetime")
151
     * @JMS\Type("DateTime")
152
     */
153
    protected $createdAt;
154
155
    /**
156
     * @var \DateTime
157
     *
158
     * @Groups({"list"})
159
     * @Gedmo\Timestampable(on="update")
160
     * @ORM\Column(type="datetime")
161
     * @JMS\Type("DateTime")
162
     */
163
    protected $updatedAt;
164
165
    /**
166
     * Constructor.
167
     */
168
    public function __construct()
169
    {
170
        $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\Resource\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...
171
        $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\Resource\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...
172
        $this->comments = new ArrayCollection();
173
        $this->createdAt = new \DateTime();
174
    }
175
176
    /**
177
     * @return string
178
     */
179
    public function __toString()
180
    {
181
        return (string) $this->getPathForDisplay();
182
    }
183
184
    /**
185
     * @return Course
186
     */
187
    public function getCourse(): ?Course
188
    {
189
        return $this->course;
190
    }
191
192
    public function isCourseNode(): bool
193
    {
194
        return null !== $this->course;
195
    }
196
197
    public function isIllustrationNode(): bool
198
    {
199
        return null !== $this->illustration;
200
    }
201
202
    /**
203
     * Returns the resource id.
204
     *
205
     * @return int
206
     */
207
    public function getId()
208
    {
209
        return $this->id;
210
    }
211
212
    /**
213
     * @param int $id
214
     *
215
     * @return $this
216
     */
217
    public function setId($id)
218
    {
219
        $this->id = $id;
220
221
        return $this;
222
    }
223
224
    /**
225
     * Returns the resource creator.
226
     *
227
     * @return User
228
     */
229
    public function getCreator(): ?User
230
    {
231
        return $this->creator;
232
    }
233
234
    public function setCreator(User $creator = null)
235
    {
236
        $this->creator = $creator;
237
238
        return $this;
239
    }
240
241
    /**
242
     * Returns the children resource instances.
243
     *
244
     * @return ResourceNode[]|ArrayCollection
245
     */
246
    public function getChildren()
247
    {
248
        return $this->children;
249
    }
250
251
    /**
252
     * Sets the parent resource.
253
     *
254
     * @param ResourceNode $parent
255
     *
256
     * @return $this
257
     */
258
    public function setParent(self $parent = null)
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
    /**
348
     * @return string
349
     */
350
    public function getPathForDisplayRemoveBase(string $base)
351
    {
352
        $path = str_replace($base, '', $this->path);
353
354
        return self::convertPathForDisplay($path);
355
    }
356
357
    public function getSlug()
358
    {
359
        return $this->slug;
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