Completed
Pull Request — master (#6)
by ARCANEDEV
04:53
created

Post::getStatusNameAttribute()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 9.4285
cc 2
eloc 3
nc 1
nop 0
crap 6
1
<?php namespace Arcanesoft\Blog\Models;
2
3
use Arcanedev\LaravelSeo\Traits\Seoable;
4
use Carbon\Carbon;
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\SoftDeletes;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Support\HtmlString;
11
use Illuminate\Support\Str;
12
13
/**
14
 * Class     Post
15
 *
16
 * @package  Arcanesoft\Blog\Models
17
 * @author   ARCANEDEV <[email protected]>
18
 *
19
 * @property  int             id
20
 * @property  int             author_id
21
 * @property  int             category_id
22
 * @property  string          locale
23
 * @property  string          title
24
 * @property  string          slug
25
 * @property  string          excerpt
26
 * @property  string|null     thumbnail
27
 * @property  string          content_raw
28
 * @property  string          content_html
29
 * @property  bool            is_draft
30
 * @property  \Carbon\Carbon  published_at
31
 * @property  \Carbon\Carbon  created_at
32
 * @property  \Carbon\Carbon  updated_at
33
 * @property  \Carbon\Carbon  deleted_at
34
 *
35
 * @property  \Arcanesoft\Contracts\Auth\Models\User  user
36
 * @property  \Arcanesoft\Blog\Models\Category        category
37
 *
38
 * @method  static  \Illuminate\Database\Eloquent\Builder  published()
39
 * @method  static  \Illuminate\Database\Eloquent\Builder  publishedAt(int $year)
40
 * @method  static  \Illuminate\Database\Eloquent\Builder  localized(string|null $locale)
41
 */
42
class Post extends AbstractModel
43
{
44
    /* -----------------------------------------------------------------
45
     |  Constants
46
     | -----------------------------------------------------------------
47
     */
48
49
    const STATUS_DRAFT     = 'draft';
50
    const STATUS_PUBLISHED = 'published';
51
52
    /* -----------------------------------------------------------------
53
     |  Traits
54
     | -----------------------------------------------------------------
55
     */
56
57
    use Presenters\PostPresenter,
58
        Seoable,
59
        SoftDeletes;
60
61
    /* -----------------------------------------------------------------
62
     |  Properties
63
     | -----------------------------------------------------------------
64
     */
65
66
    /**
67
     * The database table used by the model
68
     *
69
     * @var string
70
     */
71
    protected $table = 'posts';
72
73
    /**
74
     * The attributes that are mass assignable
75
     *
76
     * @var array
77
     */
78
    protected $fillable = [
79
        'author_id', 'category_id', 'locale', 'title', 'excerpt', 'thumbnail', 'content', 'published_at',
80
    ];
81
82
    /**
83
     * The attributes that should be mutated to dates.
84
     *
85
     * @var array
86
     */
87
    protected $dates = ['published_at', 'deleted_at'];
88
89
    /**
90
     * The attributes that should be casted to native types.
91
     *
92
     * @var array
93
     */
94
    protected $casts = [
95
        'author_id'   => 'integer',
96
        'category_id' => 'integer',
97
        'is_draft'    => 'boolean',
98
    ];
99
100
    /* -----------------------------------------------------------------
101
     |  Scopes
102
     | -----------------------------------------------------------------
103
     */
104
105
    /**
106
     * Scope only published posts.
107
     *
108
     * @param  \Illuminate\Database\Eloquent\Builder  $query
109
     *
110
     * @return \Illuminate\Database\Eloquent\Builder
111
     */
112
    public function scopePublished(Builder $query)
113
    {
114
        return $query->where('is_draft', false)
115
            ->where('published_at', '<=', Carbon::now());
116
    }
117
118
    /**
119
     * Scope only published posts.
120
     *
121
     * @param  \Illuminate\Database\Eloquent\Builder  $query
122
     * @param  int                                    $year
123
     *
124
     * @return \Illuminate\Database\Eloquent\Builder
125
     */
126
    public function scopePublishedAt(Builder $query, $year)
127
    {
128
        return $this->scopePublished($query)
129
            ->where(DB::raw('YEAR(published_at)'), $year);
130
    }
131
132
    /**
133
     * Scope by post's locale.
134
     *
135
     * @param  \Illuminate\Database\Eloquent\Builder  $query
136
     * @param  string|null                            $locale
137
     *
138
     * @return \Illuminate\Database\Eloquent\Builder
139
     */
140
    public function scopeLocalized(Builder $query, $locale = null)
141
    {
142
        return $query->where('locale', $locale ?: config('app.locale'));
143
    }
144
145
    /* -----------------------------------------------------------------
146
     |  Relationships
147
     | -----------------------------------------------------------------
148
     */
149
150
    /**
151
     * Author relationship.
152
     *
153
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
154
     */
155
    public function author()
156
    {
157
        return $this->belongsTo(
158
            config('auth.providers.users.model', 'App\Models\User'),
159
            'author_id'
160
        );
161
    }
162
163
    /**
164
     * Category relationship.
165
     *
166
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
167
     */
168
    public function category()
169
    {
170
        return $this->belongsTo(Category::class);
171
    }
172
173
    /**
174
     * Tags relationship.
175
     *
176
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
177
     */
178
    public function tags()
179
    {
180
        return $this->belongsToMany(Tag::class, "{$this->prefix}post_tag");
181
    }
182
183
    /* -----------------------------------------------------------------
184
     |  Getters & Setters
185
     | -----------------------------------------------------------------
186
     */
187
188
    /**
189
     * Set the title attribute.
190
     *
191
     * @param  string  $title
192
     */
193
    public function setTitleAttribute($title)
194
    {
195
        $this->attributes['title'] = $title;
196
        $this->attributes['slug']  = Str::slug($title);
197
    }
198
199
    /**
200
     * Set the content attribute.
201
     *
202
     * @param  string  $content
203
     */
204
    public function setContentAttribute($content)
205
    {
206
        $this->attributes['content_raw']  = $content;
207
        $this->attributes['content_html'] = markdown($content);
208
    }
209
210
    /* -----------------------------------------------------------------
211
     |  Main Functions
212
     | -----------------------------------------------------------------
213
     */
214
215
    /**
216
     * Create a post.
217
     *
218
     * @param  array  $attributes
219
     *
220
     * @return self
221
     */
222
    public static function createOne(array $attributes)
223
    {
224
        $post = new self($attributes);
225
        $post->save();
226
227
        $post->tags()->sync($attributes['tags']);
228
229
        $post->createSeo(
230
            static::extractSeoAttributes($attributes)
231
        );
232
233
        return $post;
234
    }
235
236
    /**
237
     * Create a post.
238
     *
239
     * @param  array  $inputs
240
     *
241
     * @return bool|int
242
     */
243
    public function updateOne(array $inputs)
244
    {
245
        $updated = $this->setStatusAttribute($inputs['status'])
246
            ->update(Arr::except($inputs, ['author_id']));
247
248
        $this->tags()->sync($inputs['tags']);
249
250
        $seoAttributes = static::extractSeoAttributes($inputs);
251
252
        $this->hasSeo() ? $this->updateSeo($seoAttributes) : $this->createSeo($seoAttributes);
253
254
        return $updated;
255
    }
256
257
    /* -----------------------------------------------------------------
258
     |  Check Functions
259
     | -----------------------------------------------------------------
260
     */
261
262
    /**
263
     * Check if the post's status is "draft".
264
     *
265
     * @return bool
266
     */
267
    public function isDraft()
268
    {
269
        return $this->is_draft;
270
    }
271
272
    /**
273
     * Check if the post's status is "published".
274
     *
275
     * @return bool
276
     */
277
    public function isPublished()
278
    {
279
        return ! $this->isDraft();
280
    }
281
282
    /**
283
     * Check if the post has thumbnail.
284
     *
285
     * @return bool
286
     */
287
    public function hasThumbnail()
288
    {
289
        return ! is_null($this->thumbnail);
290
    }
291
292
    /* -----------------------------------------------------------------
293
     |  Other Methods
294
     | -----------------------------------------------------------------
295
     */
296
297
    /**
298
     * Get the post statuses.
299
     *
300
     * @return \Illuminate\Support\Collection
301
     */
302
    public static function getStatuses()
303
    {
304
        return Collection::make(
305
            trans('blog::posts.statuses', [])
306
        );
307
    }
308
309
    /**
310
     * Extract the seo attributes.
311
     *
312
     * @param  array  $inputs
313
     *
314
     * @return array
315
     */
316
    protected static function extractSeoAttributes(array $inputs)
317
    {
318
        return [
319
            'title'       => Arr::get($inputs, 'seo_title'),
320
            'description' => Arr::get($inputs, 'seo_description'),
321
            'keywords'    => Arr::get($inputs, 'seo_keywords'),
322
            'metas'       => Arr::get($inputs, 'seo_metas'),
323
        ];
324
    }
325
326
    /**
327
     * Get the show url.
328
     *
329
     * @return string
330
     */
331
    public function getShowUrl()
332
    {
333
        return route('admin::blog.posts.show', [$this]);
334
    }
335
336
    /**
337
     * Get the edit url.
338
     *
339
     * @return string
340
     */
341
    public function getEditUrl()
342
    {
343
        return route('admin::blog.posts.edit', [$this]);
344
    }
345
}
346