TagModel::removeTagFromPost()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 2
dl 0
loc 12
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($this->tagTbl);
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->finalExecute();
113
    }
114
115
    /**
116
     * @return array the list of all the tags
117
     * @throws \ReflectionException
118
     */
119
    public function getTags(): array
120
    {
121
        if($this->countTags() > 0)
122
        {
123
            return $this->getResultSet($this->tagTbl);
124
        }
125
        return [];
126
    }
127
128
    /**
129
     * Add a tag to the post
130
     * @param int $postId the post id
131
     * @param int $tagId the tag id
132
     * @throws \Exception
133
     */
134
    public function addTagToPost(int $postId, int $tagId)
135
    {
136
        //if the post already has the tag, do nothing
137
        if ($this->postHasTag($postId, $tagId)) {
138
            return;
139
        }
140
141
        $sql = "INSERT INTO $this->tagAssoTbl (post_idposts, tag_idtags) VALUES (:postId, :tagId)";
142
        $this->query($sql);
143
        $this->bind(':postId', $postId);
144
        $this->bind(':tagId', $tagId);
145
        $this->finalExecute();
146
    }
147
148
    /**
149
     * Add a new tag to a post
150
     * @param int $postId
151
     * @param string $tag
152
     * @throws \Exception
153
     */
154
    public function addNewTagToPost(int $postId, string $tag)
155
    {
156
        //check if tag doesn't already exist
157
        $tagId = $this->getTagId($tag);
158
        if ($tagId === 0) {
159
            $tagId = $this->createNewTag($tag);
160
        }
161
        $this->addTagToPost($postId, $tagId);
162
    }
163
164
    /**
165
     * removes a tag from the post
166
     * @param int $postId the post id
167
     * @param int $tagId the tag id
168
     * @throws \Exception
169
     */
170
    public function removeTagFromPost(int $postId, int $tagId)
171
    {
172
        //if the tag isn't present, do nothing
173
        if (!$this->postHasTag($postId, $tagId)) {
174
            return;
175
        }
176
177
        $sql = "DELETE FROM $this->tagAssoTbl WHERE post_idposts = :postId AND tag_idtags = :tagId";
178
        $this->query($sql);
179
        $this->bind(':postId', $postId);
180
        $this->bind(':tagId', $tagId);
181
        $this->finalExecute();
182
    }
183
184
    /**
185
     * get all tags associated to a post
186
     * @param int $postId the post ID
187
     * @return array the associated tags
188
     * @throws \Exception
189
     */
190
    public function getTagsOnPost(int $postId)
191
    {
192
        $sql = "SELECT tag_name, idtags FROM $this->tagTbl 
193
        INNER JOIN $this->tagAssoTbl ON  $this->tagTbl.idtags = $this->tagAssoTbl.tag_idtags
194
        WHERE post_idposts = :postId
195
        ";
196
        $this->query($sql);
197
        $this->bind(":postId", $postId);
198
        $this->execute();
199
200
        return $this->fetchAll();
201
    }
202
203
204
    /**
205
     * Remove all tags from a post
206
     * @param int $postId the post ID
207
     * @throws \Exception
208
     */
209
    public function removeTagsOnPost(int $postId)
210
    {
211
        $sql = "
212
            DELETE FROM $this->tagAssoTbl
213
            WHERE post_idposts = :postId
214
        ;";
215
        $this->query($sql);
216
        $this->bind(":postId", $postId);
217
        $this->finalExecute();
218
    }
219
220
    /**
221
     * return all the tag details
222
     * @param int $tagId
223
     * @return array
224
     * @throws \ReflectionException
225
     */
226
    public function getTagDetails(int $tagId)
227
    {
228
        return $this->getRowById($tagId);
229
    }
230
231
    /**
232
     * create a new tag
233
     * @param string $tag
234
     * @return bool
235
     * @throws \Exception
236
     */
237
    public function new(string $tag)
238
    {
239
        $tagId = $this->createNewTag($tag);
240
        return is_int($tagId);
241
    }
242
243
    /**
244
     * Update an existing tag
245
     * @param int $tagId
246
     * @param string $tagName
247
     * @return bool
248
     * @throws \Exception
249
     */
250
    public function update(int $tagId, string $tagName)
251
    {
252
        $sql = "
253
            UPDATE $this->tagTbl 
254
            SET
255
              tag_name = :tagName
256
            WHERE
257
              idtags = :tagId
258
        ";
259
        $this->query($sql);
260
        $this->bind(":tagName", $tagName);
261
        $this->bind(":tagId", $tagId);
262
        return $this->finalExecute();
263
    }
264
265
    /**
266
     * Delete a tag
267
     * @param int $tagId
268
     * @return bool
269
     * @throws \Exception
270
     */
271
    public function delete(int $tagId)
272
    {
273
        $this->deleteTagOnAllPosts($tagId);
274
        $sql = "
275
        DELETE
276
        FROM $this->tagTbl
277
        WHERE idtags = :tagId
278
        ";
279
        $this->query($sql);
280
        $this->bind(":tagId", $tagId);
281
        return $this->finalExecute();
282
    }
283
284
    /**
285
     * get tag name from ID
286
     * @param int $tagId
287
     * @return mixed
288
     * @throws \Exception
289
     */
290
    public function getNameFromId(int $tagId)
291
    {
292
        $sql = "SELECT tag_name from $this->tagTbl WHERE idtags = :tagId";
293
        $this->query($sql);
294
        $this->bind(":tagId", $tagId);
295
        $this->execute();
296
        return $this->stmt->fetchColumn();
297
    }
298
299
}