Completed
Push — master ( 2078fd...5b4604 )
by ARCANEDEV
18s queued 10s
created

Post::isDeletable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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