diff options
Diffstat (limited to 'app/Filter')
30 files changed, 1503 insertions, 0 deletions
diff --git a/app/Filter/BaseFilter.php b/app/Filter/BaseFilter.php new file mode 100644 index 00000000..a7e6a61a --- /dev/null +++ b/app/Filter/BaseFilter.php @@ -0,0 +1,119 @@ +<?php + +namespace Kanboard\Filter; + +use PicoDb\Table; + +/** + * Base filter class + * + * @package filter + * @author Frederic Guillot + */ +abstract class BaseFilter +{ + /** + * @var Table + */ + protected $query; + + /** + * @var mixed + */ + protected $value; + + /** + * BaseFilter constructor + * + * @access public + * @param mixed $value + */ + public function __construct($value = null) + { + $this->value = $value; + } + + /** + * Get object instance + * + * @static + * @access public + * @param mixed $value + * @return static + */ + public static function getInstance($value = null) + { + $self = new static($value); + return $self; + } + + /** + * Set query + * + * @access public + * @param Table $query + * @return \Kanboard\Core\Filter\FilterInterface + */ + public function withQuery(Table $query) + { + $this->query = $query; + return $this; + } + + /** + * Set the value + * + * @access public + * @param string $value + * @return \Kanboard\Core\Filter\FilterInterface + */ + public function withValue($value) + { + $this->value = $value; + return $this; + } + + /** + * Parse operator in the input string + * + * @access protected + * @return string + */ + protected function parseOperator() + { + $operators = array( + '<=' => 'lte', + '>=' => 'gte', + '<' => 'lt', + '>' => 'gt', + ); + + foreach ($operators as $operator => $method) { + if (strpos($this->value, $operator) === 0) { + $this->value = substr($this->value, strlen($operator)); + return $method; + } + } + + return ''; + } + + /** + * Apply a date filter + * + * @access protected + * @param string $field + */ + protected function applyDateFilter($field) + { + $timestamp = strtotime($this->value); + $method = $this->parseOperator(); + + if ($method !== '') { + $this->query->$method($field, $timestamp); + } else { + $this->query->gte($field, $timestamp); + $this->query->lte($field, $timestamp + 86399); + } + } +} diff --git a/app/Filter/ProjectGroupRoleProjectFilter.php b/app/Filter/ProjectGroupRoleProjectFilter.php new file mode 100644 index 00000000..b0950868 --- /dev/null +++ b/app/Filter/ProjectGroupRoleProjectFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\ProjectGroupRole; + +/** + * Filter ProjectGroupRole users by project + * + * @package filter + * @author Frederic Guillot + */ +class ProjectGroupRoleProjectFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array(); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(ProjectGroupRole::TABLE.'.project_id', $this->value); + return $this; + } +} diff --git a/app/Filter/ProjectGroupRoleUsernameFilter.php b/app/Filter/ProjectGroupRoleUsernameFilter.php new file mode 100644 index 00000000..c10855bc --- /dev/null +++ b/app/Filter/ProjectGroupRoleUsernameFilter.php @@ -0,0 +1,44 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\GroupMember; +use Kanboard\Model\ProjectGroupRole; +use Kanboard\Model\User; + +/** + * Filter ProjectGroupRole users by username + * + * @package filter + * @author Frederic Guillot + */ +class ProjectGroupRoleUsernameFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array(); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query + ->join(GroupMember::TABLE, 'group_id', 'group_id', ProjectGroupRole::TABLE) + ->join(User::TABLE, 'id', 'user_id', GroupMember::TABLE) + ->ilike(User::TABLE.'.username', $this->value.'%'); + + return $this; + } +} diff --git a/app/Filter/ProjectIdsFilter.php b/app/Filter/ProjectIdsFilter.php new file mode 100644 index 00000000..641f7f18 --- /dev/null +++ b/app/Filter/ProjectIdsFilter.php @@ -0,0 +1,43 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Project; + +/** + * Filter project by ids + * + * @package filter + * @author Frederic Guillot + */ +class ProjectIdsFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('project_ids'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (empty($this->value)) { + $this->query->eq(Project::TABLE.'.id', 0); + } else { + $this->query->in(Project::TABLE.'.id', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/ProjectStatusFilter.php b/app/Filter/ProjectStatusFilter.php new file mode 100644 index 00000000..a994600c --- /dev/null +++ b/app/Filter/ProjectStatusFilter.php @@ -0,0 +1,45 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Project; + +/** + * Filter project by status + * + * @package filter + * @author Frederic Guillot + */ +class ProjectStatusFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('status'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Project::TABLE.'.is_active', $this->value); + } elseif ($this->value === 'inactive' || $this->value === 'closed' || $this->value === 'disabled') { + $this->query->eq(Project::TABLE.'.is_active', 0); + } else { + $this->query->eq(Project::TABLE.'.is_active', 1); + } + + return $this; + } +} diff --git a/app/Filter/ProjectTypeFilter.php b/app/Filter/ProjectTypeFilter.php new file mode 100644 index 00000000..e085e2f6 --- /dev/null +++ b/app/Filter/ProjectTypeFilter.php @@ -0,0 +1,45 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Project; + +/** + * Filter project by type + * + * @package filter + * @author Frederic Guillot + */ +class ProjectTypeFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('type'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Project::TABLE.'.is_private', $this->value); + } elseif ($this->value === 'private') { + $this->query->eq(Project::TABLE.'.is_private', Project::TYPE_PRIVATE); + } else { + $this->query->eq(Project::TABLE.'.is_private', Project::TYPE_TEAM); + } + + return $this; + } +} diff --git a/app/Filter/ProjectUserRoleProjectFilter.php b/app/Filter/ProjectUserRoleProjectFilter.php new file mode 100644 index 00000000..3b880df5 --- /dev/null +++ b/app/Filter/ProjectUserRoleProjectFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\ProjectUserRole; + +/** + * Filter ProjectUserRole users by project + * + * @package filter + * @author Frederic Guillot + */ +class ProjectUserRoleProjectFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array(); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(ProjectUserRole::TABLE.'.project_id', $this->value); + return $this; + } +} diff --git a/app/Filter/ProjectUserRoleUsernameFilter.php b/app/Filter/ProjectUserRoleUsernameFilter.php new file mode 100644 index 00000000..c00493a3 --- /dev/null +++ b/app/Filter/ProjectUserRoleUsernameFilter.php @@ -0,0 +1,41 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\User; + +/** + * Filter ProjectUserRole users by username + * + * @package filter + * @author Frederic Guillot + */ +class ProjectUserRoleUsernameFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array(); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query + ->join(User::TABLE, 'id', 'user_id') + ->ilike(User::TABLE.'.username', $this->value.'%'); + + return $this; + } +} diff --git a/app/Filter/TaskAssigneeFilter.php b/app/Filter/TaskAssigneeFilter.php new file mode 100644 index 00000000..783d6a12 --- /dev/null +++ b/app/Filter/TaskAssigneeFilter.php @@ -0,0 +1,75 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; +use Kanboard\Model\User; + +/** + * Filter tasks by assignee + * + * @package filter + * @author Frederic Guillot + */ +class TaskAssigneeFilter extends BaseFilter implements FilterInterface +{ + /** + * Current user id + * + * @access private + * @var int + */ + private $currentUserId = 0; + + /** + * Set current user id + * + * @access public + * @param integer $userId + * @return TaskAssigneeFilter + */ + public function setCurrentUserId($userId) + { + $this->currentUserId = $userId; + return $this; + } + + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('assignee'); + } + + /** + * Apply filter + * + * @access public + * @return string + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Task::TABLE.'.owner_id', $this->value); + } else { + switch ($this->value) { + case 'me': + $this->query->eq(Task::TABLE.'.owner_id', $this->currentUserId); + break; + case 'nobody': + $this->query->eq(Task::TABLE.'.owner_id', 0); + break; + default: + $this->query->beginOr(); + $this->query->ilike(User::TABLE.'.username', '%'.$this->value.'%'); + $this->query->ilike(User::TABLE.'.name', '%'.$this->value.'%'); + $this->query->closeOr(); + } + } + } +} diff --git a/app/Filter/TaskCategoryFilter.php b/app/Filter/TaskCategoryFilter.php new file mode 100644 index 00000000..517f24d9 --- /dev/null +++ b/app/Filter/TaskCategoryFilter.php @@ -0,0 +1,46 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Category; +use Kanboard\Model\Task; + +/** + * Filter tasks by category + * + * @package filter + * @author Frederic Guillot + */ +class TaskCategoryFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('category'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Task::TABLE.'.category_id', $this->value); + } elseif ($this->value === 'none') { + $this->query->eq(Task::TABLE.'.category_id', 0); + } else { + $this->query->eq(Category::TABLE.'.name', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/TaskColorFilter.php b/app/Filter/TaskColorFilter.php new file mode 100644 index 00000000..784162d4 --- /dev/null +++ b/app/Filter/TaskColorFilter.php @@ -0,0 +1,60 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Color; +use Kanboard\Model\Task; + +/** + * Filter tasks by color + * + * @package filter + * @author Frederic Guillot + */ +class TaskColorFilter extends BaseFilter implements FilterInterface +{ + /** + * Color object + * + * @access private + * @var Color + */ + private $colorModel; + + /** + * Set color model object + * + * @access public + * @param Color $colorModel + * @return TaskColorFilter + */ + public function setColorModel(Color $colorModel) + { + $this->colorModel = $colorModel; + return $this; + } + + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('color', 'colour'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(Task::TABLE.'.color_id', $this->colorModel->find($this->value)); + return $this; + } +} diff --git a/app/Filter/TaskColumnFilter.php b/app/Filter/TaskColumnFilter.php new file mode 100644 index 00000000..9a4d4253 --- /dev/null +++ b/app/Filter/TaskColumnFilter.php @@ -0,0 +1,44 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Column; +use Kanboard\Model\Task; + +/** + * Filter tasks by column + * + * @package filter + * @author Frederic Guillot + */ +class TaskColumnFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('column'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Task::TABLE.'.column_id', $this->value); + } else { + $this->query->eq(Column::TABLE.'.title', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/TaskCompletionDateFilter.php b/app/Filter/TaskCompletionDateFilter.php new file mode 100644 index 00000000..5166bebf --- /dev/null +++ b/app/Filter/TaskCompletionDateFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by completion date + * + * @package filter + * @author Frederic Guillot + */ +class TaskCompletionDateFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('completed'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->applyDateFilter(Task::TABLE.'.date_completed'); + return $this; + } +} diff --git a/app/Filter/TaskCreationDateFilter.php b/app/Filter/TaskCreationDateFilter.php new file mode 100644 index 00000000..26318b3e --- /dev/null +++ b/app/Filter/TaskCreationDateFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by creation date + * + * @package filter + * @author Frederic Guillot + */ +class TaskCreationDateFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('created'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->applyDateFilter(Task::TABLE.'.date_creation'); + return $this; + } +} diff --git a/app/Filter/TaskDescriptionFilter.php b/app/Filter/TaskDescriptionFilter.php new file mode 100644 index 00000000..6dda58ae --- /dev/null +++ b/app/Filter/TaskDescriptionFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by description + * + * @package filter + * @author Frederic Guillot + */ +class TaskDescriptionFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('description', 'desc'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->ilike(Task::TABLE.'.description', '%'.$this->value.'%'); + return $this; + } +} diff --git a/app/Filter/TaskDueDateFilter.php b/app/Filter/TaskDueDateFilter.php new file mode 100644 index 00000000..6ba55eb9 --- /dev/null +++ b/app/Filter/TaskDueDateFilter.php @@ -0,0 +1,41 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by due date + * + * @package filter + * @author Frederic Guillot + */ +class TaskDueDateFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('due'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->neq(Task::TABLE.'.date_due', 0); + $this->query->notNull(Task::TABLE.'.date_due'); + $this->applyDateFilter(Task::TABLE.'.date_due'); + + return $this; + } +} diff --git a/app/Filter/TaskDueDateRangeFilter.php b/app/Filter/TaskDueDateRangeFilter.php new file mode 100644 index 00000000..10deb0d3 --- /dev/null +++ b/app/Filter/TaskDueDateRangeFilter.php @@ -0,0 +1,39 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by due date range + * + * @package filter + * @author Frederic Guillot + */ +class TaskDueDateRangeFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array(); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->gte(Task::TABLE.'.date_due', is_numeric($this->value[0]) ? $this->value[0] : strtotime($this->value[0])); + $this->query->lte(Task::TABLE.'.date_due', is_numeric($this->value[1]) ? $this->value[1] : strtotime($this->value[1])); + return $this; + } +} diff --git a/app/Filter/TaskIdExclusionFilter.php b/app/Filter/TaskIdExclusionFilter.php new file mode 100644 index 00000000..8bfefb2b --- /dev/null +++ b/app/Filter/TaskIdExclusionFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Exclude task ids + * + * @package filter + * @author Frederic Guillot + */ +class TaskIdExclusionFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('exclude'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->notin(Task::TABLE.'.id', $this->value); + return $this; + } +} diff --git a/app/Filter/TaskIdFilter.php b/app/Filter/TaskIdFilter.php new file mode 100644 index 00000000..87bac794 --- /dev/null +++ b/app/Filter/TaskIdFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by id + * + * @package filter + * @author Frederic Guillot + */ +class TaskIdFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('id'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(Task::TABLE.'.id', $this->value); + return $this; + } +} diff --git a/app/Filter/TaskLinkFilter.php b/app/Filter/TaskLinkFilter.php new file mode 100644 index 00000000..18a13a09 --- /dev/null +++ b/app/Filter/TaskLinkFilter.php @@ -0,0 +1,85 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Link; +use Kanboard\Model\Task; +use Kanboard\Model\TaskLink; +use PicoDb\Database; +use PicoDb\Table; + +/** + * Filter tasks by link name + * + * @package filter + * @author Frederic Guillot + */ +class TaskLinkFilter extends BaseFilter implements FilterInterface +{ + /** + * Database object + * + * @access private + * @var Database + */ + private $db; + + /** + * Set database object + * + * @access public + * @param Database $db + * @return TaskLinkFilter + */ + public function setDatabase(Database $db) + { + $this->db = $db; + return $this; + } + + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('link'); + } + + /** + * Apply filter + * + * @access public + * @return string + */ + public function apply() + { + $task_ids = $this->getSubQuery()->findAllByColumn('task_id'); + + if (! empty($task_ids)) { + $this->query->in(Task::TABLE.'.id', $task_ids); + } else { + $this->query->eq(Task::TABLE.'.id', 0); // No match + } + } + + /** + * Get subquery + * + * @access protected + * @return Table + */ + protected function getSubQuery() + { + return $this->db->table(TaskLink::TABLE) + ->columns( + TaskLink::TABLE.'.task_id', + Link::TABLE.'.label' + ) + ->join(Link::TABLE, 'id', 'link_id', TaskLink::TABLE) + ->ilike(Link::TABLE.'.label', $this->value); + } +} diff --git a/app/Filter/TaskModificationDateFilter.php b/app/Filter/TaskModificationDateFilter.php new file mode 100644 index 00000000..d8838bce --- /dev/null +++ b/app/Filter/TaskModificationDateFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by modification date + * + * @package filter + * @author Frederic Guillot + */ +class TaskModificationDateFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('updated', 'modified'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->applyDateFilter(Task::TABLE.'.date_modification'); + return $this; + } +} diff --git a/app/Filter/TaskProjectFilter.php b/app/Filter/TaskProjectFilter.php new file mode 100644 index 00000000..e432efee --- /dev/null +++ b/app/Filter/TaskProjectFilter.php @@ -0,0 +1,44 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Project; +use Kanboard\Model\Task; + +/** + * Filter tasks by project + * + * @package filter + * @author Frederic Guillot + */ +class TaskProjectFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('project'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Task::TABLE.'.project_id', $this->value); + } else { + $this->query->ilike(Project::TABLE.'.name', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/TaskProjectsFilter.php b/app/Filter/TaskProjectsFilter.php new file mode 100644 index 00000000..e0fc09cf --- /dev/null +++ b/app/Filter/TaskProjectsFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by project ids + * + * @package filter + * @author Frederic Guillot + */ +class TaskProjectsFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('projects'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->in(Task::TABLE.'.project_id', $this->value); + return $this; + } +} diff --git a/app/Filter/TaskReferenceFilter.php b/app/Filter/TaskReferenceFilter.php new file mode 100644 index 00000000..4ad47dd5 --- /dev/null +++ b/app/Filter/TaskReferenceFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by reference + * + * @package filter + * @author Frederic Guillot + */ +class TaskReferenceFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('reference', 'ref'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->eq(Task::TABLE.'.reference', $this->value); + return $this; + } +} diff --git a/app/Filter/TaskStartDateFilter.php b/app/Filter/TaskStartDateFilter.php new file mode 100644 index 00000000..d45bc0d4 --- /dev/null +++ b/app/Filter/TaskStartDateFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by start date + * + * @package filter + * @author Frederic Guillot + */ +class TaskStartDateFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('started'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->applyDateFilter(Task::TABLE.'.date_started'); + return $this; + } +} diff --git a/app/Filter/TaskStatusFilter.php b/app/Filter/TaskStatusFilter.php new file mode 100644 index 00000000..0ba4361e --- /dev/null +++ b/app/Filter/TaskStatusFilter.php @@ -0,0 +1,43 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by status + * + * @package filter + * @author Frederic Guillot + */ +class TaskStatusFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('status'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if ($this->value === 'open' || $this->value === 'closed') { + $this->query->eq(Task::TABLE.'.is_active', $this->value === 'open' ? Task::STATUS_OPEN : Task::STATUS_CLOSED); + } else { + $this->query->eq(Task::TABLE.'.is_active', $this->value); + } + + return $this; + } +} diff --git a/app/Filter/TaskSubtaskAssigneeFilter.php b/app/Filter/TaskSubtaskAssigneeFilter.php new file mode 100644 index 00000000..4c757315 --- /dev/null +++ b/app/Filter/TaskSubtaskAssigneeFilter.php @@ -0,0 +1,140 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Subtask; +use Kanboard\Model\Task; +use Kanboard\Model\User; +use PicoDb\Database; +use PicoDb\Table; + +/** + * Filter tasks by subtasks assignee + * + * @package filter + * @author Frederic Guillot + */ +class TaskSubtaskAssigneeFilter extends BaseFilter implements FilterInterface +{ + /** + * Database object + * + * @access private + * @var Database + */ + private $db; + + /** + * Current user id + * + * @access private + * @var int + */ + private $currentUserId = 0; + + /** + * Set current user id + * + * @access public + * @param integer $userId + * @return TaskSubtaskAssigneeFilter + */ + public function setCurrentUserId($userId) + { + $this->currentUserId = $userId; + return $this; + } + + /** + * Set database object + * + * @access public + * @param Database $db + * @return TaskSubtaskAssigneeFilter + */ + public function setDatabase(Database $db) + { + $this->db = $db; + return $this; + } + + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('subtask:assignee'); + } + + /** + * Apply filter + * + * @access public + * @return string + */ + public function apply() + { + $task_ids = $this->getSubQuery()->findAllByColumn('task_id'); + + if (! empty($task_ids)) { + $this->query->in(Task::TABLE.'.id', $task_ids); + } else { + $this->query->eq(Task::TABLE.'.id', 0); // No match + } + } + + /** + * Get subquery + * + * @access protected + * @return Table + */ + protected function getSubQuery() + { + $subquery = $this->db->table(Subtask::TABLE) + ->columns( + Subtask::TABLE.'.user_id', + Subtask::TABLE.'.task_id', + User::TABLE.'.name', + User::TABLE.'.username' + ) + ->join(User::TABLE, 'id', 'user_id', Subtask::TABLE) + ->neq(Subtask::TABLE.'.status', Subtask::STATUS_DONE); + + return $this->applySubQueryFilter($subquery); + } + + /** + * Apply subquery filter + * + * @access protected + * @param Table $subquery + * @return Table + */ + protected function applySubQueryFilter(Table $subquery) + { + if (is_int($this->value) || ctype_digit($this->value)) { + $subquery->eq(Subtask::TABLE.'.user_id', $this->value); + } else { + switch ($this->value) { + case 'me': + $subquery->eq(Subtask::TABLE.'.user_id', $this->currentUserId); + break; + case 'nobody': + $subquery->eq(Subtask::TABLE.'.user_id', 0); + break; + default: + $subquery->beginOr(); + $subquery->ilike(User::TABLE.'.username', $this->value.'%'); + $subquery->ilike(User::TABLE.'.name', '%'.$this->value.'%'); + $subquery->closeOr(); + } + } + + return $subquery; + } +} diff --git a/app/Filter/TaskSwimlaneFilter.php b/app/Filter/TaskSwimlaneFilter.php new file mode 100644 index 00000000..4e030244 --- /dev/null +++ b/app/Filter/TaskSwimlaneFilter.php @@ -0,0 +1,50 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Project; +use Kanboard\Model\Swimlane; +use Kanboard\Model\Task; + +/** + * Filter tasks by swimlane + * + * @package filter + * @author Frederic Guillot + */ +class TaskSwimlaneFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('swimlane'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (is_int($this->value) || ctype_digit($this->value)) { + $this->query->eq(Task::TABLE.'.swimlane_id', $this->value); + } elseif ($this->value === 'default') { + $this->query->eq(Task::TABLE.'.swimlane_id', 0); + } else { + $this->query->beginOr(); + $this->query->ilike(Swimlane::TABLE.'.name', $this->value); + $this->query->ilike(Project::TABLE.'.default_swimlane', $this->value); + $this->query->closeOr(); + } + + return $this; + } +} diff --git a/app/Filter/TaskTitleFilter.php b/app/Filter/TaskTitleFilter.php new file mode 100644 index 00000000..9853369c --- /dev/null +++ b/app/Filter/TaskTitleFilter.php @@ -0,0 +1,46 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; +use Kanboard\Model\Task; + +/** + * Filter tasks by title + * + * @package filter + * @author Frederic Guillot + */ +class TaskTitleFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('title'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + if (ctype_digit($this->value) || (strlen($this->value) > 1 && $this->value{0} === '#' && ctype_digit(substr($this->value, 1)))) { + $this->query->beginOr(); + $this->query->eq(Task::TABLE.'.id', str_replace('#', '', $this->value)); + $this->query->ilike(Task::TABLE.'.title', '%'.$this->value.'%'); + $this->query->closeOr(); + } else { + $this->query->ilike(Task::TABLE.'.title', '%'.$this->value.'%'); + } + + return $this; + } +} diff --git a/app/Filter/UserNameFilter.php b/app/Filter/UserNameFilter.php new file mode 100644 index 00000000..dfb07fdd --- /dev/null +++ b/app/Filter/UserNameFilter.php @@ -0,0 +1,35 @@ +<?php + +namespace Kanboard\Filter; + +use Kanboard\Core\Filter\FilterInterface; + +class UserNameFilter extends BaseFilter implements FilterInterface +{ + /** + * Get search attribute + * + * @access public + * @return string[] + */ + public function getAttributes() + { + return array('name'); + } + + /** + * Apply filter + * + * @access public + * @return FilterInterface + */ + public function apply() + { + $this->query->beginOr() + ->ilike('username', '%'.$this->value.'%') + ->ilike('name', '%'.$this->value.'%') + ->closeOr(); + + return $this; + } +} |