Completed
Pull Request — master (#10)
by ARCANEDEV
06:09
created

Post::author()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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