1 | <?php |
||||||
2 | |||||||
3 | namespace Translation\Traits; |
||||||
4 | |||||||
5 | use Illuminate\Support\Facades\Config; |
||||||
6 | use Illuminate\Support\Facades\Lang; |
||||||
7 | use Illuminate\Support\Str; |
||||||
8 | use Translation\Events\TranslationHasBeenSet; |
||||||
9 | use Translation\Exceptions\AttributeIsNotTranslatable; |
||||||
10 | use Translation\Repositories\ModelTranslationRepository; |
||||||
11 | use Translation\Services\GoogleTranslate; |
||||||
12 | |||||||
13 | /** |
||||||
14 | * Model has Translations |
||||||
15 | * |
||||||
16 | * Usage: Add in model |
||||||
17 | * use HasTranslations; |
||||||
18 | * |
||||||
19 | * public $translatable = ['name']; |
||||||
20 | */ |
||||||
21 | trait HasTranslations |
||||||
22 | { |
||||||
23 | use Translatable; |
||||||
24 | // @todo retirado tava dando pau, veio do cms |
||||||
25 | // protected $appends = [ |
||||||
26 | // 'translations', |
||||||
27 | // ]; |
||||||
28 | |||||||
29 | /** |
||||||
30 | * From Siravel |
||||||
31 | |||||||
32 | */ |
||||||
33 | |||||||
34 | // /** |
||||||
35 | // * Get a translation. |
||||||
36 | // * |
||||||
37 | // * @param string $lang |
||||||
38 | // * |
||||||
39 | // * @return mixed |
||||||
40 | // */ |
||||||
41 | // public function translation($lang) |
||||||
42 | // { |
||||||
43 | // return app(ModelTranslationRepository::class)->getTranslation($this->id, get_class($this), $lang); |
||||||
44 | // } |
||||||
45 | |||||||
46 | /** |
||||||
47 | * Get translation data. |
||||||
48 | * |
||||||
49 | * @param string $lang |
||||||
50 | * |
||||||
51 | * @return array|null |
||||||
52 | */ |
||||||
53 | public function translationData($lang) |
||||||
54 | { |
||||||
55 | $translation = $this->translation($lang); |
||||||
56 | |||||||
57 | if ($translation) { |
||||||
58 | return json_decode($translation->entity_data); |
||||||
59 | } |
||||||
60 | |||||||
61 | return null; |
||||||
62 | } |
||||||
63 | |||||||
64 | /** |
||||||
65 | * Peguei da Spatie |
||||||
66 | */ |
||||||
67 | public function getAttributeValue($key) |
||||||
68 | { |
||||||
69 | if (! $this->isTranslatableAttribute($key)) { |
||||||
70 | return parent::getAttributeValue($key); |
||||||
71 | } |
||||||
72 | |||||||
73 | return $this->getTranslation($key, $this->getLocale()); |
||||||
74 | } |
||||||
75 | |||||||
76 | public function setAttribute($key, $value) |
||||||
77 | { |
||||||
78 | // Pass arrays and untranslatable attributes to the parent method. |
||||||
79 | if (! $this->isTranslatableAttribute($key) || is_array($value)) { |
||||||
80 | return parent::setAttribute($key, $value); |
||||||
81 | } |
||||||
82 | |||||||
83 | // If the attribute is translatable and not already translated, set a |
||||||
84 | // translation for the current app locale. |
||||||
85 | return $this->setTranslation($key, $this->getLocale(), $value); |
||||||
86 | } |
||||||
87 | |||||||
88 | public function translate(string $key, string $locale = '', bool $useFallbackLocale = true): string |
||||||
89 | { |
||||||
90 | return $this->getTranslation($key, $locale, $useFallbackLocale); |
||||||
91 | } |
||||||
92 | |||||||
93 | public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true) |
||||||
94 | { |
||||||
95 | $locale = $this->normalizeLocale($key, $locale, $useFallbackLocale); |
||||||
96 | |||||||
97 | $translations = $this->getTranslations($key); |
||||||
98 | |||||||
99 | $translation = $translations[$locale] ?? ''; |
||||||
100 | |||||||
101 | if ($this->hasGetMutator($key)) { |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
102 | return $this->mutateAttribute($key, $translation); |
||||||
0 ignored issues
–
show
It seems like
mutateAttribute() 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
![]() |
|||||||
103 | } |
||||||
104 | |||||||
105 | return $translation; |
||||||
106 | } |
||||||
107 | |||||||
108 | public function getTranslationWithFallback(string $key, string $locale): string |
||||||
109 | { |
||||||
110 | return $this->getTranslation($key, $locale, true); |
||||||
111 | } |
||||||
112 | |||||||
113 | public function getTranslationWithoutFallback(string $key, string $locale) |
||||||
114 | { |
||||||
115 | return $this->getTranslation($key, $locale, false); |
||||||
116 | } |
||||||
117 | public function getTranslatedAttribute(string $key = null): string |
||||||
118 | { |
||||||
119 | return $this->getTranslation($key, $this->getLocale()); |
||||||
0 ignored issues
–
show
It seems like
$key can also be of type null ; however, parameter $key of Translation\Traits\HasTr...tions::getTranslation() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
120 | } |
||||||
121 | public function getTranslations(string $key = null): array |
||||||
122 | { |
||||||
123 | if ($key !== null) { |
||||||
124 | $this->guardAgainstNonTranslatableAttribute($key); |
||||||
125 | |||||||
126 | return array_filter( |
||||||
127 | json_decode($this->getAttributes()[$key] ?? '' ?: '{}', true) ?: [], |
||||||
0 ignored issues
–
show
The method
getAttributes() does not exist on Translation\Traits\HasTranslations . Did you maybe mean getAttributeValue() ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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. ![]() |
|||||||
128 | function ($value) { |
||||||
129 | return $value !== null && $value !== ''; |
||||||
130 | } |
||||||
131 | ); |
||||||
132 | } |
||||||
133 | |||||||
134 | return array_reduce( |
||||||
135 | $this->getTranslatableAttributes(), |
||||||
136 | function ($result, $item) { |
||||||
137 | $result[$item] = $this->getTranslations($item); |
||||||
138 | |||||||
139 | return $result; |
||||||
140 | } |
||||||
141 | ); |
||||||
142 | } |
||||||
143 | |||||||
144 | public function setTranslation(string $key, string $locale, $value)//: HasTranslations |
||||||
145 | { |
||||||
146 | $this->guardAgainstNonTranslatableAttribute($key); |
||||||
147 | |||||||
148 | $translations = $this->getTranslations($key); |
||||||
149 | |||||||
150 | $oldValue = $translations[$locale] ?? ''; |
||||||
151 | |||||||
152 | if ($this->hasSetMutator($key)) { |
||||||
0 ignored issues
–
show
It seems like
hasSetMutator() 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
![]() |
|||||||
153 | $method = 'set'.Str::studly($key).'Attribute'; |
||||||
154 | |||||||
155 | $this->{$method}($value, $locale); |
||||||
156 | |||||||
157 | $value = $this->attributes[$key]; |
||||||
158 | } |
||||||
159 | |||||||
160 | $translations[$locale] = $value; |
||||||
161 | |||||||
162 | $this->attributes[$key] = $this->asJson($translations); |
||||||
0 ignored issues
–
show
It seems like
asJson() 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
![]() |
|||||||
163 | |||||||
164 | event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value)); |
||||||
0 ignored issues
–
show
The function
event was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
165 | |||||||
166 | return $this; |
||||||
167 | } |
||||||
168 | |||||||
169 | public function setTranslations(string $key, array $translations)//: HasTranslations |
||||||
170 | { |
||||||
171 | $this->guardAgainstNonTranslatableAttribute($key); |
||||||
172 | |||||||
173 | foreach ($translations as $locale => $translation) { |
||||||
174 | $this->setTranslation($key, $locale, $translation); |
||||||
175 | } |
||||||
176 | |||||||
177 | return $this; |
||||||
178 | } |
||||||
179 | |||||||
180 | public function forgetTranslation(string $key, string $locale)//: HasTranslations |
||||||
181 | { |
||||||
182 | $translations = $this->getTranslations($key); |
||||||
183 | |||||||
184 | unset( |
||||||
185 | $translations[$locale], |
||||||
186 | $this->$key |
||||||
187 | ); |
||||||
188 | |||||||
189 | $this->setTranslations($key, $translations); |
||||||
190 | |||||||
191 | return $this; |
||||||
192 | } |
||||||
193 | |||||||
194 | public function forgetAllTranslations(string $locale)//: HasTranslations |
||||||
195 | { |
||||||
196 | collect($this->getTranslatableAttributes())->each( |
||||||
197 | function (string $attribute) use ($locale) { |
||||||
198 | $this->forgetTranslation($attribute, $locale); |
||||||
199 | } |
||||||
200 | ); |
||||||
201 | |||||||
202 | return $this; |
||||||
203 | } |
||||||
204 | |||||||
205 | public function getTranslatedLocales(string $key): array |
||||||
206 | { |
||||||
207 | return array_keys($this->getTranslations($key)); |
||||||
208 | } |
||||||
209 | |||||||
210 | public function isTranslatableAttribute(string $key): bool |
||||||
211 | { |
||||||
212 | return in_array($key, $this->getTranslatableAttributes()); |
||||||
213 | } |
||||||
214 | |||||||
215 | public function hasTranslation(string $key, string $locale = null): bool |
||||||
216 | { |
||||||
217 | $locale = $locale ?: $this->getLocale(); |
||||||
218 | |||||||
219 | return isset($this->getTranslations($key)[$locale]); |
||||||
220 | } |
||||||
221 | |||||||
222 | protected function guardAgainstNonTranslatableAttribute(string $key) |
||||||
223 | { |
||||||
224 | if (! $this->isTranslatableAttribute($key)) { |
||||||
225 | throw AttributeIsNotTranslatable::make($key, $this); |
||||||
226 | } |
||||||
227 | } |
||||||
228 | |||||||
229 | protected function normalizeLocale(string $key, string $locale, bool $useFallbackLocale): string |
||||||
230 | { |
||||||
231 | if (in_array($locale, $this->getTranslatedLocales($key))) { |
||||||
232 | return $locale; |
||||||
233 | } |
||||||
234 | |||||||
235 | if (! $useFallbackLocale) { |
||||||
236 | return $locale; |
||||||
237 | } |
||||||
238 | |||||||
239 | if (! is_null($fallbackLocale = config('translatable.fallback_locale'))) { |
||||||
0 ignored issues
–
show
The call to
config() has too few arguments starting with defaultValue .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
240 | return $fallbackLocale; |
||||||
241 | } |
||||||
242 | |||||||
243 | if (! is_null($fallbackLocale = config('app.fallback_locale'))) { |
||||||
244 | return $fallbackLocale; |
||||||
245 | } |
||||||
246 | |||||||
247 | return $locale; |
||||||
248 | } |
||||||
249 | |||||||
250 | protected function getLocale(): string |
||||||
251 | { |
||||||
252 | return config('app.locale'); |
||||||
0 ignored issues
–
show
The call to
config() has too few arguments starting with defaultValue .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
253 | } |
||||||
254 | |||||||
255 | public function getTranslatableAttributes(): array |
||||||
256 | { |
||||||
257 | if (!property_exists($this, 'translatable')) { |
||||||
258 | return []; |
||||||
259 | } |
||||||
260 | return is_array($this->translatable) |
||||||
261 | ? $this->translatable |
||||||
262 | : []; |
||||||
263 | } |
||||||
264 | |||||||
265 | |||||||
266 | /** |
||||||
267 | * Get a translations attribute. |
||||||
268 | * |
||||||
269 | * @return array |
||||||
270 | */ |
||||||
271 | public function getTranslationsAttribute(): array |
||||||
272 | { |
||||||
273 | return collect($this->getTranslatableAttributes()) |
||||||
274 | ->mapWithKeys( |
||||||
275 | function (string $key) { |
||||||
276 | return [$key => $this->getTranslations($key)]; |
||||||
277 | } |
||||||
278 | ) |
||||||
279 | ->toArray(); |
||||||
280 | } |
||||||
281 | |||||||
282 | /** |
||||||
283 | * Veio do Siravel @todo |
||||||
284 | * |
||||||
285 | * @return array |
||||||
286 | * public function getTranslationsAttribute() |
||||||
287 | * { |
||||||
288 | * $translationData = []; |
||||||
289 | * $translations = ModelTranslation::where('entity_id', $this->id)->where('entity_type', get_class($this))->get(); |
||||||
290 | * |
||||||
291 | * foreach ($translations as $translation) { |
||||||
292 | * $translationData[] = $translation->data->attributes; |
||||||
293 | * } |
||||||
294 | * |
||||||
295 | * return $translationData; |
||||||
296 | * } |
||||||
297 | */ |
||||||
298 | |||||||
299 | public function getCasts(): array |
||||||
300 | { |
||||||
301 | return array_merge( |
||||||
302 | parent::getCasts(), |
||||||
303 | array_fill_keys($this->getTranslatableAttributes(), 'array') |
||||||
304 | ); |
||||||
305 | } |
||||||
306 | |||||||
307 | |||||||
308 | /** |
||||||
309 | * Get a model as a translatable object (From CMS) |
||||||
310 | * |
||||||
311 | * @return Object |
||||||
312 | */ |
||||||
313 | public function asObject() |
||||||
314 | { |
||||||
315 | if (! is_null(request('lang')) && request('lang') !== config('cms.default-language', 'en')) { |
||||||
0 ignored issues
–
show
The function
request was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
316 | return $this->translationData(request('lang')); |
||||||
317 | } |
||||||
318 | |||||||
319 | return $this; |
||||||
320 | } |
||||||
321 | } |
||||||
322 |