Passed
Push — master ( c77a82...266f6d )
by Jonas
12:30
created

RecursiveRelationsHook   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 105
c 1
b 0
f 0
dl 0
loc 181
ccs 29
cts 29
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A setTreeRelationProperties() 0 24 4
A run() 0 12 3
A setGraphRelationProperties() 0 22 3
1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\IdeHelper;
4
5
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
6
use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;
7
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Support\Str;
10
use Staudenmeir\LaravelAdjacencyList\Eloquent\Collection;
11
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasGraphRelationships;
12
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
13
14
/**
15
 * @template RT { name: string, manyRelation: boolean, comment: string }
16
 */
17
class RecursiveRelationsHook implements ModelHookInterface
18
{
19
    /**
20
     * @var array<array<RT>>
21
     */
22
    protected static array $treeRelationMap = [
23
        [
24
            'name' => 'ancestors',
25
            'manyRelation' => true,
26
            'comment' => "The model's recursive parents.",
27
        ],
28
        [
29
            'name' => 'ancestorsAndSelf',
30
            'manyRelation' => true,
31
            'comment' => "The model's recursive parents and itself.",
32
        ],
33
        [
34
            'name' => 'bloodline',
35
            'manyRelation' => true,
36
            'comment' => "The model's ancestors, descendants and itself.",
37
        ],
38
        [
39
            'name' => 'children',
40
            'manyRelation' => true,
41
            'comment' => "The model's direct children.",
42
        ],
43
        [
44
            'name' => 'childrenAndSelf',
45
            'manyRelation' => true,
46
            'comment' => "The model's direct children and itself.",
47
        ],
48
        [
49
            'name' => 'descendants',
50
            'manyRelation' => true,
51
            'comment' => "The model's recursive children.",
52
        ],
53
        [
54
            'name' => 'descendantsAndSelf',
55
            'manyRelation' => true,
56
            'comment' => "The model's recursive children and itself.",
57
        ],
58
        [
59
            'name' => 'parent',
60
            'manyRelation' => false,
61
            'comment' => "The model's direct parent.",
62
        ],
63
        [
64
            'name' => 'parentAndSelf',
65
            'manyRelation' => true,
66
            'comment' => "The model's direct parent and itself.",
67
        ],
68
        [
69
            'name' => 'rootAncestor',
70
            'manyRelation' => false,
71
            'comment' => "The model's topmost parent.",
72
        ],
73
        [
74
            'name' => 'siblings',
75
            'manyRelation' => true,
76
            'comment' => "The parent's other children.",
77
        ],
78
        [
79
            'name' => 'siblingsAndSelf',
80
            'manyRelation' => true,
81
            'comment' => "All the parent's children.",
82
        ]
83
    ];
84
85
    /**
86
     * @var array<array<RT>>
87
     */
88
    protected static array $graphRelationMap = [
89
        [
90
            'name' => 'ancestors',
91
            'manyRelation' => true,
92
            'comment' => "The node's recursive parents.",
93
        ],
94
        [
95
            'name' => 'ancestorsAndSelf',
96
            'manyRelation' => true,
97
            'comment' => "The node's recursive parents and itself.",
98
        ],
99
        [
100
            'name' => 'children',
101
            'manyRelation' => true,
102
            'comment' => "The node's direct children.",
103
        ],
104
        [
105
            'name' => 'childrenAndSelf',
106
            'manyRelation' => true,
107
            'comment' => "The node's direct children and itself.",
108
        ],
109
        [
110
            'name' => 'descendants',
111
            'manyRelation' => true,
112
            'comment' => "The node's recursive children.",
113
        ],
114
        [
115
            'name' => 'descendantsAndSelf',
116
            'manyRelation' => true,
117
            'comment' => "The node's recursive children and itself.",
118
        ],
119
        [
120
            'name' => 'parents',
121
            'manyRelation' => true,
122
            'comment' => "The node's direct parents.",
123
        ],
124
        [
125
            'name' => 'parentsAndSelf',
126
            'manyRelation' => true,
127
            'comment' => "The node's direct parents and itself.",
128
        ],
129
    ];
130
131 10
    public function run(ModelsCommand $command, Model $model): void
132
    {
133 10
        $traits = collect(
134 10
            class_uses_recursive($model)
0 ignored issues
show
Bug introduced by
class_uses_recursive($model) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

134
            /** @scrutinizer ignore-type */ class_uses_recursive($model)
Loading history...
135
        );
136
137 10
        if ($traits->contains(HasRecursiveRelationships::class)) {
138 5
            $this->setTreeRelationProperties($command, $model);
139
        }
140
141 10
        if ($traits->contains(HasGraphRelationships::class)) {
142 5
            $this->setGraphRelationProperties($command, $model);
143
        }
144
    }
145
146
147 5
    protected function setTreeRelationProperties(ModelsCommand $command, Model $model): void
148
    {
149 5
        foreach (static::$treeRelationMap as $relationDefinition) {
150 5
            $type = $relationDefinition['manyRelation']
151 5
                ? '\\' . Collection::class . '|' . class_basename($model) . '[]'
152 5
                : class_basename($model);
153
154 5
            $command->setProperty(
155 5
                $relationDefinition['name'],
156
                $type,
157
                true,
158
                false,
159 5
                $relationDefinition['comment'],
160 5
                !$relationDefinition['manyRelation']
161
            );
162
163 5
            if ($relationDefinition['manyRelation']) {
164 5
                $command->setProperty(
165 5
                    Str::snake($relationDefinition['name']) . '_count',
166
                    'int',
167
                    true,
168
                    false,
169
                    null,
170
                    true
171
                );
172
            }
173
        }
174
    }
175
176 5
    protected function setGraphRelationProperties(ModelsCommand $command, Model $model): void
177
    {
178 5
        foreach (static::$graphRelationMap as $relationDefinition) {
179 5
            $type = '\\' . EloquentCollection::class . '|' . class_basename($model) . '[]';
180
181 5
            $command->setProperty(
182 5
                $relationDefinition['name'],
183
                $type,
184
                true,
185
                false,
186 5
                $relationDefinition['comment'],
187 5
                !$relationDefinition['manyRelation']
188
            );
189
190 5
            if ($relationDefinition['manyRelation']) {
191 5
                $command->setProperty(
192 5
                    Str::snake($relationDefinition['name']) . '_count',
193
                    'int',
194
                    true,
195
                    false,
196
                    null,
197
                    true
198
                );
199
            }
200
        }
201
    }
202
}
203