Passed
Push — Showing-Posts ( 0498b6...15c50f )
by Stone
01:42
created

PostModel::getAllPosts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
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
    //does our query need the tags table to be joined ?
21
    private $queryWithTags = false;
22
23
    public function __construct(Container $container)
24
    {
25
        parent::__construct($container);
26
        $this->postsTbl = $this->getTablePrefix("posts");
27
        $this->categoriesTbl = $this->getTablePrefix("categories");
28
        $this->usersTbl = $this->getTablePrefix("users");
29
        $this->postTagTbl = $this->getTablePrefix("posts_has_tags");
30
    }
31
32
    /**
33
     * the base Select SQL to get the information from the post table and joined tables
34
     * @param bool $withTags
35
     * @return string
36
     */
37
    private function basePostSelect(): string
38
    {
39
        $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
40
                FROM $this->postsTbl 
41
                INNER JOIN $this->categoriesTbl ON $this->postsTbl.categories_idcategories = $this->categoriesTbl.idcategories 
42
                INNER JOIN $this->usersTbl ON $this->postsTbl.author_iduser = $this->usersTbl.idusers";
43
        if ($this->queryWithTags) {
44
            $sql .= " LEFT JOIN $this->postTagTbl ON $this->postsTbl.idposts = $this->postTagTbl.post_idposts";
45
        }
46
        return $sql;
47
    }
48
49
    /**
50
     * add the excerpt to a post list
51
     * @param array $posts
52
     * @return array
53
     * @throws \ErrorException
54
     */
55
    private function addExcerpt(array $posts): array
56
    {
57
        $sendResults = [];
58
        //we create the excerpt for the text and add it to the object
59
        foreach ($posts as $post) {
60
            $post->{'excerpt'} = $this->getExcerpt($post->article);
61
            $sendResults[] = $post;
62
        }
63
        return $sendResults;
64
    }
65
66
    /**
67
     * get all posts, no restriction
68
     */
69
    private function getAllPosts(int $offset, int $limit)
0 ignored issues
show
Unused Code introduced by
The method getAllPosts() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
70
    {
71
        $sql = $this->basePostSelect();
72
        $sql .= " ORDER BY $this->postsTbl.creation_date DESC";
73
        $sql .= " LIMIT :limit OFFSET :offset";
74
        $this->bind(":limit", $limit);
75
        $this->bind(":offset", $offset);
76
        $this->execute();
77
        $results = $this->fetchAll();
78
        return $this->addExcerpt($results);
79
    }
80
81
    /**
82
     * get all the posts with details. Only selecting posts that are published
83
     * @param int $offset where to start (for pagination)
84
     * @param int $limit the number of posts
85
     * @param bool $isFrontPage extract only front page posts
86
     * @param array $select list of select limiters
87
     * @param bool $withTags
88
     * @return array list of posts
89
     * @throws \ErrorException
90
     */
91
    private function getAllPublishedPosts(
92
        int $offset,
93
        int $limit,
94
        bool $isFrontPage = false,
95
        array $select = []
96
    ): array {
97
        $sql = $this->basePostSelect();
98
        $sql .= " WHERE published = 1";
99
        if ($isFrontPage) {
100
            $sql .= " AND on_front_page = 1";
101
        }
102
        //if we have a limiting parameter
103
        if ($select != null) {
104
            foreach ($select as $col => $val) {
105
                if (!$this->isAlphaNum($col)) {
106
                    throw new Exception("Invalid column name");
107
                }
108
                $sql .= " AND $col = :$col";
109
            }
110
        }
111
        $sql .= " ORDER BY $this->postsTbl.creation_date DESC";
112
        $sql .= " LIMIT :limit OFFSET :offset";
113
        $this->query($sql);
114
        if ($select != null) {
115
            foreach ($select as $col => $val) {
116
                $this->bind(":" . $col, $val);
117
            }
118
        }
119
        $this->bind(":limit", $limit);
120
        $this->bind(":offset", $offset);
121
        $this->execute();
122
        $results = $this->fetchAll();
123
        return $this->addExcerpt($results);
124
    }
125
126
    /**
127
     * Count the number of published posts
128
     * @param array $select list of select limiters
129
     * @param bool $withTags
130
     * @return int number of posts
131
     * @throws Exception
132
     */
133
    private function countNumberPosts(array $select = [], $published=true): int
134
    {
135
        $sql = "SELECT COUNT(*) FROM $this->postsTbl";
136
        if ($this->queryWithTags) {
137
            $sql .= " LEFT JOIN $this->postTagTbl ON $this->postsTbl.idposts = $this->postTagTbl.post_idposts";
138
        }
139
        if($published)
140
        {
141
            $sql .= " WHERE published = 1";
142
        }
143
        if ($select != null) {
144
            foreach ($select as $col => $val) {
145
                if (!$this->isAlphaNum($col)) {
146
                    throw new Exception("Invalid column name");
147
                }
148
                $sql .= " AND $col = :$col";
149
            }
150
        }
151
        $this->query($sql);
152
        if ($select != null) {
153
            foreach ($select as $col => $val) {
154
                $this->bind(":" . $col, $val);
155
            }
156
        }
157
        $this->execute();
158
        return $this->stmt->fetchColumn();
159
    }
160
161
    /**
162
     * get the total number of posts
163
     * @return int
164
     * @throws Exception
165
     */
166
    public function totalNumberPosts(): int
167
    {
168
        return $this->countNumberPosts();
169
    }
170
171
    /**
172
     * get the total number of posts + unpublished
173
     * @return int
174
     * @throws Exception
175
     */
176
    public function totalNumberFullPosts(): int
177
    {
178
        return $this->countNumberPosts([], false);
179
    }
180
181
    /**
182
     * get the total number of posts in a category
183
     * @param int $categoryId
184
     * @return int
185
     * @throws Exception
186
     */
187
    public function totalNumberPostsInCategory(int $categoryId): int
188
    {
189
        return $this->countNumberPosts(["categories_idcategories" => $categoryId]);
190
    }
191
192
    /**
193
     * get the total number of posts by an author
194
     * @param int $authorId
195
     * @return int
196
     * @throws Exception
197
     */
198
    public function totalNumberPostsByAuthor(int $authorId): int
199
    {
200
        return $this->countNumberPosts(["author_iduser" => $authorId]);
201
    }
202
203
    /**
204
     * get the total number of posts with tag
205
     * @param int $tagId
206
     * @return int
207
     * @throws Exception
208
     */
209
    public function totalNumberPostsByTag(int $tagId): int
210
    {
211
        $this->queryWithTags = true;
212
        return $this->countNumberPosts(["tag_idtags" => $tagId]);
213
    }
214
215
    /**
216
     * get the list of front posts
217
     * @param int $offset
218
     * @param int $limit
219
     * @return array
220
     * @throws \ErrorException
221
     */
222
    public function getFrontPosts(int $offset = 0, int $limit = Constant::FRONT_PAGE_POSTS): array
223
    {
224
        return $this->getAllPublishedPosts($offset, $limit, true);
225
    }
226
227
    /**
228
 * get the list of all the posts.
229
 * @param int $offset
230
 * @param array $select array of limiters [$key => $val] will convert to "where $key = $val"
231
 * @param int $limit
232
 * @return array
233
 * @throws \ErrorException
234
 */
235
    public function getPosts(int $offset = 0, array $select = [], int $limit = Constant::POSTS_PER_PAGE): array
236
    {
237
        return $this->getAllPublishedPosts($offset, $limit, false, $select);
238
    }
239
240
241
    /**
242
     * get all the posts from a certain category
243
     * @param int $categoryId the id of the category
244
     * @param int $offset the offset for pagination
245
     * @param int $limit the limit to display
246
     * @return array list of posts in set category
247
     * @throws Exception
248
     */
249
    public function getPostsInCategory(int $categoryId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
250
    {
251
        return $this->getPosts($offset, ["categories_idcategories" => $categoryId], $limit);
252
    }
253
254
    /**
255
     * get all the posts with a specific author
256
     * @param int $authorId
257
     * @param int $offset
258
     * @param int $limit
259
     * @return array
260
     * @throws \ErrorException
261
     */
262
    public function getPostsWithAuthor(int $authorId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
263
    {
264
        return $this->getPosts($offset, ["author_iduser" => $authorId], $limit);
265
    }
266
267
    /**
268
     * get all the posts with a certain tag
269
     * @param int $tagId
270
     * @param int $offset
271
     * @param int $limit
272
     * @return array
273
     * @throws \ErrorException
274
     */
275
    public function getPostsWithTag(int $tagId, int $offset = 0, int $limit = Constant::POSTS_PER_PAGE): array
276
    {
277
        $this->queryWithTags = true;
278
        return $this->getPosts($offset, ["tag_idtags" => $tagId], $limit);
279
    }
280
281
    /**
282
     * get a single post from it's ID
283
     * @param int $postid the post ID to get
284
     * @return array the single post details
285
     * @throws Exception
286
     */
287
    public function getSinglePost(int $postid)
288
    {
289
        $sql = $this->basePostSelect();
290
        $sql .= " WHERE idposts = :postId;";
291
        $this->query($sql);
292
        $this->bind(":postId", $postid, \PDO::PARAM_INT);
293
        $this->execute();
294
295
        return $this->fetch();
296
    }
297
298
    /**
299
     * Create a new post
300
     * @param string $title
301
     * @param string $postImage
302
     * @param int $idCategory
303
     * @param string $article
304
     * @param int $idUser
305
     * @param int $published
306
     * @param int $onFrontPage
307
     * @param string $postSlug
308
     * @return int the id of created post
309
     * @throws Exception
310
     */
311
    public function newPost(
312
        string $title,
313
        string $postImage,
314
        int $idCategory,
315
        string $article,
316
        int $idUser,
317
        int $published,
318
        int $onFrontPage,
319
        string $postSlug
320
    ): int {
321
        $sql = "
322
          INSERT INTO $this->postsTbl (title, post_image, categories_idcategories, article, author_iduser, creation_date, last_update, published, on_front_page, posts_slug)
323
          VALUES (:title, :post_image, :categories_idcategories, :article, :author_iduser, NOW(), NOW(), :published, :on_front_page, :posts_slug)
324
        ";
325
        $this->query($sql);
326
        $this->bind(':title', $title);
327
        $this->bind(':post_image', $postImage);
328
        $this->bind(':categories_idcategories', $idCategory);
329
        $this->bind(':article', $article);
330
        $this->bind(':author_iduser', $idUser);
331
        $this->bind(':published', $published);
332
        $this->bind(':on_front_page', $onFrontPage);
333
        $this->bind(':posts_slug', $postSlug);
334
335
        $this->execute();
336
337
        return (int)$this->dbh->lastInsertId();
338
    }
339
340
    /**
341
     * Update a post with new values
342
     * @param int $postId
343
     * @param string $title
344
     * @param string $postImage
345
     * @param int $idCategory
346
     * @param string $article
347
     * @param int $published
348
     * @param int $onFrontPage
349
     * @param string $postSlug
350
     * @return bool success
351
     * @throws Exception
352
     */
353
    public function modifyPost(
354
        int $postId,
355
        string $title,
356
        string $postImage,
357
        int $idCategory,
358
        string $article,
359
        int $published,
360
        int $onFrontPage,
361
        string $postSlug
362
    ): bool {
363
        $sql = "
364
            UPDATE $this->postsTbl 
365
            SET 
366
                title = :title,
367
                post_image = :postImage,
368
                categories_idcategories = :idCategory,
369
                article = :article,
370
                last_update = NOW(),
371
                published = :published,
372
                on_front_page = :onFrontPage,
373
                posts_slug = :postSlug
374
            WHERE
375
              idposts = :postId
376
        ;";
377
        $this->query($sql);
378
        $this->bind(":title", $title);
379
        $this->bind(":postImage", $postImage);
380
        $this->bind(":idCategory", $idCategory);
381
        $this->bind(":article", $article);
382
        $this->bind(":published", $published);
383
        $this->bind(":onFrontPage", $onFrontPage);
384
        $this->bind(":postSlug", $postSlug);
385
        $this->bind(":postId", $postId);
386
387
        return $this->execute();
388
    }
389
390
391
}