Completed
Push — master ( f6198e...300d99 )
by Paweł
53:20
created

MenuItem::isCurrent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Menu Bundle.
7
 *
8
 * Copyright 2016 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2016 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\MenuBundle\Model;
18
19
use Doctrine\Common\Collections\ArrayCollection;
20
use Doctrine\Common\Collections\Collection;
21
use Knp\Menu\FactoryInterface;
22
use Knp\Menu\ItemInterface;
23
24
class MenuItem implements MenuItemInterface
25
{
26
    /**
27
     * @var mixed
28
     */
29
    protected $id;
30
31
    /**
32
     * @var MenuItemInterface
33
     */
34
    protected $root;
35
36
    /**
37
     * @var int
38
     */
39
    protected $lft;
40
41
    /**
42
     * @var int
43
     */
44
    protected $rgt;
45
46
    /**
47
     * @var int
48
     */
49
    protected $level;
50
51
    /**
52
     * Name of this menu item (used for id by parent menu).
53
     *
54
     * @var string
55
     */
56
    protected $name = null;
57
58
    /**
59
     * Label to output.
60
     *
61
     * @var string
62
     */
63
    protected $label = null;
64
65
    /**
66
     * Attributes for the item link.
67
     *
68
     * @var array
69
     */
70
    protected $linkAttributes = [];
71
72
    /**
73
     * Attributes for the children list.
74
     *
75
     * @var array
76
     */
77
    protected $childrenAttributes = [];
78
79
    /**
80
     * Attributes for the item text.
81
     *
82
     * @var array
83
     */
84
    protected $labelAttributes = [];
85
86
    /**
87
     * Uri to use in the anchor tag.
88
     *
89
     * @var string
90
     */
91
    protected $uri = null;
92
93
    /**
94
     * Attributes for the item.
95
     *
96
     * @var array
97
     */
98
    protected $attributes = [];
99
100
    /**
101
     * Extra stuff associated to the item.
102
     *
103
     * @var array
104
     */
105
    protected $extras = [];
106
107
    /**
108
     * Whether the item is displayed.
109
     *
110
     * @var bool
111
     */
112
    protected $display = true;
113
114
    /**
115
     * Whether the children of the item are displayed.
116
     *
117
     * @var bool
118
     */
119
    protected $displayChildren = true;
120
121
    /**
122
     * Child items.
123
     *
124
     * @var Collection|ItemInterface[]
125
     */
126
    protected $children = [];
127
128
    /**
129
     * Parent item.
130
     *
131
     * @var ItemInterface|null
132
     */
133
    protected $parent = null;
134
135
    /**
136
     * whether the item is current. null means unknown.
137
     *
138
     * @var bool|null
139
     */
140
    protected $isCurrent = null;
141
142
    /**
143
     * @var int
144
     */
145
    protected $position;
146
147
    /**
148
     * MenuItem constructor.
149
     */
150 17
    public function __construct()
151
    {
152 17
        $this->setChildren([]);
153 17
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158 16
    public function getId()
159
    {
160 16
        return $this->id;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166 10
    public function getRoot()
167
    {
168 10
        return $this->root;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function getLeft(): int
175
    {
176
        return $this->lft;
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function setLeft(int $left)
183
    {
184
        $this->lft = $left;
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190
    public function getRight(): int
191
    {
192
        return $this->rgt;
193
    }
194
195
    /**
196
     * @param int $right
197
     */
198
    public function setRight(int $right)
199
    {
200
        $this->rgt = $right;
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function getLevel(): int
207
    {
208
        return $this->level;
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function setLevel(int $level)
215
    {
216
        $this->level = $level;
217
    }
218
219
    /**
220
     * {@inheritdoc}
221
     */
222
    public function setFactory(FactoryInterface $factory)
223
    {
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229 14
    public function getName()
230
    {
231 14
        return $this->name;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237 17
    public function setName($name)
238
    {
239 17
        $this->name = $name;
240
241 17
        return $this;
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247 14
    public function getUri()
248
    {
249 14
        return $this->uri;
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255 17
    public function setUri($uri)
256
    {
257 17
        $this->uri = $uri;
258
259 17
        return $this;
260
    }
261
262
    /**
263
     * {@inheritdoc}
264
     */
265 14
    public function getLabel()
266
    {
267 14
        return $this->label;
268
    }
269
270
    /**
271
     * {@inheritdoc}
272
     */
273 17
    public function setLabel($label)
274
    {
275 17
        $this->label = $label;
276
277 17
        return $this;
278
    }
279
280
    /**
281
     * {@inheritdoc}
282
     */
283
    public function getAttributes()
284
    {
285
        return $this->attributes;
286
    }
287
288
    /**
289
     * {@inheritdoc}
290
     */
291 17
    public function setAttributes(array $attributes)
292
    {
293 17
        $this->attributes = $attributes;
294
295 17
        return $this;
296
    }
297
298
    /**
299
     * {@inheritdoc}
300
     */
301
    public function getAttribute($name, $default = null)
302
    {
303
        if (isset($this->attributes[$name])) {
304
            return $this->attributes[$name];
305
        }
306
307
        return $default;
308
    }
309
310
    /**
311
     * {@inheritdoc}
312
     */
313
    public function setAttribute($name, $value)
314
    {
315
        $this->attributes[$name] = $value;
316
317
        return $this;
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323
    public function getLinkAttributes()
324
    {
325
        return $this->linkAttributes;
326
    }
327
328
    /**
329
     * {@inheritdoc}
330
     */
331 17
    public function setLinkAttributes(array $linkAttributes)
332
    {
333 17
        $this->linkAttributes = $linkAttributes;
334
335 17
        return $this;
336
    }
337
338
    /**
339
     * {@inheritdoc}
340
     */
341
    public function getLinkAttribute($name, $default = null)
342
    {
343
        if (isset($this->linkAttributes[$name])) {
344
            return $this->linkAttributes[$name];
345
        }
346
347
        return $default;
348
    }
349
350
    /**
351
     * {@inheritdoc}
352
     */
353
    public function setLinkAttribute($name, $value)
354
    {
355
        $this->linkAttributes[$name] = $value;
356
357
        return $this;
358
    }
359
360
    /**
361
     * {@inheritdoc}
362
     */
363
    public function getChildrenAttributes()
364
    {
365
        return $this->childrenAttributes;
366
    }
367
368
    /**
369
     * {@inheritdoc}
370
     */
371 17
    public function setChildrenAttributes(array $childrenAttributes)
372
    {
373 17
        $this->childrenAttributes = $childrenAttributes;
374
375 17
        return $this;
376
    }
377
378
    /**
379
     * {@inheritdoc}
380
     */
381
    public function getChildrenAttribute($name, $default = null)
382
    {
383
        if (isset($this->childrenAttributes[$name])) {
384
            return $this->childrenAttributes[$name];
385
        }
386
387
        return $default;
388
    }
389
390
    /**
391
     * {@inheritdoc}
392
     */
393
    public function setChildrenAttribute($name, $value)
394
    {
395
        $this->childrenAttributes[$name] = $value;
396
397
        return $this;
398
    }
399
400
    /**
401
     * {@inheritdoc}
402
     */
403
    public function getLabelAttributes()
404
    {
405
        return $this->labelAttributes;
406
    }
407
408
    /**
409
     * {@inheritdoc}
410
     */
411 17
    public function setLabelAttributes(array $labelAttributes)
412
    {
413 17
        $this->labelAttributes = $labelAttributes;
414
415 17
        return $this;
416
    }
417
418
    /**
419
     * {@inheritdoc}
420
     */
421
    public function getLabelAttribute($name, $default = null)
422
    {
423
        if (isset($this->labelAttributes[$name])) {
424
            return $this->labelAttributes[$name];
425
        }
426
427
        return $default;
428
    }
429
430
    /**
431
     * {@inheritdoc}
432
     */
433
    public function setLabelAttribute($name, $value)
434
    {
435
        $this->labelAttributes[$name] = $value;
436
437
        return $this;
438
    }
439
440
    /**
441
     * {@inheritdoc}
442
     */
443
    public function getExtras()
444
    {
445
        return $this->extras;
446
    }
447
448
    /**
449
     * {@inheritdoc}
450
     */
451
    public function setExtras(array $extras)
452
    {
453
        $this->extras = $extras;
454
455
        return $this;
456
    }
457
458
    /**
459
     * {@inheritdoc}
460
     */
461
    public function getExtra($name, $default = null)
462
    {
463
        if (isset($this->extras[$name])) {
464
            return $this->extras[$name];
465
        }
466
467
        return $default;
468
    }
469
470
    /**
471
     * {@inheritdoc}
472
     */
473
    public function setExtra($name, $value)
474
    {
475
        $this->extras[$name] = $value;
476
477
        return $this;
478
    }
479
480
    /**
481
     * {@inheritdoc}
482
     */
483
    public function getDisplayChildren()
484
    {
485
        return $this->displayChildren;
486
    }
487
488
    /**
489
     * {@inheritdoc}
490
     */
491 17
    public function setDisplayChildren($bool)
492
    {
493 17
        $this->displayChildren = (bool) $bool;
494
495 17
        return $this;
496
    }
497
498
    /**
499
     * {@inheritdoc}
500
     */
501
    public function isDisplayed()
502
    {
503
        return $this->display;
504
    }
505
506
    /**
507
     * {@inheritdoc}
508
     */
509 17
    public function setDisplay($bool)
510
    {
511 17
        $this->display = (bool) $bool;
512
513 17
        return $this;
514
    }
515
516
    /**
517
     * {@inheritdoc}
518
     */
519
    public function hasChild(ItemInterface $menuItem): bool
520
    {
521
        return $this->children->contains($menuItem);
522
    }
523
524
    /**
525
     * {@inheritdoc}
526
     */
527
    public function addChild($child, array $options = array())
528
    {
529
        if (!$this->hasChild($child)) {
0 ignored issues
show
Bug introduced by
It seems like $child defined by parameter $child on line 527 can also be of type string; however, SWP\Bundle\MenuBundle\Model\MenuItem::hasChild() does only seem to accept object<Knp\Menu\ItemInterface>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
530
            $child->setParent($this);
0 ignored issues
show
Bug introduced by
It seems like $child is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
531
            $this->children->set($child->getName(), $child);
532
        }
533
534
        return $child;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $child; of type Knp\Menu\ItemInterface|string is incompatible with the return type declared by the interface Knp\Menu\ItemInterface::addChild of type Knp\Menu\ItemInterface as it can also be of type string which is not included in this return type.
Loading history...
535
    }
536
537
    /**
538
     * {@inheritdoc}
539
     */
540
    public function getChild($name)
541
    {
542
        return $this->children->get($name);
543
    }
544
545
    /**
546
     * {@inheritdoc}
547
     */
548
    public function reorderChildren($order)
549
    {
550
        if (count($order) != $this->count()) {
551
            throw new \InvalidArgumentException('Cannot reorder children, order does not contain all children.');
552
        }
553
554
        $newChildren = array();
555
        foreach ($order as $name) {
556
            if (!$this->children->containsKey($name)) {
557
                throw new \InvalidArgumentException('Cannot find children named '.$name);
558
            }
559
            $child
560
                = $this->getChild($name);
561
            $newChildren[$name] = $child;
562
        }
563
564
        $this->setChildren($newChildren);
565
566
        return $this;
567
    }
568
569
    /**
570
     * {@inheritdoc}
571
     */
572
    public function copy()
573
    {
574
        $newMenu = clone $this;
575
        $newMenu->children = new ArrayCollection();
576
        $newMenu->setParent(null);
577
        foreach ($this->getChildren() as $child) {
578
            $newMenu->addChild($child->copy());
579
        }
580
581
        return $newMenu;
582
    }
583
584
    /**
585
     * {@inheritdoc}
586
     */
587 15
    public function isRoot()
588
    {
589 15
        return null === $this->parent;
590
    }
591
592
    /**
593
     * {@inheritdoc}
594
     */
595 16
    public function getParent()
596
    {
597 16
        return $this->parent;
598
    }
599
600
    /**
601
     * {@inheritdoc}
602
     */
603 10
    public function setParent(ItemInterface $parent = null)
604
    {
605 10
        if ($parent === $this) {
606
            throw new \InvalidArgumentException('Item cannot be a child of itself');
607
        }
608
609 10
        $this->parent = $parent;
610
611 10
        return $this;
612
    }
613
614
    /**
615
     * {@inheritdoc}
616
     */
617
    public function getChildren()
618
    {
619
        if (is_array($this->children)) {
620
            return $this->children;
621
        }
622
623
        return $this->children->toArray();
624
    }
625
626
    /**
627
     * {@inheritdoc}
628
     */
629 17
    public function setChildren(array $children)
630
    {
631 17
        $this->children = new ArrayCollection($children);
632
633 17
        return $this;
634
    }
635
636
    /**
637
     * {@inheritdoc}
638
     */
639
    public function removeChild($name)
640
    {
641
        $name = $name instanceof ItemInterface ? $name->getName() : $name;
642
        $child = $this->getChild($name);
643
644
        if ($child !== null) {
645
            $child->setParent(null);
646
            $this->children->remove($name);
647
        }
648
649
        return $this;
650
    }
651
652
    /**
653
     * {@inheritdoc}
654
     */
655
    public function getFirstChild()
656
    {
657
        return $this->children->first();
658
    }
659
660
    /**
661
     * {@inheritdoc}
662
     */
663
    public function getLastChild()
664
    {
665
        return $this->children->last();
666
    }
667
668
    /**
669
     * {@inheritdoc}
670
     */
671
    public function hasChildren()
672
    {
673
        foreach ($this->children as $child) {
674
            if ($child->isDisplayed()) {
675
                return true;
676
            }
677
        }
678
679
        return false;
680
    }
681
682
    /**
683
     * {@inheritdoc}
684
     */
685 17
    public function setCurrent($bool)
686
    {
687 17
        $this->isCurrent = $bool;
688
689 17
        return $this;
690
    }
691
692
    /**
693
     * {@inheritdoc}
694
     */
695
    public function isCurrent()
696
    {
697
        return $this->isCurrent;
698
    }
699
700
    /**
701
     * {@inheritdoc}
702
     */
703
    public function isLast()
704
    {
705
        // if this is root, then return false
706
        if ($this->isRoot()) {
707
            return false;
708
        }
709
710
        return $this->getParent()->getLastChild() === $this;
711
    }
712
713
    /**
714
     * {@inheritdoc}
715
     */
716
    public function isFirst()
717
    {
718
        // if this is root, then return false
719
        if ($this->isRoot()) {
720
            return false;
721
        }
722
723
        return $this->getParent()->getFirstChild() === $this;
724
    }
725
726
    /**
727
     * {@inheritdoc}
728
     */
729 View Code Duplication
    public function actsLikeFirst()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
730
    {
731
        // root items are never "marked" as first
732
        if ($this->isRoot()) {
733
            return false;
734
        }
735
736
        // A menu acts like first only if it is displayed
737
        if (!$this->isDisplayed()) {
738
            return false;
739
        }
740
741
        // if we're first and visible, we're first, period.
742
        if ($this->isFirst()) {
743
            return true;
744
        }
745
746
        $children = $this->getParent()->getChildren();
747
        foreach ($children as $child) {
748
            // loop until we find a visible menu. If its this menu, we're first
749
            if ($child->isDisplayed()) {
750
                return $child->getName() === $this->getName();
751
            }
752
        }
753
754
        return false;
755
    }
756
757
    /**
758
     * {@inheritdoc}
759
     */
760 View Code Duplication
    public function actsLikeLast()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
761
    {
762
        // root items are never "marked" as last
763
        if ($this->isRoot()) {
764
            return false;
765
        }
766
767
        // A menu acts like last only if it is displayed
768
        if (!$this->isDisplayed()) {
769
            return false;
770
        }
771
772
        // if we're last and visible, we're last, period.
773
        if ($this->isLast()) {
774
            return true;
775
        }
776
777
        /** @var ItemInterface[] $children */
778
        $children = array_reverse($this->getParent()->getChildren());
779
        foreach ($children as $child) {
780
            // loop until we find a visible menu. If its this menu, we're first
781
            if ($child->isDisplayed()) {
782
                return $child->getName() === $this->getName();
783
            }
784
        }
785
786
        return false;
787
    }
788
789
    /**
790
     * {@inheritdoc}
791
     */
792
    public function count()
793
    {
794
        return count($this->children);
795
    }
796
797
    /**
798
     * {@inheritdoc}
799
     */
800 14
    public function getIterator()
801
    {
802 14
        return new \ArrayIterator($this->children);
803
    }
804
805
    /**
806
     * {@inheritdoc}
807
     */
808
    public function offsetExists($name)
809
    {
810
        return isset($this->children[$name]);
811
    }
812
813
    /**
814
     * {@inheritdoc}
815
     */
816
    public function offsetGet($name)
817
    {
818
        return $this->getChild($name);
819
    }
820
821
    /**
822
     * {@inheritdoc}
823
     */
824
    public function offsetSet($name, $value)
825
    {
826
        return $this->addChild($name)->setLabel($value);
827
    }
828
829
    /**
830
     * {@inheritdoc}
831
     */
832
    public function offsetUnset($name)
833
    {
834
        $this->removeChild($name);
835
    }
836
837
    /**
838
     * {@inheritdoc}
839
     */
840 5
    public function getPosition(): int
841
    {
842 5
        return $this->position;
843
    }
844
845
    /**
846
     * {@inheritdoc}
847
     */
848 3
    public function setPosition(int $position)
849
    {
850 3
        $this->position = $position;
851 3
    }
852
853
    /**
854
     * {@inheritdoc}
855
     */
856
    public function getParentId()
857
    {
858
        /** @var MenuItemInterface $parent */
859
        if (null !== $parent = $this->getParent()) {
860
            return (int) $parent->getId();
861
        }
862
    }
863
864
    /**
865
     * {@inheritdoc}
866
     */
867
    public function getRootId()
868
    {
869
        if (null !== $this->root) {
870
            return (int) $this->root->getId();
871
        }
872
    }
873
}
874