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

Apps/Model/Front/Content/EntityContentRead.php (1 issue)

1
<?php
2
3
namespace Apps\Model\Front\Content;
4
5
use Apps\ActiveRecord\Content;
6
use Apps\ActiveRecord\ContentCategory;
7
use Ffcms\Core\App;
8
use Ffcms\Core\Arch\Model;
9
use Ffcms\Core\Exception\ForbiddenException;
10
use Ffcms\Core\Helper\Date;
11
use Ffcms\Core\Helper\FileSystem\Directory;
12
use Ffcms\Core\Helper\FileSystem\File;
13
use Ffcms\Core\Helper\Simplify;
14
use Ffcms\Core\Helper\Type\Any;
15
use Ffcms\Core\Helper\Type\Arr;
16
use Ffcms\Core\Helper\Type\Str;
17
18
/**
19
 * Class EntityContentRead. Prepare record object data to display.
20
 * @package Apps\Model\Front\Content
21
 */
22
class EntityContentRead extends Model
23
{
24
    public $id;
25
    public $title;
26
    public $path;
27
    public $text;
28
    public $display;
29
    public $createDate;
30
    public $editDate;
31
    public $catName;
32
    public $catPath;
33
    public $authorId;
34
    public $authorName;
35
    public $views;
36
    public $catNesting = [];
37
    public $source;
38
    public $posterThumb;
39
    public $posterFull;
40
    public $rating;
41
    public $canRate;
42
43
    public $metaTitle;
44
    public $metaDescription;
45
    public $metaKeywords;
46
47
    // gallery image key-value array as thumb->full
48
    public $galleryItems;
49
50
    // private ActiveRecord relation objects
51
    private $_category;
52
    private $_content;
53
54
    /**
55
     * EntityContentRead constructor. Pass active record objects
56
     * @param ContentCategory $category
57
     * @param Content $content
58
     */
59
    public function __construct(ContentCategory $category, Content $content)
60
    {
61
        $this->_category = $category;
62
        $this->_content = $content;
63
        parent::__construct();
64
    }
65
66
    /**
67
     * Prepare model attributes from passed objects
68
     * @throws ForbiddenException
69
    */
70
    public function before()
71
    {
72
        // set class attributes from ActiveRecord objects
73
        $this->setAttributes();
74
        $this->parseAttributes();
75
        // build category nesting sorted array
76
        $this->expandCategoryNesting();
77
        // set gallery thumbnail & image if exist
78
        $this->prepareGallery();
79
    }
80
81
    /**
82
     * Set class attributes from Content and ContentCategory objects
83
     * @return void
84
     */
85
    private function setAttributes(): void
86
    {
87
        $this->id = $this->_content->id;
88
        $this->title = $this->_content->getLocaled('title');
89
        $this->text = $this->_content->getLocaled('text');
90
        $this->display = (bool)$this->_content->display;
91
92
        $this->metaTitle = $this->_content->getLocaled('meta_title');
93
        $this->metaDescription = $this->_content->getLocaled('meta_description');
94
        $tmpKeywords = $this->_content->getLocaled('meta_keywords');
95
        $this->metaKeywords = explode(',', $tmpKeywords);
0 ignored issues
show
It seems like $tmpKeywords can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        $this->metaKeywords = explode(',', /** @scrutinizer ignore-type */ $tmpKeywords);
Loading history...
96
97
        // set content date, category data
98
        $this->createDate = Date::humanize($this->_content->created_at);
99
        $this->catName = $this->_category->getLocaled('title');
100
        $this->catPath = $this->_category->path;
101
102
        // set author user info
103
        if (App::$User->isExist($this->_content->author_id)) {
104
            $this->authorId = $this->_content->author_id;
105
            $this->authorName = Simplify::parseUserNick($this->authorId);
106
        }
107
108
        $this->source = $this->_content->source;
109
        $this->views = $this->_content->views+1;
110
        $this->rating = $this->_content->rating;
111
112
        // update views count
113
        $this->_content->views += 1;
114
        $this->_content->save();
115
    }
116
117
    /**
118
     * Parse attribute by conditions and apply results
119
     * @throws ForbiddenException
120
     */
121
    private function parseAttributes(): void
122
    {
123
        // check if title and text are exists
124
        if (Str::length($this->title) < 1 || Str::length($this->text) < 1) {
125
            throw new ForbiddenException('Content of this page is empty!');
126
        }
127
128
        // check if meta title is exist or set default title value
129
        if (Any::isEmpty($this->metaTitle)) {
130
            $this->metaTitle = $this->title;
131
        }
132
133
        $ignoredRate = App::$Session->get('content.rate.ignore');
134
        $this->canRate = true;
135
        if (Any::isArray($ignoredRate) && Arr::in((string)$this->id, $ignoredRate)) {
136
            $this->canRate = false;
137
        }
138
        if (!App::$User->isAuth()) {
139
            $this->canRate = false;
140
        } elseif ($this->authorId === App::$User->identity()->getId()) {
141
            $this->canRate = false;
142
        }
143
    }
144
145
    /**
146
     * Prepare gallery items, poster and thumb
147
     */
148
    private function prepareGallery()
149
    {
150
        // get gallery images and poster data
151
        $galleryPath = '/upload/gallery/' . $this->_content->id;
152
        // check if gallery folder is exist
153
        if (Directory::exist($galleryPath)) {
154
            $originImages = File::listFiles($galleryPath . '/orig/', ['.jpg', '.png', '.gif', '.jpeg', '.bmp', '.webp'], true);
155
            // generate poster data
156
            if (Arr::in($this->_content->poster, $originImages)) {
157
                // original poster
158
                $posterName = $this->_content->poster;
159
                $this->posterFull = $galleryPath . '/orig/' . $posterName;
160
                if (!File::exist($this->posterFull)) {
161
                    $this->posterFull = null;
162
                }
163
164
                // thumb poster
165
                $posterSplit = explode('.', $posterName);
166
                array_pop($posterSplit);
167
                $posterCleanName = implode('.', $posterSplit);
168
                $this->posterThumb = $galleryPath . '/thumb/' . $posterCleanName . '.jpg';
169
                if (!File::exist($this->posterThumb)) {
170
                    $this->posterThumb = null;
171
                }
172
            }
173
174
            // generate full gallery
175
            foreach ($originImages as $image) {
176
                $imageSplit = explode('.', $image);
177
                array_pop($imageSplit);
178
                $imageClearName = implode('.', $imageSplit);
179
                // skip image used in poster
180
                if (Str::startsWith($imageClearName, $this->_content->poster)) {
181
                    continue;
182
                }
183
184
                $thumbPath = $galleryPath . '/thumb/' . $imageClearName . '.jpg';
185
                if (File::exist($thumbPath)) {
186
                    $this->galleryItems[$thumbPath] = $galleryPath . '/orig/' . $image;
187
                }
188
            }
189
        }
190
    }
191
192
    /**
193
     * Expand category nesting array
194
     * @return void
195
     */
196
    private function expandCategoryNesting(): void
197
    {
198
        // check for dependence, add '' for general cat, ex: general/depend1/depend2/.../depend-n
199
        $catNestingArray = Arr::merge([0 => ''], explode('/', $this->catPath));
200
        if ($catNestingArray > 1) {
201
            // latest element its a current nesting level, lets cleanup it
202
            array_pop($catNestingArray);
203
            $catNestingPath = null;
204
            foreach ($catNestingArray as $cPath) {
205
                $catNestingPath .= $cPath;
206
207
                // try to find category by path in db
208
                $record = ContentCategory::getByPath($catNestingPath);
209
                if ($record !== null && $record->count() > 0) {
210
                    // if founded - add to nesting data
211
                    $this->catNesting[] = [
212
                        'name' => $record->getLocaled('title'),
213
                        'path' => $record->path
214
                    ];
215
                }
216
                if (!Str::likeEmpty($catNestingPath)) {
217
                    $catNestingPath .= '/';
218
                }
219
            }
220
        }
221
222
        $this->catNesting[] = [
223
            'name' => $this->catName,
224
            'path' => $this->catPath
225
        ];
226
    }
227
228
    /**
229
     * Get content record obj
230
     * @return Content
231
     */
232
    public function getRecord()
233
    {
234
        return $this->_content;
235
    }
236
237
    /**
238
     * Get category relation of this content
239
     * @return ContentCategory
240
     */
241
    public function getCategory()
242
    {
243
        return $this->_category;
244
    }
245
}
246