Add formatters
This commit is contained in:
14
app/Formatter/FormatterInterface.php
Normal file
14
app/Formatter/FormatterInterface.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Formatter;
|
||||
|
||||
/**
|
||||
* Formatter Interface
|
||||
*
|
||||
* @package formatter
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
public function format();
|
||||
}
|
||||
90
app/Formatter/ProjectGanttFormatter.php
Normal file
90
app/Formatter/ProjectGanttFormatter.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
33
app/Formatter/TaskFilterAutoCompleteFormatter.php
Normal file
33
app/Formatter/TaskFilterAutoCompleteFormatter.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
76
app/Formatter/TaskFilterCalendarEvent.php
Normal file
76
app/Formatter/TaskFilterCalendarEvent.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
52
app/Formatter/TaskFilterCalendarFormatter.php
Normal file
52
app/Formatter/TaskFilterCalendarFormatter.php
Normal file
@@ -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';
|
||||
}
|
||||
}
|
||||
78
app/Formatter/TaskFilterGanttFormatter.php
Normal file
78
app/Formatter/TaskFilterGanttFormatter.php
Normal file
@@ -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']),
|
||||
);
|
||||
}
|
||||
}
|
||||
135
app/Formatter/TaskFilterICalendarFormatter.php
Normal file
135
app/Formatter/TaskFilterICalendarFormatter.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user