Passed
Push — ft/urls ( 5c631b...3903c5 )
by Ben
95:30 queued 50:10
created

Page::menuLabel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
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 177
    public function __construct(array $attributes = [])
71
    {
72 177
        $this->constructWithSnippets();
73
74 177
        if (!isset($this->baseViewPath)) {
75 177
            $this->baseViewPath = config('thinktomorrow.chief.base-view-paths.pages', 'pages');
76
        }
77
78 177
        parent::__construct($attributes);
79 177
    }
80
81 433
    public static function managedModelKey(): string
82
    {
83 433
        if(isset(static::$managedModelKey)){
84 433
            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 152
    public function getAttribute($value)
98
    {
99 152
        $value = $this->getTranslatableAttribute($value);
100
101 152
        if ($this->shouldParseWithSnippets($value)) {
102 1
            $value = $this->parseWithSnippets($value);
103
        }
104
105 152
        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 2
    public function modules()
115
    {
116 2
        return $this->hasMany(Module::class, 'page_id')->where('morph_key', '<>', 'text');
117
    }
118
119 9
    public function flatReference(): FlatReference
120
    {
121 9
        return new FlatReference(static::class, $this->id);
122
    }
123
124 67
    public function flatReferenceLabel(): string
125
    {
126 67
        if ($this->exists) {
127 54
            $status = ! $this->isPublished() ? ' [' . $this->statusAsPlainLabel().']' : null;
128
129 54
            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 17
        return '';
133
    }
134
135 5
    public function flatReferenceGroup(): string
136
    {
137 5
        $classKey = get_class($this);
138 5
        $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 5
        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 1
    public function scopeSortedByCreated($query)
159
    {
160 1
        $query->orderBy('created_at', 'DESC');
161 1
    }
162
163
    /** @inheritdoc */
164 47
    public function url(string $locale = null): string
165
    {
166 47
        if (!$locale) {
167 43
            $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 47
            $slug = MemoizedUrlRecord::findByModel($this, $locale)->slug;
172
173 31
            return $this->resolveUrl($locale, [$slug]);
174 18
        } catch (UrlRecordNotFound $e) {
175 18
            return '';
176
        }
177
    }
178
179 57
    public function resolveUrl(string $locale = null, $parameters = null): string
180
    {
181 57
        $routeName = config('thinktomorrow.chief.route.name');
182
183 57
        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 52
    public function previewUrl(string $locale = null): string
188
    {
189 52
        return $this->url($locale).'?preview-mode';
190
    }
191
192
193
    /** @inheritdoc */
194 51
    public static function baseUrlSegment(string $locale = null): string
195
    {
196 51
        if (!isset(static::$baseUrlSegment)) {
197
            return '/';
198
        }
199
200 51
        if (!is_array(static::$baseUrlSegment)) {
0 ignored issues
show
introduced by
The condition is_array(static::baseUrlSegment) is always false.
Loading history...
201 43
            return static::$baseUrlSegment;
202
        }
203
204
        // When an array, we try to locate the expected segment by locale
205 8
        $key = $locale ?? app()->getlocale();
206
207 8
        if (isset(static::$baseUrlSegment[$key])) {
208 8
            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 7
    public function menuLabel(): string
216
    {
217 7
        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 63
    public function isPublished()
227
    {
228 63
        return (!!$this->published && is_null($this->archived_at));
229
    }
230
231 62
    public function isDraft()
232
    {
233 62
        return (!$this->published && is_null($this->archived_at));
234
    }
235
236 6
    public function publish()
237
    {
238 6
        $this->published = 1;
239 6
        $this->archived_at = null;
240
241 6
        $this->save();
242 6
    }
243
244 1
    public function draft()
245
    {
246 1
        $this->published = 0;
247 1
        $this->archived_at = null;
248
249 1
        $this->save();
250 1
    }
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 53
    public function statusAsPlainLabel()
270
    {
271 53
        if ($this->isPublished()) {
272
            return 'online';
273
        }
274
275 53
        if ($this->isDraft()) {
276 51
            return 'offline';
277
        }
278
279 3
        if ($this->isArchived()) {
280 3
            return 'gearchiveerd';
281
        }
282
283
        return '-';
284
    }
285
}
286