I'm developing a simple question tags database association in postgresql. A question can have multiple tags and one tag can be associated to multiple questions. That's why I have a M-M table, questiontags. Using php I want to create a question and verify if the tags given dont exist on the tags table already. If they do exist:
- Don't add my tag to the tags table
- Associate the pre existant tag to the question on my questiontags table
If the tag doesnt exist I want to add it to the tags table and then create an assoaciation.
For that I was trying something like this:
function update_tags($questionid, $tags) {
global $conn;
//Check if question already exists. If Yes, delete it from the array -> //EDIT PROPOSES
$questiontags = get_all_tags();
$existant_tags = [];
foreach ($questiontags as $tag_idx => $tag) {
if(in_array($tag['name'], $tags)){
$key = array_search($tag['name'], $tags);
unset($tags[$key]);
$existant_tags[] = $tag['tagid'];
associate_only_tag($tag['tagid'], $questionid);
}
$questiontags[$tag_idx] = $tag['tagid'];
}
foreach ($tags as $tag) {
associate_tag($tag, $questionid);
}
$tags_to_delete = array_diff($questiontags, $existant_tags);
foreach ($tags_to_delete as $tagid) {
delete_tag_from_question($tagid, $questionid);
}
}
function get_all_tags() {
global $conn;
$query=$conn->prepare("SELECT tags.tagid, tags.name FROM tags ");
$query->execute();
return $query->fetchAll();
}
function get_tags_from_question($questionid) {
global $conn;
$query=$conn->prepare("SELECT tags.tagid, tags.name FROM tags
INNER JOIN questiontags
ON tags.tagid = questiontags.tagid
WHERE questiontags.questionid = :question
");
$query->execute(['question' => $questionid]);
return $query->fetchAll();
}
function insert_tag($tag)
{
global $conn;
$stmt = $conn->prepare("INSERT INTO tags (name) VALUES(:tag)");
$stmt->execute([$tag]);
return (int)$conn->lastInsertId();
}
function associate_tag($tag, $questionid)
{
global $conn;
$tagid = insert_tag($tag);
$stmt = $conn->prepare("INSERT INTO questiontags (questionid, tagid) VALUES(:question, :tag)");
$stmt->execute(['question' => $questionid, 'tag' => $tagid]);
}
function associate_only_tag($tagid, $questionid)
{
global $conn;
$stmt = $conn->prepare("INSERT INTO questiontags (questionid, tagid) VALUES(:question, :tag)");
$stmt->execute(['question' => $questionid, 'tag' => $tagid]);
}
function delete_tag_from_question($tagid, $questionid) {
global $conn;
$query = $conn->prepare("DELETE FROM questiontags WHERE questionid = :question AND tagid = :tag");
$query->execute(['question' => $questionid, 'tag' => $tagid]);
}
The problem is that this only works for a new question and not when I update the question. When I do associate_only_tag
I need something that checks if the question exists and then update instead of trying to create a new row questiontags
. After a lot of effort I can't figure it out.
Is there any way to accomplish this?