Test Setup Failed
Pull Request — master (#508)
by
unknown
126:59 queued 61:48
created

Translatable::getLocaleKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Dimsav\Translatable;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Query\JoinClause;
8
use Illuminate\Database\Eloquent\Relations\Relation;
9
use Illuminate\Database\Query\Builder as QueryBuilder;
10
use Dimsav\Translatable\Exception\LocalesNotDefinedException;
11
12
trait Translatable
13
{
14
    protected static $autoloadTranslations = null;
15
16
    protected $defaultLocale;
17
18
    /**
19
     * Alias for getTranslation().
20
     *
21
     * @param string|null $locale
22
     * @param bool        $withFallback
23
     *
24
     * @return \Illuminate\Database\Eloquent\Model|null
25
     */
26
    public function translate($locale = null, $withFallback = false)
27
    {
28
        return $this->getTranslation($locale, $withFallback);
29
    }
30
31
    /**
32
     * Alias for getTranslation().
33
     *
34
     * @param string $locale
35
     *
36
     * @return \Illuminate\Database\Eloquent\Model|null
37
     */
38
    public function translateOrDefault($locale = null)
39
    {
40
        return $this->getTranslation($locale, true);
41
    }
42
43
    /**
44
     * Alias for getTranslationOrNew().
45
     *
46
     * @param string $locale
47
     *
48
     * @return \Illuminate\Database\Eloquent\Model|null
49
     */
50
    public function translateOrNew($locale = null)
51
    {
52
        return $this->getTranslationOrNew($locale);
53
    }
54
55
    /**
56
     * @param string|null $locale
57
     * @param bool        $withFallback
58
     *
59
     * @return \Illuminate\Database\Eloquent\Model|null
60
     */
61
    public function getTranslation($locale = null, $withFallback = null)
62
    {
63
        $configFallbackLocale = $this->getFallbackLocale();
64
        $locale = $locale ?: $this->locale();
65
        $withFallback = $withFallback === null ? $this->useFallback() : $withFallback;
66
        $fallbackLocale = $this->getFallbackLocale($locale);
67
68
        if ($translation = $this->getTranslationByLocaleKey($locale)) {
69
            return $translation;
70
        }
71
        if ($withFallback && $fallbackLocale) {
72
            if ($translation = $this->getTranslationByLocaleKey($fallbackLocale)) {
73
                return $translation;
74
            }
75
            if ($fallbackLocale !== $configFallbackLocale && $translation = $this->getTranslationByLocaleKey($configFallbackLocale)) {
76
                return $translation;
77
            }
78
        }
79
80
        return null;
81
    }
82
83
    /**
84
     * @param string|null $locale
85
     *
86
     * @return bool
87
     */
88
    public function hasTranslation($locale = null)
89
    {
90
        $locale = $locale ?: $this->locale();
91
92
        foreach ($this->translations as $translation) {
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
93
            if ($translation->getAttribute($this->getLocaleKey()) == $locale) {
94
                return true;
95
            }
96
        }
97
98
        return false;
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    public function getTranslationModelName()
105
    {
106
        return $this->translationModel ?: $this->getTranslationModelNameDefault();
0 ignored issues
show
Bug introduced by
The property translationModel does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    public function getTranslationModelNameDefault()
113
    {
114
        $fullModelName = $this->getTranslationModelNamespace().'\\'.class_basename(get_class($this));
115
116
        return $fullModelName.config('translatable.translation_suffix', 'Translation');
117
    }
118
119
    /**
120
     * @return string
121
     */
122
    public function getTranslationModelNamespace()
123
    {
124
        return config('translatable.translation_model_namespace', 'App');
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getRelationKey()
131
    {
132
        if ($this->translationForeignKey) {
133
            $key = $this->translationForeignKey;
0 ignored issues
show
Bug introduced by
The property translationForeignKey does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
134
        } elseif ($this->primaryKey !== 'id') {
0 ignored issues
show
Bug introduced by
The property primaryKey does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
135
            $key = $this->primaryKey;
136
        } else {
137
            $key = $this->getForeignKey();
0 ignored issues
show
Bug introduced by
It seems like getForeignKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
138
        }
139
140
        return $key;
141
    }
142
143
    /**
144
     * @return string
145
     */
146
    public function getLocaleKey()
147
    {
148
        return $this->localeKey ?: config('translatable.locale_key', 'locale');
0 ignored issues
show
Bug introduced by
The property localeKey does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
149
    }
150
151
    /**
152
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
153
     */
154
    public function translations()
155
    {
156
        return $this->hasMany($this->getTranslationModelName(), $this->getRelationKey());
0 ignored issues
show
Bug introduced by
It seems like hasMany() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
157
    }
158
159
    /**
160
     * @return bool
161
     */
162
    private function usePropertyFallback()
163
    {
164
        return $this->useFallback() && config('translatable.use_property_fallback', false);
165
    }
166
167
    /**
168
     * Returns the attribute value from fallback translation if value of attribute
169
     * is empty and the property fallback is enabled in the configuration.
170
     * in model.
171
     * @param $locale
172
     * @param $attribute
173
     * @return mixed
174
     */
175
    private function getAttributeOrFallback($locale, $attribute)
176
    {
177
        $translation = $this->getTranslation($locale);
178
179
        if (
180
            (
181
                ! $translation instanceof Model ||
182
                empty($translation->$attribute)
183
            ) &&
184
            $this->usePropertyFallback()
185
        ) {
186
            $translation = $this->getTranslation($this->getFallbackLocale(), false);
187
        }
188
189
        if ($translation instanceof Model) {
190
            return $translation->$attribute;
191
        }
192
193
        return null;
194
    }
195
196
    /**
197
     * @param string $key
198
     *
199
     * @return mixed
200
     */
201
    public function getAttribute($key)
202
    {
203
        list($attribute, $locale) = $this->getAttributeAndLocale($key);
204
205
        if ($this->isTranslationAttribute($attribute)) {
206
            if ($this->getTranslation($locale) === null) {
207
                return $this->getAttributeValue($attribute);
0 ignored issues
show
Bug introduced by
The method getAttributeValue() does not exist on Dimsav\Translatable\Translatable. Did you maybe mean getAttribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
208
            }
209
210
            // If the given $attribute has a mutator, we push it to $attributes and then call getAttributeValue
211
            // on it. This way, we can use Eloquent's checking for Mutation, type casting, and
212
            // Date fields.
213
            if ($this->hasGetMutator($attribute)) {
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?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
214
                $this->attributes[$attribute] = $this->getAttributeOrFallback($locale, $attribute);
0 ignored issues
show
Bug introduced by
The property attributes does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
215
216
                return $this->getAttributeValue($attribute);
0 ignored issues
show
Bug introduced by
The method getAttributeValue() does not exist on Dimsav\Translatable\Translatable. Did you maybe mean getAttribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
217
            }
218
219
            return $this->getAttributeOrFallback($locale, $attribute);
220
        }
221
222
        return parent::getAttribute($key);
223
    }
224
225
    /**
226
     * @param string $key
227
     * @param mixed  $value
228
     *
229
     * @return $this
230
     */
231
    public function setAttribute($key, $value)
232
    {
233
        list($attribute, $locale) = $this->getAttributeAndLocale($key);
234
235
        if ($this->isTranslationAttribute($attribute)) {
236
            $this->getTranslationOrNew($locale)->$attribute = $value;
237
        } else {
238
            return parent::setAttribute($key, $value);
239
        }
240
241
        return $this;
242
    }
243
244
    /**
245
     * @param array $options
246
     *
247
     * @return bool
248
     */
249
    public function save(array $options = [])
250
    {
251
        if ($this->exists) {
0 ignored issues
show
Bug introduced by
The property exists does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
252
            if ($this->isDirty()) {
0 ignored issues
show
Bug introduced by
It seems like isDirty() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
253
                // If $this->exists and dirty, parent::save() has to return true. If not,
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
254
                // an error has occurred. Therefore we shouldn't save the translations.
255
                if (parent::save($options)) {
256
                    return $this->saveTranslations();
257
                }
258
259
                return false;
260
            } else {
261
                // If $this->exists and not dirty, parent::save() skips saving and returns
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
262
                // false. So we have to save the translations
263
                if ($this->fireModelEvent('saving') === false) {
0 ignored issues
show
Bug introduced by
It seems like fireModelEvent() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
264
                    return false;
265
                }
266
267
                if ($saved = $this->saveTranslations()) {
268
                    $this->fireModelEvent('saved', false);
0 ignored issues
show
Bug introduced by
It seems like fireModelEvent() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
269
                    $this->fireModelEvent('updated', false);
0 ignored issues
show
Bug introduced by
It seems like fireModelEvent() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
270
                }
271
272
                return $saved;
273
            }
274
        } elseif (parent::save($options)) {
275
            // We save the translations only if the instance is saved in the database.
276
            return $this->saveTranslations();
277
        }
278
279
        return false;
280
    }
281
282
    /**
283
     * @param string $locale
284
     *
285
     * @return \Illuminate\Database\Eloquent\Model
286
     */
287
    protected function getTranslationOrNew($locale = null)
288
    {
289
        $locale = $locale ?: $this->locale();
290
291
        if (($translation = $this->getTranslation($locale, false)) === null) {
292
            $translation = $this->getNewTranslation($locale);
293
        }
294
295
        return $translation;
296
    }
297
298
    /**
299
     * @param array $attributes
300
     *
301
     * @throws \Illuminate\Database\Eloquent\MassAssignmentException
302
     * @return $this
303
     */
304
    public function fill(array $attributes)
305
    {
306
        foreach ($attributes as $key => $values) {
307
            if ($this->isKeyALocale($key)) {
308
                $this->getTranslationOrNew($key)->fill($values);
309
                unset($attributes[$key]);
310
            } else {
311
                list($attribute, $locale) = $this->getAttributeAndLocale($key);
312
                if ($this->isTranslationAttribute($attribute) and $this->isKeyALocale($locale)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
313
                    $this->getTranslationOrNew($locale)->fill([$attribute => $values]);
314
                    unset($attributes[$key]);
315
                }
316
            }
317
        }
318
319
        return parent::fill($attributes);
320
    }
321
322
    /**
323
     * @param string $key
324
     */
325
    private function getTranslationByLocaleKey($key)
326
    {
327
        foreach ($this->translations as $translation) {
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
328
            if ($translation->getAttribute($this->getLocaleKey()) == $key) {
329
                return $translation;
330
            }
331
        }
332
333
        return null;
334
    }
335
336
    /**
337
     * @param null $locale
338
     *
339
     * @return string
340
     */
341
    private function getFallbackLocale($locale = null)
342
    {
343
        if ($locale && $this->isLocaleCountryBased($locale)) {
344
            if ($fallback = $this->getLanguageFromCountryBasedLocale($locale)) {
345
                return $fallback;
346
            }
347
        }
348
349
        return config('translatable.fallback_locale');
350
    }
351
352
    /**
353
     * @param $locale
354
     *
355
     * @return bool
356
     */
357
    private function isLocaleCountryBased($locale)
358
    {
359
        return strpos($locale, $this->getLocaleSeparator()) !== false;
360
    }
361
362
    /**
363
     * @param $locale
364
     *
365
     * @return string
366
     */
367
    private function getLanguageFromCountryBasedLocale($locale)
368
    {
369
        $parts = explode($this->getLocaleSeparator(), $locale);
370
371
        return array_get($parts, 0);
372
    }
373
374
    /**
375
     * @return bool|null
376
     */
377
    private function useFallback()
378
    {
379
        if (isset($this->useTranslationFallback) && $this->useTranslationFallback !== null) {
380
            return $this->useTranslationFallback;
0 ignored issues
show
Bug introduced by
The property useTranslationFallback does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
381
        }
382
383
        return config('translatable.use_fallback');
384
    }
385
386
    /**
387
     * @param string $key
388
     *
389
     * @return bool
390
     */
391
    public function isTranslationAttribute($key)
392
    {
393
        return in_array($key, $this->translatedAttributes);
0 ignored issues
show
Bug introduced by
The property translatedAttributes does not seem to exist. Did you mean attributes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
394
    }
395
396
    /**
397
     * @param string $key
398
     *
399
     * @throws \Dimsav\Translatable\Exception\LocalesNotDefinedException
400
     * @return bool
401
     */
402
    protected function isKeyALocale($key)
403
    {
404
        $locales = $this->getLocales();
405
406
        return in_array($key, $locales);
407
    }
408
409
    /**
410
     * @throws \Dimsav\Translatable\Exception\LocalesNotDefinedException
411
     * @return array
412
     */
413
    protected function getLocales()
414
    {
415
        $localesConfig = (array) config('translatable.locales');
416
417
        if (empty($localesConfig)) {
418
            throw new LocalesNotDefinedException('Please make sure you have run "php artisan config:publish dimsav/laravel-translatable" '.
419
                ' and that the locales configuration is defined.');
420
        }
421
422
        $locales = [];
423
        foreach ($localesConfig as $key => $locale) {
424
            if (is_array($locale)) {
425
                $locales[] = $key;
426
                foreach ($locale as $countryLocale) {
427
                    $locales[] = $key.$this->getLocaleSeparator().$countryLocale;
428
                }
429
            } else {
430
                $locales[] = $locale;
431
            }
432
        }
433
434
        return $locales;
435
    }
436
437
    /**
438
     * @return string
439
     */
440
    protected function getLocaleSeparator()
441
    {
442
        return config('translatable.locale_separator', '-');
443
    }
444
445
    /**
446
     * @return bool
447
     */
448
    protected function saveTranslations()
449
    {
450
        $saved = true;
451
        foreach ($this->translations as $translation) {
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
452
            if ($saved && $this->isTranslationDirty($translation)) {
453
                if (! empty($connectionName = $this->getConnectionName())) {
0 ignored issues
show
Bug introduced by
It seems like getConnectionName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
454
                    $translation->setConnection($connectionName);
455
                }
456
457
                $translation->setAttribute($this->getRelationKey(), $this->getKey());
0 ignored issues
show
Bug introduced by
It seems like getKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
458
                $saved = $translation->save();
459
            }
460
        }
461
462
        return $saved;
463
    }
464
465
    /**
466
     * @param array
467
     *
468
     * @return \Illuminate\Database\Eloquent\Model
469
     */
470
    public function replicateWithTranslations(array $except = null)
471
    {
472
        $newInstance = parent::replicate($except);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (replicate() instead of replicateWithTranslations()). Are you sure this is correct? If so, you might want to change this to $this->replicate().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
473
474
        unset($newInstance->translations);
475
        foreach ($this->translations as $translation) {
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
476
            $newTranslation = $translation->replicate();
477
            $newInstance->translations->add($newTranslation);
478
        }
479
480
        return  $newInstance;
481
    }
482
483
    /**
484
     * @param \Illuminate\Database\Eloquent\Model $translation
485
     *
486
     * @return bool
487
     */
488
    protected function isTranslationDirty(Model $translation)
489
    {
490
        $dirtyAttributes = $translation->getDirty();
491
        unset($dirtyAttributes[$this->getLocaleKey()]);
492
493
        return count($dirtyAttributes) > 0;
494
    }
495
496
    /**
497
     * @param string $locale
498
     *
499
     * @return \Illuminate\Database\Eloquent\Model
500
     */
501
    public function getNewTranslation($locale)
502
    {
503
        $modelName = $this->getTranslationModelName();
504
        $translation = new $modelName();
505
        $translation->setAttribute($this->getLocaleKey(), $locale);
506
        $this->translations->add($translation);
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
507
508
        return $translation;
509
    }
510
511
    /**
512
     * @param $key
513
     *
514
     * @return bool
515
     */
516
    public function __isset($key)
517
    {
518
        return $this->isTranslationAttribute($key) || parent::__isset($key);
519
    }
520
521
    /**
522
     * @param \Illuminate\Database\Eloquent\Builder $query
523
     * @param string                                $locale
524
     *
525
     * @return \Illuminate\Database\Eloquent\Builder|static
526
     */
527 View Code Duplication
    public function scopeTranslatedIn(Builder $query, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
528
    {
529
        $locale = $locale ?: $this->locale();
530
531
        return $query->whereHas('translations', function (Builder $q) use ($locale) {
532
            $q->where($this->getLocaleKey(), '=', $locale);
533
        });
534
    }
535
536
    /**
537
     * @param \Illuminate\Database\Eloquent\Builder $query
538
     * @param string                                $locale
539
     *
540
     * @return \Illuminate\Database\Eloquent\Builder|static
541
     */
542 View Code Duplication
    public function scopeNotTranslatedIn(Builder $query, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
543
    {
544
        $locale = $locale ?: $this->locale();
545
546
        return $query->whereDoesntHave('translations', function (Builder $q) use ($locale) {
547
            $q->where($this->getLocaleKey(), '=', $locale);
548
        });
549
    }
550
551
    /**
552
     * @param \Illuminate\Database\Eloquent\Builder $query
553
     *
554
     * @return \Illuminate\Database\Eloquent\Builder|static
555
     */
556
    public function scopeTranslated(Builder $query)
557
    {
558
        return $query->has('translations');
559
    }
560
561
    /**
562
     * Adds scope to get a list of translated attributes, using the current locale.
563
     * Example usage: Country::listsTranslations('name')->get()->toArray()
564
     * Will return an array with items:
565
     *  [
566
     *      'id' => '1',                // The id of country
567
     *      'name' => 'Griechenland'    // The translated name
568
     *  ].
569
     *
570
     * @param \Illuminate\Database\Eloquent\Builder $query
571
     * @param string                                $translationField
572
     */
573
    public function scopeListsTranslations(Builder $query, $translationField)
574
    {
575
        $withFallback = $this->useFallback();
576
        $translationTable = $this->getTranslationsTable();
577
        $localeKey = $this->getLocaleKey();
578
579
        $query
0 ignored issues
show
Bug introduced by
The method select() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean createSelectWithConstraint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
580
            ->select($this->getTable().'.'.$this->getKeyName(), $translationTable.'.'.$translationField)
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
Bug introduced by
It seems like getKeyName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
581
            ->leftJoin($translationTable, $translationTable.'.'.$this->getRelationKey(), '=', $this->getTable().'.'.$this->getKeyName())
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
Bug introduced by
It seems like getKeyName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
582
            ->where($translationTable.'.'.$localeKey, $this->locale());
583
        if ($withFallback) {
584
            $query->orWhere(function (Builder $q) use ($translationTable, $localeKey) {
585
                $q->where($translationTable.'.'.$localeKey, $this->getFallbackLocale())
586
                  ->whereNotIn($translationTable.'.'.$this->getRelationKey(), function (QueryBuilder $q) use (
587
                      $translationTable,
588
                      $localeKey
589
                  ) {
590
                      $q->select($translationTable.'.'.$this->getRelationKey())
591
                        ->from($translationTable)
592
                        ->where($translationTable.'.'.$localeKey, $this->locale());
593
                  });
594
            });
595
        }
596
    }
597
598
    /**
599
     * This scope eager loads the translations for the default and the fallback locale only.
600
     * We can use this as a shortcut to improve performance in our application.
601
     *
602
     * @param Builder $query
603
     */
604
    public function scopeWithTranslation(Builder $query)
605
    {
606
        $query->with([
607
            'translations' => function (Relation $query) {
608
                if ($this->useFallback()) {
609
                    $locale = $this->locale();
610
                    $countryFallbackLocale = $this->getFallbackLocale($locale); // e.g. de-DE => de
611
                    $locales = array_unique([$locale, $countryFallbackLocale, $this->getFallbackLocale()]);
612
613
                    return $query->whereIn($this->getTranslationsTable().'.'.$this->getLocaleKey(), $locales);
614
                }
615
616
                return $query->where($this->getTranslationsTable().'.'.$this->getLocaleKey(), $this->locale());
617
            },
618
        ]);
619
    }
620
621
    /**
622
     * This scope filters results by checking the translation fields.
623
     *
624
     * @param \Illuminate\Database\Eloquent\Builder $query
625
     * @param string                                $key
626
     * @param string                                $value
627
     * @param string                                $locale
628
     *
629
     * @return \Illuminate\Database\Eloquent\Builder|static
630
     */
631 View Code Duplication
    public function scopeWhereTranslation(Builder $query, $key, $value, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
632
    {
633
        return $query->whereHas('translations', function (Builder $query) use ($key, $value, $locale) {
634
            $query->where($this->getTranslationsTable().'.'.$key, $value);
635
            if ($locale) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $locale of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
636
                $query->where($this->getTranslationsTable().'.'.$this->getLocaleKey(), $locale);
637
            }
638
        });
639
    }
640
641
    /**
642
     * This scope filters results by checking the translation fields.
643
     *
644
     * @param \Illuminate\Database\Eloquent\Builder $query
645
     * @param string                                $key
646
     * @param string                                $value
647
     * @param string                                $locale
648
     *
649
     * @return \Illuminate\Database\Eloquent\Builder|static
650
     */
651 View Code Duplication
    public function scopeOrWhereTranslation(Builder $query, $key, $value, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
652
    {
653
        return $query->orWhereHas('translations', function (Builder $query) use ($key, $value, $locale) {
654
            $query->where($this->getTranslationsTable().'.'.$key, $value);
655
            if ($locale) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $locale of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
656
                $query->where($this->getTranslationsTable().'.'.$this->getLocaleKey(), $locale);
657
            }
658
        });
659
    }
660
661
    /**
662
     * This scope filters results by checking the translation fields.
663
     *
664
     * @param \Illuminate\Database\Eloquent\Builder $query
665
     * @param string                                $key
666
     * @param string                                $value
667
     * @param string                                $locale
668
     *
669
     * @return \Illuminate\Database\Eloquent\Builder|static
670
     */
671 View Code Duplication
    public function scopeWhereTranslationLike(Builder $query, $key, $value, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
672
    {
673
        return $query->whereHas('translations', function (Builder $query) use ($key, $value, $locale) {
674
            $query->where($this->getTranslationsTable().'.'.$key, 'LIKE', $value);
675
            if ($locale) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $locale of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
676
                $query->where($this->getTranslationsTable().'.'.$this->getLocaleKey(), 'LIKE', $locale);
677
            }
678
        });
679
    }
680
681
    /**
682
     * This scope filters results by checking the translation fields.
683
     *
684
     * @param \Illuminate\Database\Eloquent\Builder $query
685
     * @param string                                $key
686
     * @param string                                $value
687
     * @param string                                $locale
688
     *
689
     * @return \Illuminate\Database\Eloquent\Builder|static
690
     */
691 View Code Duplication
    public function scopeOrWhereTranslationLike(Builder $query, $key, $value, $locale = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
692
    {
693
        return $query->orWhereHas('translations', function (Builder $query) use ($key, $value, $locale) {
694
            $query->where($this->getTranslationsTable().'.'.$key, 'LIKE', $value);
695
            if ($locale) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $locale of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
696
                $query->where($this->getTranslationsTable().'.'.$this->getLocaleKey(), 'LIKE', $locale);
697
            }
698
        });
699
    }
700
701
    /**
702
     * This scope sorts results by the given translation field.
703
     *
704
     * @param \Illuminate\Database\Eloquent\Builder $query
705
     * @param string                                $key
706
     * @param string                                $sortmethod
707
     *
708
     * @return \Illuminate\Database\Eloquent\Builder|static
709
     */
710
    public function scopeOrderByTranslation(Builder $query, $key, $sortmethod = 'asc')
711
    {
712
        $translationTable = $this->getTranslationsTable();
713
        $localeKey = $this->getLocaleKey();
714
        $table = $this->getTable();
0 ignored issues
show
Bug introduced by
It seems like getTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
715
        $keyName = $this->getKeyName();
0 ignored issues
show
Bug introduced by
It seems like getKeyName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
716
717
        return $query
718
            ->join($translationTable, function (JoinClause $join) use ($translationTable, $localeKey, $table, $keyName) {
719
                $join
720
                    ->on($translationTable.'.'.$this->getRelationKey(), '=', $table.'.'.$keyName)
721
                    ->where($translationTable.'.'.$localeKey, $this->locale());
722
            })
723
            ->orderBy($translationTable.'.'.$key, $sortmethod)
724
            ->select($table.'.*')
725
            ->with('translations');
726
    }
727
728
    /**
729
     * @return array
730
     */
731
    public function attributesToArray()
732
    {
733
        $attributes = parent::attributesToArray();
734
735
        if (
736
            (! $this->relationLoaded('translations') && ! $this->toArrayAlwaysLoadsTranslations() && is_null(self::$autoloadTranslations))
0 ignored issues
show
Bug introduced by
It seems like relationLoaded() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
737
            || self::$autoloadTranslations === false
738
        ) {
739
            return $attributes;
740
        }
741
742
        $hiddenAttributes = $this->getHidden();
0 ignored issues
show
Bug introduced by
It seems like getHidden() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
743
744
        foreach ($this->translatedAttributes as $field) {
0 ignored issues
show
Bug introduced by
The property translatedAttributes does not seem to exist. Did you mean attributes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
745
            if (in_array($field, $hiddenAttributes)) {
746
                continue;
747
            }
748
749
            $attributes[$field] = $this->getAttributeOrFallback(null, $field);
750
        }
751
752
        return $attributes;
753
    }
754
755
    /**
756
     * @return array
757
     */
758
    public function getTranslationsArray()
759
    {
760
        $translations = [];
761
762
        foreach ($this->translations as $translation) {
0 ignored issues
show
Bug introduced by
The property translations does not seem to exist. Did you mean autoloadTranslations?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
763
            foreach ($this->translatedAttributes as $attr) {
0 ignored issues
show
Bug introduced by
The property translatedAttributes does not seem to exist. Did you mean attributes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
764
                $translations[$translation->{$this->getLocaleKey()}][$attr] = $translation->{$attr};
765
            }
766
        }
767
768
        return $translations;
769
    }
770
771
    /**
772
     * @return string
773
     */
774
    private function getTranslationsTable()
775
    {
776
        return app()->make($this->getTranslationModelName())->getTable();
777
    }
778
779
    /**
780
     * @return string
781
     */
782
    protected function locale()
783
    {
784
        if ($this->defaultLocale) {
785
            return $this->defaultLocale;
786
        }
787
788
        return config('translatable.locale')
789
            ?: app()->make('translator')->getLocale();
790
    }
791
792
    /**
793
     * Set the default locale on the model.
794
     *
795
     * @param $locale
796
     *
797
     * @return $this
798
     */
799
    public function setDefaultLocale($locale)
800
    {
801
        $this->defaultLocale = $locale;
802
803
        return $this;
804
    }
805
806
    /**
807
     * Get the default locale on the model.
808
     *
809
     * @return mixed
810
     */
811
    public function getDefaultLocale()
812
    {
813
        return $this->defaultLocale;
814
    }
815
816
    /**
817
     * Deletes all translations for this model.
818
     *
819
     * @param string|array|null $locales The locales to be deleted (array or single string)
820
     *                                   (e.g., ["en", "de"] would remove these translations).
821
     */
822
    public function deleteTranslations($locales = null)
823
    {
824
        if ($locales === null) {
825
            $translations = $this->translations()->get();
826
        } else {
827
            $locales = (array) $locales;
828
            $translations = $this->translations()->whereIn($this->getLocaleKey(), $locales)->get();
829
        }
830
        foreach ($translations as $translation) {
831
            $translation->delete();
832
        }
833
834
        // we need to manually "reload" the collection built from the relationship
835
        // otherwise $this->translations()->get() would NOT be the same as $this->translations
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
836
        $this->load('translations');
0 ignored issues
show
Bug introduced by
It seems like load() must be provided by classes using this trait. How about adding it as abstract method to this trait?

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

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). 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.

Loading history...
837
    }
838
839
    /**
840
     * @param $key
841
     *
842
     * @return array
843
     */
844
    private function getAttributeAndLocale($key)
845
    {
846
        if (str_contains($key, ':')) {
847
            return explode(':', $key);
848
        }
849
850
        return [$key, $this->locale()];
851
    }
852
853
    /**
854
     * @return bool
855
     */
856
    private function toArrayAlwaysLoadsTranslations()
857
    {
858
        return config('translatable.to_array_always_loads_translations', true);
859
    }
860
861
    public static function enableAutoloadTranslations()
862
    {
863
        self::$autoloadTranslations = true;
864
    }
865
866
    public static function defaultAutoloadTranslations()
867
    {
868
        self::$autoloadTranslations = null;
869
    }
870
871
    public static function disableAutoloadTranslations()
872
    {
873
        self::$autoloadTranslations = false;
874
    }
875
}
876