Translatable::getTranslations()   A
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 17
rs 9.6111
1
<?php
2
3
namespace Translation\Traits;
4
5
use App\Models\SiravelModel;
0 ignored issues
show
Bug introduced by
The type App\Models\SiravelModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Translation\Models\Translation;
7
use Translation\Models\ModelTranslation;
8
use Translation\Repositories\TranslationRepository;
9
use Templeiro\Services\CmsService;
0 ignored issues
show
Bug introduced by
The type Templeiro\Services\CmsService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Exception;
11
use Illuminate\Support\Facades\Config;
12
use Illuminate\Support\Str;
13
use Log;
14
use Translation\GoogleTranslate;
0 ignored issues
show
Bug introduced by
The type Translation\GoogleTranslate was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
16
trait Translatable
17
{
18
    /**
19
     * Get a translation.
20
     *
21
     * @param string $lang
22
     *
23
     * @return mixed
24
     */
25
    public function translation($lang)
26
    {
27
        return ModelTranslation::where('entity_id', $this->id)
28
            ->where('entity_type', get_class($this))
29
            ->where('entity_data', 'LIKE', '%"lang":"'.$lang.'"%')
30
            ->first();
31
    }
32
33
    /**
34
     * Get translation data.
35
     *
36
     * @param string $lang
37
     *
38
     * @return array|null
39
     */
40
    public function translationData($lang)
41
    {
42
        $translation = $this->translation($lang);
43
44
        if ($translation) {
45
            return json_decode($translation->entity_data);
46
        }
47
48
        return null;
49
    }
50
51
    /**
52
     * Get a translations attribute.
53
     *
54
     * @return array
55
     */
56
    public function getTranslationsAttribute(): array
57
    {
58
        $translationData = [];
59
        $translations = ModelTranslation::where('entity_id', $this->id)->where('entity_type', get_class($this))->get();
60
61
        foreach ($translations as $translation) {
62
            $translationData[] = $translation->data->attributes;
63
        }
64
65
        return $translationData;
66
    }
67
    /**
68
     * COmentado .. Essa funcao é a equivalente do Spatie @todo
69
     *
70
     * @return array
71
     */
72
    // public function getTranslationsAttribute(): array
73
    // {
74
    //     return collect($this->getTranslatableAttributes())
75
    //         ->mapWithKeys(function (string $key) {
76
    //             return [$key => $this->getTranslations($key)];
77
    //         })
78
    //         ->toArray();
79
    // }
80
81
    /**
82
     * After the item is created in the database.
83
     *
84
     * @param object $payload
85
     */
86
    public function afterCreate($payload)
87
    {
88
        if (config('cms.auto-translate', false)) {
89
            $entry = $payload->toArray();
90
91
            unset($entry['created_at']);
92
            unset($entry['updated_at']);
93
            unset($entry['translations']);
94
            unset($entry['is_published']);
95
            unset($entry['published_at']);
96
            unset($entry['id']);
97
98
            foreach (config('cms.languages') as $code => $language) {
99
                if ($code != config('cms.default-language')) {
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

99
                if ($code != /** @scrutinizer ignore-call */ config('cms.default-language')) {

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...
100
                    $tr = new GoogleTranslate(config('cms.default-language'), $code);
101
                    $translation = [
102
                        'lang' => $code,
103
                        'template' => 'show',
104
                    ];
105
106
                    foreach ($entry as $key => $value) {
107
                        if (!empty($value)) {
108
                            try {
109
                                $translation[$key] = json_decode(json_encode($tr->translate(strip_tags($value))));
110
                            } catch (Exception $e) {
111
                                Log::info('[Translate] Erro> '.$e->getMessage());
112
                                unset($translation[$key]);
113
                            }
114
                        }
115
                    }
116
117
                    if (isset($translation['url'])) {
118
                        $translation['url'] = app(CmsService::class)->convertToURL($translation['url']);
0 ignored issues
show
Bug introduced by
The function app 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

118
                        $translation['url'] = /** @scrutinizer ignore-call */ app(CmsService::class)->convertToURL($translation['url']);
Loading history...
119
                    }
120
121
                    $entityId = $payload->id;
122
                    $entityType = get_class($payload);
123
                    app(TranslationRepository::class)->createOrUpdate($entityId, $entityType, $code, $translation);
124
                }
125
            }
126
        }
127
    }
128
    
129
    /**
130
     * Peguei da Spatie
131
     */
132
133
    public function getAttributeValue($key)
134
    {
135
        if (! $this->isTranslatableAttribute($key)) {
136
            return parent::getAttributeValue($key);
137
        }
138
139
        return $this->getTranslation($key, $this->getLocale());
140
    }
141
142
    public function setAttribute($key, $value)
143
    {
144
        // Pass arrays and untranslatable attributes to the parent method.
145
        if (! $this->isTranslatableAttribute($key) || is_array($value)) {
146
            return parent::setAttribute($key, $value);
147
        }
148
149
        // If the attribute is translatable and not already translated, set a
150
        // translation for the current app locale.
151
        return $this->setTranslation($key, $this->getLocale(), $value);
152
    }
153
154
    public function translate(string $key, string $locale = ''): string
155
    {
156
        return $this->getTranslation($key, $locale);
157
    }
158
159
    public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true)
160
    {
161
        $locale = $this->normalizeLocale($key, $locale, $useFallbackLocale);
162
163
        $translations = $this->getTranslations($key);
164
165
        $translation = $translations[$locale] ?? '';
166
167
        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

167
        if ($this->/** @scrutinizer ignore-call */ hasGetMutator($key)) {
Loading history...
168
            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

168
            return $this->/** @scrutinizer ignore-call */ mutateAttribute($key, $translation);
Loading history...
169
        }
170
171
        return $translation;
172
    }
173
174
    public function getTranslationWithFallback(string $key, string $locale): string
175
    {
176
        return $this->getTranslation($key, $locale, true);
177
    }
178
179
    public function getTranslationWithoutFallback(string $key, string $locale)
180
    {
181
        return $this->getTranslation($key, $locale, false);
182
    }
183
184
    public function getTranslations(string $key = null) : array
185
    {
186
        if ($key !== null) {
187
            $this->guardAgainstNonTranslatableAttribute($key);
188
189
            return array_filter(
190
                json_decode($this->getAttributes()[$key] ?? '' ?: '{}', true) ?: [], function ($value) {
0 ignored issues
show
Bug introduced by
The method getAttributes() does not exist on Translation\Traits\Translatable. 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

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

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...
191
                    return $value !== null && $value !== '';
192
                }
193
            );
194
        }
195
196
        return array_reduce(
197
            $this->getTranslatableAttributes(), function ($result, $item) {
198
                $result[$item] = $this->getTranslations($item);
199
200
                return $result;
201
            }
202
        );
203
    }
204
205
    public function setTranslation(string $key, string $locale, $value): HasTranslations
206
    {
207
        $this->guardAgainstNonTranslatableAttribute($key);
208
209
        $translations = $this->getTranslations($key);
210
211
        $oldValue = $translations[$locale] ?? '';
212
213
        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

213
        if ($this->/** @scrutinizer ignore-call */ hasSetMutator($key)) {
Loading history...
214
            $method = 'set'.Str::studly($key).'Attribute';
215
216
            $this->{$method}($value, $locale);
217
218
            $value = $this->attributes[$key];
219
        }
220
221
        $translations[$locale] = $value;
222
223
        $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

223
        /** @scrutinizer ignore-call */ 
224
        $this->attributes[$key] = $this->asJson($translations);
Loading history...
224
225
        event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value));
0 ignored issues
show
Bug introduced by
The type Translation\Traits\TranslationHasBeenSet was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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

225
        /** @scrutinizer ignore-call */ 
226
        event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value));
Loading history...
226
227
        return $this;
228
    }
229
230
    public function setTranslations(string $key, array $translations): HasTranslations
231
    {
232
        $this->guardAgainstNonTranslatableAttribute($key);
233
234
        foreach ($translations as $locale => $translation) {
235
            $this->setTranslation($key, $locale, $translation);
236
        }
237
238
        return $this;
239
    }
240
241
    public function forgetTranslation(string $key, string $locale): HasTranslations
242
    {
243
        $translations = $this->getTranslations($key);
244
245
        unset($translations[$locale]);
246
247
        $this->setAttribute($key, $translations);
248
249
        return $this;
250
    }
251
252
    public function forgetAllTranslations(string $locale): HasTranslations
253
    {
254
        collect($this->getTranslatableAttributes())->each(
255
            function (string $attribute) use ($locale) {
256
                $this->forgetTranslation($attribute, $locale);
257
            }
258
        );
259
260
        return $this;
261
    }
262
263
    public function getTranslatedLocales(string $key) : array
264
    {
265
        return array_keys($this->getTranslations($key));
266
    }
267
268
    public function isTranslatableAttribute(string $key) : bool
269
    {
270
        return in_array($key, $this->getTranslatableAttributes());
271
    }
272
273
    public function hasTranslation(string $key, string $locale = null): bool
274
    {
275
        $locale = $locale ?: $this->getLocale();
276
277
        return isset($this->getTranslations($key)[$locale]);
278
    }
279
280
    protected function guardAgainstNonTranslatableAttribute(string $key)
281
    {
282
        if (! $this->isTranslatableAttribute($key)) {
283
            throw AttributeIsNotTranslatable::make($key, $this);
0 ignored issues
show
Bug introduced by
The type Translation\Traits\AttributeIsNotTranslatable was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
284
        }
285
    }
286
287
    protected function normalizeLocale(string $key, string $locale, bool $useFallbackLocale) : string
288
    {
289
        if (in_array($locale, $this->getTranslatedLocales($key))) {
290
            return $locale;
291
        }
292
293
        if (! $useFallbackLocale) {
294
            return $locale;
295
        }
296
297
        if (! is_null($fallbackLocale = Config::get('translatable.fallback_locale'))) {
298
            return $fallbackLocale;
299
        }
300
301
        if (! is_null($fallbackLocale = Config::get('app.fallback_locale'))) {
302
            return $fallbackLocale;
303
        }
304
305
        return $locale;
306
    }
307
308
    protected function getLocale() : string
309
    {
310
        return Config::get('app.locale');
311
    }
312
313
    public function getTranslatableAttributes() : array
314
    {
315
        return is_array($this->translatable)
316
            ? $this->translatable
317
            : [];
318
    }
319
320
    public function getCasts() : array
321
    {
322
        return array_merge(
323
            parent::getCasts(),
324
            array_fill_keys($this->getTranslatableAttributes(), 'array')
325
        );
326
    }
327
}
328