Completed
Push — master ( dca802...7eb0de )
by Ryan
07:03
created

EntryModel::stream()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 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\Database\Eloquent\Builder;
14
use Robbo\Presenter\PresentableInterface;
15
16
/**
17
 * Class EntryModel
18
 *
19
 * @method        Builder sorted()
20
 * @link    http://anomaly.is/streams-platform
21
 * @author  AnomalyLabs, Inc. <[email protected]>
22
 * @author  Ryan Thompson <[email protected]>
23
 * @package Anomaly\Streams\Platform\Entry
24
 */
25
class EntryModel extends EloquentModel implements EntryInterface, PresentableInterface
26
{
27
28
    /**
29
     * The validation rules. These are
30
     * overridden on the compiled models.
31
     *
32
     * @var array
33
     */
34
    protected $rules = [];
35
36
    /**
37
     * The field slugs. These are
38
     * overridden on compiled models.
39
     *
40
     * @var array
41
     */
42
    protected $fields = [];
43
44
    /**
45
     * The entry relationships by field slug.
46
     *
47
     * @var array
48
     */
49
    protected $relationships = [];
50
51
    /**
52
     * The compiled stream data.
53
     *
54
     * @var array|StreamInterface
55
     */
56
    protected $stream = [];
57
58
    /**
59
     * Boot the model
60
     */
61
    protected static function boot()
62
    {
63
        $instance = new static;
64
65
        $class    = get_class($instance);
66
        $events   = $instance->getObservableEvents();
67
        $observer = substr($class, 0, -5) . 'Observer';
68
69
        if ($events && class_exists($observer)) {
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...
70
            self::observe(app($observer));
71
        }
72
73
        if ($events && !static::$dispatcher->hasListeners('eloquent.' . array_shift($events) . ': ' . $class)) {
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...
74
            self::observe(EntryObserver::class);
75
        }
76
77
        parent::boot();
78
    }
79
80
    /**
81
     * Sort the query.
82
     *
83
     * @param Builder $builder
84
     * @param string  $direction
85
     */
86
    public function scopeSorted(Builder $builder, $direction = 'asc')
87
    {
88
        $builder->orderBy('sort_order', $direction);
89
    }
90
91
    /**
92
     * Get the ID.
93
     *
94
     * @return mixed
95
     */
96
    public function getId()
97
    {
98
        return $this->getKey();
99
    }
100
101
    /**
102
     * Get the entry ID.
103
     *
104
     * @return mixed
105
     */
106
    public function getEntryId()
107
    {
108
        return $this->getId();
109
    }
110
111
    /**
112
     * Get the entry title.
113
     *
114
     * @return mixed
115
     */
116
    public function getEntryTitle()
117
    {
118
        return $this->getTitle();
119
    }
120
121
    /**
122
     * Get the sort order.
123
     *
124
     * @return int
125
     */
126
    public function getSortOrder()
127
    {
128
        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...
129
    }
130
131
    /**
132
     * Get the entries title.
133
     *
134
     * @return mixed
135
     */
136
    public function getTitle()
137
    {
138
        return $this->{$this->getTitleName()};
139
    }
140
141
    /**
142
     * Get a field value.
143
     *
144
     * @param      $fieldSlug
145
     * @param null $locale
146
     * @return mixed
147
     */
148
    public function getFieldValue($fieldSlug, $locale = null)
149
    {
150
        if (!$locale) {
151
            $locale = config('app.locale');
152
        }
153
154
        $assignment = $this->getAssignment($fieldSlug);
155
156
        $type = $assignment->getFieldType();
157
158
        $accessor = $type->getAccessor();
159
        $modifier = $type->getModifier();
160
161
        if ($assignment->isTranslatable()) {
162
163
            $entry = $this->translateOrDefault($locale);
164
165
            $type->setLocale($locale);
166
        } else {
167
            $entry = $this;
168
        }
169
170
        $type->setEntry($entry);
171
172
        $value = $modifier->restore($accessor->get());
173
174
        if (
175
            $value === null &&
176
            $assignment->isTranslatable() &&
177
            $assignment->isRequired() &&
178
            $translation = $this->translate()
179
        ) {
180
181
            $type->setEntry($translation);
182
183
            $value = $modifier->restore($accessor->get());
184
        }
185
186
        return $value;
187
    }
188
189
    /**
190
     * Set a field value.
191
     *
192
     * @param $fieldSlug
193
     * @param $value
194
     */
195
    public function setFieldValue($fieldSlug, $value)
196
    {
197
        $assignment = $this->getAssignment($fieldSlug);
198
199
        $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...
200
201
        $type->setEntry($this);
202
203
        $accessor = $type->getAccessor();
204
        $modifier = $type->getModifier();
205
206
        $accessor->set($modifier->modify($value));
207
    }
208
209
    /**
210
     * Get an entry field.
211
     *
212
     * @param  $slug
213
     * @return FieldInterface|null
214
     */
215
    public function getField($slug)
216
    {
217
        $assignment = $this->getAssignment($slug);
218
219
        if (!$assignment instanceof AssignmentInterface) {
220
            return null;
221
        }
222
223
        return $assignment->getField();
224
    }
225
226
    /**
227
     * Return whether an entry has
228
     * a field with a given slug.
229
     *
230
     * @param  $slug
231
     * @return bool
232
     */
233
    public function hasField($slug)
234
    {
235
        return ($this->getField($slug) !== null);
236
    }
237
238
    /**
239
     * Get the field type from a field slug.
240
     *
241
     * @param  $fieldSlug
242
     * @return null|FieldType
243
     */
244 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...
245
    {
246
        $locale = config('app.locale');
247
248
        $assignment = $this->getAssignment($fieldSlug);
249
250
        if (!$assignment) {
251
            return null;
252
        }
253
254
        $type = $assignment->getFieldType();
255
256
        if ($assignment->isTranslatable()) {
257
258
            $entry = $this->translateOrDefault($locale);
259
260
            $type->setLocale($locale);
261
        } else {
262
            $entry = $this;
263
        }
264
265
        $type->setEntry($entry);
266
267
        $type->setValue($this->getFieldValue($fieldSlug));
268
        $type->setEntry($this);
269
270
        return $type;
271
    }
272
273
    /**
274
     * Get the field type query.
275
     *
276
     * @param $fieldSlug
277
     * @return FieldTypeQuery
278
     */
279
    public function getFieldTypeQuery($fieldSlug)
280
    {
281
        if (!$type = $this->getFieldType($fieldSlug)) {
282
            return null;
283
        }
284
285
        return $type->getQuery();
286
    }
287
288
    /**
289
     * Get the field type presenter.
290
     *
291
     * @param $fieldSlug
292
     * @return FieldTypePresenter
293
     */
294
    public function getFieldTypePresenter($fieldSlug)
295
    {
296
        if (!$type = $this->getFieldType($fieldSlug)) {
297
            return null;
298
        }
299
300
        return $type->getPresenter();
301
    }
302
303
    /**
304
     * Set a given attribute on the model.
305
     * Override the behavior here to give
306
     * the field types a chance to modify things.
307
     *
308
     * @param  string $key
309
     * @param  mixed  $value
310
     * @return $this
311
     */
312
    public function setAttribute($key, $value)
313
    {
314
        if (!$this->isKeyALocale($key) && !$this->hasSetMutator($key) && $this->getFieldType($key)) {
315
            $this->setFieldValue($key, $value);
316
        } else {
317
            parent::setAttribute($key, $value);
318
        }
319
320
        return $this;
321
    }
322
323
    /**
324
     * Get a given attribute on the model.
325
     * Override the behavior here to give
326
     * the field types a chance to modify things.
327
     *
328
     * @param  string $key
329
     * @return mixed
330
     */
331
    public function getAttribute($key)
332
    {
333
        // Check if it's a relationship first.
334
        if (in_array($key, $this->relationships)) {
335
            return parent::getAttribute(camel_case($key));
336
        }
337
338
        if (
339
            !$this->hasGetMutator($key)
340
            && in_array($key, $this->fields)
341
        ) {
342
            return $this->getFieldValue($key);
343
        } else {
344
            return parent::getAttribute($key);
345
        }
346
    }
347
348
    /**
349
     * Get a raw unmodified attribute.
350
     *
351
     * @param      $key
352
     * @param bool $process
353
     * @return mixed|null
354
     */
355
    public function getRawAttribute($key, $process = true)
356
    {
357
        if (!$process) {
358
            return $this->getAttributeFromArray($key);
359
        }
360
361
        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...
362
    }
363
364
    /**
365
     * Set a raw unmodified attribute.
366
     *
367
     * @param $key
368
     * @param $value
369
     * @return $this
370
     */
371
    public function setRawAttribute($key, $value)
372
    {
373
        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...
374
375
        return $this;
376
    }
377
378
    /**
379
     * Get the stream.
380
     *
381
     * @return StreamInterface
382
     */
383
    public function getStream()
384
    {
385
        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 385 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...
386
    }
387
388
    /**
389
     * Get the stream namespace.
390
     *
391
     * @return string
392
     */
393
    public function getStreamNamespace()
394
    {
395
        $stream = $this->getStream();
396
397
        return $stream->getNamespace();
398
    }
399
400
    /**
401
     * Get the stream slug.
402
     *
403
     * @return string
404
     */
405
    public function getStreamSlug()
406
    {
407
        $stream = $this->getStream();
408
409
        return $stream->getSlug();
410
    }
411
412
    /**
413
     * Get the entry's stream name.
414
     *
415
     * @return string
416
     */
417
    public function getStreamName()
418
    {
419
        $stream = $this->getStream();
420
421
        return $stream->getName();
422
    }
423
424
    /**
425
     * Get the stream prefix.
426
     *
427
     * @return string
428
     */
429
    public function getStreamPrefix()
430
    {
431
        $stream = $this->getStream();
432
433
        return $stream->getPrefix();
434
    }
435
436
    /**
437
     * Get the table name.
438
     *
439
     * @return string
440
     */
441
    public function getTableName()
442
    {
443
        $stream = $this->getStream();
444
445
        return $stream->getEntryTableName();
446
    }
447
448
    /**
449
     * Get the translations table name.
450
     *
451
     * @return string
452
     */
453
    public function getTranslationsTableName()
454
    {
455
        $stream = $this->getStream();
456
457
        return $stream->getEntryTranslationsTableName();
458
    }
459
460
    /**
461
     * Get all assignments.
462
     *
463
     * @return AssignmentCollection
464
     */
465
    public function getAssignments()
466
    {
467
        $stream = $this->getStream();
468
469
        return $stream->getAssignments();
470
    }
471
472
    /**
473
     * Get the field slugs for assigned fields.
474
     *
475
     * @param null $prefix
476
     * @return array
477
     */
478
    public function getAssignmentFieldSlugs($prefix = null)
479
    {
480
        $assignments = $this->getAssignments();
481
482
        return $assignments->fieldSlugs($prefix);
483
    }
484
485
    /**
486
     * Get all assignments of the
487
     * provided field type namespace.
488
     *
489
     * @param $fieldType
490
     * @return AssignmentCollection
491
     */
492
    public function getAssignmentsByFieldType($fieldType)
493
    {
494
        $assignments = $this->getAssignments();
495
496
        return $assignments->findAllByFieldType($fieldType);
497
    }
498
499
    /**
500
     * Get an assignment by field slug.
501
     *
502
     * @param  $fieldSlug
503
     * @return AssignmentInterface
504
     */
505
    public function getAssignment($fieldSlug)
506
    {
507
        $assignments = $this->getAssignments();
508
509
        return $assignments->findByFieldSlug($fieldSlug);
510
    }
511
512
    /**
513
     * Return translated assignments.
514
     *
515
     * @return AssignmentCollection
516
     */
517
    public function getTranslatableAssignments()
518
    {
519
        $stream      = $this->getStream();
520
        $assignments = $stream->getAssignments();
521
522
        return $assignments->translatable();
523
    }
524
525
    /**
526
     * Return relation assignments.
527
     *
528
     * @return AssignmentCollection
529
     */
530
    public function getRelationshipAssignments()
531
    {
532
        $stream      = $this->getStream();
533
        $assignments = $stream->getAssignments();
534
535
        return $assignments->relations();
536
    }
537
538
    /**
539
     * Get the translatable flag.
540
     *
541
     * @return bool
542
     */
543
    public function isTranslatable()
544
    {
545
        $stream = $this->getStream();
546
547
        return $stream->isTranslatable();
548
    }
549
550
    /**
551
     * Return whether the entry is trashable or not.
552
     *
553
     * @return bool
554
     */
555
    public function isTrashable()
556
    {
557
        $stream = $this->getStream();
558
559
        return $stream->isTrashable();
560
    }
561
562
    /**
563
     * Return the last modified datetime.
564
     *
565
     * @return Carbon
566
     */
567
    public function lastModified()
568
    {
569
        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...
570
    }
571
572
    /**
573
     * Return whether the title column is
574
     * translatable or not.
575
     *
576
     * @return bool
577
     */
578
    public function titleColumnIsTranslatable()
579
    {
580
        return $this->assignmentIsTranslatable($this->getTitleName());
581
    }
582
583
    /**
584
     * Return whether or not the assignment for
585
     * the given field slug is translatable.
586
     *
587
     * @param $fieldSlug
588
     * @return bool
589
     */
590
    public function assignmentIsTranslatable($fieldSlug)
591
    {
592
        return $this->isTranslatedAttribute($fieldSlug);
593
    }
594
595
    /**
596
     * Return whether or not the assignment for
597
     * the given field slug is a relationship.
598
     *
599
     * @param $fieldSlug
600
     * @return bool
601
     */
602
    public function assignmentIsRelationship($fieldSlug)
603
    {
604
        $relationships = $this->getRelationshipAssignments();
605
606
        return in_array($fieldSlug, $relationships->fieldSlugs());
607
    }
608
609
    /**
610
     * Fire field type events.
611
     *
612
     * @param       $trigger
613
     * @param array $payload
614
     */
615
    public function fireFieldTypeEvents($trigger, $payload = [])
616
    {
617
        $assignments = $this->getAssignments();
618
619
        /* @var AssignmentInterface $assignment */
620
        foreach ($assignments->notTranslatable() as $assignment) {
621
622
            $fieldType = $assignment->getFieldType();
623
624
            $fieldType->setValue($this->getFieldValue($assignment->getFieldSlug()));
625
626
            $fieldType->setEntry($this);
627
628
            $payload['entry']     = $this;
629
            $payload['fieldType'] = $fieldType;
630
631
            $fieldType->fire($trigger, $payload);
632
        }
633
    }
634
635
    /**
636
     * Return the related stream.
637
     *
638
     * @return StreamInterface|array
639
     */
640
    public function stream()
641
    {
642
        if (!$this->stream instanceof StreamInterface) {
643
            $this->stream = app('Anomaly\Streams\Platform\Stream\StreamModel')->make($this->stream);
644
        }
645
646
        return $this->stream;
647
    }
648
649
    /**
650
     * @param array $items
651
     * @return EntryCollection
652
     */
653
    public function newCollection(array $items = [])
654
    {
655
        $collection = substr(get_class($this), 0, -5) . 'Collection';
656
657
        if (class_exists($collection)) {
658
            return new $collection($items);
659
        }
660
661
        return new EntryCollection($items);
662
    }
663
664
    /**
665
     * Return the entry presenter.
666
     *
667
     * This is against standards but required
668
     * by the presentable interface.
669
     *
670
     * @return EntryPresenter
671
     */
672 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...
673
    {
674
        $presenter = substr(get_class($this), 0, -5) . 'Presenter';
675
676
        if (class_exists($presenter)) {
677
            return app()->make($presenter, ['object' => $this]);
678
        }
679
680
        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...
681
    }
682
683
    /**
684
     * Return a new presenter instance.
685
     *
686
     * @return EntryPresenter
687
     */
688
    public function newPresenter()
689
    {
690
        return $this->getPresenter();
691
    }
692
693
    /**
694
     * Get a new query builder for the model's table.
695
     *
696
     * @return \Illuminate\Database\Eloquent\Builder
697
     */
698 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...
699
    {
700
        $builder = new EntryQueryBuilder($this->newBaseQueryBuilder());
701
702
        // Once we have the query builders, we will set the model instances so the
703
        // builder can easily access any information it may need from the model
704
        // while it is constructing and executing various queries against it.
705
        $builder->setModel($this)->with($this->with);
706
707
        return $this->applyGlobalScopes($builder);
708
    }
709
710
    /**
711
     * Override the __get method.
712
     *
713
     * @param string $key
714
     * @return EntryPresenter|mixed
715
     */
716
    public function __get($key)
717
    {
718
        if ($key === 'decorated') {
719
            return $this->getPresenter();
720
        }
721
722
        return parent::__get($key); // TODO: Change the autogenerated stub
723
    }
724
}
725