Completed
Pull Request — master (#433)
by Paul
11:06 queued 04:27
created

View::addTranslation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
dl 0
loc 7
rs 9.4285
c 2
b 0
f 2
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Victoire\Bundle\CoreBundle\Entity;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Collection;
7
use Doctrine\ORM\Mapping as ORM;
8
use Gedmo\Mapping\Annotation as Gedmo;
9
use JMS\Serializer\Annotation as Serializer;
10
use Symfony\Component\PropertyAccess\PropertyAccess;
11
use Symfony\Component\Validator\Constraints as Assert;
12
use Victoire\Bundle\BusinessPageBundle\Entity\BusinessTemplate;
13
use Victoire\Bundle\I18nBundle\Entity\ViewTranslation;
14
use Victoire\Bundle\TemplateBundle\Entity\Template;
15
use Victoire\Bundle\ViewReferenceBundle\ViewReference\ViewReference;
16
use Victoire\Bundle\WidgetBundle\Entity\Widget;
17
use Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap;
18
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
19
20
/**
21
 * Victoire View
22
 * A victoire view is a visual representation with a widget map.
23
 *
24
 * @Gedmo\Tree(type="nested")
25
 * @Gedmo\TranslationEntity(class="Victoire\Bundle\I18nBundle\Entity\ViewTranslation")
26
 * @ORM\InheritanceType("SINGLE_TABLE")
27
 * @ORM\DiscriminatorColumn(name="type", type="string")
28
 * @ORM\Entity(repositoryClass="Victoire\Bundle\CoreBundle\Repository\ViewRepository")
29
 * @ORM\Table("vic_view")
30
 * @ORM\HasLifecycleCallbacks
31
 */
32
abstract class View
33
{
34
    use \Gedmo\Timestampable\Traits\TimestampableEntity;
35
    use Translatable;
36
37
    /**
38
     * @var int
39
     *
40
     * @ORM\Column(name="id", type="integer")
41
     * @ORM\Id
42
     * @ORM\GeneratedValue(strategy="AUTO")
43
     */
44
    protected $id;
45
46
    /**
47
     * @var string
48
     *
49
     * @ORM\Column(name="bodyId", type="string", length=255, nullable=true)
50
     */
51
    protected $bodyId;
52
53
    /**
54
     * @var string
55
     *
56
     * @ORM\Column(name="bodyClass", type="string", length=255, nullable=true)
57
     */
58
    protected $bodyClass;
59
60
    /**
61
     * @var [WidgetMap]
62
     *
63
     * @ORM\OneToMany(targetEntity="\Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap", mappedBy="view", orphanRemoval=true, cascade={"persist", "remove"})
64
     */
65
    protected $widgetMaps = [];
66
67
    /**
68
     * @Gedmo\TreeParent
69
     * @ORM\ManyToOne(targetEntity="View", inversedBy="children", cascade={"persist"})
70
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
71
     */
72
    protected $parent;
73
74
    /**
75
     * @var int
76
     *
77
     * @ORM\Column(name="position", type="integer", nullable=false)
78
     */
79
    protected $position = 0;
80
81
    /**
82
     * @Gedmo\TreeLeft
83
     * @ORM\Column(name="lft", type="integer")
84
     */
85
    protected $lft;
86
87
    /**
88
     * @Gedmo\TreeLevel
89
     * @ORM\Column(name="lvl", type="integer")
90
     */
91
    protected $lvl;
92
93
    /**
94
     * @Gedmo\TreeRight
95
     * @ORM\Column(name="rgt", type="integer")
96
     */
97
    protected $rgt;
98
99
    /**
100
     * @Gedmo\TreeRoot
101
     * @ORM\Column(name="root", type="integer", nullable=true)
102
     */
103
    protected $root;
104
105
    /**
106
     * @ORM\OneToMany(targetEntity="View", mappedBy="parent", cascade={"remove"})
107
     * @ORM\OrderBy({"lft" = "ASC"})
108
     */
109
    protected $children = [];
110
111
    /**
112
     * This relation is dynamicly added by PageSubscriber.
113
     */
114
    protected $author;
115
116
    /**
117
     * @var string
118
     *
119
     * @ORM\Column(name="undeletable", type="boolean")
120
     */
121
    protected $undeletable = false;
122
123
    /**
124
     * @var ViewReference[]
125
     *                      The reference is related to viewsReferences.xml file which list all app views.
126
     *                      This is used to speed up the routing system and identify virtual pages (BusinessPage).
127
     */
128
    protected $references;
129
130
    /**
131
     * @var string
132
     *
133
     * @ORM\ManyToOne(targetEntity="\Victoire\Bundle\TemplateBundle\Entity\Template", inversedBy="inheritors", cascade={"persist"})
134
     * @ORM\JoinColumn(name="template_id", referencedColumnName="id", onDelete="CASCADE")
135
     */
136
    protected $template;
137
138
    /**
139
     * @var string
140
     *
141
     * @ORM\Column(name="cssHash", type="string", length=40 ,nullable=true)
142
     */
143
    protected $cssHash;
144
145
    /**
146
     * @deprecated
147
     * @ORM\Column(name="widget_map", type="array")
148
     */
149
    protected $widgetMap = [];
150
151
    /**
152
     * @var string
153
     *
154
     * @ORM\OneToMany(targetEntity="\Victoire\Bundle\WidgetBundle\Entity\Widget", mappedBy="view", cascade={"persist", "remove"})
155
     * @ORM\OrderBy({"id" = "ASC"})
156
     */
157
    protected $widgets;
158
    /**
159
     * @var bool
160
     *
161
     * @ORM\Column(name="cssUpToDate", type="boolean")
162
     */
163
    protected $cssUpToDate = false;
164
165
    /**
166
     * Construct.
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 object<Doctrine\Common\C...ctions\ArrayCollection> is incompatible with the declared type array 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->widgetMaps = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Doctrine\Common\Collections\ArrayCollection() of type object<Doctrine\Common\C...ctions\ArrayCollection> is incompatible with the declared type array of property $widgetMaps.

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->translations = new ArrayCollection();
173
        $this->references = [];
174
    }
175
176
    /**
177
     * to string.
178
     *
179
     * @return string
180
     **/
181
    public function __toString()
182
    {
183
        return $this->getName();
184
    }
185
186
    /**
187
     * Get id.
188
     *
189
     * @return int
190
     */
191
    public function getId()
192
    {
193
        return $this->id;
194
    }
195
196
    /**
197
     * Set id.
198
     *
199
     * @param id $id
200
     */
201
    public function setId($id)
202
    {
203
        $this->id = $id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $id of type object<Victoire\Bundle\CoreBundle\Entity\id> is incompatible with the declared type integer of property $id.

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
    }
205
206
    /**
207
     * Set template.
208
     *
209
     * @param View $template
210
     *
211
     * @return View
212
     */
213
    public function setTemplate($template)
214
    {
215
        $this->template = $template;
0 ignored issues
show
Documentation Bug introduced by
It seems like $template of type object<Victoire\Bundle\CoreBundle\Entity\View> is incompatible with the declared type string of property $template.

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...
216
217
        return $this;
218
    }
219
220
    /**
221
     * Get template.
222
     *
223
     * @return string
224
     */
225
    public function getTemplate()
226
    {
227
        return $this->template;
228
    }
229
230
    /**
231
     * Set parent.
232
     *
233
     * @param View $parent
234
     */
235
    public function setParent(View $parent = null)
236
    {
237
        $this->parent = $parent;
238
    }
239
240
    /**
241
     * Get parent.
242
     *
243
     * @return View parent
244
     */
245
    public function getParent()
246
    {
247
        return $this->parent;
248
    }
249
250
    /**
251
     * Set children.
252
     *
253
     * @param View[] $children
254
     *
255
     * @return View
256
     */
257
    public function setChildren($children)
258
    {
259
        $this->children = $children;
260
        if ($children !== null) {
261
            foreach ($children as $child) {
262
                $child->setParent($this);
263
            }
264
        }
265
266
        return $this;
267
    }
268
269
    /**
270
     * Get children.
271
     *
272
     * @return View[]
273
     */
274
    public function getChildren()
275
    {
276
        return $this->children;
277
    }
278
279
    /**
280
     * Has children.
281
     *
282
     * @return int
283
     */
284
    public function hasChildren()
285
    {
286
        return count($this->children);
287
    }
288
289
    /**
290
     * Get WebView children.
291
     *
292
     * @return string
293
     */
294
    public function getWebViewChildren()
295
    {
296
        $webViewChildren = [];
297
        foreach ($this->children as $child) {
298
            if (!$child instanceof BusinessTemplate) {
299
                $webViewChildren[] = $child;
300
            }
301
        }
302
303
        return $webViewChildren;
304
    }
305
306
    /**
307
     * Add child.
308
     *
309
     * @param View $child
310
     */
311
    public function addChild(View $child)
312
    {
313
        $this->children[] = $child;
314
    }
315
316
    /**
317
     * Remove child.
318
     *
319
     * @param View $child
320
     */
321
    public function removeChild(View $child)
322
    {
323
        $this->children->removeElement($child);
0 ignored issues
show
Bug introduced by
The method removeElement cannot be called on $this->children (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
324
    }
325
326
    /**
327
     * Get the left value.
328
     *
329
     * @return int
330
     */
331
    public function getLft()
332
    {
333
        return $this->lft;
334
    }
335
336
    /**
337
     * Set the left value.
338
     *
339
     * @param int $lft
340
     */
341
    public function setLft($lft)
342
    {
343
        $this->lft = $lft;
344
    }
345
346
    /**
347
     * Get the right value.
348
     *
349
     * @return int
350
     */
351
    public function getRgt()
352
    {
353
        return $this->rgt;
354
    }
355
356
    /**
357
     * Set the right value.
358
     *
359
     * @param int $rgt
360
     */
361
    public function setRgt($rgt)
362
    {
363
        $this->rgt = $rgt;
364
    }
365
366
    /**
367
     * Get the level value.
368
     *
369
     * @return int
370
     */
371
    public function getLvl()
372
    {
373
        return $this->lvl;
374
    }
375
376
    /**
377
     * Set the level value.
378
     *
379
     * @param int $lvl
380
     */
381
    public function setLvl($lvl)
382
    {
383
        $this->lvl = $lvl;
384
    }
385
386
    /**
387
     * Get the root value.
388
     *
389
     * @return int
390
     */
391
    public function getRoot()
392
    {
393
        return $this->root;
394
    }
395
396
    /**
397
     * Set the root value.
398
     *
399
     * @param int $root
400
     */
401
    public function setRoot($root)
402
    {
403
        $this->root = $root;
404
    }
405
406
    /**
407
     * Set undeletable.
408
     *
409
     * @param bool $undeletable
410
     *
411
     * @return View The current instance
412
     */
413
    public function setUndeletable($undeletable)
414
    {
415
        $this->undeletable = $undeletable;
0 ignored issues
show
Documentation Bug introduced by
The property $undeletable was declared of type string, but $undeletable is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
416
417
        return $this;
418
    }
419
420
    /**
421
     * Is the widget is undeletable.
422
     *
423
     * @return string
424
     */
425
    public function isUndeletable()
426
    {
427
        return $this->undeletable;
428
    }
429
430
    /**
431
     * Get author.
432
     *
433
     * @return string
434
     */
435
    public function getAuthor()
436
    {
437
        return $this->author;
438
    }
439
440
    /**
441
     * Set author.
442
     *
443
     * @param string $author
444
     *
445
     * @return $this
446
     */
447
    public function setAuthor($author)
448
    {
449
        $this->author = $author;
450
451
        return $this;
452
    }
453
454
    /**
455
     * Get bodyId.
456
     *
457
     * @return string
458
     */
459
    public function getBodyId()
460
    {
461
        return $this->bodyId;
462
    }
463
464
    /**
465
     * Set bodyId.
466
     *
467
     * @param string $bodyId
468
     *
469
     * @return $this
470
     */
471
    public function setBodyId($bodyId)
472
    {
473
        $this->bodyId = $bodyId;
474
475
        return $this;
476
    }
477
478
    /**
479
     * Get bodyClass.
480
     *
481
     * @return string
482
     */
483
    public function getBodyClass()
484
    {
485
        return $this->bodyClass;
486
    }
487
488
    /**
489
     * Set bodyClass.
490
     *
491
     * @param string $bodyClass
492
     *
493
     * @return $this
494
     */
495
    public function setBodyClass($bodyClass)
496
    {
497
        $this->bodyClass = $bodyClass;
498
499
        return $this;
500
    }
501
502
    /**
503
     * Set widgets.
504
     *
505
     * @param [WidgetMap] $widgetMaps
0 ignored issues
show
Documentation introduced by
The doc-type [WidgetMap] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
506
     *
507
     * @return View
508
     */
509
    public function setWidgetMaps($widgetMaps)
510
    {
511
        $this->widgetMaps = $widgetMaps;
512
513
        return $this;
514
    }
515
516
    /**
517
     * Get widgets.
518
     *
519
     * @return Collection[WidgetMap]
0 ignored issues
show
Documentation introduced by
The doc-type Collection[WidgetMap] could not be parsed: Expected "]" at position 2, but found "WidgetMap". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
520
     */
521
    public function getWidgetMaps()
522
    {
523
        return $this->widgetMaps;
524
    }
525
526
    /**
527
     * Add widget.
528
     *
529
     * @param Widget $widgetMap
530
     */
531
    public function addWidgetMap(WidgetMap $widgetMap)
532
    {
533
        if (!$widgetMap->getView()) {
534
            $widgetMap->setView($this);
535
        }
536
        $this->widgetMaps[] = $widgetMap;
537
    }
538
539
    /**
540
     * Remove a widgetMap.
541
     *
542
     * @param WidgetMap $widgetMap
543
     */
544
    public function removeWidgetMap(WidgetMap $widgetMap)
545
    {
546
        $this->widgetMaps->removeElement($widgetMap);
0 ignored issues
show
Bug introduced by
The method removeElement cannot be called on $this->widgetMaps (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
547
    }
548
549
    /**
550
     * Get widgets ids as array.
551
     *
552
     * @return array
553
     */
554
    public function getWidgetsIds()
555
    {
556
        $widgetIds = [];
557
        foreach ($this->getBuiltWidgetMap() as $slot => $_widgetMaps) {
558
            foreach ($_widgetMaps as $widgetMap) {
559
                foreach ($widgetMap->getWidgets() as $widget) {
560
                    $widgetIds[] = $widget->getId();
561
                }
562
            }
563
        }
564
565
        return $widgetIds;
566
    }
567
568
    /**
569
     * Get builtWidgetMap.
570
     *
571
     * @return array
572
     */
573
    public function getBuiltWidgetMap()
574
    {
575
        return $this->builtWidgetMap;
0 ignored issues
show
Bug introduced by
The property builtWidgetMap does not seem to exist. Did you mean widgetMap?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
576
    }
577
578
    /**
579
     * Set builtWidgetMap.
580
     *
581
     * @param string $builtWidgetMap
582
     *
583
     * @return $this
584
     */
585
    public function setBuiltWidgetMap($builtWidgetMap)
586
    {
587
        $this->builtWidgetMap = $builtWidgetMap;
0 ignored issues
show
Bug introduced by
The property builtWidgetMap does not seem to exist. Did you mean widgetMap?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
588
589
        return $this;
590
    }
591
592
    /**
593
     * Get discriminator type.
594
     *
595
     * @return int
596
     */
597
    public function getType()
598
    {
599
        $class = get_called_class();
600
601
        return $class::TYPE;
602
    }
603
604
    /**
605
     * Set position.
606
     *
607
     * @param int $position
608
     */
609
    public function setPosition($position)
610
    {
611
        $this->position = $position;
612
    }
613
614
    /**
615
     * Get position.
616
     *
617
     * @return int
618
     */
619
    public function getPosition()
620
    {
621
        return $this->position;
622
    }
623
624
    /**
625
     * Get reference according to the current locale.
626
     *
627
     * @param string $locale
628
     *
629
     * @return null|ViewReference
630
     */
631
    public function getReference($locale = null)
632
    {
633
        $locale = $locale ?: $this->getCurrentLocale();
634
        if (is_array($this->references) && isset($this->references[$locale])) {
635
            return $this->references[$locale];
636
        }
637
    }
638
639
    /**
640
     * Get references.
641
     *
642
     * @return ViewReference[]
643
     */
644
    public function getReferences()
645
    {
646
        return $this->references;
647
    }
648
649
    /**
650
     * Set references.
651
     *
652
     * @param ViewReference[] $references
653
     *
654
     * @return $this
655
     */
656
    public function setReferences($references)
657
    {
658
        $this->references = $references;
659
660
        return $this;
661
    }
662
663
    /**
664
     * Set reference.
665
     *
666
     * @param ViewReference $reference
667
     * @param string        $locale
668
     *
669
     * @return $this
670
     */
671
    public function setReference(ViewReference $reference, $locale = null)
672
    {
673
        $locale = $locale ?: $this->getCurrentLocale();
674
        $this->references[$locale] = $reference;
675
676
        return $this;
677
    }
678
679
    /**
680
     * Get CSS hash.
681
     *
682
     * @return string
683
     */
684
    public function getCssHash()
685
    {
686
        return $this->cssHash;
687
    }
688
689
    /**
690
     * Set CSS hash.
691
     *
692
     * @param string $cssHash
693
     *
694
     * @return $this
695
     */
696
    public function setCssHash($cssHash)
697
    {
698
        $this->cssHash = $cssHash;
699
700
        return $this;
701
    }
702
703
    /**
704
     * Change cssHash.
705
     */
706
    public function changeCssHash()
707
    {
708
        $this->cssHash = sha1(uniqid());
709
    }
710
711
    /**
712
     * @deprecated
713
     * Get widgetMap.
714
     *
715
     * @return widgetMap
716
     */
717
    public function getWidgetMap()
718
    {
719
        return $this->widgetMap;
0 ignored issues
show
Deprecated Code introduced by
The property Victoire\Bundle\CoreBundle\Entity\View::$widgetMap has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
720
    }
721
722
    /**
723
     * @deprecated
724
     * Get widgets.
725
     *
726
     * @return string
727
     */
728
    public function getWidgets()
729
    {
730
        return $this->widgets;
731
    }
732
733
    public function isTemplateOf(View $view)
734
    {
735
        while ($_view = $view->getTemplate()) {
736
            if ($this == $_view) {
737
                return true;
738
            }
739
            $view = $_view;
740
        }
741
742
        return false;
743
    }
744
745
    /**
746
     * Get cssUpToDate.
747
     *
748
     * @return bool
749
     */
750
    public function isCssUpToDate()
751
    {
752
        return $this->cssUpToDate;
753
    }
754
755
    /**
756
     * Set CssUpToDate.
757
     *
758
     * @param bool $cssUpToDate
759
     *
760
     * @return $this
761
     */
762
    public function setCssUpToDate($cssUpToDate)
763
    {
764
        $this->cssUpToDate = $cssUpToDate;
765
766
        return $this;
767
    }
768
769
    /**
770
     * @inheritdoc
771
     */
772
    public static function getTranslationEntityClass()
773
    {
774
        return '\\Victoire\\Bundle\\I18nBundle\\Entity\\ViewTranslation';
775
    }
776
777
    public function getName()
778
    {
779
        return PropertyAccess::createPropertyAccessor()->getValue($this->translate(null, false), 'getName');
780
    }
781
    
782
    public function setName($name, $locale = null)
783
    {
784
        $this->translate($locale, false)->setName($name);
0 ignored issues
show
Bug introduced by
It seems like setName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
785
        $this->mergeNewTranslations();
786
    }
787
    
788
    public function getSlug()
789
    {
790
        return PropertyAccess::createPropertyAccessor()->getValue($this->translate(null, false), 'getSlug');
791
    }
792
793
    public function setSlug($slug, $locale = null)
794
    {
795
        $this->translate($locale, false)->setSlug($slug);
0 ignored issues
show
Bug introduced by
It seems like setSlug() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
796
        $this->mergeNewTranslations();
797
    }
798
799
}
800