Completed
Push — master ( 0d0ae6...7c7732 )
by Stone
19s
created

TagModel::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 13
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
9
class TagModel extends Model
10
{
11
12
    private $tagAssoTbl;
13
    private $tagTbl;
14
15
    public function __construct(Container $container)
16
    {
17
        parent::__construct($container);
18
        $this->tagAssoTbl = $this->getTablePrefix("posts_has_tags");
19
        $this->tagTbl = $this->getTablePrefix("tags");
20
    }
21
22
    /**
23
     * Counts the number of tags in DB
24
     * @return int
25
     * @throws \Exception
26
     */
27
    public function countTags(): int
28
    {
29
        return $this->count();
30
    }
31
32
    /**
33
     * get the list of tags with pagination limit and offset
34
     * @param int $offset
35
     * @param int $limit
36
     * @return array
37
     * @throws \Exception
38
     */
39
    public function getTagList(int $offset = 0, int $limit = Constant::POSTS_PER_PAGE)
40
    {
41
        return $this->list($offset, $limit);
42
    }
43
44
    /**
45
     * check if post has a specific tag
46
     * @param int $postId
47
     * @param int $tagId
48
     * @return bool
49
     * @throws \Exception
50
     */
51
    private function postHasTag(int $postId, int $tagId): bool
52
    {
53
54
        $sql = "SELECT * FROM $this->tagAssoTbl WHERE post_idposts = :postId AND tag_idtags = :tagId";
55
        $this->query($sql);
56
        $this->bind(':postId', $postId);
57
        $this->bind(':tagId', $tagId);
58
        $this->execute();
59
60
        return $this->stmt->rowCount() > 0;
61
    }
62
63
    /**
64
     * @param string $tagName the tag to search for
65
     * @return int
66
     * @throws \Exception
67
     */
68
    private function getTagId(string $tagName): int
69
    {
70
        $sql = "SELECT idtags FROM $this->tagTbl WHERE tag_name = :tagName";
71
        $this->query($sql);
72
        $this->bind(':tagName', $tagName);
73
        $this->execute();
74
        //if no rows, return zero
75
        if (!$this->stmt->rowCount() > 0) {
76
            return 0;
77
        }
78
        return $this->stmt->fetchColumn();
79
    }
80
81
    /**
82
     * Create a new tag and return it's ID
83
     * @param string $tag tag to insert
84
     * @return int the inserted tag ID
85
     * @throws \Exception
86
     */
87
    private function createNewTag(string $tag): int
88
    {
89
        $sql = "INSERT INTO $this->tagTbl (tag_name) VALUES (:tag)";
90
        $this->query($sql);
91
        $this->bind(":tag", $tag);
92
        $this->execute();
93
        return (int)$this->dbh->lastInsertId();
94
95
    }
96
97
    /**
98
     * delete a tag from all posts
99
     * @param int $tagId
100
     * @return bool
101
     * @throws \Exception
102
     */
103
    private function deleteTagOnAllPosts(int $tagId)
104
    {
105
        $sql = "
106
        DELETE 
107
        FROM $this->tagAssoTbl 
108
        WHERE tag_idtags = :tagId
109
        ";
110
        $this->query($sql);
111
        $this->bind(":tagId", $tagId);
112
        return $this->execute();
113
    }
114
115
    /**
116
     * @return array the list of all the tags
117
     * @throws \ReflectionException
118
     */
119
    public function getTags(): array
120
    {
121
        return $this->getResultSet('tags');
122
    }
123
124
    /**
125
     * Add a tag to the post
126
     * @param int $postId the post id
127
     * @param int $tagId the tag id
128
     * @throws \Exception
129
     */
130
    public function addTagToPost(int $postId, int $tagId)
131
    {
132
        //if the post already has the tag, do nothing
133
        if ($this->postHasTag($postId, $tagId)) {
134
            return;
135
        }
136
137
        $sql = "INSERT INTO $this->tagAssoTbl (post_idposts, tag_idtags) VALUES (:postId, :tagId)";
138
        $this->query($sql);
139
        $this->bind(':postId', $postId);
140
        $this->bind(':tagId', $tagId);
141
        $this->execute();
142
    }
143
144
    /**
145
     * Add a new tag to a post
146
     * @param int $postId
147
     * @param string $tag
148
     * @throws \Exception
149
     */
150
    public function addNewTagToPost(int $postId, string $tag)
151
    {
152
        //check if tag doesn't already exist
153
        $tagId = $this->getTagId($tag);
154
        if ($tagId === 0) {
155
            $tagId = $this->createNewTag($tag);
156
        }
157
        $this->addTagToPost($postId, $tagId);
158
    }
159
160
    /**
161
     * removes a tag from the post
162
     * @param int $postId the post id
163
     * @param int $tagId the tag id
164
     * @throws \Exception
165
     */
166
    public function removeTagFromPost(int $postId, int $tagId)
167
    {
168
        //if the tag isn't present, do nothing
169
        if (!$this->postHasTag($postId, $tagId)) {
170
            return;
171
        }
172
173
        $sql = "DELETE FROM $this->tagAssoTbl WHERE post_idposts = :postId AND tag_idtags = :tagId";
174
        $this->query($sql);
175
        $this->bind(':postId', $postId);
176
        $this->bind(':tagId', $tagId);
177
        $this->execute();
178
    }
179
180
    /**
181
     * get all tags associated to a post
182
     * @param int $postId the post ID
183
     * @return array the associated tags
184
     * @throws \Exception
185
     */
186
    public function getTagsOnPost(int $postId)
187
    {
188
        $sql = "SELECT tag_name, idtags FROM $this->tagTbl 
189
        INNER JOIN $this->tagAssoTbl ON  $this->tagTbl.idtags = $this->tagAssoTbl.tag_idtags
190
        WHERE post_idposts = :postId
191
        ";
192
        $this->query($sql);
193
        $this->bind(":postId", $postId);
194
        $this->execute();
195
196
        return $this->fetchAll();
197
    }
198
199
200
    /**
201
     * Remove all tags from a post
202
     * @param int $postId the post ID
203
     * @throws \Exception
204
     */
205
    public function removeTagsOnPost(int $postId)
206
    {
207
        $sql = "
208
            DELETE FROM $this->tagAssoTbl
209
            WHERE post_idposts = :postId
210
        ;";
211
        $this->query($sql);
212
        $this->bind(":postId", $postId);
213
        $this->execute();
214
    }
215
216
    /**
217
     * return all the tag details
218
     * @param int $tagId
219
     * @return array
220
     * @throws \ReflectionException
221
     */
222
    public function getTagDetails(int $tagId)
223
    {
224
        return $this->getRowById($tagId);
225
    }
226
227
    /**
228
     * create a new tag
229
     * @param string $tag
230
     * @return bool
231
     * @throws \Exception
232
     */
233
    public function new(string $tag)
234
    {
235
        $tagId = $this->createNewTag($tag);
236
        return is_int($tagId);
237
    }
238
239
    /**
240
     * Update an existing tag
241
     * @param int $tagId
242
     * @param string $tagName
243
     * @return bool
244
     * @throws \Exception
245
     */
246
    public function update(int $tagId, string $tagName)
247
    {
248
        $sql = "
249
            UPDATE $this->tagTbl 
250
            SET
251
              tag_name = :tagName
252
            WHERE
253
              idtags = :tagId
254
        ";
255
        $this->query($sql);
256
        $this->bind(":tagName", $tagName);
257
        $this->bind(":tagId", $tagId);
258
        return $this->execute();
259
    }
260
261
    /**
262
     * Delete a tag
263
     * @param int $tagId
264
     * @return bool
265
     * @throws \Exception
266
     */
267
    public function delete(int $tagId)
268
    {
269
        $this->deleteTagOnAllPosts($tagId);
270
        $sql = "
271
        DELETE
272
        FROM $this->tagTbl
273
        WHERE idtags = :tagId
274
        ";
275
        $this->query($sql);
276
        $this->bind(":tagId", $tagId);
277
        return $this->execute();
278
    }
279
280
    /**
281
     * get tag name from ID
282
     * @param int $tagId
283
     * @return mixed
284
     * @throws \Exception
285
     */
286
    public function getNameFromId(int $tagId)
287
    {
288
        $sql = "SELECT tag_name from $this->tagTbl WHERE idtags = :tagId";
289
        $this->query($sql);
290
        $this->bind(":tagId", $tagId);
291
        $this->execute();
292
        return $this->stmt->fetchColumn();
293
    }
294
295
}