Passed
Push — Showing-Posts ( 9ab3ae...80fb19 )
by Stone
01:53
created

PostModel   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 334
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 96
dl 0
loc 334
rs 10
c 0
b 0
f 0
wmc 29

17 Methods

Rating   Name   Duplication   Size   Complexity  
A addExcerpt() 0 9 2
A basePostSelect() 0 8 1
A __construct() 0 7 1
A getPosts() 0 3 1
A newPost() 0 27 1
A getPostsWithAuthor() 0 3 1
B getAllPublishedPosts() 0 29 7
A getPostsInCategory() 0 3 1
A totalNumberPosts() 0 3 1
A modifyPost() 0 35 1
A totalNumberPostsByTag() 0 3 1
A getSinglePost() 0 9 1
A countNumberPosts() 0 23 6
A totalNumberPostsInCategory() 0 3 1
A getPostsWithTag() 0 3 1
A getFrontPosts() 0 3 1
A totalNumberPostsByAuthor() 0 3 1
1
<?php
2
3
namespace App\Models;
4
5
use Core\Constant;
6
use Core\Container;
7
use Core\Model;
8
use Core\Traits\StringFunctions;
9
use Exception;
10
11
class PostModel extends Model
12
{
13
    use StringFunctions;
14
15
    private $postsTbl;
16
    private $categoriesTbl;
17
    private $usersTbl;
18
    private $postTagTbl;
19
20
    public function __construct(Container $container)
21
    {
22
        parent::__construct($container);
23
        $this->postsTbl = $this->getTablePrefix("posts");
24
        $this->categoriesTbl = $this->getTablePrefix("categories");
25
        $this->usersTbl = $this->getTablePrefix("users");
26
        $this->postTagTbl = $this->getTablePrefix("posts_has_tags");
27
    }
28
29
    /**
30
     * the base Select SQL to get the information from the post table and joined tables
31
     * @return string
32
     */
33
    private function basePostSelect(): string
34
    {
35
        $sql = "SELECT idposts, title, post_image,article,$this->postsTbl.last_update, posts_slug, categories_idcategories, category_name, published, on_front_page, categories_slug, pseudo as author, idusers
36
                FROM $this->postsTbl 
37
                INNER JOIN $this->categoriesTbl ON $this->postsTbl.categories_idcategories = $this->categoriesTbl.idcategories 
38
                INNER JOIN $this->usersTbl ON $this->postsTbl.author_iduser = $this->usersTbl.idusers
39
                LEFT JOIN $this->postTagTbl ON $this->postsTbl.idposts = $this->postTagTbl.post_idposts";
40
        return $sql;
41
    }
42
43
    /**
44
     * add the excerpt to a post list
45
     * @param array $posts
46
     * @return array
47
     * @throws \ErrorException
48
     */
49
    private function addExcerpt(array $posts): array
50
    {
51
        $sendResults = [];
52
        //we create the excerpt for the text and add it to the object
53
        foreach ($posts as $post) {
54
            $post->{'excerpt'} = $this->getExcerpt($post->article);
55
            $sendResults[] = $post;
56
        }
57
        return $sendResults;
58
    }
59
60
    /**
61
     * get all the posts with details. Only selecting posts that are published
62
     * @param int $offset where to start (for pagination)
63
     * @param int $limit the number of posts
64
     * @param bool $isFrontPage extract only front page posts
65
     * @param array $select list of select limiters
66
     * @return array list of posts
67
     * @throws \ErrorException
68
     */
69
    private function getAllPublishedPosts(int $offset, int $limit, bool $isFrontPage = false, array $select = []): array
70
    {
71
        $sql = $this->basePostSelect();
72
        $sql .= " WHERE published = 1";
73
        if ($isFrontPage) {
74
            $sql .= " AND on_front_page = 1";
75
        }
76
        //if we have a limiting parameter
77
        if ($select != null) {
78
            foreach ($select as $col => $val) {
79
                if (!$this->isAlphaNum($col)) {
80
                    throw new Exception("Invalid column name");
81
                }
82
                $sql .= " AND $col = :$col";
83
            }
84
        }
85
        $sql .= " ORDER BY $this->postsTbl.creation_date DESC";
86
        $sql .= " LIMIT :limit OFFSET :offset";
87
        $this->query($sql);
88
        if ($select != null) {
89
            foreach ($select as $col => $val) {
90
                $this->bind(":" . $col, $val);
91
            }
92
        }
93
        $this->bind(":limit", $limit);
94
        $this->bind(":offset", $offset);
95
        $this->execute();
96
        $results = $this->fetchAll();
97
        return $this->addExcerpt($results);
98
    }
99
100
    /**
101
     * Count the number of published posts
102
     * @param array $select list of select limiters
103
     * @return int number of posts
104
     * @throws Exception
105
     */
106
    private function countNumberPosts(array $select = []): int
107
    {
108
        $sql = "
109
                SELECT COUNT(*) FROM $this->postsTbl
110
                LEFT JOIN $this->postTagTbl ON $this->postsTbl.idposts = $this->postTagTbl.post_idposts
111
                WHERE published = 1
112
                ";
113
        if ($select != null) {
114
            foreach ($select as $col => $val) {
115
                if (!$this->isAlphaNum($col)) {
116
                    throw new Exception("Invalid column name");
117
                }
118
                $sql .= " AND $col = :$col";
119
            }
120
        }
121
        $this->query($sql);
122
        if ($select != null) {
123
            foreach ($select as $col => $val) {
124
                $this->bind(":" . $col, $val);
125
            }
126
        }
127
        $this->execute();
128
        return $this->stmt->fetchColumn();
129
    }
130
131
    /**
132
     * get the total number of posts
133
     * @return int
134
     * @throws Exception
135
     */
136
    public function totalNumberPosts(): int
137
    {
138
        return $this->countNumberPosts();
139
    }
140
141
    /**
142
     * get the total number of posts in a category
143
     * @param int $categoryId
144
     * @return int
145
     * @throws Exception
146
     */
147
    public function totalNumberPostsInCategory(int $categoryId): int
148
    {
149
        return $this->countNumberPosts(["categories_idcategories" => $categoryId]);
150
    }
151
152
    /**
153
     * get the total number of posts by an author
154
     * @param int $authorId
155
     * @return int
156
     * @throws Exception
157
     */
158
    public function totalNumberPostsByAuthor(int $authorId): int
159
    {
160
        return $this->countNumberPosts(["author_iduser" => $authorId]);
161
    }
162
163
    /**
164
     * get the total number of posts with tag
165
     * @param int $tagId
166
     * @return int
167
     * @throws Exception
168
     */
169
    public function totalNumberPostsByTag(int $tagId): int
170
    {
171
        return $this->countNumberPosts(["tag_idtags" => $tagId]);
172
    }
173
174
    /**
175
     * get the list of front posts
176
     * @param int $offset
177
     * @param int $limit
178
     * @return array
179
     * @throws \ErrorException
180
     */
181
    public function getFrontPosts(int $offset = 0, int $limit = Constant::FRONT_PAGE_POSTS): array
182
    {
183
        return $this->getAllPublishedPosts($offset, $limit, true);
184
    }
185
186
    /**
187
     * get the list of all the posts.
188
     * @param int $offset
189
     * @param array $select array of limiters [$key => $val] will convert to "where $key = $val"
190
     * @param int $limit
191
     * @return array
192
     * @throws \ErrorException
193
     */
194
    public function getPosts(int $offset = 0, array $select = [], int $limit = Constant::POSTS_PER_PAGE): array
195
    {
196
        return $this->getAllPublishedPosts($offset, $limit, false, $select);
197
    }
198
199
    /**
200
     * get all the posts from a certain category
201
     * @param int $categoryId the id of the category
202
     * @param int $offset the offset for pagination
203
     * @param int $limit the limit to display
204
     * @return array list of posts in set category
205
     * @throws Exception
206
     */
207
    public function getPostsInCategory(int $categoryId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
208
    {
209
        return $this->getPosts($offset, ["categories_idcategories" => $categoryId], $limit);
210
    }
211
212
    /**
213
     * get all the posts with a specific author
214
     * @param int $authorId
215
     * @param int $offset
216
     * @param int $limit
217
     * @return array
218
     * @throws \ErrorException
219
     */
220
    public function getPostsWithAuthor(int $authorId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
221
    {
222
        return $this->getPosts($offset, ["author_iduser" => $authorId], $limit);
223
    }
224
225
    /**
226
     * get all the posts with a certan tag
227
     * @param int $tagId
228
     * @param int $offset
229
     * @param int $limit
230
     * @return array
231
     * @throws \ErrorException
232
     */
233
    public function getPostsWithTag(int $tagId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
234
    {
235
        return $this->getPosts($offset, ["tag_idtags" => $tagId], $limit);
236
    }
237
238
    /**
239
     * get a single post from it's ID
240
     * @param int $postid the post ID to get
241
     * @return array the single post details
242
     * @throws Exception
243
     */
244
    public function getSinglePost(int $postid)
245
    {
246
        $sql = $this->basePostSelect();
247
        $sql .= " WHERE idposts = :postId;";
248
        $this->query($sql);
249
        $this->bind(":postId", $postid, \PDO::PARAM_INT);
250
        $this->execute();
251
252
        return $this->fetch();
253
    }
254
255
    /**
256
     * Create a new post
257
     * @param string $title
258
     * @param string $postImage
259
     * @param int $idCategory
260
     * @param string $article
261
     * @param int $idUser
262
     * @param int $published
263
     * @param int $onFrontPage
264
     * @param string $postSlug
265
     * @return int the id of created post
266
     * @throws Exception
267
     */
268
    public function newPost(
269
        string $title,
270
        string $postImage,
271
        int $idCategory,
272
        string $article,
273
        int $idUser,
274
        int $published,
275
        int $onFrontPage,
276
        string $postSlug
277
    ): int {
278
        $sql = "
279
          INSERT INTO $this->postsTbl (title, post_image, categories_idcategories, article, author_iduser, creation_date, last_update, published, on_front_page, posts_slug)
280
          VALUES (:title, :post_image, :categories_idcategories, :article, :author_iduser, NOW(), NOW(), :published, :on_front_page, :posts_slug)
281
        ";
282
        $this->query($sql);
283
        $this->bind(':title', $title);
284
        $this->bind(':post_image', $postImage);
285
        $this->bind(':categories_idcategories', $idCategory);
286
        $this->bind(':article', $article);
287
        $this->bind(':author_iduser', $idUser);
288
        $this->bind(':published', $published);
289
        $this->bind(':on_front_page', $onFrontPage);
290
        $this->bind(':posts_slug', $postSlug);
291
292
        $this->execute();
293
294
        return $this->dbh->lastInsertId();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->dbh->lastInsertId() returns the type string which is incompatible with the type-hinted return integer.
Loading history...
295
    }
296
297
    /**
298
     * Update a post with new values
299
     * @param int $postId
300
     * @param string $title
301
     * @param string $postImage
302
     * @param int $idCategory
303
     * @param string $article
304
     * @param int $published
305
     * @param int $onFrontPage
306
     * @param string $postSlug
307
     * @return bool success
308
     * @throws Exception
309
     */
310
    public function modifyPost(
311
        int $postId,
312
        string $title,
313
        string $postImage,
314
        int $idCategory,
315
        string $article,
316
        int $published,
317
        int $onFrontPage,
318
        string $postSlug
319
    ): bool {
320
        $sql = "
321
            UPDATE $this->postsTbl 
322
            SET 
323
                title = :title,
324
                post_image = :postImage,
325
                categories_idcategories = :idCategory,
326
                article = :article,
327
                last_update = NOW(),
328
                published = :published,
329
                on_front_page = :onFrontPage,
330
                posts_slug = :postSlug
331
            WHERE
332
              idposts = :postId
333
        ;";
334
        $this->query($sql);
335
        $this->bind(":title", $title);
336
        $this->bind(":postImage", $postImage);
337
        $this->bind(":idCategory", $idCategory);
338
        $this->bind(":article", $article);
339
        $this->bind(":published", $published);
340
        $this->bind(":onFrontPage", $onFrontPage);
341
        $this->bind(":postSlug", $postSlug);
342
        $this->bind(":postId", $postId);
343
344
        return $this->execute();
345
    }
346
347
348
}