Passed
Push — master ( aa1f26...3776bc )
by Jonas
06:48
created

HasRecursiveRelationships::newMorphToManyOfDescendants()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 10
c 0
b 0
f 0
dl 0
loc 21
ccs 3
cts 3
cp 1
rs 9.9332
cc 1
nc 1
nop 9
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\Eloquent;
4
5
use Illuminate\Database\Eloquent\Builder;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Staudenmeir\LaravelAdjacencyList\Eloquent\Builder. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Str;
8
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Ancestors;
9
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Bloodline;
10
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Descendants;
11
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\RootAncestor;
12
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Siblings;
13
use Staudenmeir\LaravelCte\Eloquent\QueriesExpressions;
14
15
trait HasRecursiveRelationships
16
{
17
    use HasOfDescendantsRelationships;
18
    use HasRecursiveRelationshipScopes;
19
    use QueriesExpressions;
20
21
    /**
22
     * Get the name of the parent key column.
23
     *
24
     * @return string
25
     */
26 484
    public function getParentKeyName()
27
    {
28 484
        return 'parent_id';
29
    }
30
31
    /**
32
     * Get the qualified parent key column.
33
     *
34
     * @return string
35
     */
36 226
    public function getQualifiedParentKeyName()
37
    {
38 226
        return (new static())->getTable().'.'.$this->getParentKeyName();
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

38
        return (new static())->/** @scrutinizer ignore-call */ getTable().'.'.$this->getParentKeyName();
Loading history...
39
    }
40
41
    /**
42
     * Get the name of the local key column.
43
     *
44
     * @return string
45
     */
46 456
    public function getLocalKeyName()
47
    {
48 456
        return $this->getKeyName();
0 ignored issues
show
Bug introduced by
It seems like getKeyName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

48
        return $this->/** @scrutinizer ignore-call */ getKeyName();
Loading history...
49
    }
50
51
    /**
52
     * Get the qualified local key column.
53
     *
54
     * @return string
55
     */
56 248
    public function getQualifiedLocalKeyName()
57
    {
58 248
        return $this->qualifyColumn($this->getLocalKeyName());
0 ignored issues
show
Bug introduced by
It seems like qualifyColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

58
        return $this->/** @scrutinizer ignore-call */ qualifyColumn($this->getLocalKeyName());
Loading history...
59
    }
60
61
    /**
62
     * Get the name of the depth column.
63
     *
64
     * @return string
65
     */
66 214
    public function getDepthName()
67
    {
68 214
        return 'depth';
69
    }
70
71
    /**
72
     * Get the name of the path column.
73
     *
74
     * @return string
75
     */
76 318
    public function getPathName()
77
    {
78 318
        return 'path';
79
    }
80
81
    /**
82
     * Get the path separator.
83
     *
84
     * @return string
85
     */
86 262
    public function getPathSeparator()
87
    {
88 262
        return '.';
89
    }
90
91
    /**
92
     * Get the additional custom paths.
93
     *
94
     * @return array
95
     */
96 214
    public function getCustomPaths()
97
    {
98 214
        return [];
99
    }
100
101
    /**
102
     * Get the name of the common table expression.
103
     *
104
     * @return string
105
     */
106 416
    public function getExpressionName()
107
    {
108 416
        return 'laravel_cte';
109
    }
110
111
    /**
112
     * Get the model's ancestors.
113
     *
114
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Ancestors
115
     */
116 50
    public function ancestors()
117
    {
118 50
        return $this->newAncestors(
119 50
            (new static())->newQuery(),
0 ignored issues
show
Bug introduced by
It seems like newQuery() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

119
            (new static())->/** @scrutinizer ignore-call */ newQuery(),
Loading history...
120
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...onships::newAncestors(). ( Ignorable by Annotation )

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

120
            /** @scrutinizer ignore-type */ $this,
Loading history...
121 50
            $this->getQualifiedParentKeyName(),
122 50
            $this->getLocalKeyName(),
123 50
            false
124
        );
125
    }
126
127
    /**
128
     * Get the model's ancestors and itself.
129
     *
130
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Ancestors
131
     */
132 26
    public function ancestorsAndSelf()
133
    {
134 26
        return $this->newAncestors(
135 26
            (new static())->newQuery(),
136
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...onships::newAncestors(). ( Ignorable by Annotation )

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

136
            /** @scrutinizer ignore-type */ $this,
Loading history...
137 26
            $this->getQualifiedParentKeyName(),
138 26
            $this->getLocalKeyName(),
139 26
            true
140
        );
141
    }
142
143
    /**
144
     * Instantiate a new Ancestors relationship.
145
     *
146
     * @param \Illuminate\Database\Eloquent\Builder $query
147
     * @param \Illuminate\Database\Eloquent\Model $parent
148
     * @param string $foreignKey
149
     * @param string $localKey
150
     * @param bool $andSelf
151
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Ancestors
152
     */
153 76
    protected function newAncestors(Builder $query, Model $parent, $foreignKey, $localKey, $andSelf)
154
    {
155 76
        return new Ancestors($query, $parent, $foreignKey, $localKey, $andSelf);
156
    }
157
158
    /**
159
     * Get the model's bloodline.
160
     *
161
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Bloodline
162
     */
163 22
    public function bloodline()
164
    {
165 22
        return $this->newBloodline(
166 22
            (new static())->newQuery(),
167
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...onships::newBloodline(). ( Ignorable by Annotation )

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

167
            /** @scrutinizer ignore-type */ $this,
Loading history...
168 22
            $this->getQualifiedParentKeyName(),
169 22
            $this->getLocalKeyName()
170
        );
171
    }
172
173
    /**
174
     * Instantiate a new Bloodline relationship.
175
     *
176
     * @param \Illuminate\Database\Eloquent\Builder $query
177
     * @param \Illuminate\Database\Eloquent\Model $parent
178
     * @param string $foreignKey
179
     * @param string $localKey
180
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Bloodline
181
     */
182 22
    protected function newBloodline(Builder $query, Model $parent, $foreignKey, $localKey)
183
    {
184 22
        return new Bloodline($query, $parent, $foreignKey, $localKey);
185
    }
186
187
    /**
188
     * Get the model's children.
189
     *
190
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
191
     */
192 4
    public function children()
193
    {
194 4
        return $this->hasMany(static::class, $this->getParentKeyName(), $this->getLocalKeyName());
0 ignored issues
show
Bug introduced by
The method hasMany() does not exist on Staudenmeir\LaravelAdjac...sRecursiveRelationships. Did you maybe mean hasManyOfDescendantsAndSelf()? ( Ignorable by Annotation )

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

194
        return $this->/** @scrutinizer ignore-call */ hasMany(static::class, $this->getParentKeyName(), $this->getLocalKeyName());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
195
    }
196
197
    /**
198
     * Get the model's children and itself.
199
     *
200
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Descendants
201
     */
202 4
    public function childrenAndSelf()
203
    {
204 4
        return $this->descendantsAndSelf()->whereDepth('<=', 1);
0 ignored issues
show
Bug introduced by
The method whereDepth() does not exist on Staudenmeir\LaravelAdjac...t\Relations\Descendants. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

204
        return $this->descendantsAndSelf()->/** @scrutinizer ignore-call */ whereDepth('<=', 1);
Loading history...
205
    }
206
207
    /**
208
     * Get the model's descendants.
209
     *
210
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Descendants
211
     */
212 54
    public function descendants()
213
    {
214 54
        return $this->newDescendants(
215 54
            (new static())->newQuery(),
216
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...ships::newDescendants(). ( Ignorable by Annotation )

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

216
            /** @scrutinizer ignore-type */ $this,
Loading history...
217 54
            $this->getQualifiedParentKeyName(),
218 54
            $this->getLocalKeyName(),
219 54
            false
220
        );
221
    }
222
223
    /**
224
     * Get the model's descendants and itself.
225
     *
226
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Descendants
227
     */
228 22
    public function descendantsAndSelf()
229
    {
230 22
        return $this->newDescendants(
231 22
            (new static())->newQuery(),
232
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...ships::newDescendants(). ( Ignorable by Annotation )

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

232
            /** @scrutinizer ignore-type */ $this,
Loading history...
233 22
            $this->getQualifiedParentKeyName(),
234 22
            $this->getLocalKeyName(),
235 22
            true
236
        );
237
    }
238
239
    /**
240
     * Instantiate a new Descendants relationship.
241
     *
242
     * @param \Illuminate\Database\Eloquent\Builder $query
243
     * @param \Illuminate\Database\Eloquent\Model $parent
244
     * @param string $foreignKey
245
     * @param string $localKey
246
     * @param bool $andSelf
247
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Descendants
248
     */
249 76
    protected function newDescendants(Builder $query, Model $parent, $foreignKey, $localKey, $andSelf)
250
    {
251 76
        return new Descendants($query, $parent, $foreignKey, $localKey, $andSelf);
252
    }
253
254
    /**
255
     * Get the model's parent.
256
     *
257
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
258
     */
259 4
    public function parent()
260
    {
261 4
        return $this->belongsTo(static::class, $this->getParentKeyName(), $this->getLocalKeyName());
0 ignored issues
show
Bug introduced by
The method belongsTo() does not exist on Staudenmeir\LaravelAdjac...sRecursiveRelationships. Did you maybe mean belongsToManyOfDescendantsAndSelf()? ( Ignorable by Annotation )

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

261
        return $this->/** @scrutinizer ignore-call */ belongsTo(static::class, $this->getParentKeyName(), $this->getLocalKeyName());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
262
    }
263
264
    /**
265
     * Get the model's parent and itself.
266
     *
267
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Ancestors
268
     */
269 4
    public function parentAndSelf()
270
    {
271 4
        return $this->ancestorsAndSelf()->whereDepth('>=', -1);
0 ignored issues
show
Bug introduced by
The method whereDepth() does not exist on Staudenmeir\LaravelAdjac...ent\Relations\Ancestors. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

271
        return $this->ancestorsAndSelf()->/** @scrutinizer ignore-call */ whereDepth('>=', -1);
Loading history...
272
    }
273
274
    /**
275
     * Get the model's root ancestor.
276
     *
277
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\RootAncestor
278
     */
279 22
    public function rootAncestor()
280
    {
281 22
        return $this->newRootAncestor(
282 22
            (new static())->newQuery(),
283
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...hips::newRootAncestor(). ( Ignorable by Annotation )

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

283
            /** @scrutinizer ignore-type */ $this,
Loading history...
284 22
            $this->getQualifiedParentKeyName(),
285 22
            $this->getLocalKeyName()
286
        );
287
    }
288
289
    /**
290
     * Instantiate a new RootAncestor relationship.
291
     *
292
     * @param \Illuminate\Database\Eloquent\Builder $query
293
     * @param \Illuminate\Database\Eloquent\Model $parent
294
     * @param string $foreignKey
295
     * @param string $localKey
296
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\RootAncestor
297
     */
298 22
    protected function newRootAncestor(Builder $query, Model $parent, $foreignKey, $localKey)
299
    {
300 22
        return new RootAncestor($query, $parent, $foreignKey, $localKey);
301
    }
302
303
    /**
304
     * Get the model's siblings.
305
     *
306
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Siblings
307
     */
308 28
    public function siblings()
309
    {
310 28
        return $this->newSiblings(
311 28
            (new static())->newQuery(),
312
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...ionships::newSiblings(). ( Ignorable by Annotation )

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

312
            /** @scrutinizer ignore-type */ $this,
Loading history...
313 28
            $this->getQualifiedParentKeyName(),
314 28
            $this->getParentKeyName(),
315 28
            false
316
        );
317
    }
318
319
    /**
320
     * Get the model's siblings and itself.
321
     *
322
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Siblings
323
     */
324 24
    public function siblingsAndSelf()
325
    {
326 24
        return $this->newSiblings(
327 24
            (new static())->newQuery(),
328
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...sRecursiveRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...ionships::newSiblings(). ( Ignorable by Annotation )

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

328
            /** @scrutinizer ignore-type */ $this,
Loading history...
329 24
            $this->getQualifiedParentKeyName(),
330 24
            $this->getParentKeyName(),
331 24
            true
332
        );
333
    }
334
335
    /**
336
     * Instantiate a new Siblings relationship.
337
     *
338
     * @param \Illuminate\Database\Eloquent\Builder $query
339
     * @param \Illuminate\Database\Eloquent\Model $parent
340
     * @param string $foreignKey
341
     * @param string $localKey
342
     * @param bool $andSelf
343
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Siblings
344
     */
345 52
    protected function newSiblings(Builder $query, Model $parent, $foreignKey, $localKey, $andSelf)
346
    {
347 52
        return new Siblings($query, $parent, $foreignKey, $localKey, $andSelf);
348
    }
349
350
    /**
351
     * Get the first segment of the model's path.
352
     *
353
     * @return string
354
     */
355 48
    public function getFirstPathSegment()
356
    {
357 48
        $path = $this->attributes[$this->getPathName()];
358
359 48
        return explode($this->getPathSeparator(), $path)[0];
360
    }
361
362
    /**
363
     * Determine whether the model's path is nested.
364
     *
365
     * @return bool
366
     */
367 8
    public function hasNestedPath()
368
    {
369 8
        $path = $this->attributes[$this->getPathName()];
370
371 8
        return Str::contains($path, $this->getPathSeparator());
372
    }
373
374
    /**
375
     * Create a new Eloquent query builder for the model.
376
     *
377
     * @param \Illuminate\Database\Query\Builder $query
378
     * @return \Illuminate\Database\Eloquent\Builder|static
379
     */
380 484
    public function newEloquentBuilder($query)
381
    {
382 484
        return new \Staudenmeir\LaravelAdjacencyList\Eloquent\Builder($query);
383
    }
384
385
    /**
386
     * Create a new Eloquent Collection instance.
387
     *
388
     * @param array $models
389
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Collection
390
     */
391 480
    public function newCollection(array $models = [])
392
    {
393 480
        return new Collection($models);
394
    }
395
}
396