HasTranslations::getTranslationWithoutFallback()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
It seems like hasGetMutator() 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

101
        if ($this->/** @scrutinizer ignore-call */ hasGetMutator($key)) {
Loading history...
102
            return $this->mutateAttribute($key, $translation);
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

102
            return $this->/** @scrutinizer ignore-call */ mutateAttribute($key, $translation);
Loading history...
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
Bug introduced by
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 ignore-type  annotation

119
        return $this->getTranslation(/** @scrutinizer ignore-type */ $key, $this->getLocale());
Loading history...
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
Bug introduced by
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 ignore-call  annotation

127
                json_decode($this->/** @scrutinizer ignore-call */ getAttributes()[$key] ?? '' ?: '{}', true) ?: [],

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...
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
Bug introduced by
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 ignore-call  annotation

152
        if ($this->/** @scrutinizer ignore-call */ hasSetMutator($key)) {
Loading history...
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
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
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 ignore-call  annotation

162
        /** @scrutinizer ignore-call */ 
163
        $this->attributes[$key] = $this->asJson($translations);
Loading history...
163
164
        event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value));
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

164
        /** @scrutinizer ignore-call */ 
165
        event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value));
Loading history...
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
Bug introduced by
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 ignore-call  annotation

239
        if (! is_null($fallbackLocale = /** @scrutinizer ignore-call */ config('translatable.fallback_locale'))) {

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.

Loading history...
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
Bug introduced by
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 ignore-call  annotation

252
        return /** @scrutinizer ignore-call */ config('app.locale');

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.

Loading history...
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
Bug introduced by
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 ignore-call  annotation

315
        if (! is_null(/** @scrutinizer ignore-call */ request('lang')) && request('lang') !== config('cms.default-language', 'en')) {
Loading history...
316
            return $this->translationData(request('lang'));
317
        }
318
319
        return $this;
320
    }
321
}
322