Test Failed
Push — master ( e3c39f...fe570d )
by Mihail
07:20
created

Apps/Model/Admin/Content/FormContentUpdate.php (1 issue)

1
<?php
2
3
namespace Apps\Model\Admin\Content;
4
5
use Apps\ActiveRecord\CommentPost;
6
use Apps\ActiveRecord\Content;
7
use Apps\ActiveRecord\ContentCategory;
8
use Apps\ActiveRecord\ContentTag;
9
use Apps\ActiveRecord\User;
10
use Ffcms\Core\App;
11
use Ffcms\Core\Arch\Model;
12
use Ffcms\Core\Helper\Crypt;
13
use Ffcms\Core\Helper\Date;
14
use Ffcms\Core\Helper\FileSystem\Directory;
15
use Ffcms\Core\Helper\FileSystem\File;
16
use Ffcms\Core\Helper\Type\Any;
17
use Ffcms\Core\Helper\Type\Integer;
18
use Ffcms\Core\Helper\Type\Str;
19
use Illuminate\Support\Collection;
20
21
/**
22
 * Class FormContentUpdate. Create and update content items business model
23
 * @package Apps\Model\Admin\Content
24
 */
25
class FormContentUpdate extends Model
26
{
27
    public $title = [];
28
    public $text = [];
29
    public $path;
30
    public $poster;
31
    public $categoryId;
32
    public $authorId;
33
    public $metaTitle;
34
    public $metaKeywords = [];
35
    public $metaDescription = [];
36
    public $display = 1;
37
    public $source;
38
    public $addRating = 0;
39
    public $createdAt;
40
    public $important;
41
42
    public $galleryFreeId;
43
44
    private $_content;
45
    private $cloneId;
46
    private $_new = false;
47
48
    /**
49
     * FormContentUpdate constructor. Pass content active record inside
50
     * @param Content|Collection $content
51
     * @param int $cloneId
52
     */
53
    public function __construct(Content $content, int $cloneId = 0)
54
    {
55
        $this->_content = $content;
56
        $this->cloneId = $cloneId;
57
        parent::__construct();
58
    }
59
60
    /**
61
     * Set model properties from active record data
62
     */
63
    public function before()
64
    {
65
        // is new item?
66
        if (!$this->_content->id) {
67
            $this->_new = true;
68
            if (!$this->galleryFreeId) {
69
                $this->galleryFreeId = '_tmp_' . Str::randomLatin(mt_rand(16, 32));
70
            }
71
72
            if (!$this->authorId) {
73
                $this->authorId = App::$User->identity()->getId();
74
            }
75
76
            if (!$this->categoryId) {
77
                $this->categoryId = 1;
78
            }
79
            if (!$this->path) {
80
                $this->path = Integer::random(8) . '-' . date('d-m-Y');
81
            }
82
83
            if ($this->cloneId > 0) {
84
                $template = Content::find($this->cloneId);
85
                if ($template) {
86
                    $this->title = $template->title;
87
                    $this->text = $template->text;
88
                    $this->metaTitle = $template->meta_title;
89
                    $this->metaDescription = $template->meta_description;
90
                    $this->metaKeywords = $template->meta_keywords;
91
                }
92
            }
93
        } else { // is edit of exist item? define available data
94
            $this->title = $this->_content->title;
95
            $this->text = $this->_content->text;
96
            $this->path = $this->_content->path;
97
            $this->poster = $this->_content->poster;
98
            $this->categoryId = $this->_content->category_id;
99
            $this->authorId = $this->_content->author_id;
100
            $this->metaTitle = $this->_content->meta_title;
101
            $this->metaKeywords = $this->_content->meta_keywords;
102
            $this->metaDescription = $this->_content->meta_description;
103
            $this->display = $this->_content->display;
104
            $this->source = $this->_content->source;
105
            $this->createdAt = Date::convertToDatetime($this->_content->created_at, Date::FORMAT_TO_HOUR);
106
            $this->galleryFreeId = $this->_content->id;
107
            $this->important = $this->_content->important;
108
        }
109
    }
110
111
    /**
112
     * Validation rules
113
     * @return array
114
     */
115
    public function rules(): array
116
    {
117
        $res = [
118
            ['title.' . App::$Request->getLanguage(), 'required'],
119
            ['text.' . App::$Request->getLanguage(), 'required'],
120
            ['text', 'used'],
121
            ['path', 'reverse_match', '/[\/\'~`\!@#\$%\^&\*\(\)+=\{\}\[\]\|;:"\<\>,\?\\\]/'],
122
            [['path', 'categoryId', 'authorId', 'display', 'galleryFreeId', 'title', 'important'], 'required'],
123
            [['metaTitle', 'metaKeywords', 'metaDescription', 'poster', 'source', 'addRating', 'createdAt'], 'used'],
124
            [['addRating', 'authorId', 'display'], 'int'],
125
            [['important', 'display'], 'boolean'],
126
            ['categoryId', 'in', $this->categoryIds()],
127
            ['path', '\Apps\Model\Admin\Content\FormContentUpdate::validatePath'],
128
            ['authorId', '\App::$User::isExist']
129
        ];
130
131
        foreach (App::$Properties->get('languages') as $lang) {
132
            $res[] = ['title.' . $lang, 'length_max', 120, null, true, true];
133
            $res[] = ['keywords.' . $lang, 'length_max', 150];
134
            $res[] = ['description.' . $lang, 'length_max', 250];
135
        }
136
137
        return $res;
138
    }
139
140
    /**
141
     * Filtering attribute types
142
     * @return array
143
     */
144
    public function types(): array
145
    {
146
        return [
147
            'text' => '!secure'
148
        ];
149
    }
150
151
    /**
152
     * Form display labels
153
     * @return array
154
     */
155
    public function labels(): array
156
    {
157
        return [
158
            'title' => __('Content title'),
159
            'text' => __('Content text'),
160
            'path' => __('Path slug'),
161
            'categoryId' => __('Category'),
162
            'metaTitle' => __('Meta title'),
163
            'metaKeywords' => __('Meta keywords'),
164
            'metaDescription' => __('Meta description'),
165
            'display' => __('Public display'),
166
            'important' => __('Make important'),
167
            'createdAt' => __('Publish date'),
168
            'authorId' => __('Author identity'),
169
            'source' => __('Source URL'),
170
            'addRating' => __('Change rating'),
171
            'poster' => __('Poster')
172
        ];
173
    }
174
175
    /**
176
     * Save changes in database
177
     */
178
    public function save()
179
    {
180
        $this->_content->title = $this->title;
181
        $this->_content->text = $this->text;
182
        $this->_content->path = $this->path;
183
        $this->_content->category_id = $this->categoryId;
184
        $this->_content->author_id = $this->authorId;
185
        $this->_content->display = $this->display;
186
        $this->_content->meta_title = $this->metaTitle;
187
        $this->_content->meta_keywords = $this->metaKeywords;
188
        $this->_content->meta_description = $this->metaDescription;
189
        $this->_content->source = $this->source;
190
        $this->_content->important = (int)$this->important;
191
        // check if rating is changed
192
        if ((int)$this->addRating !== 0) {
193
            $this->_content->rating += (int)$this->addRating;
194
        }
195
196
        // check if date is updated
197
        if (!Str::likeEmpty($this->createdAt) && !Str::startsWith('0000', Date::convertToDatetime($this->createdAt, Date::FORMAT_SQL_TIMESTAMP))) {
198
            $this->_content->created_at = Date::convertToDatetime($this->createdAt, Date::FORMAT_SQL_TIMESTAMP);
199
        }
200
201
        // save poster data
202
        $posterPath = '/upload/gallery/' . $this->galleryFreeId . '/orig/' . $this->poster;
203
        if (File::exist($posterPath)) {
204
            $this->_content->poster = $this->poster;
205
        }
206
207
        // get temporary gallery id
208
        $tmpGalleryId = $this->galleryFreeId;
209
210
        // save row
211
        $this->_content->save();
212
        
213
        // update tags data in special table (relation: content->content_tags = oneToMany)
214
        ContentTag::where('content_id', $this->_content->id)->delete();
215
        $insertData = [];
216
        foreach ($this->metaKeywords as $lang => $keys) {
217
            // split keywords to tag array
218
            $tags = explode(',', $keys);
219
            foreach ($tags as $tag) {
220
                // cleanup tag from white spaces
221
                $tag = trim($tag);
222
                // prepare data to insert
223
                if (Str::length($tag) > 0) {
224
                    $insertData[] = [
225
                        'content_id' => $this->_content->id,
226
                        'lang' => $lang,
227
                        'tag' => $tag
228
                    ];
229
                }
230
            }
231
        }
232
        // insert tags
233
        ContentTag::insert($insertData);
234
235
        // move files
236
        if ($tmpGalleryId !== $this->_content->id) {
237
            Directory::rename('/upload/gallery/' . $tmpGalleryId, $this->_content->id);
238
        }
239
    }
240
241
    /**
242
     * Get allowed category ids as array
243
     * @return array
244
     */
245
    public function categoryIds(): ?array
246
    {
247
        $data = ContentCategory::getSortedCategories();
248
        return array_keys($data);
249
    }
250
251
    /**
252
     * Validate path filter
253
     * @return bool
254
     */
255
    public function validatePath(): bool
256
    {
257
        // try to find this item
258
        $find = Content::where('path', $this->path);
259
        // exclude self id
260
        if ($this->_content->id && Any::isInt($this->_content->id)) {
261
            $find->where('id', '!=', $this->_content->id);
262
        }
263
264
        // limit only current category id
265
        $find->where('category_id', $this->categoryId);
266
        return $find->count() < 1;
267
    }
268
269
    /**
270
     * Get users id->nick+mail list
271
     * @return array|null
272
     */
273
    public function getUserIdName(): ?array
274
    {
275
        $users = [];
276
        User::with('profile')->get()->each(function ($user) use (&$users) {
277
            /** @var User $user */
278
            $users[$user->id] = ($user->profile->nick ?? 'id' . $user->id) . ' (' . $user->email . ')';
279
        });
280
281
        return $users;
282
    }
283
284
    /**
285
     * Check if news is new
286
     * @return bool
287
     */
288
    public function isNew(): bool
289
    {
290
        return $this->_new;
291
    }
292
293
    /**
294
     * Get content comments
295
     * @return CommentPost[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|null
296
     */
297
    public function getComments()
298
    {
299
        if ($this->isNew()) {
300
            return null;
301
        }
302
303
        return $this->_content->commentPosts;
304
305
        /**return CommentPost::with(['user', 'user.profile'])
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
306
            ->where('app_name', 'content')
307
            ->where('app_relation_id', $this->_content->id)
308
            ->get();*/
309
    }
310
}
311