diff options
author | Frederic Guillot <fred@kanboard.net> | 2015-09-20 22:18:56 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2015-09-20 22:18:56 -0400 |
commit | 689687dd4ee186cb9cf5d0230b4648e242c53b10 (patch) | |
tree | 3d26bc2079c6eb45790ba604b3a79997be4768ab /app/Formatter | |
parent | f579663adcbc0b202d9a068d734e8f9284dc3a37 (diff) |
Add formatters
Diffstat (limited to 'app/Formatter')
-rw-r--r-- | app/Formatter/FormatterInterface.php | 14 | ||||
-rw-r--r-- | app/Formatter/ProjectGanttFormatter.php | 90 | ||||
-rw-r--r-- | app/Formatter/TaskFilterAutoCompleteFormatter.php | 33 | ||||
-rw-r--r-- | app/Formatter/TaskFilterCalendarEvent.php | 76 | ||||
-rw-r--r-- | app/Formatter/TaskFilterCalendarFormatter.php | 52 | ||||
-rw-r--r-- | app/Formatter/TaskFilterGanttFormatter.php | 78 | ||||
-rw-r--r-- | app/Formatter/TaskFilterICalendarFormatter.php | 135 |
7 files changed, 478 insertions, 0 deletions
diff --git a/app/Formatter/FormatterInterface.php b/app/Formatter/FormatterInterface.php new file mode 100644 index 00000000..4193bd4e --- /dev/null +++ b/app/Formatter/FormatterInterface.php @@ -0,0 +1,14 @@ +<?php + +namespace Formatter; + +/** + * Formatter Interface + * + * @package formatter + * @author Frederic Guillot + */ +interface FormatterInterface +{ + public function format(); +} diff --git a/app/Formatter/ProjectGanttFormatter.php b/app/Formatter/ProjectGanttFormatter.php new file mode 100644 index 00000000..652b947d --- /dev/null +++ b/app/Formatter/ProjectGanttFormatter.php @@ -0,0 +1,90 @@ +<?php + +namespace Formatter; + +use Model\Project; + +/** + * Gantt chart formatter for projects + * + * @package formatter + * @author Frederic Guillot + */ +class ProjectGanttFormatter extends Project implements FormatterInterface +{ + /** + * List of projects + * + * @access private + * @var array + */ + private $projects = array(); + + /** + * Filter projects to generate the Gantt chart + * + * @access public + * @param int[] $project_ids + * @return ProjectGanttFormatter + */ + public function filter(array $project_ids) + { + if (empty($project_ids)) { + $this->projects = array(); + } + else { + + $this->projects = $this->db + ->table(self::TABLE) + ->asc('start_date') + ->in('id', $project_ids) + ->eq('is_active', self::ACTIVE) + ->eq('is_private', 0) + ->findAll(); + } + + return $this; + } + + /** + * Format projects to be displayed in the Gantt chart + * + * @access public + * @return array + */ + public function format() + { + $colors = $this->color->getDefaultColors(); + $bars = array(); + + foreach ($this->projects as $project) { + $start = empty($project['start_date']) ? time() : strtotime($project['start_date']); + $end = empty($project['end_date']) ? $start : strtotime($project['end_date']); + $color = next($colors) ?: reset($colors); + + $bars[] = array( + 'type' => 'project', + 'id' => $project['id'], + 'title' => $project['name'], + 'start' => array( + (int) date('Y', $start), + (int) date('n', $start), + (int) date('j', $start), + ), + 'end' => array( + (int) date('Y', $end), + (int) date('n', $end), + (int) date('j', $end), + ), + 'link' => $this->helper->url->href('project', 'show', array('project_id' => $project['id'])), + 'board_link' => $this->helper->url->href('board', 'show', array('project_id' => $project['id'])), + 'gantt_link' => $this->helper->url->href('gantt', 'project', array('project_id' => $project['id'])), + 'color' => $color, + 'not_defined' => empty($project['start_date']) || empty($project['end_date']), + 'users' => $this->projectPermission->getProjectUsers($project['id']), + ); + } + + return $bars; + } +} diff --git a/app/Formatter/TaskFilterAutoCompleteFormatter.php b/app/Formatter/TaskFilterAutoCompleteFormatter.php new file mode 100644 index 00000000..999a8949 --- /dev/null +++ b/app/Formatter/TaskFilterAutoCompleteFormatter.php @@ -0,0 +1,33 @@ +<?php + +namespace Formatter; + +use Model\Task; +use Model\TaskFilter; + +/** + * Autocomplete formatter for task filter + * + * @package formatter + * @author Frederic Guillot + */ +class TaskFilterAutoCompleteFormatter extends TaskFilter implements FormatterInterface +{ + /** + * Format the tasks for the ajax autocompletion + * + * @access public + * @return array + */ + public function format() + { + $tasks = $this->query->columns(Task::TABLE.'.id', Task::TABLE.'.title')->findAll(); + + foreach ($tasks as &$task) { + $task['value'] = $task['title']; + $task['label'] = '#'.$task['id'].' - '.$task['title']; + } + + return $tasks; + } +} diff --git a/app/Formatter/TaskFilterCalendarEvent.php b/app/Formatter/TaskFilterCalendarEvent.php new file mode 100644 index 00000000..8733ee83 --- /dev/null +++ b/app/Formatter/TaskFilterCalendarEvent.php @@ -0,0 +1,76 @@ +<?php + +namespace Formatter; + +use Model\TaskFilter; + +/** + * Common class to handle calendar events + * + * @package formatter + * @author Frederic Guillot + */ +abstract class TaskFilterCalendarEvent extends TaskFilter +{ + /** + * Column used for event start date + * + * @access protected + * @var string + */ + protected $startColumn = 'date_started'; + + /** + * Column used for event end date + * + * @access protected + * @var string + */ + protected $endColumn = 'date_completed'; + + /** + * Full day event flag + * + * @access private + * @var boolean + */ + private $fullDay = false; + + /** + * 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 TaskFilterCalendarEvent + */ + public function setColumns($start_column, $end_column = '') + { + $this->startColumn = $start_column; + $this->endColumn = $end_column ?: $start_column; + return $this; + } + + /** + * When called calendar events will be full day + * + * @access public + * @return TaskFilterCalendarEvent + */ + public function setFullDay() + { + $this->fullDay = true; + return $this; + } + + /** + * Return true if the events are full day + * + * @access public + * @return boolean + */ + public function isFullDay() + { + return $this->fullDay; + } +} diff --git a/app/Formatter/TaskFilterCalendarFormatter.php b/app/Formatter/TaskFilterCalendarFormatter.php new file mode 100644 index 00000000..f3f42b97 --- /dev/null +++ b/app/Formatter/TaskFilterCalendarFormatter.php @@ -0,0 +1,52 @@ +<?php + +namespace Formatter; + +/** + * Calendar event formatter for task filter + * + * @package formatter + * @author Frederic Guillot + */ +class TaskFilterCalendarFormatter extends TaskFilterCalendarEvent implements FormatterInterface +{ + /** + * Transform tasks to calendar events + * + * @access public + * @return array + */ + public function format() + { + $events = array(); + + foreach ($this->query->findAll() as $task) { + $events[] = 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->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), + 'start' => date($this->getDateTimeFormat(), $task[$this->startColumn]), + 'end' => date($this->getDateTimeFormat(), $task[$this->endColumn] ?: time()), + 'editable' => $this->isFullDay(), + 'allday' => $this->isFullDay(), + ); + } + + return $events; + } + + /** + * Get DateTime format for event + * + * @access private + * @return string + */ + private function getDateTimeFormat() + { + return $this->isFullDay() ? 'Y-m-d' : 'Y-m-d\TH:i:s'; + } +} diff --git a/app/Formatter/TaskFilterGanttFormatter.php b/app/Formatter/TaskFilterGanttFormatter.php new file mode 100644 index 00000000..069daa3d --- /dev/null +++ b/app/Formatter/TaskFilterGanttFormatter.php @@ -0,0 +1,78 @@ +<?php + +namespace Formatter; + +use Model\TaskFilter; + +/** + * Gantt chart formatter for task filter + * + * @package formatter + * @author Frederic Guillot + */ +class TaskFilterGanttFormatter extends TaskFilter implements FormatterInterface +{ + /** + * Local cache for project columns + * + * @access private + * @var array + */ + private $columns = array(); + + /** + * Format tasks to be displayed in the Gantt chart + * + * @access public + * @return array + */ + public function format() + { + $bars = array(); + + foreach ($this->query->findAll() as $task) { + $bars[] = $this->formatTask($task); + } + + return $bars; + } + + /** + * Format a single task + * + * @access private + * @param array $task + * @return array + */ + private function formatTask(array $task) + { + if (! isset($this->columns[$task['project_id']])) { + $this->columns[$task['project_id']] = $this->board->getColumnsList($task['project_id']); + } + + $start = $task['date_started'] ?: time(); + $end = $task['date_due'] ?: $start; + + return array( + 'type' => 'task', + 'id' => $task['id'], + 'title' => $task['title'], + 'start' => array( + (int) date('Y', $start), + (int) date('n', $start), + (int) date('j', $start), + ), + 'end' => array( + (int) date('Y', $end), + (int) date('n', $end), + (int) date('j', $end), + ), + 'column_title' => $task['column_name'], + 'assignee' => $task['assignee_name'] ?: $task['assignee_username'], + 'progress' => $this->task->getProgress($task, $this->columns[$task['project_id']]).'%', + 'link' => $this->helper->url->href('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), + 'color' => $this->color->getColorProperties($task['color_id']), + 'not_defined' => empty($task['date_due']) || empty($task['date_started']), + ); + } +} diff --git a/app/Formatter/TaskFilterICalendarFormatter.php b/app/Formatter/TaskFilterICalendarFormatter.php new file mode 100644 index 00000000..8aed1e20 --- /dev/null +++ b/app/Formatter/TaskFilterICalendarFormatter.php @@ -0,0 +1,135 @@ +<?php + +namespace Formatter; + +use DateTime; +use Eluceo\iCal\Component\Calendar; +use Eluceo\iCal\Component\Event; +use Eluceo\iCal\Property\Event\Attendees; + +/** + * iCal event formatter for task filter + * + * @package formatter + * @author Frederic Guillot + */ +class TaskFilterICalendarFormatter extends TaskFilterCalendarEvent implements FormatterInterface +{ + /** + * Calendar object + * + * @access private + * @var \Eluceo\iCal\Component\Calendar + */ + private $vCalendar; + + /** + * Get Ical events + * + * @access public + * @return string + */ + public function format() + { + return $this->vCalendar->render(); + } + + /** + * Set calendar object + * + * @access public + * @param \Eluceo\iCal\Component\Calendar $vCalendar + * @return TaskFilterICalendarFormatter + */ + public function setCalendar(Calendar $vCalendar) + { + $this->vCalendar = $vCalendar; + return $this; + } + + /** + * Transform results to ical events + * + * @access public + * @return TaskFilterICalendarFormatter + */ + public function addDateTimeEvents() + { + foreach ($this->query->findAll() as $task) { + + $start = new DateTime; + $start->setTimestamp($task[$this->startColumn]); + + $end = new DateTime; + $end->setTimestamp($task[$this->endColumn] ?: time()); + + $vEvent = $this->getTaskIcalEvent($task, 'task-#'.$task['id'].'-'.$this->startColumn.'-'.$this->endColumn); + $vEvent->setDtStart($start); + $vEvent->setDtEnd($end); + + $this->vCalendar->addComponent($vEvent); + } + + return $this; + } + + /** + * Transform results to all day ical events + * + * @access public + * @return TaskFilterICalendarFormatter + */ + public function addFullDayEvents() + { + foreach ($this->query->findAll() as $task) { + + $date = new DateTime; + $date->setTimestamp($task[$this->startColumn]); + + $vEvent = $this->getTaskIcalEvent($task, 'task-#'.$task['id'].'-'.$this->startColumn); + $vEvent->setDtStart($date); + $vEvent->setDtEnd($date); + $vEvent->setNoTime(true); + + $this->vCalendar->addComponent($vEvent); + } + + return $this; + } + + /** + * Get common events for task ical events + * + * @access protected + * @param array $task + * @param string $uid + * @return Event + */ + protected function getTaskIcalEvent(array &$task, $uid) + { + $dateCreation = new DateTime; + $dateCreation->setTimestamp($task['date_creation']); + + $dateModif = new DateTime; + $dateModif->setTimestamp($task['date_modification']); + + $vEvent = new Event($uid); + $vEvent->setCreated($dateCreation); + $vEvent->setModified($dateModif); + $vEvent->setUseTimezone(true); + $vEvent->setSummary(t('#%d', $task['id']).' '.$task['title']); + $vEvent->setUrl($this->helper->url->base().$this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); + + if (! empty($task['owner_id'])) { + $vEvent->setOrganizer($task['assignee_name'] ?: $task['assignee_username'], $task['assignee_email']); + } + + if (! empty($task['creator_id'])) { + $attendees = new Attendees; + $attendees->add('MAILTO:'.($task['creator_email'] ?: $task['creator_username'].'@kanboard.local')); + $vEvent->setAttendees($attendees); + } + + return $vEvent; + } +} |