HasGraphAdjacencyList::getQualifiedChildKeyName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
ccs 0
cts 0
cp 0
cc 1
nc 1
nop 0
crap 2
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 Staudenmeir\LaravelAdjacencyList\Eloquent\Graph\Collection;
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
    use HasQueryConstraints;
16
17
    /**
18
     * Get the name of the pivot table.
19
     *
20
     * @return string
21
     */
22
    abstract public function getPivotTableName(): string;
23
24
    /**
25
     * Get the name of the parent key column.
26
     *
27
     * @return string
28
     */
29
    public function getParentKeyName(): string
30
    {
31
        return 'parent_id';
32
    }
33
34 248
    /**
35
     * Get the qualified parent key column.
36 248
     *
37
     * @return string
38
     */
39
    public function getQualifiedParentKeyName()
40
    {
41
        return $this->getPivotTableName() . '.' . $this->getParentKeyName();
42
    }
43
44 270
    /**
45
     * Get the name of the child key column.
46 270
     *
47
     * @return string
48
     */
49
    public function getChildKeyName(): string
50
    {
51
        return 'child_id';
52
    }
53
54 248
    /**
55
     * Get the qualified child key column.
56 248
     *
57
     * @return string
58
     */
59
    public function getQualifiedChildKeyName()
60
    {
61
        return $this->getPivotTableName() . '.' . $this->getChildKeyName();
62
    }
63
64 270
    /**
65
     * Get the name of the local key column.
66 270
     *
67
     * @return string
68
     */
69
    public function getLocalKeyName(): string
70
    {
71
        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

71
        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...
72
    }
73
74 248
    /**
75
     * Get the qualified local key column.
76 248
     *
77
     * @return string
78
     */
79
    public function getQualifiedLocalKeyName(): string
80
    {
81
        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

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

184
            (new static())->/** @scrutinizer ignore-call */ newQuery(),
Loading history...
185
            $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

185
            /** @scrutinizer ignore-type */ $this,
Loading history...
186 87
            $this->getPivotTableName(),
187
            $this->getParentKeyName(),
188 87
            $this->getChildKeyName(),
189 87
            $this->getLocalKeyName(),
190 87
            $this->getLocalKeyName(),
191 87
            false
192 87
        );
193 87
    }
194 87
195 87
    /**
196 87
     * Get the model's ancestors and itself.
197 87
     *
198
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Ancestors<static>
199
     */
200
    public function ancestorsAndSelf(): Ancestors
201
    {
202
        return $this->newAncestors(
203
            (new static())->newQuery(),
204
            $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

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

256
        return $this->/** @scrutinizer ignore-call */ belongsToMany(
Loading history...
257
            static::class,
258
            $this->getPivotTableName(),
259 5
            $this->getParentKeyName(),
260
            $this->getChildKeyName(),
261 5
            $this->getLocalKeyName(),
262 5
            $this->getLocalKeyName()
263 5
        )->withPivot(
264 5
            $this->getPivotColumns()
265 5
        );
266 5
    }
267 5
268 5
    /**
269 5
     * Get the model's children and itself.
270 5
     *
271
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants<static>
272
     */
273
    public function childrenAndSelf(): Descendants
274
    {
275
        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

275
        return $this->descendantsAndSelf()->/** @scrutinizer ignore-call */ whereDepth('<=', 1);
Loading history...
276
    }
277
278 4
    /**
279
     * Get the model's descendants.
280 4
     *
281
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants<static>
282
     */
283
    public function descendants(): Descendants
284
    {
285
        return $this->newDescendants(
286
            (new static())->newQuery(),
287
            $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

287
            /** @scrutinizer ignore-type */ $this,
Loading history...
288 111
            $this->getPivotTableName(),
289
            $this->getParentKeyName(),
290 111
            $this->getChildKeyName(),
291 111
            $this->getLocalKeyName(),
292 111
            $this->getLocalKeyName(),
293 111
            false
294 111
        );
295 111
    }
296 111
297 111
    /**
298 111
     * Get the model's descendants and itself.
299 111
     *
300
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Descendants<static>
301
     */
302
    public function descendantsAndSelf(): Descendants
303
    {
304
        return $this->newDescendants(
305
            (new static())->newQuery(),
306
            $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

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

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

403
        /** @scrutinizer ignore-call */ 
404
        $casts = $this->getCasts();
Loading history...
404
405 68
        return isset($casts[$attribute]) && in_array($casts[$attribute], ['int', 'integer']);
406 68
    }
407
408 68
    /**
409
     * Create a new Eloquent query builder for the model.
410 68
     *
411
     * @param \Illuminate\Database\Query\Builder $query
412
     * @return \Illuminate\Database\Eloquent\Builder|static
413
     */
414
    public function newEloquentBuilder($query)
415
    {
416
        return new \Staudenmeir\LaravelAdjacencyList\Eloquent\Builder($query);
417
    }
418
419 280
    /**
420
     * Create a new Eloquent Collection instance.
421 280
     *
422
     * @param array $models
423
     * @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Graph\Collection
424
     */
425
    public function newCollection(array $models = [])
426
    {
427
        return new Collection($models);
0 ignored issues
show
Bug introduced by
$models of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Staudenmeir\LaravelAdjac...llection::__construct(). ( Ignorable by Annotation )

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

427
        return new Collection(/** @scrutinizer ignore-type */ $models);
Loading history...
428
    }
429
430 5
    /**
431
     * Execute a query with a maximum depth constraint for the recursive query.
432 5
     *
433
     * @param int $maxDepth
434
     * @param callable $query
435
     * @return mixed
436
     */
437
    public static function withMaxDepth(int $maxDepth, callable $query): mixed
438
    {
439
        $operator = $maxDepth > 0 ? '<' : '>';
440 5
441
        return static::withRecursiveQueryConstraint(
442 5
            fn (Builder $query) => $query->whereDepth($operator, $maxDepth),
443
            $query
444
        );
445
    }
446
}
447