1 | <?php namespace Cviebrock\EloquentTaggable; |
||
15 | trait Taggable |
||
16 | { |
||
17 | |||
18 | /** |
||
19 | * Get a collection of all tags the model has. |
||
20 | * |
||
21 | * @return \Illuminate\Database\Eloquent\Relations\MorphToMany |
||
22 | 23 | */ |
|
23 | public function tags() |
||
24 | 23 | { |
|
25 | 23 | return $this->morphToMany(Tag::class, 'taggable', 'taggable_taggables', 'taggable_id', 'tag_id') |
|
|
|||
26 | ->withTimestamps(); |
||
27 | } |
||
28 | |||
29 | /** |
||
30 | * Attach one or multiple tags to the model. |
||
31 | * |
||
32 | * @param string|array $tags |
||
33 | * |
||
34 | * @return $this |
||
35 | 23 | */ |
|
36 | public function tag($tags) |
||
37 | 23 | { |
|
38 | $tags = app(TagService::class)->buildTagArray($tags); |
||
39 | 23 | ||
40 | 23 | foreach ($tags as $tagName) { |
|
41 | 23 | $this->addOneTag($tagName); |
|
42 | } |
||
43 | 23 | ||
44 | return $this->load('tags'); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Detach one or multiple tags from the model. |
||
49 | * |
||
50 | * @param string|array $tags |
||
51 | * |
||
52 | * @return $this |
||
53 | 1 | */ |
|
54 | public function untag($tags) |
||
55 | 1 | { |
|
56 | $tags = app(TagService::class)->buildTagArray($tags); |
||
57 | 1 | ||
58 | 1 | foreach ($tags as $tagName) { |
|
59 | 1 | $this->removeOneTag($tagName); |
|
60 | } |
||
61 | 1 | ||
62 | return $this->load('tags'); |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Remove all tags from the model and assign the given ones. |
||
67 | * |
||
68 | * @param string|array $tags |
||
69 | * |
||
70 | * @return $this |
||
71 | 1 | */ |
|
72 | public function retag($tags) |
||
73 | 1 | { |
|
74 | return $this->detag()->tag($tags); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Remove all tags from the model. |
||
79 | * |
||
80 | * @return $this |
||
81 | 2 | */ |
|
82 | public function detag() |
||
83 | 2 | { |
|
84 | $this->tags()->sync([]); |
||
85 | 2 | ||
86 | return $this->load('tags'); |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * Add one tag to the model. |
||
91 | * |
||
92 | * @param string $tagName |
||
93 | 23 | */ |
|
94 | protected function addOneTag($tagName) |
||
95 | 23 | { |
|
96 | $tag = app(TagService::class)->findOrCreate($tagName); |
||
97 | 23 | ||
98 | 23 | if (!$this->tags->contains($tag->getKey())) { |
|
99 | 23 | $this->tags()->attach($tag->getKey()); |
|
100 | 23 | } |
|
101 | } |
||
102 | |||
103 | /** |
||
104 | * Remove one tag from the model |
||
105 | * |
||
106 | * @param string $tagName |
||
107 | 1 | */ |
|
108 | protected function removeOneTag($tagName) |
||
109 | 1 | { |
|
110 | $tag = app(TagService::class)->find($tagName); |
||
111 | 1 | ||
112 | 1 | if ($tag) { |
|
113 | 1 | $this->tags()->detach($tag); |
|
114 | 1 | } |
|
115 | } |
||
116 | |||
117 | /** |
||
118 | * Get all the tags of the model as a delimited string. |
||
119 | * |
||
120 | * @return string |
||
121 | */ |
||
122 | 13 | public function getTagListAttribute() |
|
123 | { |
||
124 | 2 | return app(TagService::class)->makeTagList($this); |
|
125 | 13 | } |
|
126 | |||
127 | /** |
||
128 | * Get all normalized tags of a model as a delimited string. |
||
129 | * |
||
130 | * @return string |
||
131 | */ |
||
132 | public function getTagListNormalizedAttribute() |
||
136 | |||
137 | /** |
||
138 | * Get all tags of a model as an array. |
||
139 | * |
||
140 | * @return array |
||
141 | */ |
||
142 | public function getTagArrayAttribute() |
||
146 | |||
147 | /** |
||
148 | * Get all normalized tags of a model as an array. |
||
149 | * |
||
150 | * @return array |
||
151 | */ |
||
152 | public function getTagArrayNormalizedAttribute() |
||
156 | |||
157 | /** |
||
158 | * Query scope for models that have all of the given tags. |
||
159 | * |
||
160 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
161 | * @param array|string $tags |
||
162 | * |
||
163 | * @return \Illuminate\Database\Query\Builder |
||
164 | * @throws \Cviebrock\EloquentTaggable\Exceptions\NoTagsSpecifiedException |
||
165 | * @throws \ErrorException |
||
166 | 1 | */ |
|
167 | public function scopeWithAllTags(Builder $query, $tags) |
||
196 | |||
197 | /** |
||
198 | * Query scope for models that have any of the given tags. |
||
199 | * |
||
200 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
201 | * @param array|string $tags |
||
202 | * |
||
203 | 1 | * @return mixed |
|
204 | * @throws \Cviebrock\EloquentTaggable\Exceptions\NoTagsSpecifiedException |
||
205 | 1 | * @throws \ErrorException |
|
206 | */ |
||
207 | public function scopeWithAnyTags(Builder $query, $tags) |
||
229 | |||
230 | /** |
||
231 | * Query scope for models that have any tag. |
||
232 | * |
||
233 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
234 | * |
||
235 | * @return \Illuminate\Database\Eloquent\Builder |
||
236 | */ |
||
237 | public function scopeIsTagged(Builder $query) |
||
241 | |||
242 | /** |
||
243 | * Query scope for models that do not have all of the given tags. |
||
244 | * |
||
245 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
246 | * @param string|array $tags |
||
247 | * @param bool $includeUntagged |
||
248 | * |
||
249 | * @return \Illuminate\Database\Eloquent\Builder |
||
250 | * @throws \ErrorException |
||
251 | */ |
||
252 | public function scopeWithoutAllTags(Builder $query, $tags, $includeUntagged = false) |
||
272 | |||
273 | /** |
||
274 | * Query scope for models that do not have any of the given tags. |
||
275 | * |
||
276 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
277 | * @param string|array $tags |
||
278 | * @param bool $includeUntagged |
||
279 | * |
||
280 | * @return \Illuminate\Database\Eloquent\Builder |
||
281 | * @throws \ErrorException |
||
282 | */ |
||
283 | public function scopeWithoutAnyTags(Builder $query, $tags, $includeUntagged = false) |
||
302 | |||
303 | /** |
||
304 | * Query scope for models that does not have have any tags. |
||
305 | * |
||
306 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
307 | * |
||
308 | * @return \Illuminate\Database\Eloquent\Builder |
||
309 | */ |
||
310 | public function scopeIsNotTagged(Builder $query) |
||
317 | |||
318 | /** |
||
319 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
320 | * @param string $joinType |
||
321 | * |
||
322 | * @return mixed |
||
323 | */ |
||
324 | private function prepareTableJoin(Builder $query, $joinType) |
||
342 | |||
343 | /** |
||
344 | * Get a collection of all the tag models used for the called class. |
||
345 | * |
||
346 | * @return Collection |
||
347 | */ |
||
348 | public static function allTagModels() |
||
352 | |||
353 | /** |
||
354 | * Get an array of all tags used for the called class. |
||
355 | * |
||
356 | * @return array |
||
357 | */ |
||
358 | public static function allTags() |
||
365 | |||
366 | /** |
||
367 | * Get all the tags used for the called class as a delimited string. |
||
368 | * |
||
369 | * @return string |
||
370 | */ |
||
371 | public static function allTagsList() |
||
375 | } |
||
376 |
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idable
provides a methodequalsId
that in turn relies on the methodgetId()
. If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()
as an abstract method to the trait will make sure it is available.