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

PostModel::modifyPost()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 8
dl 0
loc 35
rs 9.8666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
}