Completed
Push — master ( 489a99...99d7d3 )
by Ryan
07:23
created

EloquentModel::__get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php namespace Anomaly\Streams\Platform\Model;
2
3
use Anomaly\Streams\Platform\Collection\CacheCollection;
4
use Anomaly\Streams\Platform\Traits\Hookable;
5
use Illuminate\Contracts\Support\Arrayable;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Collection;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Foundation\Bus\DispatchesJobs;
10
11
/**
12
 * Class EloquentModel
13
 *
14
 * @link    http://anomaly.is/streams-platform
15
 * @author  AnomalyLabs, Inc. <[email protected]>
16
 * @author  Ryan Thompson <[email protected]>
17
 * @package Anomaly\Streams\Platform\Model
18
 */
19
class EloquentModel extends Model implements Arrayable
20
{
21
22
    use DispatchesJobs;
23
    use Hookable;
24
25
    /**
26
     * Disable timestamps for this model.
27
     *
28
     * @var bool
29
     */
30
    public $timestamps = false;
31
32
    /**
33
     * Translatable attributes.
34
     *
35
     * @var array
36
     */
37
    protected $translatedAttributes = [];
38
39
    /**
40
     * The number of minutes to cache query results.
41
     *
42
     * @var null|false|int
43
     */
44
    protected $ttl = false;
45
46
    /**
47
     * The attributes that are
48
     * not mass assignable. Let upper
49
     * models handle this themselves.
50
     *
51
     * @var array
52
     */
53
    protected $guarded = [];
54
55
    /**
56
     * The title key.
57
     *
58
     * @var string
59
     */
60
    protected $titleKey = 'id';
61
62
    /**
63
     * Observable model events.
64
     *
65
     * @var array
66
     */
67
    protected $observables = [
68
        'updatingMultiple',
69
        'updatedMultiple',
70
        'deletingMultiple',
71
        'deletedMultiple'
72
    ];
73
74
    /**
75
     * Runtime cache.
76
     *
77
     * @var array
78
     */
79
    protected $cache = [];
80
81
    /**
82
     * Get the ID.
83
     *
84
     * @return integer
85
     */
86
    public function getId()
87
    {
88
        return $this->id;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
89
    }
90
91
    /**
92
     * Return the object's ETag fingerprint.
93
     *
94
     * @return string
95
     */
96
    public function etag()
97
    {
98
        return md5(get_class($this) . json_encode($this->toArray()));
99
    }
100
101
    /**
102
     * Alias for $this->setTtl($ttl)
103
     *
104
     * @param $ttl
105
     * @return EloquentModel
106
     */
107
    public function cache($ttl)
108
    {
109
        return $this->setTtl($ttl);
110
    }
111
112
    /**
113
     * Fire a model event.
114
     *
115
     * @param $event
116
     * @return mixed
117
     */
118
    public function fireEvent($event)
119
    {
120
        return $this->fireModelEvent($event);
121
    }
122
123
    /**
124
     * Return a new collection class with our models.
125
     *
126
     * @param  array $items
127
     * @return Collection
128
     */
129 View Code Duplication
    public function newCollection(array $items = array())
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...
130
    {
131
        $collection = substr(get_class($this), 0, -5) . 'Collection';
132
133
        if (class_exists($collection)) {
134
            return new $collection($items);
135
        }
136
137
        return new EloquentCollection($items);
138
    }
139
140
    /**
141
     * Return the translatable flag.
142
     *
143
     * @return bool
144
     */
145
    public function isTranslatable()
146
    {
147
        return isset($this->translationModel);
148
    }
149
150
    /**
151
     * Set the translatable flag.
152
     *
153
     * @param $translatable
154
     * @return $this
155
     */
156
    public function setTranslatable($translatable)
157
    {
158
        $this->translatable = $translatable;
0 ignored issues
show
Documentation introduced by
The property translatable does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
159
160
        return $this;
161
    }
162
163
    /**
164
     * Set the ttl.
165
     *
166
     * @param  $ttl
167
     * @return $this
168
     */
169
    public function setTtl($ttl)
170
    {
171
        $this->ttl = $ttl;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Get the ttl.
178
     *
179
     * @return int|mixed
180
     */
181
    public function getTtl()
182
    {
183
        return $this->ttl;
184
    }
185
186
    /**
187
     * Get cache collection key.
188
     *
189
     * @return string
190
     */
191
    public function getCacheCollectionKey()
192
    {
193
        return get_called_class();
194
    }
195
196
    /**
197
     * Get the model title.
198
     *
199
     * @return mixed
200
     */
201
    public function getTitle()
202
    {
203
        return $this->{$this->getTitleName()};
204
    }
205
206
    /**
207
     * Get the title key.
208
     *
209
     * @return string
210
     */
211
    public function getTitleName()
212
    {
213
        return $this->titleName ?: 'id';
0 ignored issues
show
Documentation introduced by
The property titleName does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
214
    }
215
216
    /**
217
     * Return if a row is deletable or not.
218
     *
219
     * @return bool
220
     */
221
    public function isDeletable()
222
    {
223
        return true;
224
    }
225
226
    /**
227
     * Return if the model is restorable or not.
228
     *
229
     * @return bool
230
     */
231
    public function isRestorable()
232
    {
233
        return true;
234
    }
235
236
    /**
237
     * Return whether the model is being
238
     * force deleted or not.
239
     *
240
     * @return bool
241
     */
242
    public function isForceDeleting()
243
    {
244
        return isset($this->forceDeleting) && $this->forceDeleting == true;
0 ignored issues
show
Documentation introduced by
The property forceDeleting does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
245
    }
246
247
    /**
248
     * Flush the model's cache.
249
     *
250
     * @return $this
251
     */
252
    public function flushCache()
253
    {
254
        (new CacheCollection())->setKey($this->getCacheCollectionKey())->flush();
255
256
        return $this;
257
    }
258
259
    /**
260
     * Get a new query builder for the model's table.
261
     *
262
     * @return \Illuminate\Database\Eloquent\Builder
263
     */
264 View Code Duplication
    public function newQuery()
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...
265
    {
266
        $builder = new EloquentQueryBuilder($this->newBaseQueryBuilder());
267
268
        // Once we have the query builders, we will set the model instances so the
269
        // builder can easily access any information it may need from the model
270
        // while it is constructing and executing various queries against it.
271
        $builder->setModel($this)->with($this->with);
272
273
        return $this->applyGlobalScopes($builder);
274
    }
275
276
    /*
277
     * Alias for getTranslation()
278
     */
279
    public function translate($locale = null, $withFallback = false)
280
    {
281
        return $this->getTranslation($locale, $withFallback);
282
    }
283
284
    /*
285
     * Alias for getTranslation()
286
     */
287
    public function translateOrDefault($locale)
288
    {
289
        return $this->getTranslation($locale, true) ?: $this;
290
    }
291
292
    /*
293
     * Alias for getTranslationOrNew()
294
     */
295
    public function translateOrNew($locale)
296
    {
297
        return $this->getTranslationOrNew($locale);
298
    }
299
300
    /**
301
     * Get related translations.
302
     *
303
     * @return EloquentCollection
304
     */
305
    public function getTranslations()
306
    {
307
        foreach ($translations = $this->translations()->get() as $translation) {
308
            $translation->setRelation('parent', $this);
309
        }
310
311
        return $translations;
312
    }
313
314
    /**
315
     * @param null $locale
316
     * @param bool|null $withFallback
317
     * @return Model|null
318
     */
319
    public function getTranslation($locale = null, $withFallback = false)
320
    {
321
        $locale = $locale ?: $this->getFallbackLocale();
322
323
        if ($translation = $this->getTranslationByLocaleKey($locale)) {
324
            return $translation;
325
        } elseif ($withFallback
326
            && $this->getFallbackLocale()
327
            && $this->getTranslationByLocaleKey($this->getFallbackLocale())
328
        ) {
329
            return $this->getTranslationByLocaleKey($this->getFallbackLocale());
330
        }
331
332
        return null;
333
    }
334
335
    public function hasTranslation($locale = null)
336
    {
337
        $locale = $locale ?: $this->getFallbackLocale();
338
339 View Code Duplication
        foreach ($this->translations as $translation) {
0 ignored issues
show
Documentation introduced by
The property translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
340
341
            $translation->setRelation('parent', $this);
342
343
            if ($translation->getAttribute($this->getLocaleKey()) == $locale) {
344
                return true;
345
            }
346
        }
347
348
        return false;
349
    }
350
351
    public function getTranslationModel()
352
    {
353
        return new $this->translationModel;
0 ignored issues
show
Documentation introduced by
The property translationModel does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
354
    }
355
356
    public function getTranslationModelName()
357
    {
358
        return $this->translationModel;
0 ignored issues
show
Documentation introduced by
The property translationModel does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
359
    }
360
361
    public function getTranslationModelNameDefault()
362
    {
363
        return get_class($this) . 'Translation';
364
    }
365
366
    public function getRelationKey()
367
    {
368
        return $this->translationForeignKey ?: $this->getForeignKey();
0 ignored issues
show
Documentation introduced by
The property translationForeignKey does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
369
    }
370
371
    public function getLocaleKey()
372
    {
373
        return $this->localeKey ?: 'locale';
0 ignored issues
show
Documentation introduced by
The property localeKey does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
374
    }
375
376
    public function translations()
377
    {
378
        return $this->hasMany($this->getTranslationModelName(), $this->getRelationKey());
379
    }
380
381
    public function getAttribute($key)
382
    {
383
        if ($this->isTranslatedAttribute($key)) {
384
            if ($this->getTranslation() === null) {
385
                return null;
386
            }
387
388
            $translation = $this->getTranslation();
389
390
            $translation->setRelation('parent', $this);
391
392
            return $translation->$key;
393
        }
394
395
        return parent::getAttribute($key);
396
    }
397
398
    public function setAttribute($key, $value)
399
    {
400
        if (in_array($key, $this->translatedAttributes)) {
401
            $this->getTranslationOrNew(config('app.locale'))->$key = $value;
402
        } else {
403
            parent::setAttribute($key, $value);
404
        }
405
    }
406
407
    /**
408
     * Save the model.
409
     *
410
     * We have some customization here to
411
     * accommodate translations. First sa
412
     * then save translations is translatable.
413
     *
414
     * @param array $options
415
     * @return bool
416
     */
417
    public function save(array $options = array())
418
    {
419
        if (!$this->getTranslationModelName()) {
420
            return $this->saveModel($options);
421
        }
422
423
        if ($this->exists) {
424
425
            if (count($this->getDirty()) > 0) {
426
427
                // If $this->exists and dirty, $this->saveModel() 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...
428
                // an error has occurred. Therefore we shouldn't save the translations.
429
                if ($this->saveModel($options)) {
430
                    return $this->saveTranslations();
431
                }
432
433
                return false;
434
            } else {
435
436
                // If $this->exists and not dirty, $this->saveModel() 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...
437
                // false. So we have to save the translations
438
                return $this->saveTranslations();
439
            }
440
        } elseif ($this->saveModel($options)) {
441
442
            // We save the translations only if the instance is saved in the database.
443
            return $this->saveTranslations();
444
        }
445
446
        return false;
447
    }
448
449
    /**
450
     * Save the model to the database.
451
     *
452
     * This is a direct port from Eloquent
453
     * with the only exception being that if
454
     * the model is translatable it will NOT
455
     * fire the saved event. The saveTranslations
456
     * method will do that instead.
457
     *
458
     * @param  array $options
459
     * @return bool
460
     */
461
    public function saveModel(array $options = array())
462
    {
463
        $query = $this->newQueryWithoutScopes();
464
465
        // If the "saving" event returns false we'll bail out of the save and return
466
        // false, indicating that the save failed. This provides a chance for any
467
        // listeners to cancel save operations if validations fail or whatever.
468
        if ($this->fireModelEvent('saving') === false) {
469
            return false;
470
        }
471
472
        // If the model already exists in the database we can just update our record
473
        // that is already in this database using the current IDs in this "where"
474
        // clause to only update this model. Otherwise, we'll just insert them.
475
        if ($this->exists) {
476
            $saved = $this->performUpdate($query, $options);
477
        }
478
479
        // If the model is brand new, we'll insert it into our database and set the
480
        // ID attribute on the model to the value of the newly inserted row's ID
481
        // which is typically an auto-increment value managed by the database.
482
        else {
483
            $saved = $this->performInsert($query, $options);
484
        }
485
486
        if ($saved && !$this->isTranslatable()) {
487
            $this->finishSave($options);
488
        }
489
490
        return $saved;
491
    }
492
493
    /**
494
     * Save translations to the database.
495
     *
496
     * @return bool
497
     */
498 View Code Duplication
    protected function saveTranslations()
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...
499
    {
500
        $saved = true;
501
502
        foreach ($this->translations as $translation) {
0 ignored issues
show
Documentation introduced by
The property translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
503
504
            $translation->setRelation('parent', $this);
505
506
            /* @var EloquentModel $translation */
507
            if ($saved && $this->isTranslationDirty($translation)) {
508
509
                $translation->setAttribute($this->getRelationKey(), $this->getKey());
510
511
                $saved = $translation->save();
512
            }
513
        }
514
515
        $this->finishSave([]);
516
517
        return $saved;
518
    }
519
520
    protected function getTranslationOrNew($locale)
521
    {
522
        if (($translation = $this->getTranslation($locale, false)) === null) {
523
            $translation = $this->getNewTranslation($locale);
524
        }
525
526
        return $translation;
527
    }
528
529
    public function fill(array $attributes)
530
    {
531
        foreach ($attributes as $key => $values) {
532
            if (is_array($values) && $this->isKeyALocale($key)) {
533
                foreach ($values as $translationAttribute => $translationValue) {
534
                    if ($this->alwaysFillable() || $this->isFillable($translationAttribute)) {
535
                        $this->getTranslationOrNew($key)->$translationAttribute = $translationValue;
536
                    }
537
                }
538
                unset($attributes[$key]);
539
            }
540
        }
541
542
        return parent::fill($attributes);
543
    }
544
545
    private function getTranslationByLocaleKey($key)
546
    {
547 View Code Duplication
        foreach ($this->translations as $translation) {
0 ignored issues
show
Documentation introduced by
The property translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
548
549
            $translation->setRelation('parent', $this);
550
551
            if ($translation->getAttribute($this->getLocaleKey()) == $key) {
552
                return $translation;
553
            }
554
        }
555
556
        return null;
557
    }
558
559
    public function isTranslatedAttribute($key)
560
    {
561
        return in_array($key, $this->translatedAttributes);
562
    }
563
564
    protected function isTranslationAttribute($key)
565
    {
566
        return in_array($key, $this->translatedAttributes);
567
    }
568
569
    protected function isKeyALocale($key)
570
    {
571
        return config('streams::locales.supported.' . $key) !== null;
572
    }
573
574
    protected function isTranslationDirty(Model $translation)
575
    {
576
        $dirtyAttributes = $translation->getDirty();
577
        unset($dirtyAttributes[$this->getLocaleKey()]);
578
579
        return count($dirtyAttributes) > 0;
580
    }
581
582 View Code Duplication
    public function getNewTranslation($locale)
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...
583
    {
584
        $modelName = $this->getTranslationModelName();
585
586
        /* @var EloquentModel $translation */
587
        $translation = new $modelName;
588
589
        $translation->setRelation('parent', $this);
590
591
        $translation->setAttribute($this->getLocaleKey(), $locale);
592
        $translation->setAttribute($this->getRelationKey(), $this->getKey());
593
594
        $this->translations->add($translation);
0 ignored issues
show
Documentation introduced by
The property translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
595
596
        return $translation;
597
    }
598
599
    public function scopeTranslatedIn(Builder $query, $locale)
600
    {
601
        return $query->whereHas(
602
            'translations',
603
            function (Builder $q) use ($locale) {
604
                $q->where($this->getLocaleKey(), '=', $locale);
605
            }
606
        );
607
    }
608
609
    public function scopeTranslated(Builder $query)
610
    {
611
        return $query->has('translations');
612
    }
613
614
    /**
615
     * Return unguarded attributes.
616
     *
617
     * @return array
618
     */
619
    public function getUnguardedAttributes()
620
    {
621
        foreach ($attributes = $this->getAttributes() as $attribute => $value) {
622
            $attributes[$attribute] = $this->{$attribute};
623
        }
624
625
        return array_filter(array_diff_key($attributes, array_flip($this->getGuarded())));
626
    }
627
628
    /**
629
     * Get the fallback locale.
630
     *
631
     * @return string
632
     */
633
    protected function getFallbackLocale()
634
    {
635
        if (isset($this->cache['fallback_locale'])) {
636
            return $this->cache['fallback_locale'];
637
        }
638
639
        return $this->cache['fallback_locale'] = config('app.fallback_locale');
640
    }
641
642
    /**
643
     * This is to keep consistency with the
644
     * entry interface above us.
645
     *
646
     * @return string
647
     */
648
    public function getTableName()
649
    {
650
        return $this->getTable();
651
    }
652
653
    /**
654
     * Return if the entry is trashed or not.
655
     *
656
     * @return bool
657
     */
658
    public function trashed()
659
    {
660
        return parent::trashed();
661
    }
662
663
    public function toArray()
664
    {
665
        $attributes = $this->attributesToArray();
666
667
        foreach ($this->translatedAttributes as $field) {
668
            if ($translation = $this->getTranslation()) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $translation is correct as $this->getTranslation() (which targets Anomaly\Streams\Platform...Model::getTranslation()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
669
                $attributes[$field] = $translation->$field;
670
            }
671
        }
672
673
        return $attributes;
674
    }
675
676
    private function alwaysFillable()
677
    {
678
        return false;
679
    }
680
681
    public function __get($key)
682
    {
683
        if ($this->hasHook($key)) {
684
            return $this->call($key, []);
685
        }
686
687
        return parent::__get($key); // TODO: Change the autogenerated stub
688
    }
689
690
    public function __call($method, $parameters)
691
    {
692
        if ($this->hasHook($hook = snake_case($method))) {
693
            return $this->call($hook, $parameters);
694
        }
695
696
        return parent::__call($method, $parameters);
697
    }
698
699
    /**
700
     * Check if an attribute exists.
701
     *
702
     * @param string $key
703
     * @return bool
704
     */
705
    public function __isset($key)
706
    {
707
        return (in_array($key, $this->translatedAttributes) || parent::__isset($key));
708
    }
709
710
    /**
711
     * Return the string form of the model.
712
     *
713
     * @return string
714
     */
715
    function __toString()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
716
    {
717
        return json_encode($this->toArray());
718
    }
719
}
720