Add project calendars (merge/refactoring of #490)
This commit is contained in:
@@ -37,6 +37,7 @@ class Acl extends Base
|
||||
'project' => array('show', 'tasks', 'search', 'activity'),
|
||||
'subtask' => '*',
|
||||
'task' => '*',
|
||||
'calendar' => '*',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -258,16 +258,19 @@ class Board extends Base
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @param boolean $prepend Prepend default value
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnStats($project_id)
|
||||
public function getColumnStats($project_id, $prepend = false)
|
||||
{
|
||||
return $this->db
|
||||
->table(Task::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', 1)
|
||||
->groupBy('column_id')
|
||||
->listing('column_id', 'COUNT(*) AS total');
|
||||
$listing = $this->db
|
||||
->table(Task::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', 1)
|
||||
->groupBy('column_id')
|
||||
->listing('column_id', 'COUNT(*) AS total');
|
||||
|
||||
return $prepend ? array(-1 => t('All columns')) + $listing : $listing;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,11 +290,13 @@ class Board extends Base
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param boolean $prepend Prepend a default value
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnsList($project_id)
|
||||
public function getColumnsList($project_id, $prepend = false)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->listing('id', 'title');
|
||||
$listing = $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->listing('id', 'title');
|
||||
return $prepend ? array(-1 => t('All columns')) + $listing : $listing;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,22 +3,68 @@
|
||||
namespace Model;
|
||||
|
||||
/**
|
||||
* Color model (TODO: model for the future color picker)
|
||||
* Color model
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Color extends Base
|
||||
{
|
||||
/**
|
||||
* Default colors
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $default_colors = array(
|
||||
'yellow' => array(
|
||||
'name' => 'Yellow',
|
||||
'background' => 'rgb(245, 247, 196)',
|
||||
'border' => 'rgb(223, 227, 45)',
|
||||
),
|
||||
'blue' => array(
|
||||
'name' => 'Blue',
|
||||
'background' => 'rgb(219, 235, 255)',
|
||||
'border' => 'rgb(168, 207, 255)',
|
||||
),
|
||||
'green' => array(
|
||||
'name' => 'Green',
|
||||
'background' => 'rgb(189, 244, 203)',
|
||||
'border' => 'rgb(74, 227, 113)',
|
||||
),
|
||||
'purple' => array(
|
||||
'name' => 'Purple',
|
||||
'background' => 'rgb(223, 176, 255)',
|
||||
'border' => 'rgb(205, 133, 254)',
|
||||
),
|
||||
'red' => array(
|
||||
'name' => 'Red',
|
||||
'background' => 'rgb(255, 187, 187)',
|
||||
'border' => 'rgb(255, 151, 151)',
|
||||
),
|
||||
'orange' => array(
|
||||
'name' => 'Orange',
|
||||
'background' => 'rgb(255, 215, 179)',
|
||||
'border' => 'rgb(255, 172, 98)',
|
||||
),
|
||||
'grey' => array(
|
||||
'name' => 'Grey',
|
||||
'background' => 'rgb(238, 238, 238)',
|
||||
'border' => 'rgb(204, 204, 204)',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Get available colors
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getList()
|
||||
public function getList($prepend = false)
|
||||
{
|
||||
return array(
|
||||
$listing = $prepend ? array('' => t('All colors')) : array();
|
||||
|
||||
return $listing + array(
|
||||
'yellow' => t('Yellow'),
|
||||
'blue' => t('Blue'),
|
||||
'green' => t('Green'),
|
||||
@@ -39,4 +85,57 @@ class Color extends Base
|
||||
{
|
||||
return 'yellow'; // TODO: make this parameter configurable
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Bordercolor from string
|
||||
*
|
||||
* @access public
|
||||
* @param string $color_id Color id
|
||||
* @return string
|
||||
*/
|
||||
public function getBorderColor($color_id)
|
||||
{
|
||||
if (isset($this->default_colors[$color_id])) {
|
||||
return $this->default_colors[$color_id]['border'];
|
||||
}
|
||||
|
||||
return $this->default_colors[$this->getDefaultColor()]['border'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get background color from the color_id
|
||||
*
|
||||
* @access public
|
||||
* @param string $color_id Color id
|
||||
* @return string
|
||||
*/
|
||||
public function getBackgroundColor($color_id)
|
||||
{
|
||||
if (isset($this->default_colors[$color_id])) {
|
||||
return $this->default_colors[$color_id]['background'];
|
||||
}
|
||||
|
||||
return $this->default_colors[$this->getDefaultColor()]['background'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS stylesheet of all colors
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getCss()
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
foreach ($this->default_colors as $color => $values) {
|
||||
$buffer .= 'td.color-'.$color.',';
|
||||
$buffer .= 'div.color-'.$color.' {';
|
||||
$buffer .= 'background-color: '.$values['background'].';';
|
||||
$buffer .= 'border-color: '.$values['border'];
|
||||
$buffer .= '}';
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,18 @@ class DateParser extends Base
|
||||
return mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a timetstamp from an ISO date format
|
||||
*
|
||||
* @access public
|
||||
* @param string $date Date format
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimestampFromIsoFormat($date)
|
||||
{
|
||||
return $this->resetDateToMidnight(strtotime($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date (form display)
|
||||
*
|
||||
|
||||
@@ -161,20 +161,20 @@ class Swimlane extends Base
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @param boolean $prepend Prepend default value
|
||||
* @return array
|
||||
*/
|
||||
public function getSwimlanesList($project_id)
|
||||
public function getList($project_id, $prepend = false)
|
||||
{
|
||||
$swimlanes = $this->db->table(self::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->orderBy('position', 'asc')
|
||||
->listing('id', 'name');
|
||||
$swimlanes = array();
|
||||
$swimlanes[] = $this->db->table(Project::TABLE)->eq('id', $project_id)->findOneColumn('default_swimlane');
|
||||
|
||||
$swimlanes[0] = $this->db->table(Project::TABLE)
|
||||
->eq('id', $project_id)
|
||||
->findOneColumn('default_swimlane');
|
||||
$swimlanes = array_merge(
|
||||
$swimlanes,
|
||||
$this->db->table(self::TABLE)->eq('project_id', $project_id)->orderBy('name', 'asc')->listing('id', 'name')
|
||||
);
|
||||
|
||||
return $swimlanes;
|
||||
return $prepend ? array(-1 => t('All swimlanes')) + $swimlanes : $swimlanes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ class TaskExport extends Base
|
||||
public function export($project_id, $from, $to)
|
||||
{
|
||||
$tasks = $this->getTasks($project_id, $from, $to);
|
||||
$swimlanes = $this->swimlane->getSwimlanesList($project_id);
|
||||
$swimlanes = $this->swimlane->getList($project_id);
|
||||
$results = array($this->getColumns());
|
||||
|
||||
foreach ($tasks as &$task) {
|
||||
|
||||
117
app/Model/TaskFilter.php
Normal file
117
app/Model/TaskFilter.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
/**
|
||||
* Task Filter
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFilter extends Base
|
||||
{
|
||||
private $query;
|
||||
|
||||
public function create()
|
||||
{
|
||||
$this->query = $this->db->table(Task::TABLE);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByProject($project_id)
|
||||
{
|
||||
if ($project_id > 0) {
|
||||
$this->query->eq('project_id', $project_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByCategory($category_id)
|
||||
{
|
||||
if ($category_id >= 0) {
|
||||
$this->query->eq('category_id', $category_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByOwner($owner_id)
|
||||
{
|
||||
if ($owner_id >= 0) {
|
||||
$this->query->eq('owner_id', $owner_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByColor($color_id)
|
||||
{
|
||||
if ($color_id !== '') {
|
||||
$this->query->eq('color_id', $color_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByColumn($column_id)
|
||||
{
|
||||
if ($column_id >= 0) {
|
||||
$this->query->eq('column_id', $column_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterBySwimlane($swimlane_id)
|
||||
{
|
||||
if ($swimlane_id >= 0) {
|
||||
$this->query->eq('swimlane_id', $swimlane_id);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByStatus($is_active)
|
||||
{
|
||||
if ($is_active >= 0) {
|
||||
$this->query->eq('is_active', $is_active);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByDueDateRange($start, $end)
|
||||
{
|
||||
$this->query->gte('date_due', $this->dateParser->getTimestampFromIsoFormat($start));
|
||||
$this->query->lte('date_due', $this->dateParser->getTimestampFromIsoFormat($end));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function findAll()
|
||||
{
|
||||
return $this->query->findAll();
|
||||
}
|
||||
|
||||
public function toCalendarEvents()
|
||||
{
|
||||
$events = array();
|
||||
|
||||
foreach ($this->query->findAll() as $task) {
|
||||
$events[] = array(
|
||||
'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'])),
|
||||
);
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,23 @@ use Event\TaskEvent;
|
||||
*/
|
||||
class TaskStatus extends Base
|
||||
{
|
||||
/**
|
||||
* Return the list of statuses
|
||||
*
|
||||
* @access public
|
||||
* @param boolean $prepend Prepend default value
|
||||
* @return array
|
||||
*/
|
||||
public function getList($prepend = false)
|
||||
{
|
||||
$listing = $prepend ? array(-1 => t('All status')) : array();
|
||||
|
||||
return $listing + array(
|
||||
Task::STATUS_OPEN => t('Open'),
|
||||
Task::STATUS_CLOSED => t('Closed'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the task is closed
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user