Test Failed
Push — ft/fields-refactor ( 9f047d...e6f9ef )
by Ben
315:03 queued 288:46
created

Page::statusAsLabel()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 0
1
<?php
2
3
namespace Thinktomorrow\Chief\Pages;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Database\Eloquent\Model;
7
use Thinktomorrow\Chief\Management\ManagedModel;
8
use Thinktomorrow\Chief\Urls\MemoizedUrlRecord;
9
use Thinktomorrow\Chief\Urls\ProvidesUrl\ProvidesUrl;
10
use Thinktomorrow\Chief\Urls\ProvidesUrl\ResolvingRoute;
11
use Thinktomorrow\Chief\Concerns\Viewable\Viewable;
12
use Thinktomorrow\Chief\Concerns\Viewable\ViewableContract;
13
use Thinktomorrow\Chief\Modules\Module;
14
use Thinktomorrow\Chief\Audit\AuditTrait;
15
use Spatie\MediaLibrary\HasMedia\HasMedia;
16
use Thinktomorrow\Chief\Concerns\Featurable;
17
use Thinktomorrow\Chief\Menu\ActsAsMenuItem;
18
use Illuminate\Database\Eloquent\SoftDeletes;
19
use Thinktomorrow\Chief\Relations\ActsAsChild;
20
use Thinktomorrow\Chief\Snippets\WithSnippets;
21
use Thinktomorrow\Chief\Relations\ActsAsParent;
22
use Thinktomorrow\Chief\Relations\ActingAsChild;
23
use Thinktomorrow\AssetLibrary\Traits\AssetTrait;
24
use Thinktomorrow\Chief\Relations\ActingAsParent;
25
use Thinktomorrow\Chief\Concerns\Morphable\Morphable;
26
use Thinktomorrow\Chief\FlatReferences\FlatReference;
27
use Thinktomorrow\Chief\Concerns\Archivable\Archivable;
28
use Dimsav\Translatable\Translatable as BaseTranslatable;
29
use Thinktomorrow\Chief\Concerns\Publishable\Publishable;
30
use Thinktomorrow\Chief\Concerns\Translatable\Translatable;
31
use Thinktomorrow\Chief\Concerns\Morphable\MorphableContract;
32
use Thinktomorrow\Chief\Concerns\Translatable\TranslatableContract;
33
use Thinktomorrow\Chief\Urls\UrlRecordNotFound;
34
35
class Page extends Model implements ManagedModel, TranslatableContract, HasMedia, ActsAsParent, ActsAsChild, ActsAsMenuItem, MorphableContract, ViewableContract, ProvidesUrl
36
{
37
    use BaseTranslatable {
0 ignored issues
show
introduced by
The trait Dimsav\Translatable\Translatable requires some properties which are not provided by Thinktomorrow\Chief\Pages\Page: $translations, $useTranslationFallback, $localeKey
Loading history...
38
        getAttribute as getTranslatableAttribute;
39
    }
40
41
    use Morphable,
0 ignored issues
show
introduced by
The trait Thinktomorrow\Chief\Concerns\Morphable\Morphable requires some properties which are not provided by Thinktomorrow\Chief\Pages\Page: $translations, $morph_key
Loading history...
Bug introduced by
The trait Thinktomorrow\Chief\Conc...anslatable\Translatable requires the property $translations which is not provided by Thinktomorrow\Chief\Pages\Page.
Loading history...
introduced by
The trait Thinktomorrow\Chief\Concerns\Viewable\Viewable requires some properties which are not provided by Thinktomorrow\Chief\Pages\Page: $content, $viewKey
Loading history...
introduced by
The trait Thinktomorrow\AssetLibrary\Traits\AssetTrait requires some properties which are not provided by Thinktomorrow\Chief\Pages\Page: $assets, $pivot, $each, $locale, $mediaConversionRegistrations, $media, $type, $collection_name
Loading history...
42
        AssetTrait,
43
        Translatable,
44
        SoftDeletes,
45
        Publishable,
46
        Featurable,
47
        Archivable,
48
        AuditTrait,
49
        ActingAsParent,
50
        ActingAsChild,
51
        WithSnippets,
52
        ResolvingRoute,
53
        Viewable;
54
55
    // Explicitly mention the translation model so on inheritance the child class uses the proper default translation model
56
    protected $translationModel      = PageTranslation::class;
57
    protected $translationForeignKey = 'page_id';
58
    protected $translatedAttributes  = [
59
        'title', 'content', 'short', 'seo_title', 'seo_description', 'seo_keywords', 'seo_image'
60
    ];
61
62
    public $table          = "pages";
63
    protected $guarded     = [];
64
    protected $dates       = ['deleted_at', 'archived_at'];
65
    protected $with        = ['translations'];
66
67
    protected $baseViewPath;
68
    protected static $baseUrlSegment = '/';
69
70
    public function __construct(array $attributes = [])
71
    {
72
        $this->constructWithSnippets();
73
74
        if (!isset($this->baseViewPath)) {
75
            $this->baseViewPath = config('thinktomorrow.chief.base-view-paths.pages', 'pages');
76
        }
77
78
        parent::__construct($attributes);
79
    }
80
81
    public static function managedModelKey(): string
82
    {
83
        if(isset(static::$managedModelKey)){
84
            return static::$managedModelKey;
0 ignored issues
show
Bug introduced by
The property managedModelKey does not seem to exist on Thinktomorrow\Chief\Pages\Page. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
85
        }
86
87
        throw new \Exception('Missing required static property \'managedModelKey\' on ' . static::class. '.');
88
    }
89
90
    /**
91
     * Parse and render any found snippets in custom
92
     * or translatable attribute values.
93
     *
94
     * @param string $value
95
     * @return mixed|null|string|string[]
96
     */
97
    public function getAttribute($value)
98
    {
99
        $value = $this->getTranslatableAttribute($value);
100
101
        if ($this->shouldParseWithSnippets($value)) {
102
            $value = $this->parseWithSnippets($value);
103
        }
104
105
        return $value;
106
    }
107
108
    /**
109
     * Page specific modules. We exclude text modules since they are modules in pure
110
     * technical terms and not so much as behavioural elements for the admin.
111
     *
112
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
113
     */
114
    public function modules()
115
    {
116
        return $this->hasMany(Module::class, 'page_id')->where('morph_key', '<>', 'text');
117
    }
118
119
    public function flatReference(): FlatReference
120
    {
121
        return new FlatReference(static::class, $this->id);
122
    }
123
124
    public function flatReferenceLabel(): string
125
    {
126
        if ($this->exists) {
127
            $status = ! $this->isPublished() ? ' [' . $this->statusAsPlainLabel().']' : null;
128
129
            return $this->title ? $this->title . $status : '';
0 ignored issues
show
Bug introduced by
The property title does not seem to exist on Thinktomorrow\Chief\Pages\Page. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
130
        }
131
132
        return '';
133
    }
134
135
    public function flatReferenceGroup(): string
136
    {
137
        $classKey = get_class($this);
138
        $labelSingular = property_exists($this, 'labelSingular') ? $this->labelSingular : str_singular($classKey);
0 ignored issues
show
Deprecated Code introduced by
The function str_singular() has been deprecated: Str::singular() should be used directly instead. Will be removed in Laravel 5.9. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

138
        $labelSingular = property_exists($this, 'labelSingular') ? $this->labelSingular : /** @scrutinizer ignore-deprecated */ str_singular($classKey);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug introduced by
The property labelSingular does not seem to exist on Thinktomorrow\Chief\Pages\Page. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
139
140
        return $labelSingular;
141
    }
142
143
    public function mediaUrls($type = null): Collection
144
    {
145
        return $this->getAllFiles($type)->map->getFileUrl();
146
    }
147
148
    public function mediaUrl($type = null): ?string
149
    {
150
        return $this->mediaUrls($type)->first();
151
    }
152
153
    public static function findPublished($id)
154
    {
155
        return static::published()->find($id);
156
    }
157
158
    public function scopeSortedByCreated($query)
159
    {
160
        $query->orderBy('created_at', 'DESC');
161
    }
162
163
    /** @inheritdoc */
164
    public function url(string $locale = null): string
165
    {
166
        if (!$locale) {
167
            $locale = app()->getLocale();
0 ignored issues
show
introduced by
The method getLocale() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

167
            $locale = app()->/** @scrutinizer ignore-call */ getLocale();
Loading history...
168
        }
169
170
        try {
171
            $slug = MemoizedUrlRecord::findByModel($this, $locale)->slug;
172
173
            return $this->resolveUrl($locale, [$slug]);
174
        } catch (UrlRecordNotFound $e) {
175
            return '';
176
        }
177
    }
178
179
    public function resolveUrl(string $locale = null, $parameters = null): string
180
    {
181
        $routeName = config('thinktomorrow.chief.route.name');
182
183
        return $this->resolveRoute($routeName, $parameters, $locale);
0 ignored issues
show
Bug introduced by
It seems like $locale can also be of type string; however, parameter $locale of Thinktomorrow\Chief\Pages\Page::resolveRoute() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

183
        return $this->resolveRoute($routeName, $parameters, /** @scrutinizer ignore-type */ $locale);
Loading history...
184
    }
185
186
    /** @inheritdoc */
187
    public function previewUrl(string $locale = null): string
188
    {
189
        return $this->url($locale).'?preview-mode';
190
    }
191
192
193
    /** @inheritdoc */
194
    public static function baseUrlSegment(string $locale = null): string
195
    {
196
        if (!isset(static::$baseUrlSegment)) {
197
            return '/';
198
        }
199
200
        if (!is_array(static::$baseUrlSegment)) {
0 ignored issues
show
introduced by
The condition is_array(static::baseUrlSegment) is always false.
Loading history...
201
            return static::$baseUrlSegment;
202
        }
203
204
        // When an array, we try to locate the expected segment by locale
205
        $key = $locale ?? app()->getlocale();
206
207
        if (isset(static::$baseUrlSegment[$key])) {
208
            return static::$baseUrlSegment[$key];
209
        }
210
211
        // Fall back to first entry in case no match is found
212
        return reset(static::$baseUrlSegment);
213
    }
214
215
    public function menuLabel(): string
216
    {
217
        return $this->title ?? '';
0 ignored issues
show
Bug introduced by
The property title does not seem to exist on Thinktomorrow\Chief\Pages\Page. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
218
    }
219
220
    /**
221
     * We override the publishable trait defaults because Page needs
222
     * to be concerned with the archived state as well.
223
     *
224
     * TODO: IMPROVEMENT SHOULD BE TO MANAGE THE PAGE STATES IN ONE LOCATION. eg state machine
225
     */
226
    public function isPublished()
227
    {
228
        return (!!$this->published && is_null($this->archived_at));
229
    }
230
231
    public function isDraft()
232
    {
233
        return (!$this->published && is_null($this->archived_at));
234
    }
235
236
    public function publish()
237
    {
238
        $this->published = 1;
239
        $this->archived_at = null;
240
241
        $this->save();
242
    }
243
244
    public function draft()
245
    {
246
        $this->published = 0;
247
        $this->archived_at = null;
248
249
        $this->save();
250
    }
251
252
    public function statusAsLabel()
253
    {
254
        if ($this->isPublished()) {
255
            return '<a href="'.$this->url().'" target="_blank"><em>online</em></a>';
256
        }
257
258
        if ($this->isDraft()) {
259
            return '<a href="'.$this->previewUrl().'" target="_blank" class="text-error"><em>offline</em></a>';
260
        }
261
262
        if ($this->isArchived()) {
263
            return '<span><em>gearchiveerd</em></span>';
264
        }
265
266
        return '-';
267
    }
268
269
    public function statusAsPlainLabel()
270
    {
271
        if ($this->isPublished()) {
272
            return 'online';
273
        }
274
275
        if ($this->isDraft()) {
276
            return 'offline';
277
        }
278
279
        if ($this->isArchived()) {
280
            return 'gearchiveerd';
281
        }
282
283
        return '-';
284
    }
285
}
286