Categorizable::normalize()   A
last analyzed

Complexity

Conditions 5
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 9
cts 9
cp 1
rs 9.4222
c 0
b 0
f 0
cc 5
nc 1
nop 1
crap 5
1
<?php
2
namespace UniSharp\Categorizable;
3
4
use Illuminate\Database\Eloquent\Builder;
5
use UniSharp\Categorizable\Models\Category;
6
use Illuminate\Database\Eloquent\Relations\MorphToMany;
7
8
trait Categorizable
9
{
10 26
    public function categories(): MorphToMany
11
    {
12 26
        return $this->morphToMany(Category::class, 'categorizable', 'categorizable');
13
    }
14
15 18
    public function categorize(...$categories): self
16
    {
17 18
        $this->categories()->attach($this->differenceBetweenExistences($this->normalize($categories)));
18 18
        return $this->load('categories');
19
    }
20
21 2
    public function uncategorize(...$categories): self
22
    {
23 2
        $this->categories()->detach($this->normalize($categories));
24 2
        return $this->load('categories');
25
    }
26
27 4
    public function decategorize(): self
28
    {
29 4
        $this->categories()->sync([]);
30 4
        return $this->load('categories');
31
    }
32
33 2
    public function recategorize(...$categories): self
34
    {
35 2
        $this->decategorize()->categorize(...$categories);
36 2
        return $this->load('categories');
37
    }
38
39
    public function scopeHasCategories(Builder $builder, ...$categories): Builder
40
    {
41 6
        return $builder->whereHas('categories', function (Builder $query) use ($categories) {
42 6
            $query->whereIn('category_id', Category::descendantsAndSelf($this->normalize($categories))->pluck('id'));
43 6
        });
44
    }
45
46
    public function scopeHasStrictCategories(Builder $builder, ...$categories): Builder
47
    {
48 2
        return $builder->whereHas('categories', function (Builder $query) use ($categories) {
49 2
            $query->whereIn('category_id', $this->normalize($categories));
50 2
        });
51
    }
52
53
    /*
54
     * Convert everything to category ids
55
     */
56
    public function normalize(array $categories): array
57
    {
58 32
        $ids = collect($categories)->map(function ($categories) {
59
            switch (true) {
60 32
                case is_integer($categories) || is_numeric($categories):
61 22
                    return $categories;
62 18
                case is_string($categories):
63 14
                    return Category::firstOrCreate(['name' => $categories])->id;
0 ignored issues
show
Bug introduced by
The method firstOrCreate() does not exist on UniSharp\Categorizable\Models\Category. Did you maybe mean create()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
64 6
                case is_array($categories):
65 6
                    return $this->normalize($categories);
66
            }
67 32
        })->flatten()->toArray();
68
69
        // reject ids not exist in database
70 32
        return Category::whereIn('id', $ids)->pluck('id')->toArray();
71
    }
72
73 18
    protected function differenceBetweenExistences(array $ids): array
74
    {
75 18
        return array_diff($ids, $this->categories->pluck('id')->toArray());
0 ignored issues
show
Bug introduced by
The property categories does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
76
    }
77
78
    abstract public function morphToMany(
79
        $related,
80
        $name,
81
        $table = null,
82
        $foreignPivotKey = null,
83
        $relatedPivotKey = null,
84
        $parentKey = null,
85
        $relatedKey = null,
86
        $inverse = false
87
    );
88
89
    abstract public function load($relations);
90
}
91