Completed
Push — master ( 38efb8...5cc558 )
by Ryan
05:49
created

EntryModel::createdBy()   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
     * Boot the model
70
     */
71
    protected static function boot()
72
    {
73
        $instance = new static;
74
75
        $class     = get_class($instance);
76
        $events    = $instance->getObservableEvents();
77
        $observer  = substr($class, 0, -5) . 'Observer';
78
        $observing = class_exists($observer);
79
80
        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...
81
            self::observe(app($observer));
82
        }
83
84
        if (!$instance->isSearchable()) {
85
            ModelObserver::disableSyncingFor(get_class(new static));
86
        }
87
88
        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...
89
            self::observe(EntryObserver::class);
90
        }
91
92
        parent::boot();
93
    }
94
95
    /**
96
     * Sort the query.
97
     *
98
     * @param Builder $builder
99
     * @param string  $direction
100
     */
101
    public function scopeSorted(Builder $builder, $direction = 'asc')
102
    {
103
        $builder->orderBy('sort_order', $direction);
104
    }
105
106
    /**
107
     * Get the ID.
108
     *
109
     * @return mixed
110
     */
111
    public function getId()
112
    {
113
        return $this->getKey();
114
    }
115
116
    /**
117
     * Get the entry ID.
118
     *
119
     * @return mixed
120
     */
121
    public function getEntryId()
122
    {
123
        return $this->getId();
124
    }
125
126
    /**
127
     * Get the entry title.
128
     *
129
     * @return mixed
130
     */
131
    public function getEntryTitle()
132
    {
133
        return $this->getTitle();
134
    }
135
136
    /**
137
     * Get the model's bound name.
138
     *
139
     * @return string
140
     */
141
    public function getBoundModelName()
142
    {
143
        return get_class(app(get_class($this)));
144
    }
145
146
    /**
147
     * Get the model's bound namespace.
148
     *
149
     * @return string
150
     */
151
    public function getBoundModelNamespace()
152
    {
153
        $namespace = explode('\\', $this->getBoundModelName());
154
155
        array_pop($namespace);
156
157
        return implode('\\', $namespace);
158
    }
159
160
    /**
161
     * Get the sort order.
162
     *
163
     * @return int
164
     */
165
    public function getSortOrder()
166
    {
167
        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...
168
    }
169
170
    /**
171
     * Get the entries title.
172
     *
173
     * @return mixed
174
     */
175
    public function getTitle()
176
    {
177
        return $this->{$this->getTitleName()};
178
    }
179
180
    /**
181
     * Get a field value.
182
     *
183
     * @param        $fieldSlug
184
     * @param  null  $locale
185
     * @return mixed
186
     */
187
    public function getFieldValue($fieldSlug, $locale = null)
188
    {
189
        if (!$locale) {
190
            $locale = config('app.locale');
191
        }
192
193
        $assignment = $this->getAssignment($fieldSlug);
194
195
        $type = $assignment->getFieldType();
196
197
        $accessor = $type->getAccessor();
198
        $modifier = $type->getModifier();
199
200
        if ($assignment->isTranslatable()) {
201
            $entry = $this->translateOrDefault($locale);
202
203
            $type->setLocale($locale);
204
        } else {
205
            $entry = $this;
206
        }
207
208
        $type->setEntry($entry);
209
210
        $value = $modifier->restore($accessor->get());
211
212
        if (
213
            $value === null &&
214
            $assignment->isTranslatable() &&
215
            $assignment->isRequired() &&
216
            $translation = $this->translate()
217
        ) {
218
            $type->setEntry($translation);
219
220
            $value = $modifier->restore($accessor->get());
221
        }
222
223
        return $value;
224
    }
225
226
    /**
227
     * Set a field value.
228
     *
229
     * @param        $fieldSlug
230
     * @param        $value
231
     * @param  null  $locale
232
     * @return $this
233
     */
234
    public function setFieldValue($fieldSlug, $value, $locale = null)
235
    {
236
        if (!$locale) {
237
            $locale = config('app.locale');
238
        }
239
240
        $assignment = $this->getAssignment($fieldSlug);
241
242
        $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...
243
244
        if ($assignment->isTranslatable()) {
245
            $entry = $this->translateOrNew($locale);
246
247
            $type->setLocale($locale);
248
        } else {
249
            $entry = $this;
250
        }
251
252
        $type->setEntry($entry);
253
254
        $accessor = $type->getAccessor();
255
        $modifier = $type->getModifier();
256
257
        $accessor->set($modifier->modify($value));
258
259
        return $this;
260
    }
261
262
    /**
263
     * Get an entry field.
264
     *
265
     * @param  $slug
266
     * @return FieldInterface|null
267
     */
268
    public function getField($slug)
269
    {
270
        $assignment = $this->getAssignment($slug);
271
272
        if (!$assignment instanceof AssignmentInterface) {
273
            return null;
274
        }
275
276
        return $assignment->getField();
277
    }
278
279
    /**
280
     * Return whether an entry has
281
     * a field with a given slug.
282
     *
283
     * @param  $slug
284
     * @return bool
285
     */
286
    public function hasField($slug)
287
    {
288
        return ($this->getField($slug) !== null);
289
    }
290
291
    /**
292
     * Get the field type from a field slug.
293
     *
294
     * @param  $fieldSlug
295
     * @return null|FieldType
296
     */
297 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...
298
    {
299
        $locale = config('app.locale');
300
301
        $assignment = $this->getAssignment($fieldSlug);
302
303
        if (!$assignment) {
304
            return null;
305
        }
306
307
        $type = $assignment->getFieldType();
308
309
        if ($assignment->isTranslatable()) {
310
            $entry = $this->translateOrDefault($locale);
311
312
            $type->setLocale($locale);
313
        } else {
314
            $entry = $this;
315
        }
316
317
        $type->setEntry($entry);
318
319
        $type->setValue($this->getFieldValue($fieldSlug));
320
        $type->setEntry($this);
321
322
        return $type;
323
    }
324
325
    /**
326
     * Get the field type query.
327
     *
328
     * @param $fieldSlug
329
     * @return FieldTypeQuery
330
     */
331
    public function getFieldTypeQuery($fieldSlug)
332
    {
333
        if (!$type = $this->getFieldType($fieldSlug)) {
334
            return null;
335
        }
336
337
        return $type->getQuery();
338
    }
339
340
    /**
341
     * Get the field type presenter.
342
     *
343
     * @param $fieldSlug
344
     * @return FieldTypePresenter
345
     */
346
    public function getFieldTypePresenter($fieldSlug)
347
    {
348
        if (!$type = $this->getFieldType($fieldSlug)) {
349
            return null;
350
        }
351
352
        return $type->getPresenter();
353
    }
354
355
    /**
356
     * Set a given attribute on the model.
357
     * Override the behavior here to give
358
     * the field types a chance to modify things.
359
     *
360
     * @param  string $key
361
     * @param  mixed  $value
362
     * @return $this
363
     */
364
    public function setAttribute($key, $value)
365
    {
366
        if (!$this->isKeyALocale($key) && !$this->hasSetMutator($key) && $this->getFieldType($key)) {
367
            $this->setFieldValue($key, $value);
368
        } else {
369
            parent::setAttribute($key, $value);
370
        }
371
372
        return $this;
373
    }
374
375
    /**
376
     * Get a given attribute on the model.
377
     * Override the behavior here to give
378
     * the field types a chance to modify things.
379
     *
380
     * @param  string $key
381
     * @return mixed
382
     */
383
    public function getAttribute($key)
384
    {
385
        // Check if it's a relationship first.
386
        if (in_array($key, array_merge($this->relationships, ['created_by', 'updated_by']))) {
387
            return parent::getAttribute(camel_case($key));
388
        }
389
390
        if (
391
            !$this->hasGetMutator($key)
392
            && in_array($key, $this->fields)
393
        ) {
394
            return $this->getFieldValue($key);
395
        } else {
396
            return parent::getAttribute($key);
397
        }
398
    }
399
400
    /**
401
     * Get a raw unmodified attribute.
402
     *
403
     * @param             $key
404
     * @param  bool       $process
405
     * @return mixed|null
406
     */
407
    public function getRawAttribute($key, $process = true)
408
    {
409
        if (!$process) {
410
            return $this->getAttributeFromArray($key);
411
        }
412
413
        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...
414
    }
415
416
    /**
417
     * Set a raw unmodified attribute.
418
     *
419
     * @param $key
420
     * @param $value
421
     * @return $this
422
     */
423
    public function setRawAttribute($key, $value)
424
    {
425
        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...
426
427
        return $this;
428
    }
429
430
    /**
431
     * Get the stream.
432
     *
433
     * @return StreamInterface
434
     */
435
    public function getStream()
436
    {
437
        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 437 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...
438
    }
439
440
    /**
441
     * Get the stream namespace.
442
     *
443
     * @return string
444
     */
445
    public function getStreamNamespace()
446
    {
447
        $stream = $this->getStream();
448
449
        return $stream->getNamespace();
450
    }
451
452
    /**
453
     * Get the stream slug.
454
     *
455
     * @return string
456
     */
457
    public function getStreamSlug()
458
    {
459
        $stream = $this->getStream();
460
461
        return $stream->getSlug();
462
    }
463
464
    /**
465
     * Get the entry's stream name.
466
     *
467
     * @return string
468
     */
469
    public function getStreamName()
470
    {
471
        $stream = $this->getStream();
472
473
        return $stream->getName();
474
    }
475
476
    /**
477
     * Get the stream prefix.
478
     *
479
     * @return string
480
     */
481
    public function getStreamPrefix()
482
    {
483
        $stream = $this->getStream();
484
485
        return $stream->getPrefix();
486
    }
487
488
    /**
489
     * Get the table name.
490
     *
491
     * @return string
492
     */
493
    public function getTableName()
494
    {
495
        $stream = $this->getStream();
496
497
        return $stream->getEntryTableName();
498
    }
499
500
    /**
501
     * Get the translations table name.
502
     *
503
     * @return string
504
     */
505
    public function getTranslationsTableName()
506
    {
507
        $stream = $this->getStream();
508
509
        return $stream->getEntryTranslationsTableName();
510
    }
511
512
    /**
513
     * Get all assignments.
514
     *
515
     * @return AssignmentCollection
516
     */
517
    public function getAssignments()
518
    {
519
        $stream = $this->getStream();
520
521
        return $stream->getAssignments();
522
    }
523
524
    /**
525
     * Get the field slugs for assigned fields.
526
     *
527
     * @param  null $prefix
528
     * @return array
529
     */
530
    public function getAssignmentFieldSlugs($prefix = null)
531
    {
532
        $assignments = $this->getAssignments();
533
534
        return $assignments->fieldSlugs($prefix);
535
    }
536
537
    /**
538
     * Get all assignments of the
539
     * provided field type namespace.
540
     *
541
     * @param $fieldType
542
     * @return AssignmentCollection
543
     */
544
    public function getAssignmentsByFieldType($fieldType)
545
    {
546
        $assignments = $this->getAssignments();
547
548
        return $assignments->findAllByFieldType($fieldType);
549
    }
550
551
    /**
552
     * Get an assignment by field slug.
553
     *
554
     * @param  $fieldSlug
555
     * @return AssignmentInterface
556
     */
557
    public function getAssignment($fieldSlug)
558
    {
559
        $assignments = $this->getAssignments();
560
561
        return $assignments->findByFieldSlug($fieldSlug);
562
    }
563
564
    /**
565
     * Return translated assignments.
566
     *
567
     * @return AssignmentCollection
568
     */
569
    public function getTranslatableAssignments()
570
    {
571
        $stream      = $this->getStream();
572
        $assignments = $stream->getAssignments();
573
574
        return $assignments->translatable();
575
    }
576
577
    /**
578
     * Return relation assignments.
579
     *
580
     * @return AssignmentCollection
581
     */
582
    public function getRelationshipAssignments()
583
    {
584
        $stream      = $this->getStream();
585
        $assignments = $stream->getAssignments();
586
587
        return $assignments->relations();
588
    }
589
590
    /**
591
     * Get the translatable flag.
592
     *
593
     * @return bool
594
     */
595
    public function isTranslatable()
596
    {
597
        $stream = $this->getStream();
598
599
        return $stream->isTranslatable();
600
    }
601
602
    /**
603
     * Return whether the entry is trashable or not.
604
     *
605
     * @return bool
606
     */
607
    public function isTrashable()
608
    {
609
        $stream = $this->getStream();
610
611
        return $stream->isTrashable();
612
    }
613
614
    /**
615
     * Return the last modified datetime.
616
     *
617
     * @return Carbon
618
     */
619
    public function lastModified()
620
    {
621
        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...
622
    }
623
624
    /**
625
     * Return the related creator.
626
     *
627
     * @return Authenticatable
628
     */
629
    public function getCreatedBy()
630
    {
631
        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...
632
    }
633
634
    /**
635
     * Return the creator relation.
636
     *
637
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
638
     */
639
    public function createdBy()
640
    {
641
        return $this->belongsTo(config('auth.providers.users.model'));
642
    }
643
644
    /**
645
     * Return the related updater.
646
     *
647
     * @return Authenticatable
648
     */
649
    public function getUpdatedBy()
650
    {
651
        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...
652
    }
653
654
    /**
655
     * Return the updater relation.
656
     *
657
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
658
     */
659
    public function updatedBy()
660
    {
661
        return $this->belongsTo(config('auth.providers.users.model'));
662
    }
663
664
    /**
665
     * Return whether the title column is
666
     * translatable or not.
667
     *
668
     * @return bool
669
     */
670
    public function titleColumnIsTranslatable()
671
    {
672
        return $this->assignmentIsTranslatable($this->getTitleName());
673
    }
674
675
    /**
676
     * Return whether or not the assignment for
677
     * the given field slug is translatable.
678
     *
679
     * @param $fieldSlug
680
     * @return bool
681
     */
682
    public function assignmentIsTranslatable($fieldSlug)
683
    {
684
        return $this->isTranslatedAttribute($fieldSlug);
685
    }
686
687
    /**
688
     * Return whether or not the assignment for
689
     * the given field slug is a relationship.
690
     *
691
     * @param $fieldSlug
692
     * @return bool
693
     */
694
    public function assignmentIsRelationship($fieldSlug)
695
    {
696
        $relationships = $this->getRelationshipAssignments();
697
698
        return in_array($fieldSlug, $relationships->fieldSlugs());
699
    }
700
701
    /**
702
     * Fire field type events.
703
     *
704
     * @param       $trigger
705
     * @param array $payload
706
     */
707
    public function fireFieldTypeEvents($trigger, $payload = [])
708
    {
709
        $assignments = $this->getAssignments();
710
711
        /* @var AssignmentInterface $assignment */
712
        foreach ($assignments->notTranslatable() as $assignment) {
713
            $fieldType = $assignment->getFieldType();
714
715
            $fieldType->setValue($this->getRawAttribute($assignment->getFieldSlug()));
716
717
            $fieldType->setEntry($this);
718
719
            $payload['entry']     = $this;
720
            $payload['fieldType'] = $fieldType;
721
722
            $fieldType->fire($trigger, $payload);
723
        }
724
    }
725
726
    /**
727
     * Return the related stream.
728
     *
729
     * @return StreamInterface|array
730
     */
731
    public function stream()
732
    {
733
        if (!$this->stream instanceof StreamInterface) {
734
            $this->stream = app('Anomaly\Streams\Platform\Stream\StreamModel')->make($this->stream);
735
        }
736
737
        return $this->stream;
738
    }
739
740
    /**
741
     * @param  array $items
742
     * @return EntryCollection
743
     */
744 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...
745
    {
746
        $collection = substr(get_class($this), 0, -5) . 'Collection';
747
748
        if (class_exists($collection)) {
749
            return new $collection($items);
750
        }
751
752
        return new EntryCollection($items);
753
    }
754
755
    /**
756
     * Return the entry presenter.
757
     *
758
     * This is against standards but required
759
     * by the presentable interface.
760
     *
761
     * @return EntryPresenter
762
     */
763 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...
764
    {
765
        $presenter = substr(get_class($this), 0, -5) . 'Presenter';
766
767
        if (class_exists($presenter)) {
768
            return app()->make($presenter, ['object' => $this]);
769
        }
770
771
        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...
772
    }
773
774
    /**
775
     * Return a new presenter instance.
776
     *
777
     * @return EntryPresenter
778
     */
779
    public function newPresenter()
780
    {
781
        return $this->getPresenter();
782
    }
783
784
    /**
785
     * Return a model route.
786
     *
787
     * @return string
788
     */
789
    public function route($route, array $parameters = [])
790
    {
791
        $router = $this->getRouter();
792
793
        return $router->make($route, $parameters);
794
    }
795
796
    /**
797
     * Return a new router instance.
798
     *
799
     * @return EntryRouter
800
     */
801
    public function newRouter()
802
    {
803
        return app()->make($this->getRouterName(), ['entry' => $this]);
804
    }
805
806
    /**
807
     * Get the router.
808
     *
809
     * @return EntryRouter
810
     */
811
    public function getRouter()
812
    {
813
        if (isset($this->cache['router'])) {
814
            return $this->cache['router'];
815
        }
816
817
        return $this->cache['router'] = $this->newRouter();
818
    }
819
820
    /**
821
     * Get the router name.
822
     *
823
     * @return string
824
     */
825
    public function getRouterName()
826
    {
827
        $router = substr(get_class($this), 0, -5) . 'Router';
828
829
        return class_exists($router) ? $router : EntryRouter::class;
830
    }
831
832
    /**
833
     * Create a new Eloquent query builder for the model.
834
     *
835
     * @param  \Illuminate\Database\Query\Builder $query
836
     * @return \Illuminate\Database\Eloquent\Builder|static
837
     */
838
    public function newEloquentBuilder($query)
839
    {
840
        return new EntryQueryBuilder($query);
841
    }
842
843
    /**
844
     * Get the criteria class.
845
     *
846
     * @return string
847
     */
848
    public function getCriteriaName()
849
    {
850
        $criteria = substr(get_class($this), 0, -5) . 'Criteria';
851
852
        return class_exists($criteria) ? $criteria : EntryCriteria::class;
853
    }
854
855
    /**
856
     * Return whether the model is searchable or not.
857
     *
858
     * @return boolean
859
     */
860
    public function isSearchable()
861
    {
862
        return $this->searchable;
863
    }
864
865
    /**
866
     * Return a searchable array.
867
     *
868
     * @return array
869
     */
870
    public function toSearchableArray()
871
    {
872
        $array = $this->toArray();
873
874
        foreach ($array as $key => &$value) {
875
            if (is_array($value)) {
876
                $value = json_encode($value);
877
                continue;
878
            }
879
        }
880
881
        return $array;
882
    }
883
884
    /**
885
     * Override the __get method.
886
     *
887
     * @param  string $key
888
     * @return EntryPresenter|mixed
889
     */
890
    public function __get($key)
891
    {
892
        if ($key === 'decorated') {
893
            return $this->getPresenter();
894
        }
895
896
        return parent::__get($key); // TODO: Change the autogenerated stub
897
    }
898
}
899