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