Completed
Push — master ( 5c6350...61c78a )
by Nicolas
14:48 queued 11:44
created

TaggableTrait::createTagsModel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Modules\Tag\Traits;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Modules\Tag\Entities\Tag;
7
8
trait TaggableTrait
9
{
10
    /**
11
     * {@inheritdoc}
12
     */
13
    protected static $tagsModel = Tag::class;
14
15
    /**
16
     * {@inheritdoc}
17
     */
18
    public static function getTagsModel()
19
    {
20
        return static::$tagsModel;
21
    }
22
23
    /**
24
     * {@inheritdoc}
25
     */
26
    public static function setTagsModel($model)
27
    {
28
        static::$tagsModel = $model;
29
    }
30
31
    /**
32
     * {@inheritdoc}
33
     */
34 1
    public function scopeWhereTag(Builder $query, $tags, $type = 'slug')
35
    {
36 1
        if (is_string($tags) === true) {
37
            $tags = [$tags];
38
        }
39 1
        $query->with('translations');
40
41 1
        foreach ($tags as $tag) {
42
            $query->whereHas('tags', function (Builder $query) use ($type, $tag) {
43
                $query->whereHas('translations', function (Builder $query) use ($type, $tag) {
44 1
                    $query->where($type, $tag);
45 1
                });
46 1
            });
47 1
        }
48
49 1
        return $query;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 1
    public function scopeWithTag(Builder $query, $tags, $type = 'slug')
56
    {
57 1
        if (is_string($tags) === true) {
58
            $tags = [$tags];
59
        }
60 1
        $query->with('translations');
61
62
        return $query->whereHas('tags', function (Builder $query) use ($type, $tags) {
63
            $query->whereHas('translations', function (Builder $query) use ($type, $tags) {
64 1
                $query->whereIn($type, $tags);
65 1
            });
66 1
        });
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 7
    public function tags()
73
    {
74 7
        return $this->morphToMany(static::$tagsModel, 'taggable', 'tag__tagged', 'taggable_id', 'tag_id');
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 7
    public static function createTagsModel()
81
    {
82 7
        return new static::$tagsModel;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 1
    public static function allTags()
89
    {
90 1
        $instance = new static;
91
92 1
        return $instance->createTagsModel()->with('translations')->whereNamespace($instance->getEntityClassName());
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 7
    public function setTags($tags, $type = 'slug')
99
    {
100
        // Get the current entity tags
101 7
        $entityTags = $this->tags->pluck($type)->all();
102
103
        // Prepare the tags to be added and removed
104 7
        $tagsToAdd = array_diff($tags, $entityTags);
105 7
        $tagsToDel = array_diff($entityTags, $tags);
106
107
        // Detach the tags
108 7
        if (count($tagsToDel) > 0) {
109 1
            $this->untag($tagsToDel);
110 1
        }
111
112
        // Attach the tags
113 7
        if (count($tagsToAdd) > 0) {
114 7
            $this->tag($tagsToAdd);
115 7
        }
116
117 7
        return true;
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 7
    public function tag($tags)
124
    {
125 7
        foreach ($tags as $tag) {
126 7
            $this->addTag($tag);
127 7
        }
128
129 7
        return true;
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135 7
    public function addTag($name)
136
    {
137 7
        $tag = $this->createTagsModel()->where('namespace', $this->getEntityClassName())
138 7
            ->with('translations')
139
            ->whereHas('translations', function (Builder $q) use ($name) {
140 7
            $q->where('slug', $this->generateTagSlug($name));
141 7
        })->first();
142
143 7
        if ($tag === null) {
144 7
            $tag = new Tag([
145 7
                'namespace' => $this->getEntityClassName(),
146 7
                locale() => [
147 7
                    'slug' => $this->generateTagSlug($name),
148 7
                    'name' => $name,
149 7
                ],
150 7
            ]);
151 7
        }
152 7
        if ($tag->exists === false) {
153 7
            $tag->save();
154 7
        }
155
156 7
        if ($this->tags->contains($tag->id) === false) {
157 7
            $this->tags()->attach($tag);
158 7
        }
159 7
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164 1
    public function untag($tags = null)
165
    {
166 1
        $tags = $tags ?: $this->tags->pluck('name')->all();
167
168 1
        foreach ($tags as $tag) {
169 1
            $this->removeTag($tag);
170 1
        }
171
172 1
        return true;
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 1
    public function removeTag($name)
179
    {
180 1
        $tag = $this->createTagsModel()
181 1
            ->where('namespace', $this->getEntityClassName())
182 1
            ->with('translations')
183 1
            ->whereHas('translations', function (Builder $q) use ($name) {
184 1
                $q->orWhere('name', $this->generateTagSlug($name));
185 1
                $q->orWhere('slug', $this->generateTagSlug($name));
186 1
            })->first();
187
188 1
        if ($tag) {
189 1
            $this->tags()->detach($tag);
190 1
        }
191 1
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 7
    protected function getEntityClassName()
197
    {
198 7
        if (isset(static::$entityNamespace)) {
199 7
            return static::$entityNamespace;
200
        }
201
202
        return $this->tags()->getMorphClass();
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208 7
    protected function generateTagSlug($name)
209
    {
210 7
        return str_slug($name);
211
    }
212
}
213