/** * * * @param $discussion_id * @param $tags * @param array $types * @param int $category_id * @param string $new_type * @throws Exception */ public function saveDiscussion($discussion_id, $tags, $types = array(''), $category_id = 0, $new_type = '') { // First grab all of the current tags. $all_tags = $current_tags = $this->getDiscussionTags($discussion_id, TagModel::IX_TAGID); // Put all the default tag types in the types if necessary. if (in_array('', $types)) { $types = array_merge($types, array_keys($this->defaultTypes())); $types = array_unique($types); } // Remove the types from the current tags that we don't need anymore. $current_tags = array_filter($current_tags, function ($row) use($types) { if (in_array($row['Type'], $types)) { return true; } return false; }); // Turn the tags into a nice array. if (is_string($tags)) { $tags = TagModel::SplitTags($tags); } $new_tags = array(); $tag_ids = array(); // See which tags are new and which ones aren't. foreach ($tags as $tag_id) { if (is_id($tag_id)) { $tag_ids[$tag_id] = true; } else { $new_tags[TagModel::tagSlug($tag_id)] = $tag_id; } } // See if any of the new tags actually exist by searching by name. if (!empty($new_tags)) { $found_tags = $this->getWhere(array('Name' => array_keys($new_tags)))->resultArray(); foreach ($found_tags as $found_tag_row) { $tag_ids[$found_tag_row['TagID']] = $found_tag_row; unset($new_tags[TagModel::TagSlug($found_tag_row['Name'])]); } } // Add any remaining tags that need to be added. if (Gdn::session()->checkPermission('Plugins.Tagging.Add')) { foreach ($new_tags as $name => $full_name) { $new_tag = array('Name' => trim(str_replace(' ', '-', strtolower($name)), '-'), 'FullName' => $full_name, 'Type' => $new_type, 'CategoryID' => $category_id, 'InsertUserID' => Gdn::session()->UserID, 'DateInserted' => Gdn_Format::toDateTime(), 'CountDiscussions' => 0); $tag_id = $this->SQL->options('Ignore', true)->insert('Tag', $new_tag); $tag_ids[$tag_id] = true; } } // Grab the tags so we can see more information about them. $save_tags = $this->getWhere(array('TagID' => array_keys($tag_ids)))->resultArray(); // Add any parent tags that may need to be added. foreach ($save_tags as $save_tag) { $parent_tag_id = val('ParentTagID', $save_tag); if ($parent_tag_id) { $tag_ids[$parent_tag_id] = true; } $all_tags[$save_tag['TagID']] = $save_tag; } // Remove tags that are already associated with the discussion. // $same_tag_ids = array_intersect_key($tag_ids, $current_tags); // $current_tags = array_diff_key($current_tags, $same_tag_ids); // $tag_ids = array_diff_key($tag_ids, $same_tag_ids); // Figure out the tags we need to add. $insert_tag_ids = array_diff_key($tag_ids, $current_tags); // Figure out the tags we need to remove. $delete_tag_ids = array_diff_key($current_tags, $tag_ids); $now = Gdn_Format::toDateTime(); // Insert the new tag mappings. foreach ($insert_tag_ids as $tag_id => $bool) { if (isset($all_tags[$tag_id])) { $insert_category_id = $all_tags[$tag_id]['CategoryID']; } else { $insert_category_id = $category_id; } $this->SQL->options('Ignore', true)->insert('TagDiscussion', array('DiscussionID' => $discussion_id, 'TagID' => $tag_id, 'DateInserted' => $now, 'CategoryID' => $insert_category_id)); } // Delete the old tag mappings. if (!empty($delete_tag_ids)) { $this->SQL->delete('TagDiscussion', array('DiscussionID' => $discussion_id, 'TagID' => array_keys($delete_tag_ids))); } // Increment the tag counts. if (!empty($insert_tag_ids)) { $this->SQL->update('Tag')->set('CountDiscussions', 'CountDiscussions + 1', false)->whereIn('TagID', array_keys($insert_tag_ids))->put(); } // Decrement the tag counts. if (!empty($delete_tag_ids)) { $this->SQL->update('Tag')->set('CountDiscussions', 'CountDiscussions - 1', false)->whereIn('TagID', array_keys($delete_tag_ids))->put(); } }