summaryrefslogtreecommitdiff
path: root/app/Model
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-05-16 21:04:46 -0400
committerFrederic Guillot <fred@kanboard.net>2015-05-16 21:04:46 -0400
commite94a2f6a00b59a6e2b63d461794b01a2b9d07473 (patch)
tree4e097bcad8f070515dcf9a0edf1af5acef0305aa /app/Model
parentb028b3586c5022753e9ff390a042aac9f5b863f4 (diff)
Display tasks in the calendar + improve settings
Diffstat (limited to 'app/Model')
-rw-r--r--app/Model/Base.php44
-rw-r--r--app/Model/SubtaskTimeTracking.php45
-rw-r--r--app/Model/TaskFilter.php221
3 files changed, 267 insertions, 43 deletions
diff --git a/app/Model/Base.php b/app/Model/Base.php
index b4f9a9e2..dd902bb3 100644
--- a/app/Model/Base.php
+++ b/app/Model/Base.php
@@ -162,4 +162,48 @@ abstract class Base
}
}
}
+
+ /**
+ * Build SQL condition for a given time range
+ *
+ * @access protected
+ * @param string $start_time Start timestamp
+ * @param string $end_time End timestamp
+ * @param string $start_column Start column name
+ * @param string $end_column End column name
+ * @return string
+ */
+ protected function getCalendarCondition($start_time, $end_time, $start_column, $end_column)
+ {
+ $start_column = $this->db->escapeIdentifier($start_column);
+ $end_column = $this->db->escapeIdentifier($end_column);
+
+ $conditions = array(
+ "($start_column >= '$start_time' AND $start_column <= '$end_time')",
+ "($start_column <= '$start_time' AND $end_column >= '$start_time')",
+ "($start_column <= '$start_time' AND ($end_column = '0' OR $end_column IS NULL))",
+ );
+
+ return '('.implode(' OR ', $conditions).')';
+ }
+
+ /**
+ * Get common properties for task calendar events
+ *
+ * @access protected
+ * @param array $task
+ * @return array
+ */
+ protected function getTaskCalendarProperties(array &$task)
+ {
+ return array(
+ 'timezoneParam' => $this->config->getCurrentTimezone(),
+ 'id' => $task['id'],
+ 'title' => t('#%d', $task['id']).' '.$task['title'],
+ 'backgroundColor' => $this->color->getBackgroundColor($task['color_id']),
+ 'borderColor' => $this->color->getBorderColor($task['color_id']),
+ 'textColor' => 'black',
+ 'url' => $this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])),
+ );
+ }
}
diff --git a/app/Model/SubtaskTimeTracking.php b/app/Model/SubtaskTimeTracking.php
index a984533f..6d4a3467 100644
--- a/app/Model/SubtaskTimeTracking.php
+++ b/app/Model/SubtaskTimeTracking.php
@@ -135,8 +135,13 @@ class SubtaskTimeTracking extends Base
public function getUserCalendarEvents($user_id, $start, $end)
{
$result = $this->getUserQuery($user_id)
- ->addCondition($this->getCalendarCondition($start, $end))
- ->findAll();
+ ->addCondition($this->getCalendarCondition(
+ $this->dateParser->getTimestampFromIsoFormat($start),
+ $this->dateParser->getTimestampFromIsoFormat($end),
+ 'start',
+ 'end'
+ ))
+ ->findAll();
$result = $this->timetable->calculateEventsIntersect($user_id, $result, $start, $end);
@@ -154,38 +159,20 @@ class SubtaskTimeTracking extends Base
*/
public function getProjectCalendarEvents($project_id, $start, $end)
{
- $result = $this->getProjectQuery($project_id)
- ->addCondition($this->getCalendarCondition($start, $end))
- ->findAll();
+ $result = $this
+ ->getProjectQuery($project_id)
+ ->addCondition($this->getCalendarCondition(
+ $this->dateParser->getTimestampFromIsoFormat($start),
+ $this->dateParser->getTimestampFromIsoFormat($end),
+ 'start',
+ 'end'
+ ))
+ ->findAll();
return $this->toCalendarEvents($result);
}
/**
- * Get time slots that should be displayed in the calendar time range
- *
- * @access private
- * @param string $start ISO8601 start date
- * @param string $end ISO8601 end date
- * @return string
- */
- private function getCalendarCondition($start, $end)
- {
- $start_time = $this->dateParser->getTimestampFromIsoFormat($start);
- $end_time = $this->dateParser->getTimestampFromIsoFormat($end);
- $start_column = $this->db->escapeIdentifier('start');
- $end_column = $this->db->escapeIdentifier('end');
-
- $conditions = array(
- "($start_column >= '$start_time' AND $start_column <= '$end_time')",
- "($start_column <= '$start_time' AND $end_column >= '$start_time')",
- "($start_column <= '$start_time' AND $end_column = '0')",
- );
-
- return '('.implode(' OR ', $conditions).')';
- }
-
- /**
* Convert a record set to calendar events
*
* @access private
diff --git a/app/Model/TaskFilter.php b/app/Model/TaskFilter.php
index 94f6bab0..21e77e63 100644
--- a/app/Model/TaskFilter.php
+++ b/app/Model/TaskFilter.php
@@ -10,20 +10,59 @@ namespace Model;
*/
class TaskFilter extends Base
{
- private $query;
-
+ /**
+ * Query
+ *
+ * @access public
+ * @var \PicoDb\Table
+ */
+ public $query;
+
+ /**
+ * Create a new query
+ *
+ * @access public
+ * @return TaskFilter
+ */
public function create()
{
$this->query = $this->db->table(Task::TABLE);
return $this;
}
+ /**
+ * Clone the filter
+ *
+ * @access public
+ * @return TaskFilter
+ */
+ public function copy()
+ {
+ $filter = clone($this);
+ $filter->query = clone($this->query);
+ return $filter;
+ }
+
+ /**
+ * Exclude a list of task_id
+ *
+ * @access public
+ * @param array $task_ids
+ * @return TaskFilter
+ */
public function excludeTasks(array $task_ids)
{
$this->query->notin('id', $task_ids);
return $this;
}
+ /**
+ * Filter by id
+ *
+ * @access public
+ * @param integer $task_id
+ * @return TaskFilter
+ */
public function filterById($task_id)
{
if ($task_id > 0) {
@@ -33,18 +72,39 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by title
+ *
+ * @access public
+ * @param string $title
+ * @return TaskFilter
+ */
public function filterByTitle($title)
{
$this->query->ilike('title', '%'.$title.'%');
return $this;
}
+ /**
+ * Filter by a list of project id
+ *
+ * @access public
+ * @param array $project_ids
+ * @return TaskFilter
+ */
public function filterByProjects(array $project_ids)
{
$this->query->in('project_id', $project_ids);
return $this;
}
+ /**
+ * Filter by project id
+ *
+ * @access public
+ * @param integer $project_id
+ * @return TaskFilter
+ */
public function filterByProject($project_id)
{
if ($project_id > 0) {
@@ -54,6 +114,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by category id
+ *
+ * @access public
+ * @param integer $category_id
+ * @return TaskFilter
+ */
public function filterByCategory($category_id)
{
if ($category_id >= 0) {
@@ -63,6 +130,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by assignee
+ *
+ * @access public
+ * @param integer $owner_id
+ * @return TaskFilter
+ */
public function filterByOwner($owner_id)
{
if ($owner_id >= 0) {
@@ -72,6 +146,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by color
+ *
+ * @access public
+ * @param string $color_id
+ * @return TaskFilter
+ */
public function filterByColor($color_id)
{
if ($color_id !== '') {
@@ -81,6 +162,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by column
+ *
+ * @access public
+ * @param integer $column_id
+ * @return TaskFilter
+ */
public function filterByColumn($column_id)
{
if ($column_id >= 0) {
@@ -90,6 +178,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by swimlane
+ *
+ * @access public
+ * @param integer $swimlane_id
+ * @return TaskFilter
+ */
public function filterBySwimlane($swimlane_id)
{
if ($swimlane_id >= 0) {
@@ -99,6 +194,13 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by status
+ *
+ * @access public
+ * @param integer $is_active
+ * @return TaskFilter
+ */
public function filterByStatus($is_active)
{
if ($is_active >= 0) {
@@ -108,6 +210,14 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by due date (range)
+ *
+ * @access public
+ * @param integer $start
+ * @param integer $end
+ * @return TaskFilter
+ */
public function filterByDueDateRange($start, $end)
{
$this->query->gte('date_due', $this->dateParser->getTimestampFromIsoFormat($start));
@@ -116,11 +226,63 @@ class TaskFilter extends Base
return $this;
}
+ /**
+ * Filter by start date (range)
+ *
+ * @access public
+ * @param integer $start
+ * @param integer $end
+ * @return TaskFilter
+ */
+ public function filterByStartDateRange($start, $end)
+ {
+ $this->query->addCondition($this->getCalendarCondition(
+ $this->dateParser->getTimestampFromIsoFormat($start),
+ $this->dateParser->getTimestampFromIsoFormat($end),
+ 'date_started',
+ 'date_completed'
+ ));
+
+ return $this;
+ }
+
+ /**
+ * Filter by creation date
+ *
+ * @access public
+ * @param integer $start
+ * @param integer $end
+ * @return TaskFilter
+ */
+ public function filterByCreationDateRange($start, $end)
+ {
+ $this->query->addCondition($this->getCalendarCondition(
+ $this->dateParser->getTimestampFromIsoFormat($start),
+ $this->dateParser->getTimestampFromIsoFormat($end),
+ 'date_creation',
+ 'date_completed'
+ ));
+
+ return $this;
+ }
+
+ /**
+ * Get all results of the filter
+ *
+ * @access public
+ * @return array
+ */
public function findAll()
{
return $this->query->findAll();
}
+ /**
+ * Format the results to the ajax autocompletion
+ *
+ * @access public
+ * @return array
+ */
public function toAutoCompletion()
{
return $this->query->columns('id', 'title')->filter(function(array $results) {
@@ -135,22 +297,53 @@ class TaskFilter extends Base
})->findAll();
}
- public function toCalendarEvents()
+ /**
+ * Transform results to calendar events
+ *
+ * @access public
+ * @param string $start_column Column name for the start date
+ * @param string $end_column Column name for the end date
+ * @return array
+ */
+ public function toDateTimeCalendarEvents($start_column, $end_column)
{
$events = array();
foreach ($this->query->findAll() as $task) {
- $events[] = array(
- 'timezoneParam' => $this->config->getCurrentTimezone(),
- 'id' => $task['id'],
- 'title' => t('#%d', $task['id']).' '.$task['title'],
- 'start' => date('Y-m-d', $task['date_due']),
- 'end' => date('Y-m-d', $task['date_due']),
- 'allday' => true,
- 'backgroundColor' => $this->color->getBackgroundColor($task['color_id']),
- 'borderColor' => $this->color->getBorderColor($task['color_id']),
- 'textColor' => 'black',
- 'url' => $this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])),
+
+ $events[] = array_merge(
+ $this->getTaskCalendarProperties($task),
+ array(
+ 'start' => date('Y-m-d\TH:i:s', $task[$start_column]),
+ 'end' => date('Y-m-d\TH:i:s', $task[$end_column] ?: time()),
+ 'editable' => false,
+ )
+ );
+ }
+
+ return $events;
+ }
+
+ /**
+ * Transform results to all day calendar events
+ *
+ * @access public
+ * @param string $column Column name for the date
+ * @return array
+ */
+ public function toAllDayCalendarEvents($column = 'date_due')
+ {
+ $events = array();
+
+ foreach ($this->query->findAll() as $task) {
+
+ $events[] = array_merge(
+ $this->getTaskCalendarProperties($task),
+ array(
+ 'start' => date('Y-m-d', $task[$column]),
+ 'end' => date('Y-m-d', $task[$column]),
+ 'allday' => true,
+ )
);
}