Passed
Push — 0.4.6 ( 783da4...4f316f )
by Philippe
10:55 queued 03:49
created

MenuItem::nodeEntries()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.0729

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 22
ccs 6
cts 7
cp 0.8571
rs 9.5222
c 0
b 0
f 0
cc 5
nc 4
nop 1
crap 5.0729
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\Menu;
6
7
use Astrotomic\Translatable\Translatable as BaseTranslatable;
8
use Illuminate\Database\Eloquent\Model;
9
use Thinktomorrow\Chief\Concerns\Morphable\GlobalMorphableScope;
10
use Thinktomorrow\Chief\Concerns\Morphable\Morphables;
11
use Thinktomorrow\Chief\Concerns\Translatable\Translatable;
12
use Thinktomorrow\Chief\Concerns\Translatable\TranslatableContract;
13
use Thinktomorrow\Chief\Pages\Page;
14
use Vine\Source as VineSource;
15
use Vine\Node;
16
17
class MenuItem extends Model implements TranslatableContract, VineSource
18
{
19
    const TYPE_INTERNAL = 'internal';
20
    const TYPE_CUSTOM = 'custom';
21
    const TYPE_NOLINK = 'nolink';
22
23
    use Translatable;
24
25
    use BaseTranslatable;
0 ignored issues
show
Bug introduced by
The trait Astrotomic\Translatable\Translatable requires the property $each which is not provided by Thinktomorrow\Chief\Menu\MenuItem.
Loading history...
26
27
    protected $translationModel = MenuItemTranslation::class;
28
    protected $translationForeignKey = 'menu_item_id';
29
    protected $translatedAttributes = [
30
        'label',
31
        'url',
32
    ];
33
34
    protected $with = ['page', 'translations'];
35
36
    public $timestamps = false;
37
    public $guarded = [];
38
39 9
    public function ofType($type): bool
40
    {
41 9
        return $this->type == $type;
42
    }
43
44 4
    public function menuType()
45
    {
46 4
        return $this->menu_type;
47
    }
48
49 27
    public function page()
50
    {
51 27
        return $this->belongsTo(Page::class, 'page_id')
52 27
            ->withoutGlobalScope(GlobalMorphableScope::class);
53
    }
54
55 2
    public function parent()
56
    {
57 2
        return $this->belongsTo(MenuItem::class, 'parent_id');
58
    }
59
60 2
    public function children()
61
    {
62 2
        return $this->hasMany(MenuItem::class, 'parent_id')->orderBy('order', 'ASC');
63
    }
64
65 1
    public function siblings()
66
    {
67 1
        return static:: where('parent_id', $this->parent_id)->where('menu_type', $this->menuType())->where('id', '<>', $this->id)->orderBy('order', 'ASC')->get();
68
    }
69
70
    public function siblingsIncludingSelf()
71
    {
72
        return static:: where('parent_id', $this->parent_id)->where('menu_type', $this->menuType())->orderBy('order', 'ASC')->get();
73
    }
74
75
    public function scopeOnlyGrandParents($query)
76
    {
77
        return $query->whereNull('parent_id');
78
    }
79
80 13
    public function url()
81
    {
82 13
        if ($this->ofType(static::TYPE_INTERNAL) && $page = $this->page) {
83
            return $page->url();
84
        }
85
86
        return $this->url;
87
    }
88
89
    /**
90
     * Full array of original data rows
91
     * These are the rows to be converted to the tree model
92
     *
93
     * @return array
94
     */
95
    public function nodeEntries($type = 'main'): array
96
    {
97
        $items = $this->where('menu_type', $type)->get();
98
        $collectionItems = collect([]);
99
100
        // Expose the collection items and populate them with the collection data
101
        foreach ($items as $k => $item) {
102
            // Fetch the urls of the internal links
103
            if ($item->ofType(static::TYPE_INTERNAL) && $page = $item->page) {
104
                if ($page->isArchived()) {
105 13
                    unset($items[$k]);
106
                } else {
107 13
                    $item->url = self::composePageUrl($item, $page);
0 ignored issues
show
Bug introduced by
The property url does not seem to exist on Thinktomorrow\Chief\Menu\MenuItem. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
108 13
                    $item->page_label = $page->menuLabel();
0 ignored issues
show
Bug introduced by
The property page_label does not seem to exist on Thinktomorrow\Chief\Menu\MenuItem. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
109
                    $item->hidden_in_menu = $page->hidden_in_menu;
110
                    $item->draft = $page->isDraft();
0 ignored issues
show
Bug introduced by
The property draft does not seem to exist on Thinktomorrow\Chief\Menu\MenuItem. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
111 13
                    $items[$k] = $item;
112
                }
113 9
            }
114 2
        }
115
116
        return array_merge($items->all(), $collectionItems->all());
117 2
    }
118 2
119
    private static function composePageUrl(MenuItem $item, Page $page)
0 ignored issues
show
Unused Code introduced by
The parameter $item is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

119
    private static function composePageUrl(/** @scrutinizer ignore-unused */ MenuItem $item, Page $page)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
120 2
    {
121 2
        return $page->url();
122 2
    }
123 2
124 2
    /**
125 2
     * Attribute key of the primary identifier of each row. e.g. 'id'
126 2
     *
127
     * @return string
128 2
     */
129
    public function nodeKeyIdentifier(): string
130
    {
131 9
        return 'id';
132 6
    }
133
134
    /**
135 6
     * Attribute key of the parent foreign identifier of each row. e.g. 'parent_id'
136 6
     *
137 6
     * @return string
138 6
     */
139 9
    public function nodeParentKeyIdentifier(): string
140
    {
141
        return 'parent_id';
142
    }
143
144 13
    /**
145
     * Convert entire models to condensed data arrays
146
     *
147 7
     * @param Node $node
148
     */
149 7
    public function entry(Node $node)
150
    {
151
        return (object)[
152
            'id'             => $node->id,
153
            'type'           => $node->type,
154
            'label'          => $node->label,
155
            'page_label'     => $node->page_label,                       // Extra info when dealing with internal links
156
            'url'            => $node->url,
157
            'order'          => $node->order,
158
            'page_id'        => $node->page_id,
159
            'parent_id'      => $node->parent_id,
160
            'morph_key'      => $node->morph_key,
161
            'hidden_in_menu' => $node->hidden_in_menu,
162
            'draft'          => $node->draft,
163
        ];
164
    }
165
}
166