summaryrefslogtreecommitdiff
path: root/app/Model/TaskTagModel.php
diff options
context:
space:
mode:
Diffstat (limited to 'app/Model/TaskTagModel.php')
-rw-r--r--app/Model/TaskTagModel.php184
1 files changed, 184 insertions, 0 deletions
diff --git a/app/Model/TaskTagModel.php b/app/Model/TaskTagModel.php
new file mode 100644
index 00000000..0553cc6c
--- /dev/null
+++ b/app/Model/TaskTagModel.php
@@ -0,0 +1,184 @@
+<?php
+
+namespace Kanboard\Model;
+
+use Kanboard\Core\Base;
+
+/**
+ * Class TaskTagModel
+ *
+ * @package Kanboard\Model
+ * @author Frederic Guillot
+ */
+class TaskTagModel extends Base
+{
+ /**
+ * SQL table name
+ *
+ * @var string
+ */
+ const TABLE = 'task_has_tags';
+
+ /**
+ * Get all tags not available in a project
+ *
+ * @access public
+ * @param integer $task_id
+ * @param integer $project_id
+ * @return array
+ */
+ public function getTagIdsByTaskNotAvailableInProject($task_id, $project_id)
+ {
+ return $this->db->table(TagModel::TABLE)
+ ->eq(self::TABLE.'.task_id', $task_id)
+ ->notIn(TagModel::TABLE.'.project_id', array(0, $project_id))
+ ->join(self::TABLE, 'tag_id', 'id')
+ ->findAllByColumn(TagModel::TABLE.'.id');
+ }
+
+ /**
+ * Get all tags associated to a task
+ *
+ * @access public
+ * @param integer $task_id
+ * @return array
+ */
+ public function getTagsByTask($task_id)
+ {
+ return $this->db->table(TagModel::TABLE)
+ ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name')
+ ->eq(self::TABLE.'.task_id', $task_id)
+ ->join(self::TABLE, 'tag_id', 'id')
+ ->findAll();
+ }
+
+ /**
+ * Get all tags associated to a list of tasks
+ *
+ * @access public
+ * @param integer[] $task_ids
+ * @return array
+ */
+ public function getTagsByTasks($task_ids)
+ {
+ if (empty($task_ids)) {
+ return array();
+ }
+
+ $tags = $this->db->table(TagModel::TABLE)
+ ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name', self::TABLE.'.task_id')
+ ->in(self::TABLE.'.task_id', $task_ids)
+ ->join(self::TABLE, 'tag_id', 'id')
+ ->findAll();
+
+ return array_column_index($tags, 'task_id');
+ }
+
+ /**
+ * Get dictionary of tags
+ *
+ * @access public
+ * @param integer $task_id
+ * @return array
+ */
+ public function getList($task_id)
+ {
+ $tags = $this->getTagsByTask($task_id);
+ return array_column($tags, 'name', 'id');
+ }
+
+ /**
+ * Add or update a list of tags to a task
+ *
+ * @access public
+ * @param integer $project_id
+ * @param integer $task_id
+ * @param string[] $tags
+ * @return boolean
+ */
+ public function save($project_id, $task_id, array $tags)
+ {
+ $task_tags = $this->getList($task_id);
+ $tags = array_filter($tags);
+
+ return $this->associateTags($project_id, $task_id, $task_tags, $tags) &&
+ $this->dissociateTags($task_id, $task_tags, $tags);
+ }
+
+ /**
+ * Associate a tag to a task
+ *
+ * @access public
+ * @param integer $task_id
+ * @param integer $tag_id
+ * @return boolean
+ */
+ public function associateTag($task_id, $tag_id)
+ {
+ return $this->db->table(self::TABLE)->insert(array(
+ 'task_id' => $task_id,
+ 'tag_id' => $tag_id,
+ ));
+ }
+
+ /**
+ * Dissociate a tag from a task
+ *
+ * @access public
+ * @param integer $task_id
+ * @param integer $tag_id
+ * @return boolean
+ */
+ public function dissociateTag($task_id, $tag_id)
+ {
+ return $this->db->table(self::TABLE)
+ ->eq('task_id', $task_id)
+ ->eq('tag_id', $tag_id)
+ ->remove();
+ }
+
+ /**
+ * Associate missing tags
+ *
+ * @access protected
+ * @param integer $project_id
+ * @param integer $task_id
+ * @param array $task_tags
+ * @param string[] $tags
+ * @return bool
+ */
+ protected function associateTags($project_id, $task_id, $task_tags, $tags)
+ {
+ foreach ($tags as $tag) {
+ $tag_id = $this->tagModel->findOrCreateTag($project_id, $tag);
+
+ if (! isset($task_tags[$tag_id]) && ! $this->associateTag($task_id, $tag_id)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Dissociate removed tags
+ *
+ * @access protected
+ * @param integer $task_id
+ * @param array $task_tags
+ * @param string[] $tags
+ * @return bool
+ */
+ protected function dissociateTags($task_id, $task_tags, $tags)
+ {
+ foreach ($task_tags as $tag_id => $tag) {
+ if (! in_array($tag, $tags)) {
+ if (! $this->dissociateTag($task_id, $tag_id)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}