Passed
Branch master (407c50)
by Jonas
02:53
created

HasGraphAdjacencyList::getPivotColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\Eloquent\Traits;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
8
use Illuminate\Support\Str;
9
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors;
10
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants;
11
12
trait HasGraphAdjacencyList
13
{
14
    use HasGraphRelationshipScopes;
15
16
    /**
17
     * The additional constraint for the recursive query.
18
     *
19
     * @var callable|null
20
     */
21
    public static $recursiveQueryConstraint;
22
23
    /**
24
     * Get the name of the pivot table.
25
     *
26
     * @return string
27
     */
28
    abstract public function getPivotTableName(): string;
29
30
    /**
31
     * Get the name of the parent key column.
32
     *
33
     * @return string
34
     */
35 214
    public function getParentKeyName(): string
36
    {
37 214
        return 'parent_id';
38
    }
39
40
    /**
41
     * Get the qualified parent key column.
42
     *
43
     * @return string
44
     */
45 206
    public function getQualifiedParentKeyName()
46
    {
47 206
        return $this->getPivotTableName() . '.' . $this->getParentKeyName();
48
    }
49
50
    /**
51
     * Get the name of the child key column.
52
     *
53
     * @return string
54
     */
55 214
    public function getChildKeyName(): string
56
    {
57 214
        return 'child_id';
58
    }
59
60
    /**
61
     * Get the qualified child key column.
62
     *
63
     * @return string
64
     */
65 206
    public function getQualifiedChildKeyName()
66
    {
67 206
        return $this->getPivotTableName() . '.' . $this->getChildKeyName();
68
    }
69
70
    /**
71
     * Get the name of the local key column.
72
     *
73
     * @return string
74
     */
75 214
    public function getLocalKeyName(): string
76
    {
77 214
        return $this->getKeyName();
0 ignored issues
show
Bug introduced by
The method getKeyName() does not exist on Staudenmeir\LaravelAdjac...s\HasGraphAdjacencyList. Did you maybe mean getChildKeyName()? ( Ignorable by Annotation )

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

77
        return $this->/** @scrutinizer ignore-call */ getKeyName();

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...
78
    }
79
80
    /**
81
     * Get the qualified local key column.
82
     *
83
     * @return string
84
     */
85 206
    public function getQualifiedLocalKeyName(): string
86
    {
87 206
        return $this->qualifyColumn(
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

87
        return $this->/** @scrutinizer ignore-call */ qualifyColumn(
Loading history...
88 206
            $this->getLocalKeyName()
89
        );
90
    }
91
92
    /**
93
     * Get the name of the depth column.
94
     *
95
     * @return string
96
     */
97 206
    public function getDepthName(): string
98
    {
99 206
        return 'depth';
100
    }
101
102
    /**
103
     * Get the name of the path column.
104
     *
105
     * @return string
106
     */
107 208
    public function getPathName(): string
108
    {
109 208
        return 'path';
110
    }
111
112
    /**
113
     * Get the path separator.
114
     *
115
     * @return string
116
     */
117 206
    public function getPathSeparator(): string
118
    {
119 206
        return '.';
120
    }
121
122
    /**
123
     * Get the additional custom paths.
124
     *
125
     * @return array
126
     */
127 206
    public function getCustomPaths(): array
128
    {
129 206
        return [];
130
    }
131
132
    /**
133
     * Get the pivot table columns to retrieve.
134
     *
135
     * @return array
136
     */
137 206
    public function getPivotColumns(): array
138
    {
139 206
        return [];
140
    }
141
142
    /**
143
     * Get the name of the common table expression.
144
     *
145
     * @return string
146
     */
147 206
    public function getExpressionName(): string
148
    {
149 206
        return 'laravel_cte';
150
    }
151
152
    /**
153
     * Whether to enable cycle detection.
154
     *
155
     * @return bool
156
     */
157 130
    public function enableCycleDetection(): bool
158
    {
159 130
        return false;
160
    }
161
162
    /**
163
     * Whether to include the first row of the cycle in the query results.
164
     *
165
     * @return bool
166
     */
167 38
    public function includeCycleStart(): bool
168
    {
169 38
        return false;
170
    }
171
172
    /**
173
     * Get the name of the cycle detection column.
174
     *
175
     * @return string
176
     */
177 38
    public function getCycleDetectionColumnName(): string
178
    {
179 38
        return 'is_cycle';
180
    }
181
182
    /**
183
     * Get the model's ancestors.
184
     *
185
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors
186
     */
187 58
    public function ancestors(): Ancestors
188
    {
189 58
        return $this->newAncestors(
190 58
            (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

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

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

191
            /** @scrutinizer ignore-type */ $this,
Loading history...
192 58
            $this->getPivotTableName(),
193 58
            $this->getParentKeyName(),
194 58
            $this->getChildKeyName(),
195 58
            $this->getLocalKeyName(),
196 58
            $this->getLocalKeyName(),
197
            false
198
        );
199
    }
200
201
    /**
202
     * Get the model's ancestors and itself.
203
     *
204
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors
205
     */
206 41
    public function ancestorsAndSelf(): Ancestors
207
    {
208 41
        return $this->newAncestors(
209 41
            (new static())->newQuery(),
210
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...s\HasGraphAdjacencyList is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...ncyList::newAncestors(). ( Ignorable by Annotation )

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

210
            /** @scrutinizer ignore-type */ $this,
Loading history...
211 41
            $this->getPivotTableName(),
212 41
            $this->getParentKeyName(),
213 41
            $this->getChildKeyName(),
214 41
            $this->getLocalKeyName(),
215 41
            $this->getLocalKeyName(),
216
            true
217
        );
218
    }
219
220
    /**
221
     * Instantiate a new Ancestors relationship.
222
     *
223
     * @param \Illuminate\Database\Eloquent\Builder $query
224
     * @param \Illuminate\Database\Eloquent\Model $parent
225
     * @param string $table
226
     * @param string $foreignPivotKey
227
     * @param string $relatedPivotKey
228
     * @param string $parentKey
229
     * @param string $relatedKey
230
     * @param bool $andSelf
231
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors
232
     */
233 99
    protected function newAncestors(
234
        Builder $query,
235
        Model $parent,
236
        string $table,
237
        string $foreignPivotKey,
238
        string $relatedPivotKey,
239
        string $parentKey,
240
        string $relatedKey,
241
        bool $andSelf
242
    ): Ancestors {
243 99
        return new Ancestors(
244
            $query,
245
            $parent,
246
            $table,
247
            $foreignPivotKey,
248
            $relatedPivotKey,
249
            $parentKey,
250
            $relatedKey,
251
            $andSelf
252
        );
253
    }
254
255
    /**
256
     * Get the model's children.
257
     *
258
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
259
     */
260 4
    public function children(): BelongsToMany
261
    {
262 4
        return $this->belongsToMany(
0 ignored issues
show
Bug introduced by
It seems like belongsToMany() 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

262
        return $this->/** @scrutinizer ignore-call */ belongsToMany(
Loading history...
263
            static::class,
264 4
            $this->getPivotTableName(),
265 4
            $this->getParentKeyName(),
266 4
            $this->getChildKeyName(),
267 4
            $this->getLocalKeyName(),
268 4
            $this->getLocalKeyName()
269
        );
270
    }
271
272
    /**
273
     * Get the model's children and itself.
274
     *
275
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants
276
     */
277 4
    public function childrenAndSelf(): Descendants
278
    {
279 4
        return $this->descendantsAndSelf()->whereDepth('<=', 1);
0 ignored issues
show
Bug introduced by
The method whereDepth() does not exist on Staudenmeir\LaravelAdjac...tions\Graph\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

279
        return $this->descendantsAndSelf()->/** @scrutinizer ignore-call */ whereDepth('<=', 1);
Loading history...
280
    }
281
282
    /**
283
     * Get the model's descendants.
284
     *
285
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants
286
     */
287 76
    public function descendants(): Descendants
288
    {
289 76
        return $this->newDescendants(
290 76
            (new static())->newQuery(),
291
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...s\HasGraphAdjacencyList is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...yList::newDescendants(). ( Ignorable by Annotation )

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

291
            /** @scrutinizer ignore-type */ $this,
Loading history...
292 76
            $this->getPivotTableName(),
293 76
            $this->getParentKeyName(),
294 76
            $this->getChildKeyName(),
295 76
            $this->getLocalKeyName(),
296 76
            $this->getLocalKeyName(),
297
            false
298
        );
299
    }
300
301
    /**
302
     * Get the model's descendants and itself.
303
     *
304
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants
305
     */
306 47
    public function descendantsAndSelf(): Descendants
307
    {
308 47
        return $this->newDescendants(
309 47
            (new static())->newQuery(),
310
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\LaravelAdjac...s\HasGraphAdjacencyList is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\LaravelAdjac...yList::newDescendants(). ( Ignorable by Annotation )

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

310
            /** @scrutinizer ignore-type */ $this,
Loading history...
311 47
            $this->getPivotTableName(),
312 47
            $this->getParentKeyName(),
313 47
            $this->getChildKeyName(),
314 47
            $this->getLocalKeyName(),
315 47
            $this->getLocalKeyName(),
316
            true
317
        );
318
    }
319
320
    /**
321
     * Instantiate a new Descendants relationship.
322
     *
323
     * @param \Illuminate\Database\Eloquent\Builder $query
324
     * @param \Illuminate\Database\Eloquent\Model $parent
325
     * @param string $table
326
     * @param string $foreignPivotKey
327
     * @param string $relatedPivotKey
328
     * @param string $parentKey
329
     * @param string $relatedKey
330
     * @param bool $andSelf
331
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants
332
     */
333 123
    protected function newDescendants(
334
        Builder $query,
335
        Model $parent,
336
        string $table,
337
        string $foreignPivotKey,
338
        string $relatedPivotKey,
339
        string $parentKey,
340
        string $relatedKey,
341
        bool $andSelf
342
    ): Descendants {
343 123
        return new Descendants(
344
            $query,
345
            $parent,
346
            $table,
347
            $foreignPivotKey,
348
            $relatedPivotKey,
349
            $parentKey,
350
            $relatedKey,
351
            $andSelf
352
        );
353
    }
354
355
    /**
356
     * Get the model's parents.
357
     *
358
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
359
     */
360 4
    public function parents(): BelongsToMany
361
    {
362 4
        return $this->belongsToMany(
363
            static::class,
364 4
            $this->getPivotTableName(),
365 4
            $this->getChildKeyName(),
366 4
            $this->getParentKeyName(),
367 4
            $this->getLocalKeyName(),
368 4
            $this->getLocalKeyName()
369
        );
370
    }
371
372
    /**
373
     * Get the model's parents and itself.
374
     *
375
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors
376
     */
377 4
    public function parentsAndSelf(): Ancestors
378
    {
379 4
        return $this->ancestorsAndSelf()->whereDepth('>=', -1);
0 ignored issues
show
Bug introduced by
The method whereDepth() does not exist on Staudenmeir\LaravelAdjac...lations\Graph\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

379
        return $this->ancestorsAndSelf()->/** @scrutinizer ignore-call */ whereDepth('>=', -1);
Loading history...
380
    }
381
382
    /**
383
     * Get the first segment of the model's path.
384
     *
385
     * @return string
386
     */
387 64
    public function getFirstPathSegment(): string
388
    {
389 64
        $path = $this->attributes[$this->getPathName()];
390
391 64
        return explode($this->getPathSeparator(), $path)[0];
392
    }
393
394
    /**
395
     * Determine if an attribute is an integer.
396
     *
397
     * @param string $attribute
398
     * @return bool
399
     */
400 58
    public function isIntegerAttribute(string $attribute): bool
401
    {
402 58
        $segments = explode('.', $attribute);
403 58
        $attribute = end($segments);
404
405 58
        $casts = $this->getCasts();
0 ignored issues
show
Bug introduced by
It seems like getCasts() 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

405
        /** @scrutinizer ignore-call */ 
406
        $casts = $this->getCasts();
Loading history...
406
407 58
        return isset($casts[$attribute]) && in_array($casts[$attribute], ['int', 'integer']);
408
    }
409
410
    /**
411
     * Create a new Eloquent query builder for the model.
412
     *
413
     * @param \Illuminate\Database\Query\Builder $query
414
     * @return \Illuminate\Database\Eloquent\Builder|static
415
     */
416 214
    public function newEloquentBuilder($query)
417
    {
418 214
        return new \Staudenmeir\LaravelAdjacencyList\Eloquent\Builder($query);
419
    }
420
421
    /**
422
     * Set an additional constraint for the recursive query.
423
     *
424
     * @param callable $constraint
425
     * @return void
426
     */
427 4
    public static function setRecursiveQueryConstraint(callable $constraint): void
428
    {
429 4
        static::$recursiveQueryConstraint = $constraint;
430
    }
431
432
    /**
433
     * Unset the additional constraint for the recursive query.
434
     *
435
     * @return void
436
     */
437 4
    public static function unsetRecursiveQueryConstraint(): void
438
    {
439 4
        static::$recursiveQueryConstraint = null;
440
    }
441
442
    /**
443
     * Execute a query with an additional constraint for the recursive query.
444
     *
445
     * @param callable $constraint
446
     * @param callable $query
447
     * @return mixed
448
     */
449 4
    public static function withRecursiveQueryConstraint(callable $constraint, callable $query): mixed
450
    {
451 4
        $previous = static::$recursiveQueryConstraint;
452
453 4
        static::$recursiveQueryConstraint = $constraint;
454
455 4
        $result = $query();
456
457 4
        static::$recursiveQueryConstraint = $previous;
458
459 4
        return $result;
460
    }
461
}
462