Issues (121)

src/Models/PostModel.php (1 issue)

Severity
1
<?php
2
3
namespace Jidaikobo\Kontiki\Models;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Query\Builder;
7
use Jidaikobo\Kontiki\Core\Auth;
8
use Jidaikobo\Kontiki\Core\Database;
9
use Jidaikobo\Kontiki\Services\ValidationService;
10
11
class PostModel extends BaseModel
12
{
13
    use Traits\CRUDTrait;
14
    use Traits\MetaDataTrait;
0 ignored issues
show
The trait Jidaikobo\Kontiki\Models\Traits\MetaDataTrait requires some properties which are not provided by Jidaikobo\Kontiki\Models\PostModel: $meta_key, $meta_value
Loading history...
15
    use Traits\IndexTrait;
16
    use Traits\SoftDeleteTrait;
17
    use Traits\PublishedTrait;
18
    use Traits\DraftTrait;
19
    use Traits\PendingTrait;
20
    use Traits\ExpiredTrait;
21
    use Traits\TaxonomyTrait;
22
23
    protected string $table = 'posts';
24
    protected string $postType = 'post';
25
    protected string $deleteType = 'softDelete';
26
27
    private Auth $auth;
28
    private UserModel $userModel;
29
30
    public function __construct(
31
        Database $db,
32
        ValidationService $validator,
33
        Auth $auth,
34
        UserModel $userModel
35
    ) {
36
        parent::__construct($db, $validator);
37
        $this->auth = $auth;
38
        $this->userModel = $userModel;
39
    }
40
41
    protected function defineFieldDefinitions(): void
42
    {
43
        $this->fieldDefinitions = [
44
            'id' => $this->getIdField(),
45
            'title' => $this->getTitleField(),
46
            'content' => $this->getContentField(__('content')),
47
            'slug' => $this->getSlugField(),
48
            'parent_id' => $this->getParentIdField(),
49
            'status' => $this->getStatusField(),
50
            'expired_at' => $this->getExpiredAtField(),
51
            'published_at' => $this->getPublishedAtField(),
52
            'creator_id' => $this->getCreatorIdField(),
53
            'updated_at' => $this->getUpdatedAtField(),
54
            'deleted_at' => $this->getDeletedAtField(),
55
            'created_at' => $this->getCreatedAtField(),
56
            'display_updated_at' => $this->getDisplayUpdatedAtField(),
57
        ];
58
    }
59
60
    protected function defineMetaDataFieldDefinitions(): void
61
    {
62
        $hide_excerpt = env('POST_HIDE_METADATA_EXCERPT', false);
63
        $hide_eyecatch = env('POST_HIDE_METADATA_EYECATCH', false);
64
        $this->metaDataFieldDefinitions = [];
65
66
        if (!$hide_excerpt) {
67
            $this->metaDataFieldDefinitions['excerpt'] = $this->getField(
68
                __('excerpt'),
69
                [
70
                    'type' => 'textarea',
71
                    'attributes' => [
72
                        'class' => 'form-control',
73
                        'row' => 3,
74
                    ]
75
                ]
76
            );
77
        }
78
79
        if (!$hide_eyecatch) {
80
            $this->metaDataFieldDefinitions['eyecatch'] = $this->getField(
81
                __('eyecatch'),
82
                [
83
                    'attributes' => [
84
                        'class' => 'form-control font-monospace kontiki-file-upload',
85
                    ],
86
                    'fieldset_template' => 'forms/fieldset/input-group.php',
87
                ]
88
            );
89
        }
90
    }
91
92
    protected function getTaxonomyDefinitions(array $params = []): array
93
    {
94
        $taxonomies = [
95
            'category' => [
96
                'label' => __('category'),
97
                'Model' => 'CategoryModel',
98
            ],
99
        ];
100
        return $taxonomies;
101
    }
102
103
    protected function getAdditionalConditions(Builder $query, string $context = 'all'): Builder
104
    {
105
        $contextConditions = [
106
            'all'       => ['applyNotSoftDeletedConditions'],
107
            'published' => [
108
                'applyNotSoftDeletedConditions',
109
                'applyNotExpiredConditions',
110
                'applyPublisedConditions',
111
                'applyNotDraftConditions'
112
            ],
113
            'trash'     => ['applySoftDeletedConditions'],
114
            'reserved'  => [
115
                'applyNotPublisedConditions',
116
                'applyNotSoftDeletedConditions'
117
            ],
118
            'expired'   => [
119
                'applyExpiredConditions',
120
                'applyNotSoftDeletedConditions'
121
            ],
122
            'pending'     => [
123
                'applyPendingConditions',
124
                'applyNotSoftDeletedConditions'
125
            ],
126
            'draft'     => [
127
                'applyDraftConditions',
128
                'applyNotSoftDeletedConditions'
129
            ],
130
        ];
131
132
        if (isset($contextConditions[$context])) {
133
            foreach ($contextConditions[$context] as $method) {
134
                $query = $this->$method($query);
135
            }
136
        }
137
138
        // jlog($context);
139
        // jlog($query->toSql());
140
        // jlog($query->getBindings());
141
142
        return $query;
143
    }
144
145
    protected function processFieldDefinitions(
146
        string $context = '',
147
        array $data = [],
148
        int $id = null
149
    ): void {
150
        // add rule
151
        $this->fieldDefinitions['slug']['rules'][] = [
152
            'unique',
153
            $this->table,
154
            'slug',
155
            $id
156
        ];
157
158
        // add options
159
        $parents = $this->getOptions('title', true, '', $id);
160
        $this->fieldDefinitions['parent_id']['options'] = $parents;
161
162
        // add options and default value
163
        $userOptions = $this->userModel->getOptions('username');
164
        $user = $this->auth->getCurrentUser();
165
        $this->fieldDefinitions['creator_id']['options'] = $userOptions;
166
        $this->fieldDefinitions['creator_id']['default'] = $user['id'] ?? 0; // no logged in user: 0
167
168
        // add default value
169
        if (in_array($context, ['create'])) {
170
            $this->addDefaultSlug($data);
171
        }
172
173
        // disable form elements
174
        if (in_array($context, ['trash', 'restore', 'delete'])) {
175
            $this->disableFormFieldsForContext();
176
        }
177
    }
178
179
    private function addDefaultSlug(array $data): void
180
    {
181
        // Give priority to POST values
182
        if (!empty($data['slug'])) {
183
            $this->fieldDefinitions['slug']['default'] = $data['slug'];
184
            return;
185
        }
186
187
        // recommend non exists slug
188
        $now = Carbon::now(env('TIMEZONE', 'UTC'))->format('Ymd');
189
        $slug = $this->postType . '-' . $now;
190
        $n = 1;
191
        while ($this->getByField('slug', $slug)) {
192
            $n++;
193
            $slug = $slug . '-' . $n;
194
        }
195
        $this->fieldDefinitions['slug']['default'] = $slug;
196
    }
197
198
    private function getTitleField(): array
199
    {
200
        return $this->getField(
201
            __('title'),
202
            [
203
                'rules' => ['required'],
204
                'display_in_list' => true
205
            ]
206
        );
207
    }
208
209
    private function getContentField(string $label): array
210
    {
211
        return $this->getField(
212
            $label,
213
            [
214
                'type' => 'textarea',
215
                'description' => __('content_exp'),
216
                'attributes' => [
217
                    'class' => 'form-control font-monospace kontiki-file-upload',
218
                    'data-button-class' => 'mt-2',
219
                    'rows' => '10'
220
                ]
221
            ]
222
        );
223
    }
224
225
    private function getSlugField(): array
226
    {
227
        // add dynamic rules at $this->processFieldDefinitions()
228
        return $this->getField(
229
            __('slug'),
230
            [
231
                'description' => __('slug_exp'),
232
                'rules' => [
233
                    'required',
234
                    'slug',
235
                    ['lengthMin', 3],
236
                ],
237
            ]
238
        );
239
    }
240
241
    private function getParentIdField(): array
242
    {
243
        // add options at $this->processFieldDefinitions()
244
        return $this->getField(
245
            'parent',
246
            [
247
                'type' => env('POST_HIDE_PARENT', false) ? 'hidden' : 'select',
248
                'attributes' => [
249
                    'class' => 'form-control form-select'
250
                ],
251
                'group' => 'meta',
252
            ]
253
        );
254
    }
255
256
    private function getPublishedAtField(): array
257
    {
258
        $now = Carbon::now(env('TIMEZONE', 'UTC'))->format('Y-m-d H:i');
259
        return $this->getField(
260
            'reserved_at',
261
            [
262
                'type' => 'datetime-local',
263
                'description' => __('published_at_exp'),
264
                'default' => $now,
265
                'group' => 'meta',
266
                'save_as_utc' => true,
267
                'fieldset_template' => 'forms/fieldset/details.php',
268
                'display_in_list' => 'reserved'
269
            ]
270
        );
271
    }
272
273
    private function getExpiredAtField(): array
274
    {
275
        return $this->getField(
276
            'expired_at',
277
            [
278
                'type' => 'datetime-local',
279
                'description' => __('expired_at_exp'),
280
                'group' => 'meta',
281
                'save_as_utc' => true,
282
                'fieldset_template' => 'forms/fieldset/details.php',
283
                'display_in_list' => 'expired'
284
            ]
285
        );
286
    }
287
288
    private function getStatusField(): array
289
    {
290
        return $this->getField(
291
            'status',
292
            [
293
                'type' => 'select',
294
                'options' => [
295
                    'draft' => __('draft'),
296
                    'published' => __('publishing'),
297
                    'pending' => __('pending'),
298
                ],
299
                'default' => 'published',
300
                'attributes' => [
301
                    'class' => 'form-control form-select'
302
                ],
303
                'display_in_list' => true,
304
                'group' => 'meta',
305
            ]
306
        );
307
    }
308
309
    private function getCreatorIdField(): array
310
    {
311
        // add options and default at $this->processFieldDefinitions()
312
        return $this->getField(
313
            'creator',
314
            [
315
                    'type' => env('POST_HIDE_AUTHOR', false) ? 'hidden' : 'select',
316
                    'attributes' => [
317
                        'class' => 'form-control form-select'
318
                    ],
319
                    'group' => 'meta',
320
                ]
321
        );
322
    }
323
324
    private function getCreatedAtField(): array
325
    {
326
        return $this->getReadOnlyField(
327
            __('created_at', 'Created'),
328
            [
329
                'save_as_utc' => true,
330
                'display_in_list' => true
331
            ]
332
        );
333
    }
334
335
    private function getUpdatedAtField(): array
336
    {
337
        return $this->getReadOnlyField(
338
            __('updated_at', 'Updated'),
339
            [
340
                'save_as_utc' => true
341
            ]
342
        );
343
    }
344
345
    private function getDeletedAtField(): array
346
    {
347
        return $this->getReadOnlyField(
348
            __('deleted_at', 'deleted'),
349
            [
350
                'save_as_utc' => true,
351
                'display_in_list' => 'trash'
352
            ]
353
        );
354
    }
355
356
    private function getDisplayUpdatedAtField(): array
357
    {
358
        return $this->getField(
359
            __('display_updated_at', 'Display Updated'),
360
            [
361
                'type' => 'datetime-local',
362
                'description' => __('display_updated_at_exp'),
363
                'group' => 'meta',
364
                'save_as_utc' => true,
365
                'fieldset_template' => 'forms/fieldset/details.php',
366
            ]
367
        );
368
    }
369
}
370