Completed
Push — master ( 9c542a...5db7ed )
by ARCANEDEV
13s
created

Post::setSlugAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
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    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', 'category_id', 'locale', 'title', 'slug', 'excerpt', 'thumbnail', 'content', 'published_at', 'status',
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 2
    public function scopeLocalized(Builder $query, $locale = null)
151
    {
152 2
        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 2
    public function author()
166
    {
167 2
        return $this->belongsTo(
168 2
            config('auth.providers.users.model', 'App\Models\User'),
169 2
            '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 4
    public function tags()
189
    {
190 4
        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 10
    public function setTitleAttribute($title)
204
    {
205 10
        $this->attributes['title'] = $title;
206 10
    }
207
208
    /**
209
     * Get the slug attribute.
210
     *
211
     * @param  string  $slug
212
     */
213 10
    public function setSlugAttribute($slug)
214
    {
215 10
        $this->attributes['slug'] = Str::slug($slug);
216 10
    }
217
218
    /**
219
     * Set the content attribute.
220
     *
221
     * @param  string  $content
222
     */
223 10
    public function setContentAttribute($content)
224
    {
225 10
        $this->attributes['content_raw']  = $content;
226 10
        $this->attributes['content_html'] = markdown($content);
227 10
    }
228
229
    /* -----------------------------------------------------------------
230
     |  Main Functions
231
     | -----------------------------------------------------------------
232
     */
233
234
    /**
235
     * Create a post.
236
     *
237
     * @param  array  $attributes
238
     *
239
     * @return self
240
     */
241
    public static function createOne(array $attributes)
242
    {
243 2
        return tap(new self($attributes), function (self $post) use ($attributes) {
244 2
            $post->save();
245
246 2
            $post->tags()->sync($attributes['tags']);
247
248 2
            $post->createSeo(
249 2
                static::extractSeoAttributes($attributes)
250
            );
251 2
        });
252
    }
253
254
    /**
255
     * Create a post.
256
     *
257
     * @param  array  $attributes
258
     *
259
     * @return bool|int
260
     */
261 2
    public function updateOne(array $attributes)
262
    {
263 2
        $updated = $this->update(Arr::except($attributes, ['author_id']));
264
265 2
        $this->tags()->sync($attributes['tags']);
266
267 2
        $seoAttributes = static::extractSeoAttributes($attributes);
268
269 2
        $this->hasSeo() ? $this->updateSeo($seoAttributes) : $this->createSeo($seoAttributes);
270
271 2
        return $updated;
272
    }
273
274
    /* -----------------------------------------------------------------
275
     |  Check Functions
276
     | -----------------------------------------------------------------
277
     */
278
279
    /**
280
     * Check if the post's status is "draft".
281
     *
282
     * @return bool
283
     */
284 2
    public function isDraft()
285
    {
286 2
        return is_null($this->is_draft) ? true : $this->is_draft;
287
    }
288
289
    /**
290
     * Check if the post's status is "published".
291
     *
292
     * @return bool
293
     */
294 2
    public function isPublished()
295
    {
296 2
        return ! $this->isDraft();
297
    }
298
299
    /**
300
     * Check if the post has thumbnail.
301
     *
302
     * @return bool
303
     */
304 2
    public function hasThumbnail()
305
    {
306 2
        return ! is_null($this->thumbnail);
307
    }
308
309
    /* -----------------------------------------------------------------
310
     |  Other Methods
311
     | -----------------------------------------------------------------
312
     */
313
314
    /**
315
     * Extract the seo attributes.
316
     *
317
     * @param  array  $inputs
318
     *
319
     * @return array
320
     */
321 2
    protected static function extractSeoAttributes(array $inputs)
322
    {
323
        return [
324 2
            'title'       => Arr::get($inputs, 'seo_title'),
325 2
            'description' => Arr::get($inputs, 'seo_description'),
326 2
            'keywords'    => Arr::get($inputs, 'seo_keywords'),
327 2
            'metas'       => Arr::get($inputs, 'seo_metas', []),
328
        ];
329
    }
330
}
331