Completed
Pull Request — master (#371)
by
unknown
11:37 queued 03:33
created

EntryModel::getBoundModelName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php namespace Anomaly\Streams\Platform\Entry;
2
3
use Anomaly\Streams\Platform\Addon\FieldType\FieldType;
4
use Anomaly\Streams\Platform\Addon\FieldType\FieldTypePresenter;
5
use Anomaly\Streams\Platform\Addon\FieldType\FieldTypeQuery;
6
use Anomaly\Streams\Platform\Assignment\AssignmentCollection;
7
use Anomaly\Streams\Platform\Assignment\Contract\AssignmentInterface;
8
use Anomaly\Streams\Platform\Entry\Contract\EntryInterface;
9
use Anomaly\Streams\Platform\Field\Contract\FieldInterface;
10
use Anomaly\Streams\Platform\Model\EloquentModel;
11
use Anomaly\Streams\Platform\Stream\Contract\StreamInterface;
12
use Carbon\Carbon;
13
use Illuminate\Contracts\Auth\Authenticatable;
14
use Illuminate\Database\Eloquent\Builder;
15
use Laravel\Scout\ModelObserver;
16
use Laravel\Scout\Searchable;
17
use Robbo\Presenter\PresentableInterface;
18
19
class EntryModel extends EloquentModel implements EntryInterface, PresentableInterface
20
{
21
22
    use Searchable;
23
24
    /**
25
     * The foreign key for translations.
26
     *
27
     * @var string
28
     */
29
    protected $translationForeignKey = 'entry_id';
30
31
    /**
32
     * By default nothing is searchable.
33
     *
34
     * @var boolean
35
     */
36
    protected $searchable = false;
37
38
    /**
39
     * The validation rules. These are
40
     * overridden on the compiled models.
41
     *
42
     * @var array
43
     */
44
    protected $rules = [];
45
46
    /**
47
     * The field slugs. These are
48
     * overridden on compiled models.
49
     *
50
     * @var array
51
     */
52
    protected $fields = [];
53
54
    /**
55
     * The entry relationships by field slug.
56
     *
57
     * @var array
58
     */
59
    protected $relationships = [];
60
61
    /**
62
     * The compiled stream data.
63
     *
64
     * @var array|StreamInterface
65
     */
66
    protected $stream = [];
67
68
    /**
69
     * @var bool
70
     */
71
    protected $raw = false;
72
73
    /**
74
     * Boot the model
75
     */
76
    protected static function boot()
77
    {
78
        $instance = new static;
79
80
        $class     = get_class($instance);
81
        $events    = $instance->getObservableEvents();
82
        $observer  = substr($class, 0, -5) . 'Observer';
83
        $observing = class_exists($observer);
84
85
        if ($events && $observing) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $events of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
86
            self::observe(app($observer));
87
        }
88
89
        if (!$instance->isSearchable()) {
90
            ModelObserver::disableSyncingFor(get_class(new static));
91
        }
92
93
        if ($events && !$observing) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $events of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
94
            self::observe(EntryObserver::class);
95
        }
96
97
        parent::boot();
98
    }
99
100
    /**
101
     * Sort the query.
102
     *
103
     * @param Builder $builder
104
     * @param string  $direction
105
     */
106
    public function scopeSorted(Builder $builder, $direction = 'asc')
107
    {
108
        $builder->orderBy('sort_order', $direction);
109
    }
110
111
    /**
112
     * Get the raw flag property.
113
     *
114
     * @return bool
115
     */
116
    public function getRaw()
117
    {
118
        return $this->raw;
119
    }
120
121
    /**
122
     * Set the raw flag property.
123
     *
124
     * @param bool $raw
125
     */
126
    public function setRaw($raw)
127
    {
128
        $this->raw = $raw;
129
    }
130
131
    /**
132
     * Get the ID.
133
     *
134
     * @return mixed
135
     */
136
    public function getId()
137
    {
138
        return $this->getKey();
139
    }
140
141
    /**
142
     * Get the entry ID.
143
     *
144
     * @return mixed
145
     */
146
    public function getEntryId()
147
    {
148
        return $this->getId();
149
    }
150
151
    /**
152
     * Get the entry title.
153
     *
154
     * @return mixed
155
     */
156
    public function getEntryTitle()
157
    {
158
        return $this->getTitle();
159
    }
160
161
    /**
162
     * Get the model's bound name.
163
     *
164
     * @return string
165
     */
166
    public function getBoundModelName()
167
    {
168
        return get_class(app(get_class($this)));
169
    }
170
171
    /**
172
     * Get the model's bound namespace.
173
     *
174
     * @return string
175
     */
176
    public function getBoundModelNamespace()
177
    {
178
        $namespace = explode('\\', $this->getBoundModelName());
179
180
        array_pop($namespace);
181
182
        return implode('\\', $namespace);
183
    }
184
185
    /**
186
     * Get the sort order.
187
     *
188
     * @return int
189
     */
190
    public function getSortOrder()
191
    {
192
        return $this->sort_order;
0 ignored issues
show
Documentation introduced by
The property sort_order does not exist on object<Anomaly\Streams\Platform\Entry\EntryModel>. 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...
193
    }
194
195
    /**
196
     * Get the entries title.
197
     *
198
     * @return mixed
199
     */
200
    public function getTitle()
201
    {
202
        return $this->{$this->getTitleName()};
203
    }
204
205
    /**
206
     * Get a field value.
207
     *
208
     * @param        $fieldSlug
209
     * @param  null  $locale
210
     * @return mixed
211
     */
212
    public function getFieldValue($fieldSlug, $locale = null)
213
    {
214
        if (!$locale) {
215
            $locale = config('app.locale');
216
        }
217
218
        $assignment = $this->getAssignment($fieldSlug);
219
220
        $type = $assignment->getFieldType();
221
222
        $accessor = $type->getAccessor();
223
        $modifier = $type->getModifier();
224
225
        if ($assignment->isTranslatable()) {
226
            $entry = $this->translateOrDefault($locale);
227
228
            $type->setLocale($locale);
229
        } else {
230
            $entry = $this;
231
        }
232
233
        $type->setEntry($entry);
234
235
        $value = $modifier->restore($accessor->get());
236
237
        if (
238
            $value === null &&
239
            $assignment->isTranslatable() &&
240
            $assignment->isRequired() &&
241
            $translation = $this->translate()
242
        ) {
243
            $type->setEntry($translation);
244
245
            $value = $modifier->restore($accessor->get());
246
        }
247
248
        return $value;
249
    }
250
251
    /**
252
     * Set a field value.
253
     *
254
     * @param        $fieldSlug
255
     * @param        $value
256
     * @param  null  $locale
257
     * @return $this
258
     */
259
    public function setFieldValue($fieldSlug, $value, $locale = null)
260
    {
261
        if (!$locale) {
262
            $locale = config('app.locale');
263
        }
264
265
        $assignment = $this->getAssignment($fieldSlug);
266
267
        $type = $assignment->getFieldType($this);
0 ignored issues
show
Documentation introduced by
$this is of type this<Anomaly\Streams\Platform\Entry\EntryModel>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
268
269
        if ($assignment->isTranslatable()) {
270
            $entry = $this->translateOrNew($locale);
271
272
            $type->setLocale($locale);
273
        } else {
274
            $entry = $this;
275
        }
276
277
        $type->setEntry($entry);
278
279
        $accessor = $type->getAccessor();
280
        $modifier = $type->getModifier();
281
282
        $accessor->set($modifier->modify($value));
283
284
        return $this;
285
    }
286
287
    /**
288
     * Get an entry field.
289
     *
290
     * @param  $slug
291
     * @return FieldInterface|null
292
     */
293
    public function getField($slug)
294
    {
295
        $assignment = $this->getAssignment($slug);
296
297
        if (!$assignment instanceof AssignmentInterface) {
298
            return null;
299
        }
300
301
        return $assignment->getField();
302
    }
303
304
    /**
305
     * Return whether an entry has
306
     * a field with a given slug.
307
     *
308
     * @param  $slug
309
     * @return bool
310
     */
311
    public function hasField($slug)
312
    {
313
        return ($this->getField($slug) !== null);
314
    }
315
316
    /**
317
     * Get the field type from a field slug.
318
     *
319
     * @param  $fieldSlug
320
     * @return null|FieldType
321
     */
322 View Code Duplication
    public function getFieldType($fieldSlug)
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...
323
    {
324
        $locale = config('app.locale');
325
326
        $assignment = $this->getAssignment($fieldSlug);
327
328
        if (!$assignment) {
329
            return null;
330
        }
331
332
        $type = $assignment->getFieldType();
333
334
        if ($assignment->isTranslatable()) {
335
            $entry = $this->translateOrDefault($locale);
336
337
            $type->setLocale($locale);
338
        } else {
339
            $entry = $this;
340
        }
341
342
        $type->setEntry($entry);
343
344
        $type->setValue($this->getFieldValue($fieldSlug));
345
        $type->setEntry($this);
346
347
        return $type;
348
    }
349
350
    /**
351
     * Get the field type query.
352
     *
353
     * @param $fieldSlug
354
     * @return FieldTypeQuery
355
     */
356
    public function getFieldTypeQuery($fieldSlug)
357
    {
358
        if (!$type = $this->getFieldType($fieldSlug)) {
359
            return null;
360
        }
361
362
        return $type->getQuery();
363
    }
364
365
    /**
366
     * Get the field type presenter.
367
     *
368
     * @param $fieldSlug
369
     * @return FieldTypePresenter
370
     */
371
    public function getFieldTypePresenter($fieldSlug)
372
    {
373
        if (!$type = $this->getFieldType($fieldSlug)) {
374
            return null;
375
        }
376
377
        return $type->getPresenter();
378
    }
379
380
    /**
381
     * Set a given attribute on the model.
382
     * Override the behavior here to give
383
     * the field types a chance to modify things.
384
     *
385
     * @param  string $key
386
     * @param  mixed  $value
387
     * @return $this
388
     */
389
    public function setAttribute($key, $value)
390
    {
391
        if (!$this->isKeyALocale($key) && !$this->hasSetMutator($key) && $this->getFieldType($key)) {
392
            $this->setFieldValue($key, $value);
393
        } else {
394
            parent::setAttribute($key, $value);
395
        }
396
397
        return $this;
398
    }
399
400
    /**
401
     * Get a given attribute on the model.
402
     * Override the behavior here to give
403
     * the field types a chance to modify things.
404
     *
405
     * @param  string $key
406
     * @return mixed
407
     */
408
    public function getAttribute($key)
409
    {
410
        // Check if it's a relationship first.
411
        if (in_array($key, array_merge($this->relationships, ['created_by', 'updated_by']))) {
412
            return parent::getAttribute(camel_case($key));
413
        }
414
415
        if (
416
            !$this->hasGetMutator($key)
417
            && !$this->getRaw()
418
            && in_array($key, $this->fields)
419
        ) {
420
            return $this->getFieldValue($key);
421
        } else {
422
            return parent::getAttribute($key);
423
        }
424
    }
425
426
    /**
427
     * Get a raw unmodified attribute.
428
     *
429
     * @param             $key
430
     * @param  bool       $process
431
     * @return mixed|null
432
     */
433
    public function getRawAttribute($key, $process = true)
434
    {
435
        if (!$process) {
436
            return $this->getAttributeFromArray($key);
437
        }
438
439
        return parent::getAttribute($key);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getAttribute() instead of getRawAttribute()). Are you sure this is correct? If so, you might want to change this to $this->getAttribute().

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...
440
    }
441
442
    /**
443
     * Set a raw unmodified attribute.
444
     *
445
     * @param $key
446
     * @param $value
447
     * @return $this
448
     */
449
    public function setRawAttribute($key, $value)
450
    {
451
        parent::setAttribute($key, $value);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (setAttribute() instead of setRawAttribute()). Are you sure this is correct? If so, you might want to change this to $this->setAttribute().

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...
452
453
        return $this;
454
    }
455
456
    /**
457
     * Get the stream.
458
     *
459
     * @return StreamInterface
460
     */
461
    public function getStream()
462
    {
463
        return $this->stream();
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->stream(); of type Anomaly\Streams\Platform...t\StreamInterface|array adds the type array to the return on line 463 which is incompatible with the return type declared by the interface Anomaly\Streams\Platform...tryInterface::getStream of type Anomaly\Streams\Platform...ontract\StreamInterface.
Loading history...
464
    }
465
466
    /**
467
     * Get the stream namespace.
468
     *
469
     * @return string
470
     */
471
    public function getStreamNamespace()
472
    {
473
        $stream = $this->getStream();
474
475
        return $stream->getNamespace();
476
    }
477
478
    /**
479
     * Get the stream slug.
480
     *
481
     * @return string
482
     */
483
    public function getStreamSlug()
484
    {
485
        $stream = $this->getStream();
486
487
        return $stream->getSlug();
488
    }
489
490
    /**
491
     * Get the entry's stream name.
492
     *
493
     * @return string
494
     */
495
    public function getStreamName()
496
    {
497
        $stream = $this->getStream();
498
499
        return $stream->getName();
500
    }
501
502
    /**
503
     * Get the stream prefix.
504
     *
505
     * @return string
506
     */
507
    public function getStreamPrefix()
508
    {
509
        $stream = $this->getStream();
510
511
        return $stream->getPrefix();
512
    }
513
514
    /**
515
     * Get the table name.
516
     *
517
     * @return string
518
     */
519
    public function getTableName()
520
    {
521
        $stream = $this->getStream();
522
523
        return $stream->getEntryTableName();
524
    }
525
526
    /**
527
     * Get the translations table name.
528
     *
529
     * @return string
530
     */
531
    public function getTranslationsTableName()
532
    {
533
        $stream = $this->getStream();
534
535
        return $stream->getEntryTranslationsTableName();
536
    }
537
538
    /**
539
     * Get all assignments.
540
     *
541
     * @return AssignmentCollection
542
     */
543
    public function getAssignments()
544
    {
545
        $stream = $this->getStream();
546
547
        return $stream->getAssignments();
548
    }
549
550
    /**
551
     * Get the field slugs for assigned fields.
552
     *
553
     * @param  null $prefix
554
     * @return array
555
     */
556
    public function getAssignmentFieldSlugs($prefix = null)
557
    {
558
        $assignments = $this->getAssignments();
559
560
        return $assignments->fieldSlugs($prefix);
561
    }
562
563
    /**
564
     * Get all assignments of the
565
     * provided field type namespace.
566
     *
567
     * @param $fieldType
568
     * @return AssignmentCollection
569
     */
570
    public function getAssignmentsByFieldType($fieldType)
571
    {
572
        $assignments = $this->getAssignments();
573
574
        return $assignments->findAllByFieldType($fieldType);
575
    }
576
577
    /**
578
     * Get an assignment by field slug.
579
     *
580
     * @param  $fieldSlug
581
     * @return AssignmentInterface
582
     */
583
    public function getAssignment($fieldSlug)
584
    {
585
        $assignments = $this->getAssignments();
586
587
        return $assignments->findByFieldSlug($fieldSlug);
588
    }
589
590
    /**
591
     * Return translated assignments.
592
     *
593
     * @return AssignmentCollection
594
     */
595
    public function getTranslatableAssignments()
596
    {
597
        $stream      = $this->getStream();
598
        $assignments = $stream->getAssignments();
599
600
        return $assignments->translatable();
601
    }
602
603
    /**
604
     * Return relation assignments.
605
     *
606
     * @return AssignmentCollection
607
     */
608
    public function getRelationshipAssignments()
609
    {
610
        $stream      = $this->getStream();
611
        $assignments = $stream->getAssignments();
612
613
        return $assignments->relations();
614
    }
615
616
    /**
617
     * Get the translatable flag.
618
     *
619
     * @return bool
620
     */
621
    public function isTranslatable()
622
    {
623
        $stream = $this->getStream();
624
625
        return $stream->isTranslatable();
626
    }
627
628
    /**
629
     * Return whether the entry is trashable or not.
630
     *
631
     * @return bool
632
     */
633
    public function isTrashable()
634
    {
635
        $stream = $this->getStream();
636
637
        return $stream->isTrashable();
638
    }
639
640
    /**
641
     * Return the last modified datetime.
642
     *
643
     * @return Carbon
644
     */
645
    public function lastModified()
646
    {
647
        return $this->updated_at ?: $this->created_at;
0 ignored issues
show
Documentation introduced by
The property updated_at does not exist on object<Anomaly\Streams\Platform\Entry\EntryModel>. 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...
Documentation introduced by
The property created_at does not exist on object<Anomaly\Streams\Platform\Entry\EntryModel>. 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...
648
    }
649
650
    /**
651
     * Return the related creator.
652
     *
653
     * @return Authenticatable
654
     */
655
    public function getCreatedBy()
656
    {
657
        return $this->created_by;
0 ignored issues
show
Documentation introduced by
The property created_by does not exist on object<Anomaly\Streams\Platform\Entry\EntryModel>. 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...
658
    }
659
660
    /**
661
     * Return the creator relation.
662
     *
663
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
664
     */
665
    public function createdBy()
666
    {
667
        return $this->belongsTo(config('auth.providers.users.model'));
668
    }
669
670
    /**
671
     * Return the related updater.
672
     *
673
     * @return Authenticatable
674
     */
675
    public function getUpdatedBy()
676
    {
677
        return $this->updated_by;
0 ignored issues
show
Documentation introduced by
The property updated_by does not exist on object<Anomaly\Streams\Platform\Entry\EntryModel>. 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...
678
    }
679
680
    /**
681
     * Return the updater relation.
682
     *
683
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
684
     */
685
    public function updatedBy()
686
    {
687
        return $this->belongsTo(config('auth.providers.users.model'));
688
    }
689
690
    /**
691
     * Return whether the title column is
692
     * translatable or not.
693
     *
694
     * @return bool
695
     */
696
    public function titleColumnIsTranslatable()
697
    {
698
        return $this->assignmentIsTranslatable($this->getTitleName());
699
    }
700
701
    /**
702
     * Return whether or not the assignment for
703
     * the given field slug is translatable.
704
     *
705
     * @param $fieldSlug
706
     * @return bool
707
     */
708
    public function assignmentIsTranslatable($fieldSlug)
709
    {
710
        return $this->isTranslatedAttribute($fieldSlug);
711
    }
712
713
    /**
714
     * Return whether or not the assignment for
715
     * the given field slug is a relationship.
716
     *
717
     * @param $fieldSlug
718
     * @return bool
719
     */
720
    public function assignmentIsRelationship($fieldSlug)
721
    {
722
        $relationships = $this->getRelationshipAssignments();
723
724
        return in_array($fieldSlug, $relationships->fieldSlugs());
725
    }
726
727
    /**
728
     * Fire field type events.
729
     *
730
     * @param       $trigger
731
     * @param array $payload
732
     */
733
    public function fireFieldTypeEvents($trigger, $payload = [])
734
    {
735
        $assignments = $this->getAssignments();
736
737
        /* @var AssignmentInterface $assignment */
738
        foreach ($assignments->notTranslatable() as $assignment) {
739
            $fieldType = $assignment->getFieldType();
740
741
            $fieldType->setValue($this->getRawAttribute($assignment->getFieldSlug()));
742
743
            $fieldType->setEntry($this);
744
745
            $payload['entry']     = $this;
746
            $payload['fieldType'] = $fieldType;
747
748
            $fieldType->fire($trigger, $payload);
749
        }
750
    }
751
752
    /**
753
     * Return the related stream.
754
     *
755
     * @return StreamInterface|array
756
     */
757
    public function stream()
758
    {
759
        if (!$this->stream instanceof StreamInterface) {
760
            $this->stream = app('Anomaly\Streams\Platform\Stream\StreamModel')->make($this->stream);
761
        }
762
763
        return $this->stream;
764
    }
765
766
    /**
767
     * @param  array $items
768
     * @return EntryCollection
769
     */
770 View Code Duplication
    public function newCollection(array $items = [])
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...
771
    {
772
        $collection = substr(get_class($this), 0, -5) . 'Collection';
773
774
        if (class_exists($collection)) {
775
            return new $collection($items);
776
        }
777
778
        return new EntryCollection($items);
779
    }
780
781
    /**
782
     * Return the entry presenter.
783
     *
784
     * This is against standards but required
785
     * by the presentable interface.
786
     *
787
     * @return EntryPresenter
788
     */
789 View Code Duplication
    public function getPresenter()
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...
790
    {
791
        $presenter = substr(get_class($this), 0, -5) . 'Presenter';
792
793
        if (class_exists($presenter)) {
794
            return app()->make($presenter, ['object' => $this]);
795
        }
796
797
        return new EntryPresenter($this);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \Anomaly\Stre...\EntryPresenter($this); (Anomaly\Streams\Platform\Entry\EntryPresenter) is incompatible with the return type declared by the interface Robbo\Presenter\PresentableInterface::getPresenter of type Robbo\Presenter\Robbo\Presenter\Presenter.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
798
    }
799
800
    /**
801
     * Return a new presenter instance.
802
     *
803
     * @return EntryPresenter
804
     */
805
    public function newPresenter()
806
    {
807
        return $this->getPresenter();
808
    }
809
810
    /**
811
     * Return a model route.
812
     *
813
     * @return string
814
     */
815
    public function route($route, array $parameters = [])
816
    {
817
        $router = $this->getRouter();
818
819
        return $router->make($route, $parameters);
820
    }
821
822
    /**
823
     * Return a new router instance.
824
     *
825
     * @return EntryRouter
826
     */
827
    public function newRouter()
828
    {
829
        return app()->make($this->getRouterName(), ['entry' => $this]);
830
    }
831
832
    /**
833
     * Get the router.
834
     *
835
     * @return EntryRouter
836
     */
837
    public function getRouter()
838
    {
839
        if (isset($this->cache['router'])) {
840
            return $this->cache['router'];
841
        }
842
843
        return $this->cache['router'] = $this->newRouter();
844
    }
845
846
    /**
847
     * Get the router name.
848
     *
849
     * @return string
850
     */
851
    public function getRouterName()
852
    {
853
        $router = substr(get_class($this), 0, -5) . 'Router';
854
855
        return class_exists($router) ? $router : EntryRouter::class;
856
    }
857
858
    /**
859
     * Create a new Eloquent query builder for the model.
860
     *
861
     * @param  \Illuminate\Database\Query\Builder $query
862
     * @return \Illuminate\Database\Eloquent\Builder|static
863
     */
864
    public function newEloquentBuilder($query)
865
    {
866
        return new EntryQueryBuilder($query);
867
    }
868
869
    /**
870
     * Get the criteria class.
871
     *
872
     * @return string
873
     */
874
    public function getCriteriaName()
875
    {
876
        $criteria = substr(get_class($this), 0, -5) . 'Criteria';
877
878
        return class_exists($criteria) ? $criteria : EntryCriteria::class;
879
    }
880
881
    /**
882
     * Return whether the model is searchable or not.
883
     *
884
     * @return boolean
885
     */
886
    public function isSearchable()
887
    {
888
        return $this->searchable;
889
    }
890
891
    /**
892
     * Return a searchable array.
893
     *
894
     * @return array
895
     */
896
    public function toSearchableArray()
897
    {
898
        $array = $this->toArray();
899
900
        foreach ($array as $key => &$value) {
901
            if (is_array($value)) {
902
                $value = json_encode($value);
903
                continue;
904
            }
905
        }
906
907
        return $array;
908
    }
909
910
    /**
911
     * Override the __get method.
912
     *
913
     * @param  string $key
914
     * @return EntryPresenter|mixed
915
     */
916
    public function __get($key)
917
    {
918
        if ($key === 'decorated') {
919
            return $this->getPresenter();
920
        }
921
922
        return parent::__get($key); // TODO: Change the autogenerated stub
923
    }
924
}
925