看板初始化提交
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<IfVersion >= 2.3>
|
||||
Require all denied
|
||||
</IfVersion>
|
||||
<IfVersion < 2.3>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</IfVersion>
|
||||
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Event\GenericEvent;
|
||||
|
||||
/**
|
||||
* Base class for automatic actions
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class Base extends \Kanboard\Core\Base
|
||||
{
|
||||
/**
|
||||
* Extended events
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $compatibleEvents = array();
|
||||
|
||||
/**
|
||||
* Keep history of executed events
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $callStack = [];
|
||||
|
||||
/**
|
||||
* Project id
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $projectId = 0;
|
||||
|
||||
/**
|
||||
* User parameters
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $params = array();
|
||||
|
||||
/**
|
||||
* Get automatic action name
|
||||
*
|
||||
* @final
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
final public function getName()
|
||||
{
|
||||
return '\\'.get_called_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getDescription();
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
abstract public function doAction(array $data);
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getActionRequiredParameters();
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event (check if for the event data)
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getEventRequiredParameters();
|
||||
|
||||
/**
|
||||
* Get the compatible events
|
||||
*
|
||||
* @abstract
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getCompatibleEvents();
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function hasRequiredCondition(array $data);
|
||||
|
||||
/**
|
||||
* Return class information
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$params = array();
|
||||
|
||||
foreach ($this->params as $key => $value) {
|
||||
$params[] = $key.'='.var_export($value, true);
|
||||
}
|
||||
|
||||
return $this->getName().'('.implode('|', $params).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set project id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @return Base
|
||||
*/
|
||||
public function setProjectId($project_id)
|
||||
{
|
||||
$this->projectId = $project_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project id
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId()
|
||||
{
|
||||
return $this->projectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an user defined parameter
|
||||
*
|
||||
* @access public
|
||||
* @param string $name Parameter name
|
||||
* @param mixed $value Value
|
||||
* @return Base
|
||||
*/
|
||||
public function setParam($name, $value)
|
||||
{
|
||||
$this->params[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an user defined parameter
|
||||
*
|
||||
* @access public
|
||||
* @param string $name Parameter name
|
||||
* @param mixed $default Default value
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParam($name, $default = null)
|
||||
{
|
||||
return isset($this->params[$name]) ? $this->params[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an action is executable (right project and required parameters)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data
|
||||
* @param string $eventName
|
||||
* @return bool
|
||||
*/
|
||||
public function isExecutable(array $data, $eventName)
|
||||
{
|
||||
return $this->hasCompatibleEvent($eventName) &&
|
||||
$this->hasRequiredProject($data) &&
|
||||
$this->hasRequiredParameters($data) &&
|
||||
$this->hasRequiredCondition($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event is compatible with the action
|
||||
*
|
||||
* @access public
|
||||
* @param string $eventName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCompatibleEvent($eventName)
|
||||
{
|
||||
return in_array($eventName, $this->getEvents());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data has the required project
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredProject(array $data)
|
||||
{
|
||||
return (isset($data['project_id']) && $data['project_id'] == $this->getProjectId()) ||
|
||||
(isset($data['task']['project_id']) && $data['task']['project_id'] == $this->getProjectId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data has required parameters to execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if all keys are there
|
||||
*/
|
||||
public function hasRequiredParameters(array $data, array $parameters = array())
|
||||
{
|
||||
$parameters = $parameters ?: $this->getEventRequiredParameters();
|
||||
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
return isset($data[$key]) && $this->hasRequiredParameters($data[$key], $value);
|
||||
} elseif (! isset($data[$value])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param \Kanboard\Event\GenericEvent $event
|
||||
* @param string $eventName
|
||||
* @return bool
|
||||
*/
|
||||
public function execute(GenericEvent $event, $eventName)
|
||||
{
|
||||
$data = $event->getAll();
|
||||
$hash = md5(serialize($data).$eventName);
|
||||
|
||||
// Do not call twice the same action with the same arguments.
|
||||
if (isset($this->callStack[$hash])) {
|
||||
return false;
|
||||
} else {
|
||||
$this->callStack[$hash] = true;
|
||||
}
|
||||
|
||||
$executable = $this->isExecutable($data, $eventName);
|
||||
$executed = false;
|
||||
|
||||
if ($executable) {
|
||||
$executed = $this->doAction($data);
|
||||
}
|
||||
|
||||
$this->logger->debug($this.' ['.$eventName.'] => executable='.var_export($executable, true).' exec_success='.var_export($executed, true));
|
||||
|
||||
return $executed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new event for the automatic action
|
||||
*
|
||||
* @access public
|
||||
* @param string $event
|
||||
* @param string $description
|
||||
* @return Base
|
||||
*/
|
||||
public function addEvent($event, $description = '')
|
||||
{
|
||||
if ($description !== '') {
|
||||
$this->eventManager->register($event, $description);
|
||||
}
|
||||
|
||||
$this->compatibleEvents[] = $event;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all compatible events of an automatic action
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents()
|
||||
{
|
||||
return array_unique(array_merge($this->getCompatibleEvents(), $this->compatibleEvents));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Create automatically a comment from a webhook
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CommentCreation extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Create a comment from an external provider');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (create a new comment)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return (bool) $this->commentModel->create(array(
|
||||
'reference' => isset($data['reference']) ? $data['reference'] : '',
|
||||
'comment' => $data['comment'],
|
||||
'task_id' => $data['task_id'],
|
||||
'user_id' => isset($data['user_id']) && $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return ! empty($data['comment']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Add a comment of the triggering event to the task description.
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Oren Ben-Kiki
|
||||
*/
|
||||
class CommentCreationMoveTaskColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Add a comment log when moving the task between columns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array('column_id' => t('Column'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'column_id',
|
||||
'project_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (append to the task description).
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
if (! $this->userSession->isLogged()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$column = $this->columnModel->getById($data['task']['column_id']);
|
||||
|
||||
return (bool) $this->commentModel->create(array(
|
||||
'comment' => t('Moved to column %s', $column['title']),
|
||||
'task_id' => $data['task_id'],
|
||||
'user_id' => $this->userSession->getId(),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
|
||||
/**
|
||||
* Stop the timer of all subtasks when moving a task to another column.
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class StopSubtaskTimerMoveTaskColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Stop the timer of all subtasks when moving a task to another column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'id',
|
||||
'column_id',
|
||||
'project_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (append to the task description).
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$subtasks = $this->subtaskModel->getAll($data['task']['id']);
|
||||
$results = array();
|
||||
|
||||
foreach ($subtasks as $subtask) {
|
||||
$results[] = $this->subtaskModel->update(array('id' => $subtask['id'], 'status' => SubtaskModel::STATUS_DONE));
|
||||
$results[] = $this->subtaskTimeTrackingModel->logEndTime($subtask['id'], $subtask['user_id']);
|
||||
}
|
||||
|
||||
return !in_array(false, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
|
||||
/**
|
||||
* Create a subtask and activate the timer when moving a task to another column.
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskTimerMoveTaskColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Add a subtask and activate the timer when moving a task to another column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'subtask' => t('Subtask Title'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'id',
|
||||
'column_id',
|
||||
'project_id',
|
||||
'creator_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (append to the task description).
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$subtaskID = $this->subtaskModel->create(array(
|
||||
'title' => $this->getParam('subtask'),
|
||||
'user_id' => $data['task']['creator_id'],
|
||||
'task_id' => $data['task']['id'],
|
||||
'status' => SubtaskModel::STATUS_INPROGRESS,
|
||||
));
|
||||
|
||||
if ($subtaskID !== false) {
|
||||
return $this->subtaskTimeTrackingModel->toggleTimer($subtaskID, $data['task']['creator_id'], SubtaskModel::STATUS_INPROGRESS);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set a category automatically according to the color
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCategoryColor extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a category based on a color');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'color_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the category)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'category_id' => $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['color_id'] == $this->getParam('color_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Set a category automatically according to a label
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCategoryLabel extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Change the category based on an external label');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'label' => t('Label'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'label',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the category)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'category_id' => $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['label'] == $this->getParam('label') && empty($data['category_id']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskLinkModel;
|
||||
|
||||
/**
|
||||
* Set a category automatically according to a task link
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Olivier Maridat
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCategoryLink extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a category based on a link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskLinkModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'category_id' => t('Category'),
|
||||
'link_id' => t('Link type'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_link' => array(
|
||||
'task_id',
|
||||
'link_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the category)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_link']['task_id'],
|
||||
'category_id' => $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
if ($data['task_link']['link_id'] == $this->getParam('link_id')) {
|
||||
return empty($data['task']['category_id']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a category when the task is moved to a specific swimlane
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author @Interleaved
|
||||
*/
|
||||
class TaskAssignCategorySwimlaneChange extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a category when the task is moved to a specific swimlane');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_MOVE_SWIMLANE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'swimlane_id' => t('Swimlane'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task category)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'category_id' => $this->getParam('category_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] == $this->getParam('swimlane_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a specific category
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignColorCategory extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a color based on a category');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'category_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['category_id'] == $this->getParam('category_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a task
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignColorColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a color when the task is moved to a specific column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'color_id' => t('Color'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskLinkModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a specific task link
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignColorLink extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Change task color when using a specific task link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskLinkModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
'link_id' => t('Link type'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_link' => array(
|
||||
'task_id',
|
||||
'link_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_link']['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task_link']['link_id'] == $this->getParam('link_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a priority
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Julien Buratto
|
||||
*/
|
||||
class TaskAssignColorOnDueDate extends Base
|
||||
{
|
||||
/**
|
||||
* Get action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a color when due date is expired');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_DAILY_CRONJOB,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tasks
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
if ($task['date_due'] <= time() && $task['date_due'] > 0 && $task['color_id'] != $this->getParam('color_id')) {
|
||||
$values = array(
|
||||
'id' => $task['id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
$results[] = $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color when preset start date is reached
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Christian Wolter
|
||||
*/
|
||||
class TaskAssignColorOnStartDate extends Base
|
||||
{
|
||||
/**
|
||||
* Get action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a color when preset start date is reached');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_DAILY_CRONJOB,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tasks
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
if ($task['date_started'] <= time() && $task['date_started'] > 0 && $task['color_id'] != $this->getParam('color_id')) {
|
||||
$values = array(
|
||||
'id' => $task['id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
$results[] = $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a priority
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignColorPriority extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign automatically a color based on a priority');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
'priority' => t('Priority'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'priority',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['priority'] == $this->getParam('priority');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a task based on Swimlane
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Dave Almond
|
||||
*/
|
||||
class TaskAssignColorSwimlane extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a color when the task is moved to a specific swimlane');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_MOVE_SWIMLANE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'swimlane_id' => t('Swimlane'),
|
||||
'color_id' => t('Color'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'swimlane_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] == $this->getParam('swimlane_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a color to a specific user
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignColorUser extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a color to a specific user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'color_id' => t('Color'),
|
||||
'user_id' => t('Assignee'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'owner_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (change the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'color_id' => $this->getParam('color_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['owner_id'] == $this->getParam('user_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a task to the creator
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCreator extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to its creator');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'creator_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $data['task']['creator_id'],
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a task to the logged user
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCurrentUser extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to the person who does the action');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
if (! $this->userSession->isLogged()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->userSession->getId(),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a task to the logged user on column change
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignCurrentUserColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to the person who does the action when the column is changed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
if (! $this->userSession->isLogged()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->userSession->getId(),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a task to the logged user on column change if no user is assigned already
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Glukose1
|
||||
*/
|
||||
class TaskAssignCurrentUserColumnIfNoUserAlreadySet extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a task to the logged user on column change to specified column if no user is assigned');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/*** Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'owner_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
if (!$this->userSession->isLogged()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$data['task']['owner_id']) {
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->userSession->getId(),
|
||||
);
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set the due date of task
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignDueDateOnCreation extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Automatically set the due date on task creation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'date_due' => strtotime('+'.$this->getParam('duration').'days'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set the due date when task move away from certain column
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Stefan Krüger
|
||||
*/
|
||||
class TaskAssignDueDateOnMoveColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Automatically set the due date when the task is moved away from a specific column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days'),
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
),
|
||||
'src_column_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'date_due' => strtotime('+'.$this->getParam('duration').'days'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return !empty($data['src_column_id']) && $data['src_column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set a priority automatically according to the Swimlane
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Dave Almond
|
||||
*/
|
||||
class TaskAssignPrioritySwimlane extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign a priority when the task is moved to a specific swimlane');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_MOVE_SWIMLANE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'swimlane_id' => t('Swimlane'),
|
||||
'priority' => t('Priority'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'swimlane_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the priority)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'priority' => $this->getParam('priority'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] == $this->getParam('swimlane_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a task to a specific user
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignSpecificUser extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to a specific user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'user_id' => t('Assignee'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (assign the given user)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->getParam('user_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a Task to the creator in a specific column
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Glukose1
|
||||
*/
|
||||
class TaskAssignToUserOnCreationInColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to its creator for specific columns if no assignee is set manually');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'creator_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
|
||||
$assignee_id = $this->userModel->getIdByUsername($data['task']['assignee_username']);
|
||||
|
||||
if ($data['task']['assignee_username']) {
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $assignee_id,
|
||||
);
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $data['task']['creator_id'],
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Assign a task to someone
|
||||
*
|
||||
* @package Kanboard\Actionv
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAssignUser extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Change the assignee based on an external username');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'owner_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (assign the given user)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $data['owner_id'],
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['owner_id']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Assign a user when the task is moved to a specific swimlane
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author @Interleaved
|
||||
*/
|
||||
class TaskAssignUserSwimlaneChange extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Assign the task to a specific user when the task is moved to a specific swimlane');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_MOVE_SWIMLANE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'swimlane_id' => t('Swimlane'),
|
||||
'user_id' => t('Assignee'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task category)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'owner_id' => $this->getParam('user_id'),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] == $this->getParam('swimlane_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Close automatically a task
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskClose extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Close a task');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('task_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskStatusModel->close($data['task_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Close automatically a task in a specific column
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskCloseColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Close a task in a specific column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array('column_id' => t('Column'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskStatusModel->close($data['task_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Close automatically a task after when inactive
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskCloseNoActivity extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Close a task when there is no activity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$max = (int)$this->getParam('duration') * 86400;
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = time() - $task['date_modification'];
|
||||
|
||||
if ($duration > $max) {
|
||||
$results[] = $this->taskStatusModel->close($task['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Close automatically a task after inactive and in a defined column
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskCloseNoActivityColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Close a task when there is no activity in a specific column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days'),
|
||||
'column_id' => t('Column')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$max = (int)$this->getParam('duration') * 86400;
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = time() - $task['date_modification'];
|
||||
|
||||
if ($duration > $max && $task['column_id'] == $this->getParam('column_id')) {
|
||||
$results[] = $this->taskStatusModel->close($task['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Close automatically in a defined column after a certain amount of time
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskCloseNotMovedColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Close a task in a specific column when not moved during a given period');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days'),
|
||||
'column_id' => t('Column')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$max = (int)$this->getParam('duration') * 86400;
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = time() - $task['date_moved'];
|
||||
|
||||
if ($duration > $max && $task['column_id'] == $this->getParam('column_id')) {
|
||||
$results[] = $this->taskStatusModel->close($task['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Create automatically a task from a webhook
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskCreation extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Create a task from an external provider');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'project_id',
|
||||
'reference',
|
||||
'title',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (create a new task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return (bool) $this->taskCreationModel->create(array(
|
||||
'project_id' => $data['project_id'],
|
||||
'title' => $data['title'],
|
||||
'reference' => $data['reference'],
|
||||
'description' => isset($data['description']) ? $data['description'] : '',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Duplicate a task to another project
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskDuplicateAnotherProject extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Duplicate the task to another project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
TaskModel::EVENT_CLOSE,
|
||||
TaskModel::EVENT_CREATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'project_id' => t('Project'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (duplicate the task to another project)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$destination_column_id = $this->columnModel->getFirstColumnId($this->getParam('project_id'));
|
||||
return (bool) $this->taskProjectDuplicationModel->duplicateToProject(
|
||||
$data['task_id'],
|
||||
$this->getParam('project_id'),
|
||||
null,
|
||||
$destination_column_id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id') && $data['task']['project_id'] != $this->getParam('project_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Email a task to someone
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskEmail extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Send a task by email to someone');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
TaskModel::EVENT_CLOSE,
|
||||
TaskModel::EVENT_CREATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'user_id' => t('User that will receive the email'),
|
||||
'subject' => t('Email subject'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$user = $this->userModel->getById($this->getParam('user_id'));
|
||||
$subject = $this->getParam('subject');
|
||||
|
||||
foreach ($data["task"] as $key => $value) {
|
||||
if ($value !== null) {
|
||||
$placeholder = sprintf('{{%s}}', $key);
|
||||
$subject = str_replace($placeholder, $value, $subject);
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($user['email'])) {
|
||||
$this->emailClient->send(
|
||||
$user['email'],
|
||||
$user['name'] ?: $user['username'],
|
||||
$subject,
|
||||
$this->template->render('notification/task_create', array(
|
||||
'task' => $data['task'],
|
||||
))
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Email a task with no activity
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskEmailNoActivity extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Send email when there is no activity on a task');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_DAILY_CRONJOB,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'user_id' => t('User that will receive the email'),
|
||||
'subject' => t('Email subject'),
|
||||
'duration' => t('Duration in days'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$max = (int)$this->getParam('duration') * 86400;
|
||||
$user = $this->userModel->getById($this->getParam('user_id'));
|
||||
|
||||
if (! empty($user['email'])) {
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = time() - $task['date_modification'];
|
||||
|
||||
if ($duration > $max) {
|
||||
$results[] = $this->sendEmail($task['id'], $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email
|
||||
*
|
||||
* @access private
|
||||
* @param integer $task_id
|
||||
* @param array $user
|
||||
* @return boolean
|
||||
*/
|
||||
private function sendEmail($task_id, array $user)
|
||||
{
|
||||
$task = $this->taskFinderModel->getDetails($task_id);
|
||||
|
||||
$this->emailClient->send(
|
||||
$user['email'],
|
||||
$user['name'] ?: $user['username'],
|
||||
$this->getParam('subject'),
|
||||
$this->template->render('notification/task_create', array('task' => $task))
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another project
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskMoveAnotherProject extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
TaskModel::EVENT_CLOSE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
'project_id' => t('Project'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another project)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskProjectMoveModel->moveToProject($data['task_id'], $this->getParam('project_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id') && $data['task']['project_id'] != $this->getParam('project_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when an assignee is set
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Francois Ferrand
|
||||
*/
|
||||
class TaskMoveColumnAssigned extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when assigned to a user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||
TaskModel::EVENT_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'src_column_id' => t('Source column'),
|
||||
'dest_column_id' => t('Destination column')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'owner_id',
|
||||
'position',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task_id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
$data['task']['position'],
|
||||
$data['task']['swimlane_id'],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('src_column_id') && $data['task']['owner_id'] > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when the category is changed
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Francois Ferrand
|
||||
*/
|
||||
class TaskMoveColumnCategoryChange extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when the category is changed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_UPDATE,
|
||||
TaskModel::EVENT_CREATE,
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'dest_column_id' => t('Destination column'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'category_id',
|
||||
'position',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task_id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
$data['task']['position'],
|
||||
$data['task']['swimlane_id'],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] != $this->getParam('dest_column_id') && $data['task']['category_id'] == $this->getParam('category_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when the task is closed
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskMoveColumnClosed extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when closed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CLOSE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'dest_column_id' => t('Destination column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'swimlane_id',
|
||||
'is_active',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task']['id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
1,
|
||||
$data['task']['swimlane_id'],
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] != $this->getParam('dest_column_id') && $data['task']['is_active'] == 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when not moved during a given period
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskMoveColumnNotMovedPeriod extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when not moved during a given period');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days'),
|
||||
'src_column_id' => t('Source column'),
|
||||
'dest_column_id' => t('Destination column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$max = (int)$this->getParam('duration') * 86400;
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = time() - $task['date_moved'];
|
||||
|
||||
if ($duration > $max && $task['column_id'] == $this->getParam('src_column_id')) {
|
||||
$results[] = $this->taskPositionModel->movePosition(
|
||||
$task['project_id'],
|
||||
$task['id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
1,
|
||||
$task['swimlane_id'],
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move the task from one to another column when due date is LESS than a certain number of days
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
*/
|
||||
class TaskMoveColumnOnDueDate extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when the due date is less than a certain number of days');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'duration' => t('Duration in days'),
|
||||
'src_column_id' => t('Source column'),
|
||||
'dest_column_id' => t('Destination column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
$min = (int)$this->getParam('duration') * 86400;
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
$duration = $task['date_due'] - time();
|
||||
|
||||
if ($task['date_due'] > 0 && $duration < $min && $task['column_id'] == $this->getParam('src_column_id')) {
|
||||
$results[] = $this->taskPositionModel->movePosition(
|
||||
$task['project_id'],
|
||||
$task['id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
1,
|
||||
$task['swimlane_id'],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column once a predefined start date is reached
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Christian Wolter
|
||||
*/
|
||||
class TaskMoveColumnOnStartDate extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column once a predefined start date is reached');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'src_column_id' => t('Source column'),
|
||||
'dest_column_id' => t('Destination column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$results = array();
|
||||
|
||||
foreach ($data['tasks'] as $task) {
|
||||
|
||||
if ($task['date_started'] <= time() && $task['date_started'] > 0 && $task['column_id'] == $this->getParam('src_column_id')) {
|
||||
$results[] = $this->taskPositionModel->movePosition(
|
||||
$task['project_id'],
|
||||
$task['id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
1,
|
||||
$task['swimlane_id'],
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return count($data['tasks']) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when an assignee is cleared
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Francois Ferrand
|
||||
*/
|
||||
class TaskMoveColumnUnAssigned extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another column when assignee is cleared');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||
TaskModel::EVENT_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'src_column_id' => t('Source column'),
|
||||
'dest_column_id' => t('Destination column')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'owner_id',
|
||||
'position',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task_id'],
|
||||
$this->getParam('dest_column_id'),
|
||||
$data['task']['position'],
|
||||
$data['task']['swimlane_id'],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('src_column_id') && $data['task']['owner_id'] == 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another column when an assignee is set
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Francois Ferrand
|
||||
*/
|
||||
class TaskMoveSwimlaneAssigned extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another swimlane when assigned to a user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
|
||||
TaskModel::EVENT_CREATE_UPDATE,
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||
TaskModel::EVENT_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'user_id' => t('Assignee'),
|
||||
'dest_swimlane_id' => t('Destination swimlane'),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'owner_id',
|
||||
'position',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another column)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task_id'],
|
||||
$data['task']['column_id'],
|
||||
$data['task']['position'],
|
||||
$this->getParam('dest_swimlane_id'),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
**/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] != $this->getParam('dest_swimlane_id') && $data['task']['owner_id'] == $this->getParam("user_id");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Move a task to another swimlane when the category is changed
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author @Interleaved
|
||||
*/
|
||||
class TaskMoveSwimlaneCategoryChange extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Move the task to another swimlane when the category is changed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_UPDATE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'dest_swimlane_id' => t('Destination swimlane'),
|
||||
'category_id' => t('Category'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
'category_id',
|
||||
'position',
|
||||
'swimlane_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (move the task to another swimlane)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskPositionModel->movePosition(
|
||||
$data['task']['project_id'],
|
||||
$data['task_id'],
|
||||
$data['task']['column_id'],
|
||||
$data['task']['position'],
|
||||
$this->getParam('dest_swimlane_id'),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['swimlane_id'] != $this->getParam('dest_swimlane_id') && $data['task']['category_id'] == $this->getParam('category_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
/**
|
||||
* Open automatically a task
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskOpen extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Open a task');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array('task_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (close the task)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
return $this->taskStatusModel->open($data['task_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set the start date of task
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskUpdateStartDate extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Automatically update the start date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
'column_id',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task color)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'date_started' => time(),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return $data['task']['column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Action;
|
||||
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Set the start date when task move away from certain column
|
||||
*
|
||||
* @package Kanboard\Action
|
||||
*/
|
||||
class TaskUpdateStartDateOnMoveColumn extends Base
|
||||
{
|
||||
/**
|
||||
* Get automatic action description
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return t('Automatically update the start date when the task is moved away from a specific column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of compatible events
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the action (defined by the user)
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getActionRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'column_id' => t('Column'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required parameter for the event
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEventRequiredParameters()
|
||||
{
|
||||
return array(
|
||||
'task_id',
|
||||
'task' => array(
|
||||
'project_id',
|
||||
),
|
||||
'src_column_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the action (set the task date_started)
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool True if the action was executed or false when not executed
|
||||
*/
|
||||
public function doAction(array $data)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $data['task_id'],
|
||||
'date_started' => time(),
|
||||
);
|
||||
|
||||
return $this->taskModificationModel->update($values, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event data meet the action condition
|
||||
*
|
||||
* @access public
|
||||
* @param array $data Event data dictionary
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRequiredCondition(array $data)
|
||||
{
|
||||
return empty($data['task']['date_started']) && $data['src_column_id'] == $this->getParam('column_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Average Lead and Cycle Time
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AverageLeadCycleTimeAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$stats = array(
|
||||
'count' => 0,
|
||||
'total_lead_time' => 0,
|
||||
'total_cycle_time' => 0,
|
||||
'avg_lead_time' => 0,
|
||||
'avg_cycle_time' => 0,
|
||||
);
|
||||
|
||||
$tasks = $this->getTasks($project_id);
|
||||
|
||||
foreach ($tasks as &$task) {
|
||||
$stats['count']++;
|
||||
$stats['total_lead_time'] += $this->calculateLeadTime($task);
|
||||
$stats['total_cycle_time'] += $this->calculateCycleTime($task);
|
||||
}
|
||||
|
||||
$stats['avg_lead_time'] = $this->calculateAverage($stats, 'total_lead_time');
|
||||
$stats['avg_cycle_time'] = $this->calculateAverage($stats, 'total_cycle_time');
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate average
|
||||
*
|
||||
* @access private
|
||||
* @param array &$stats
|
||||
* @param string $field
|
||||
* @return float
|
||||
*/
|
||||
private function calculateAverage(array &$stats, $field)
|
||||
{
|
||||
if ($stats['count'] > 0) {
|
||||
return (int) ($stats[$field] / $stats['count']);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate lead time
|
||||
*
|
||||
* @access private
|
||||
* @param array &$task
|
||||
* @return integer
|
||||
*/
|
||||
private function calculateLeadTime(array &$task)
|
||||
{
|
||||
$end = $task['date_completed'] ?: time();
|
||||
$start = $task['date_creation'];
|
||||
|
||||
return $end - $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cycle time
|
||||
*
|
||||
* @access private
|
||||
* @param array &$task
|
||||
* @return integer
|
||||
*/
|
||||
private function calculateCycleTime(array &$task)
|
||||
{
|
||||
$end = (int) $task['date_completed'] ?: time();
|
||||
$start = (int) $task['date_started'];
|
||||
|
||||
// Start date can be in the future when defined with the Gantt chart
|
||||
if ($start > 0 && $end > $start) {
|
||||
return $end - $start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 1000 last created tasks
|
||||
*
|
||||
* @access private
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
private function getTasks($project_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(TaskModel::TABLE)
|
||||
->columns('date_completed', 'date_creation', 'date_started')
|
||||
->eq('project_id', $project_id)
|
||||
->desc('id')
|
||||
->limit(1000)
|
||||
->findAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Average Time Spent by Column
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AverageTimeSpentColumnAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$stats = $this->initialize($project_id);
|
||||
|
||||
$this->processTasks($stats, $project_id);
|
||||
$this->calculateAverage($stats);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize default values for each column
|
||||
*
|
||||
* @access private
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
private function initialize($project_id)
|
||||
{
|
||||
$stats = array();
|
||||
$columns = $this->columnModel->getList($project_id);
|
||||
|
||||
foreach ($columns as $column_id => $column_title) {
|
||||
$stats[$column_id] = array(
|
||||
'count' => 0,
|
||||
'time_spent' => 0,
|
||||
'average' => 0,
|
||||
'title' => $column_title,
|
||||
);
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate time spent for each tasks for each columns
|
||||
*
|
||||
* @access private
|
||||
* @param array $stats
|
||||
* @param integer $project_id
|
||||
*/
|
||||
private function processTasks(array &$stats, $project_id)
|
||||
{
|
||||
$tasks = $this->getTasks($project_id);
|
||||
|
||||
foreach ($tasks as &$task) {
|
||||
foreach ($this->getTaskTimeByColumns($task) as $column_id => $time_spent) {
|
||||
if (isset($stats[$column_id])) {
|
||||
$stats[$column_id]['count']++;
|
||||
$stats[$column_id]['time_spent'] += $time_spent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate averages
|
||||
*
|
||||
* @access private
|
||||
* @param array $stats
|
||||
*/
|
||||
private function calculateAverage(array &$stats)
|
||||
{
|
||||
foreach ($stats as &$column) {
|
||||
$this->calculateColumnAverage($column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate column average
|
||||
*
|
||||
* @access private
|
||||
* @param array $column
|
||||
*/
|
||||
private function calculateColumnAverage(array &$column)
|
||||
{
|
||||
if ($column['count'] > 0) {
|
||||
$column['average'] = (int) ($column['time_spent'] / $column['count']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time spent for each column for a given task
|
||||
*
|
||||
* @access private
|
||||
* @param array $task
|
||||
* @return array
|
||||
*/
|
||||
private function getTaskTimeByColumns(array &$task)
|
||||
{
|
||||
$columns = $this->transitionModel->getTimeSpentByTask($task['id']);
|
||||
|
||||
if (! isset($columns[$task['column_id']])) {
|
||||
$columns[$task['column_id']] = 0;
|
||||
}
|
||||
|
||||
$columns[$task['column_id']] += $this->getTaskTimeSpentInCurrentColumn($task);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate time spent of a task in the current column
|
||||
*
|
||||
* @access private
|
||||
* @param array $task
|
||||
* @return integer
|
||||
*/
|
||||
private function getTaskTimeSpentInCurrentColumn(array &$task)
|
||||
{
|
||||
$end = $task['date_completed'] ?: time();
|
||||
return $end - $task['date_moved'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the last 1000 tasks
|
||||
*
|
||||
* @access private
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
private function getTasks($project_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(TaskModel::TABLE)
|
||||
->columns('id', 'date_completed', 'date_moved', 'column_id')
|
||||
->eq('project_id', $project_id)
|
||||
->desc('id')
|
||||
->limit(1000)
|
||||
->findAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Estimated vs actual time per column
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class EstimatedActualColumnAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$rows = $this->db->table(TaskModel::TABLE)
|
||||
->columns('SUM(time_estimated) AS hours_estimated', 'SUM(time_spent) AS hours_spent', 'column_id')
|
||||
->eq('project_id', $project_id)
|
||||
->groupBy('column_id')
|
||||
->findAll();
|
||||
|
||||
$columns = $this->columnModel->getList($project_id);
|
||||
|
||||
$metrics = [];
|
||||
foreach ($columns as $column_id => $column_title) {
|
||||
$metrics[$column_id] = array(
|
||||
'hours_spent' => 0,
|
||||
'hours_estimated' => 0,
|
||||
'title' => $column_title,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$metrics[$row['column_id']]['hours_spent'] = (float) $row['hours_spent'];
|
||||
$metrics[$row['column_id']]['hours_estimated'] = (float) $row['hours_estimated'];
|
||||
}
|
||||
|
||||
return $metrics;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Estimated/Spent Time Comparison
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class EstimatedTimeComparisonAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$rows = $this->db->table(TaskModel::TABLE)
|
||||
->columns('SUM(time_estimated) AS time_estimated', 'SUM(time_spent) AS time_spent', 'is_active')
|
||||
->eq('project_id', $project_id)
|
||||
->groupBy('is_active')
|
||||
->findAll();
|
||||
|
||||
$metrics = array(
|
||||
'open' => array(
|
||||
'time_spent' => 0,
|
||||
'time_estimated' => 0,
|
||||
),
|
||||
'closed' => array(
|
||||
'time_spent' => 0,
|
||||
'time_estimated' => 0,
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$key = $row['is_active'] == TaskModel::STATUS_OPEN ? 'open' : 'closed';
|
||||
$metrics[$key]['time_spent'] = (float) $row['time_spent'];
|
||||
$metrics[$key]['time_estimated'] = (float) $row['time_estimated'];
|
||||
}
|
||||
|
||||
return $metrics;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Task Distribution
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskDistributionAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$metrics = array();
|
||||
$total = 0;
|
||||
$columns = $this->columnModel->getAll($project_id);
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$nb_tasks = $this->taskFinderModel->countByColumnId($project_id, $column['id']);
|
||||
$total += $nb_tasks;
|
||||
|
||||
$metrics[] = array(
|
||||
'column_title' => $column['title'],
|
||||
'nb_tasks' => $nb_tasks,
|
||||
);
|
||||
}
|
||||
|
||||
if ($total === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($metrics as &$metric) {
|
||||
$metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2);
|
||||
}
|
||||
|
||||
return $metrics;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Analytic;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* User Distribution
|
||||
*
|
||||
* @package analytic
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserDistributionAnalytic extends Base
|
||||
{
|
||||
/**
|
||||
* Build Report
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id
|
||||
* @return array
|
||||
*/
|
||||
public function build($project_id)
|
||||
{
|
||||
$metrics = array();
|
||||
$total = 0;
|
||||
$tasks = $this->taskFinderModel->getAll($project_id);
|
||||
$users = $this->projectUserRoleModel->getAssignableUsersList($project_id);
|
||||
|
||||
foreach ($tasks as $task) {
|
||||
$user = isset($users[$task['owner_id']]) ? $users[$task['owner_id']] : $users[0];
|
||||
$total++;
|
||||
|
||||
if (! isset($metrics[$user])) {
|
||||
$metrics[$user] = array(
|
||||
'nb_tasks' => 0,
|
||||
'percentage' => 0,
|
||||
'user' => $user,
|
||||
);
|
||||
}
|
||||
|
||||
$metrics[$user]['nb_tasks']++;
|
||||
}
|
||||
|
||||
if ($total === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($metrics as &$metric) {
|
||||
$metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2);
|
||||
}
|
||||
|
||||
ksort($metrics);
|
||||
|
||||
return array_values($metrics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class ActionAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ActionAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $action_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->actionModel->getProjectId($action_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class CategoryAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CategoryAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $category_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->categoryModel->getProjectId($category_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class ColumnAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ColumnAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $column_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->columnModel->getProjectId($column_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
/**
|
||||
* Class CommentAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CommentAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $comment_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->commentModel->getProjectId($comment_id));
|
||||
$this->checkCommentAccess($comment_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $comment_id ID of the comment to check
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
*/
|
||||
protected function checkCommentAccess($comment_id)
|
||||
{
|
||||
if (empty($comment_id)) {
|
||||
throw new AccessDeniedException('Comment Not Found');
|
||||
}
|
||||
|
||||
$commentVisibility = $this->commentModel->getVisibility($comment_id);
|
||||
$userRole = $this->userSession->getRole();
|
||||
|
||||
if ($userRole === Role::APP_MANAGER && $commentVisibility === Role::APP_ADMIN) {
|
||||
throw new AccessDeniedException('Comment Access Denied');
|
||||
}
|
||||
|
||||
if ($userRole === Role::APP_USER && $commentVisibility !== Role::APP_USER) {
|
||||
throw new AccessDeniedException('Comment Access Denied');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class ProcedureAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProcedureAuthorization extends Base
|
||||
{
|
||||
private $userSpecificProcedures = array(
|
||||
'getMe',
|
||||
'getMyDashboard',
|
||||
'getMyActivityStream',
|
||||
'createMyPrivateProject',
|
||||
'getMyProjectsList',
|
||||
'getMyProjects',
|
||||
'getMyOverdueTasks',
|
||||
);
|
||||
|
||||
public function check($procedure)
|
||||
{
|
||||
if (! $this->userSession->isLogged() && in_array($procedure, $this->userSpecificProcedures)) {
|
||||
throw new AccessDeniedException('This procedure is not available with the API credentials');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class ProjectAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectAuthorization extends Base
|
||||
{
|
||||
public function check($class, $method, $project_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $project_id);
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkProjectPermission($class, $method, $project_id)
|
||||
{
|
||||
if (empty($project_id)) {
|
||||
throw new AccessDeniedException('Project Not Found');
|
||||
}
|
||||
|
||||
$role = $this->projectUserRoleModel->getUserRole($project_id, $this->userSession->getId());
|
||||
|
||||
if (! $this->apiProjectAuthorization->isAllowed($class, $method, $role)) {
|
||||
throw new AccessDeniedException('Project Access Denied');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class SubtaskAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $subtask_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->subtaskModel->getProjectId($subtask_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TagAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TagAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $tag_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$tag = $this->tagModel->getById($tag_id);
|
||||
|
||||
if (! empty($tag)) {
|
||||
$this->checkProjectPermission($class, $method, $tag['project_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $task_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($task_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskFileAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFileAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $file_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskFileModel->getProjectId($file_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskLinkAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskLinkAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $task_link_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskLinkModel->getProjectId($task_link_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class UserAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserAuthorization extends Base
|
||||
{
|
||||
public function check($class, $method)
|
||||
{
|
||||
if ($this->userSession->isLogged() && ! $this->apiAuthorization->isAllowed($class, $method, $this->userSession->getRole())) {
|
||||
throw new AccessDeniedException('You are not allowed to access to this resource');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Middleware;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use JsonRPC\Exception\AuthenticationFailureException;
|
||||
use JsonRPC\MiddlewareInterface;
|
||||
use Kanboard\Auth\ApiAccessTokenAuth;
|
||||
use Kanboard\Core\Base;
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Class AuthenticationApiMiddleware
|
||||
*
|
||||
* @package Kanboard\Api\Middleware
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AuthenticationMiddleware extends Base implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* Execute Middleware
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $procedureName
|
||||
* @throws AccessDeniedException
|
||||
* @throws AuthenticationFailureException
|
||||
*/
|
||||
public function execute($username, $password, $procedureName)
|
||||
{
|
||||
$this->dispatcher->dispatch(new Event, 'app.bootstrap');
|
||||
session_set('scope', 'API');
|
||||
|
||||
if ($this->isUserAuthenticated($username, $password)) {
|
||||
$this->userSession->initialize($this->userCacheDecorator->getByUsername($username));
|
||||
} elseif (! $this->isAppAuthenticated($username, $password)) {
|
||||
$this->logger->error('API authentication failure for '.$username);
|
||||
throw new AuthenticationFailureException('Wrong credentials');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user credentials
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
*/
|
||||
private function isUserAuthenticated($username, $password)
|
||||
{
|
||||
if ($username === 'jsonrpc') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->userLockingModel->isLocked($username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->userModel->has2FA($username)) {
|
||||
$this->logger->info('This API user ('.$username.') as 2FA enabled: only API keys are authorized');
|
||||
$this->authenticationManager->reset();
|
||||
$this->authenticationManager->register(new ApiAccessTokenAuth($this->container));
|
||||
}
|
||||
|
||||
return $this->authenticationManager->passwordAuthentication($username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check administrative credentials
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
*/
|
||||
private function isAppAuthenticated($username, $password)
|
||||
{
|
||||
return $username === 'jsonrpc' && hash_equals($this->getApiToken(), $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get API Token
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function getApiToken()
|
||||
{
|
||||
if (defined('API_AUTHENTICATION_TOKEN')) {
|
||||
return API_AUTHENTICATION_TOKEN;
|
||||
}
|
||||
|
||||
if (getenv('API_AUTHENTICATION_TOKEN')) {
|
||||
return getenv('API_AUTHENTICATION_TOKEN');
|
||||
}
|
||||
|
||||
return $this->configModel->get('api_token');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ActionAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Action API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ActionProcedure extends BaseProcedure
|
||||
{
|
||||
public function getAvailableActions()
|
||||
{
|
||||
return (object) $this->actionManager->getAvailableActions();
|
||||
}
|
||||
|
||||
public function getAvailableActionEvents()
|
||||
{
|
||||
return (object) $this->eventManager->getAll();
|
||||
}
|
||||
|
||||
public function getCompatibleActionEvents($action_name)
|
||||
{
|
||||
return (object) $this->actionManager->getCompatibleEvents($action_name);
|
||||
}
|
||||
|
||||
public function removeAction($action_id)
|
||||
{
|
||||
ActionAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAction', $action_id);
|
||||
return $this->actionModel->remove($action_id);
|
||||
}
|
||||
|
||||
public function getActions($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActions', $project_id);
|
||||
return $this->actionModel->getAllByProject($project_id);
|
||||
}
|
||||
|
||||
public function createAction($project_id, $event_name, $action_name, array $params)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createAction', $project_id);
|
||||
$values = array(
|
||||
'project_id' => $project_id,
|
||||
'event_name' => $event_name,
|
||||
'action_name' => $action_name,
|
||||
'params' => $params,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->actionValidator->validateCreation($values);
|
||||
|
||||
if (! $valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the action exists
|
||||
$actions = $this->actionManager->getAvailableActions();
|
||||
|
||||
if (! isset($actions[$action_name])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the event
|
||||
$action = $this->actionManager->getAction($action_name);
|
||||
|
||||
if (! in_array($event_name, $action->getEvents())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$required_params = $action->getActionRequiredParameters();
|
||||
|
||||
// Check missing parameters
|
||||
foreach ($required_params as $param => $value) {
|
||||
if (! isset($params[$param])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check extra parameters
|
||||
foreach ($params as $param => $value) {
|
||||
if (! isset($required_params[$param])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->actionModel->create($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* App API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AppProcedure extends BaseProcedure
|
||||
{
|
||||
public function getTimezone()
|
||||
{
|
||||
return $this->timezoneModel->getCurrentTimezone();
|
||||
}
|
||||
|
||||
public function getVersion()
|
||||
{
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
public function getDefaultTaskColor()
|
||||
{
|
||||
return $this->colorModel->getDefaultColor();
|
||||
}
|
||||
|
||||
public function getDefaultTaskColors()
|
||||
{
|
||||
return $this->colorModel->getDefaultColors();
|
||||
}
|
||||
|
||||
public function getColorList()
|
||||
{
|
||||
return $this->colorModel->getList();
|
||||
}
|
||||
|
||||
public function getApplicationRoles()
|
||||
{
|
||||
return $this->role->getApplicationRoles();
|
||||
}
|
||||
|
||||
public function getProjectRoles()
|
||||
{
|
||||
return $this->role->getProjectRoles();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProcedureAuthorization;
|
||||
use Kanboard\Api\Authorization\UserAuthorization;
|
||||
use Kanboard\Core\Base;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Base class
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseProcedure extends Base
|
||||
{
|
||||
public function beforeProcedure($procedure)
|
||||
{
|
||||
ProcedureAuthorization::getInstance($this->container)->check($procedure);
|
||||
UserAuthorization::getInstance($this->container)->check($this->getClassName(), $procedure);
|
||||
}
|
||||
|
||||
protected function filterValues(array $values)
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
protected function getClassName()
|
||||
{
|
||||
$reflection = new ReflectionClass(get_called_class());
|
||||
return $reflection->getShortName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Board API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class BoardProcedure extends BaseProcedure
|
||||
{
|
||||
public function getBoard($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getBoard', $project_id);
|
||||
|
||||
return $this->boardFormatter
|
||||
->withProjectId($project_id)
|
||||
->withQuery($this->taskFinderModel->getExtendedQuery())
|
||||
->format();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\CategoryAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Category API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CategoryProcedure extends BaseProcedure
|
||||
{
|
||||
public function getCategory($category_id)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'getCategory', $category_id);
|
||||
return $this->categoryModel->getById($category_id);
|
||||
}
|
||||
|
||||
public function getAllCategories($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllCategories', $project_id);
|
||||
return $this->categoryModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function removeCategory($category_id)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeCategory', $category_id);
|
||||
return $this->categoryModel->remove($category_id);
|
||||
}
|
||||
|
||||
public function createCategory($project_id, $name, $color_id = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createCategory', $project_id);
|
||||
|
||||
$values = array(
|
||||
'project_id' => $project_id,
|
||||
'name' => $name,
|
||||
'color_id' => $color_id,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->categoryValidator->validateCreation($values);
|
||||
return $valid ? $this->categoryModel->create($values) : false;
|
||||
}
|
||||
|
||||
public function updateCategory($id, $name, $color_id = null)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateCategory', $id);
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
'color_id' => $color_id,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->categoryValidator->validateModification($values);
|
||||
return $valid && $this->categoryModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ColumnAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Column API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ColumnProcedure extends BaseProcedure
|
||||
{
|
||||
public function getColumns($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getColumns', $project_id);
|
||||
return $this->columnModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function getColumn($column_id)
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'getColumn', $column_id);
|
||||
return $this->columnModel->getById($column_id);
|
||||
}
|
||||
|
||||
public function updateColumn($column_id, $title, $task_limit = 0, $description = '')
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateColumn', $column_id);
|
||||
return $this->columnModel->update($column_id, $title, $task_limit, $description);
|
||||
}
|
||||
|
||||
public function addColumn($project_id, $title, $task_limit = 0, $description = '')
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addColumn', $project_id);
|
||||
return $this->columnModel->create($project_id, $title, $task_limit, $description);
|
||||
}
|
||||
|
||||
public function removeColumn($column_id)
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeColumn', $column_id);
|
||||
|
||||
$projectId = $this->columnModel->getProjectId($column_id);
|
||||
$nbTasks = $this->taskFinderModel->countByColumnId($projectId, $column_id, array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED));
|
||||
|
||||
if ($nbTasks > 0) {
|
||||
$this->logger->error(__METHOD__.': This column cannot be removed because it contains '.$nbTasks.' tasks');
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->columnModel->remove($column_id);
|
||||
}
|
||||
|
||||
public function changeColumnPosition($project_id, $column_id, $position)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeColumnPosition', $project_id);
|
||||
|
||||
if ((int) $this->columnModel->getProjectId($column_id) !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->columnModel->changePosition($project_id, $column_id, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\CommentAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
/**
|
||||
* Comment API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CommentProcedure extends BaseProcedure
|
||||
{
|
||||
public function getComment($comment_id)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'getComment', $comment_id);
|
||||
return $this->commentModel->getById($comment_id);
|
||||
}
|
||||
|
||||
public function getAllComments($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllComments', $task_id);
|
||||
$comments = $this->commentModel->getAll($task_id);
|
||||
$filteredComments = [];
|
||||
$userRole = $this->userSession->getRole();
|
||||
|
||||
foreach ($comments as $comment) {
|
||||
if ($userRole === Role::APP_MANAGER && $comment['visibility'] === Role::APP_ADMIN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($userRole === Role::APP_USER && $comment['visibility'] !== Role::APP_USER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filteredComments[] = $comment;
|
||||
}
|
||||
|
||||
return $filteredComments;
|
||||
}
|
||||
|
||||
public function removeComment($comment_id)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeComment', $comment_id);
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
$loggedUserID = $this->userSession->getId();
|
||||
$comment = $this->commentModel->getById($comment_id);
|
||||
if ($comment['user_id'] != $loggedUserID) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->commentModel->remove($comment_id);
|
||||
}
|
||||
|
||||
public function createComment($task_id, $user_id, $content, $reference = '', $visibility = Role::APP_USER)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createComment', $task_id);
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
$loggedUserID = $this->userSession->getId();
|
||||
if ($user_id != $loggedUserID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userRole = $this->userSession->getRole();
|
||||
if ($userRole === Role::APP_MANAGER && $visibility === Role::APP_ADMIN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($userRole === Role::APP_USER && $visibility !== Role::APP_USER) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'task_id' => $task_id,
|
||||
'user_id' => $user_id,
|
||||
'comment' => $content,
|
||||
'reference' => $reference,
|
||||
'visibility' => $visibility,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->commentValidator->validateCreation($values);
|
||||
|
||||
return $valid ? $this->commentModel->create($values) : false;
|
||||
}
|
||||
|
||||
public function updateComment($id, $content)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateComment', $id);
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
$loggedUserID = $this->userSession->getId();
|
||||
$comment = $this->commentModel->getById($id);
|
||||
if ($comment['user_id'] != $loggedUserID) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'comment' => $content,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->commentValidator->validateModification($values);
|
||||
return $valid && $this->commentModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Group Member API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GroupMemberProcedure extends BaseProcedure
|
||||
{
|
||||
public function getMemberGroups($user_id)
|
||||
{
|
||||
return $this->groupMemberModel->getGroups($user_id);
|
||||
}
|
||||
|
||||
public function getGroupMembers($group_id)
|
||||
{
|
||||
return $this->groupMemberModel->getMembers($group_id);
|
||||
}
|
||||
|
||||
public function addGroupMember($group_id, $user_id)
|
||||
{
|
||||
return $this->groupMemberModel->addUser($group_id, $user_id);
|
||||
}
|
||||
|
||||
public function removeGroupMember($group_id, $user_id)
|
||||
{
|
||||
return $this->groupMemberModel->removeUser($group_id, $user_id);
|
||||
}
|
||||
|
||||
public function isGroupMember($group_id, $user_id)
|
||||
{
|
||||
return $this->groupMemberModel->isMember($group_id, $user_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Group API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GroupProcedure extends BaseProcedure
|
||||
{
|
||||
public function createGroup($name, $external_id = '')
|
||||
{
|
||||
return $this->groupModel->create($name, $external_id);
|
||||
}
|
||||
|
||||
public function updateGroup($group_id, $name = null, $external_id = null)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $group_id,
|
||||
'name' => $name,
|
||||
'external_id' => $external_id,
|
||||
);
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->groupModel->update($values);
|
||||
}
|
||||
|
||||
public function removeGroup($group_id)
|
||||
{
|
||||
return $this->groupModel->remove($group_id);
|
||||
}
|
||||
|
||||
public function getGroup($group_id)
|
||||
{
|
||||
return $this->groupModel->getById($group_id);
|
||||
}
|
||||
|
||||
public function getAllGroups()
|
||||
{
|
||||
return $this->groupModel->getAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Link API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LinkProcedure extends BaseProcedure
|
||||
{
|
||||
/**
|
||||
* Get a link by id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $link_id Link id
|
||||
* @return array
|
||||
*/
|
||||
public function getLinkById($link_id)
|
||||
{
|
||||
return $this->linkModel->getById($link_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a link by name
|
||||
*
|
||||
* @access public
|
||||
* @param string $label
|
||||
* @return array
|
||||
*/
|
||||
public function getLinkByLabel($label)
|
||||
{
|
||||
return $this->linkModel->getByLabel($label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the opposite link id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $link_id Link id
|
||||
* @return integer
|
||||
*/
|
||||
public function getOppositeLinkId($link_id)
|
||||
{
|
||||
return $this->linkModel->getOppositeLinkId($link_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all links
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAllLinks()
|
||||
{
|
||||
return $this->linkModel->getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new link label
|
||||
*
|
||||
* @access public
|
||||
* @param string $label
|
||||
* @param string $opposite_label
|
||||
* @return boolean|integer
|
||||
*/
|
||||
public function createLink($label, $opposite_label = '')
|
||||
{
|
||||
$values = array(
|
||||
'label' => $label,
|
||||
'opposite_label' => $opposite_label,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->linkValidator->validateCreation($values);
|
||||
return $valid ? $this->linkModel->create($label, $opposite_label) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a link
|
||||
*
|
||||
* @access public
|
||||
* @param integer $link_id
|
||||
* @param integer $opposite_link_id
|
||||
* @param string $label
|
||||
* @return boolean
|
||||
*/
|
||||
public function updateLink($link_id, $opposite_link_id, $label)
|
||||
{
|
||||
$values = array(
|
||||
'id' => $link_id,
|
||||
'opposite_id' => $opposite_link_id,
|
||||
'label' => $label,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->linkValidator->validateModification($values);
|
||||
return $valid && $this->linkModel->update($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a link a the relation to its opposite
|
||||
*
|
||||
* @access public
|
||||
* @param integer $link_id
|
||||
* @return boolean
|
||||
*/
|
||||
public function removeLink($link_id)
|
||||
{
|
||||
return $this->linkModel->remove($link_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Me API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class MeProcedure extends BaseProcedure
|
||||
{
|
||||
public function getMe()
|
||||
{
|
||||
return session_get('user');
|
||||
}
|
||||
|
||||
public function getMyDashboard()
|
||||
{
|
||||
$userId = $this->userSession->getId();
|
||||
|
||||
return $this->taskListSubtaskAssigneeFormatter
|
||||
->withQuery($this->taskFinderModel->getUserQuery($userId))
|
||||
->withUserId($userId)
|
||||
->format();
|
||||
}
|
||||
|
||||
public function getMyActivityStream()
|
||||
{
|
||||
$project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
|
||||
return $this->helper->projectActivity->getProjectsEvents($project_ids, 100);
|
||||
}
|
||||
|
||||
public function createMyPrivateProject($name, $description = null)
|
||||
{
|
||||
if ($this->configModel->get('disable_private_project', 0) == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'is_private' => 1,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateCreation($values);
|
||||
return $valid ? $this->projectModel->create($values, $this->userSession->getId(), true) : false;
|
||||
}
|
||||
|
||||
public function getMyProjectsList()
|
||||
{
|
||||
return (object) $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId());
|
||||
}
|
||||
|
||||
public function getMyOverdueTasks()
|
||||
{
|
||||
return $this->taskFinderModel->getOverdueTasksByUser($this->userSession->getId());
|
||||
}
|
||||
|
||||
public function getMyProjects()
|
||||
{
|
||||
$project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
|
||||
$projects = $this->projectModel->getAllByIds($project_ids);
|
||||
|
||||
return $this->projectsApiFormatter->withProjects($projects)->format();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Core\ObjectStorage\ObjectStorageException;
|
||||
|
||||
/**
|
||||
* Project File API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectFileProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectFile($project_id, $file_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectFile', $project_id);
|
||||
$file = $this->projectFileModel->getById($file_id);
|
||||
|
||||
if (empty($file) || (int) $file['project_id'] !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function getAllProjectFiles($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllProjectFiles', $project_id);
|
||||
return $this->projectFileModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function downloadProjectFile($project_id, $file_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadProjectFile', $project_id);
|
||||
|
||||
try {
|
||||
$file = $this->projectFileModel->getById($file_id);
|
||||
|
||||
if (! empty($file) && (int) $file['project_id'] === (int) $project_id) {
|
||||
return base64_encode($this->objectStorage->get($file['path']));
|
||||
}
|
||||
} catch (ObjectStorageException $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function createProjectFile($project_id, $filename, $blob)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createProjectFile', $project_id);
|
||||
|
||||
try {
|
||||
return $this->projectFileModel->uploadContent($project_id, $filename, $blob);
|
||||
} catch (ObjectStorageException $e) {
|
||||
$this->logger->error(__METHOD__.': '.$e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeProjectFile($project_id, $file_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectFile', $project_id);
|
||||
$file = $this->projectFileModel->getById($file_id);
|
||||
|
||||
if (empty($file) || (int) $file['project_id'] !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->projectFileModel->remove($file_id);
|
||||
}
|
||||
|
||||
public function removeAllProjectFiles($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllProjectFiles', $project_id);
|
||||
return $this->projectFileModel->removeAll($project_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Class ProjectMetadataProcedure
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectMetadataProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectMetadata($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectMetadata', $project_id);
|
||||
return (object) $this->projectMetadataModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function getProjectMetadataByName($project_id, $name)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectMetadataByName', $project_id);
|
||||
return $this->projectMetadataModel->get($project_id, $name);
|
||||
}
|
||||
|
||||
public function saveProjectMetadata($project_id, array $values)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'saveProjectMetadata', $project_id);
|
||||
return $this->projectMetadataModel->save($project_id, $values);
|
||||
}
|
||||
|
||||
public function removeProjectMetadata($project_id, $name)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectMetadata', $project_id);
|
||||
return $this->projectMetadataModel->remove($project_id, $name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
/**
|
||||
* Project Permission API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectPermissionProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectUsers($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUsers', $project_id);
|
||||
return (object) $this->projectUserRoleModel->getAllUsers($project_id);
|
||||
}
|
||||
|
||||
public function getAssignableUsers($project_id, $prepend_unassigned = false)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAssignableUsers', $project_id);
|
||||
return (object) $this->projectUserRoleModel->getAssignableUsersList($project_id, $prepend_unassigned);
|
||||
}
|
||||
|
||||
public function addProjectUser($project_id, $user_id, $role = Role::PROJECT_MEMBER)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectUser', $project_id);
|
||||
return $this->projectUserRoleModel->addUser($project_id, $user_id, $role);
|
||||
}
|
||||
|
||||
public function addProjectGroup($project_id, $group_id, $role = Role::PROJECT_MEMBER)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectGroup', $project_id);
|
||||
return $this->projectGroupRoleModel->addGroup($project_id, $group_id, $role);
|
||||
}
|
||||
|
||||
public function removeProjectUser($project_id, $user_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectUser', $project_id);
|
||||
return $this->projectUserRoleModel->removeUser($project_id, $user_id);
|
||||
}
|
||||
|
||||
public function removeProjectGroup($project_id, $group_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectGroup', $project_id);
|
||||
return $this->projectGroupRoleModel->removeGroup($project_id, $group_id);
|
||||
}
|
||||
|
||||
public function changeProjectUserRole($project_id, $user_id, $role)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectUserRole', $project_id);
|
||||
return $this->projectUserRoleModel->changeUserRole($project_id, $user_id, $role);
|
||||
}
|
||||
|
||||
public function changeProjectGroupRole($project_id, $group_id, $role)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectGroupRole', $project_id);
|
||||
return $this->projectGroupRoleModel->changeGroupRole($project_id, $group_id, $role);
|
||||
}
|
||||
|
||||
public function getProjectUserRole($project_id, $user_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUserRole', $project_id);
|
||||
return $this->projectUserRoleModel->getUserRole($project_id, $user_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Project API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectById($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectById', $project_id);
|
||||
$project = $this->projectModel->getById($project_id);
|
||||
return $this->projectApiFormatter->withProject($project)->format();
|
||||
}
|
||||
|
||||
public function getProjectByName($name)
|
||||
{
|
||||
$project = $this->projectModel->getByName($name);
|
||||
|
||||
if (empty($project)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByName', $project['id']);
|
||||
return $this->projectApiFormatter->withProject($project)->format();
|
||||
}
|
||||
|
||||
public function getProjectByIdentifier($identifier)
|
||||
{
|
||||
$project = $this->projectModel->getByIdentifier($identifier);
|
||||
|
||||
if (empty($project)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByIdentifier', $project['id']);
|
||||
return $this->projectApiFormatter->withProject($project)->format();
|
||||
}
|
||||
|
||||
public function getProjectByEmail($email)
|
||||
{
|
||||
$project = $this->projectModel->getByEmail($email);
|
||||
|
||||
if (empty($project)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByEmail', $project['id']);
|
||||
return $this->projectApiFormatter->withProject($project)->format();
|
||||
}
|
||||
|
||||
public function getAllProjects()
|
||||
{
|
||||
return $this->projectsApiFormatter->withProjects($this->projectModel->getAll())->format();
|
||||
}
|
||||
|
||||
public function removeProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProject', $project_id);
|
||||
return $this->projectModel->remove($project_id);
|
||||
}
|
||||
|
||||
public function enableProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProject', $project_id);
|
||||
return $this->projectModel->enable($project_id);
|
||||
}
|
||||
|
||||
public function disableProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProject', $project_id);
|
||||
return $this->projectModel->disable($project_id);
|
||||
}
|
||||
|
||||
public function enableProjectPublicAccess($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProjectPublicAccess', $project_id);
|
||||
return $this->projectModel->enablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function disableProjectPublicAccess($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProjectPublicAccess', $project_id);
|
||||
return $this->projectModel->disablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function getProjectActivities(array $project_ids)
|
||||
{
|
||||
foreach ($project_ids as $project_id) {
|
||||
ProjectAuthorization::getInstance($this->container)
|
||||
->check($this->getClassName(), 'getProjectActivities', $project_id);
|
||||
}
|
||||
|
||||
return $this->helper->projectActivity->getProjectsEvents($project_ids);
|
||||
}
|
||||
|
||||
public function getProjectActivity($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectActivity', $project_id);
|
||||
return $this->helper->projectActivity->getProjectEvents($project_id);
|
||||
}
|
||||
|
||||
public function createProject($name, $description = null, $owner_id = 0, $identifier = null, $start_date = null, $end_date = null, $priority_default = null, $priority_start = null, $priority_end = null, $email = null)
|
||||
{
|
||||
if ($owner_id === 0 && $this->userSession->isLogged()) {
|
||||
$owner_id = $this->userSession->getId();
|
||||
}
|
||||
|
||||
$values = $this->filterValues(array(
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'identifier' => $identifier,
|
||||
'start_date' => $start_date,
|
||||
'end_date' => $end_date,
|
||||
'priority_default' => $priority_default,
|
||||
'priority_start' => $priority_start,
|
||||
'priority_end' => $priority_end,
|
||||
'email' => $email,
|
||||
));
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateCreation($values);
|
||||
return $valid ? $this->projectModel->create($values, $owner_id, $this->userSession->isLogged()) : false;
|
||||
}
|
||||
|
||||
public function updateProject($project_id, $name = null, $description = null, $owner_id = null, $identifier = null, $start_date = null, $end_date = null, $priority_default = null, $priority_start = null, $priority_end = null, $email = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateProject', $project_id);
|
||||
|
||||
$values = $this->filterValues(array(
|
||||
'id' => $project_id,
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'owner_id' => $owner_id,
|
||||
'identifier' => $identifier,
|
||||
'start_date' => $start_date,
|
||||
'end_date' => $end_date,
|
||||
'priority_default' => $priority_default,
|
||||
'priority_start' => $priority_start,
|
||||
'priority_end' => $priority_end,
|
||||
'email' => $email,
|
||||
));
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateModification($values);
|
||||
return $valid && $this->projectModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\SubtaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
|
||||
/**
|
||||
* Subtask API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskProcedure extends BaseProcedure
|
||||
{
|
||||
public function getSubtask($subtask_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtask', $subtask_id);
|
||||
return $this->subtaskModel->getById($subtask_id);
|
||||
}
|
||||
|
||||
public function getAllSubtasks($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSubtasks', $task_id);
|
||||
return $this->subtaskModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function removeSubtask($subtask_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSubtask', $subtask_id);
|
||||
return $this->subtaskModel->remove($subtask_id);
|
||||
}
|
||||
|
||||
public function createSubtask($task_id, $title, $user_id = 0, $time_estimated = 0, $time_spent = 0, $status = 0)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createSubtask', $task_id);
|
||||
|
||||
$values = array(
|
||||
'title' => $title,
|
||||
'task_id' => $task_id,
|
||||
'user_id' => $user_id,
|
||||
'time_estimated' => $time_estimated,
|
||||
'time_spent' => $time_spent,
|
||||
'status' => $status,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->subtaskValidator->validateCreation($values);
|
||||
return $valid ? $this->subtaskModel->create($values) : false;
|
||||
}
|
||||
|
||||
public function updateSubtask($id, $task_id, $title = null, $user_id = null, $time_estimated = null, $time_spent = null, $status = null, $position = null)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateSubtask', $task_id);
|
||||
|
||||
$subtask = $this->subtaskModel->getById($id);
|
||||
if (empty($subtask) || (int) $subtask['task_id'] !== (int) $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'task_id' => $task_id,
|
||||
'title' => $title,
|
||||
'user_id' => $user_id,
|
||||
'time_estimated' => $time_estimated,
|
||||
'time_spent' => $time_spent,
|
||||
'status' => $status,
|
||||
'position' => $position
|
||||
);
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
list($valid, ) = $this->subtaskValidator->validateApiModification($values);
|
||||
return $valid && $this->subtaskModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\SubtaskAuthorization;
|
||||
|
||||
/**
|
||||
* Subtask Time Tracking API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
* @author Nikolaos Georgakis
|
||||
*/
|
||||
class SubtaskTimeTrackingProcedure extends BaseProcedure
|
||||
{
|
||||
public function hasSubtaskTimer($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'hasSubtaskTimer', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->hasTimer($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function setSubtaskStartTime($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setSubtaskStartTime', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function setSubtaskEndTime($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setSubtaskEndTime', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function getSubtaskTimeSpent($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtaskTimeSpent', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->getTimeSpent($subtask_id, $user_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Model\SwimlaneModel;
|
||||
|
||||
/**
|
||||
* Swimlane API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SwimlaneProcedure extends BaseProcedure
|
||||
{
|
||||
public function getActiveSwimlanes($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActiveSwimlanes', $project_id);
|
||||
return $this->swimlaneModel->getAllByStatus($project_id, SwimlaneModel::ACTIVE);
|
||||
}
|
||||
|
||||
public function getAllSwimlanes($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSwimlanes', $project_id);
|
||||
return $this->swimlaneModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function getSwimlaneById($swimlane_id)
|
||||
{
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneById', $swimlane['project_id']);
|
||||
return $swimlane;
|
||||
}
|
||||
|
||||
public function getSwimlaneByName($project_id, $name)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneByName', $project_id);
|
||||
return $this->swimlaneModel->getByName($project_id, $name);
|
||||
}
|
||||
|
||||
public function getSwimlane($swimlane_id)
|
||||
{
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlane', $swimlane['project_id']);
|
||||
return $swimlane;
|
||||
}
|
||||
|
||||
public function addSwimlane($project_id, $name, $description = '')
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addSwimlane', $project_id);
|
||||
return $this->swimlaneModel->create($project_id, $name, $description);
|
||||
}
|
||||
|
||||
public function updateSwimlane($project_id, $swimlane_id, $name, $description = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateSwimlane', $project_id);
|
||||
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
|
||||
if (empty($swimlane) || (int) $swimlane['project_id'] !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'project_id' => $project_id,
|
||||
'id' => $swimlane_id,
|
||||
'name' => $name,
|
||||
);
|
||||
|
||||
if (! is_null($description)) {
|
||||
$values['description'] = $description;
|
||||
}
|
||||
|
||||
list($valid, $errors) = $this->swimlaneValidator->validateModification($values);
|
||||
|
||||
if (! $valid) {
|
||||
$this->logger->debug(__METHOD__.': Validation error: '.var_export($errors, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->swimlaneModel->update($swimlane_id, $values);
|
||||
}
|
||||
|
||||
public function removeSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSwimlane', $project_id);
|
||||
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
|
||||
if (empty($swimlane) || (int) $swimlane['project_id'] !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->swimlaneModel->remove($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function disableSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableSwimlane', $project_id);
|
||||
return $this->swimlaneModel->disable($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function enableSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableSwimlane', $project_id);
|
||||
return $this->swimlaneModel->enable($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function changeSwimlanePosition($project_id, $swimlane_id, $position)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeSwimlanePosition', $project_id);
|
||||
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
|
||||
if (empty($swimlane) || (int) $swimlane['project_id'] !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->swimlaneModel->changePosition($project_id, $swimlane_id, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TagAuthorization;
|
||||
|
||||
/**
|
||||
* Class TagProcedure
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TagProcedure extends BaseProcedure
|
||||
{
|
||||
public function getAllTags()
|
||||
{
|
||||
if ($this->userSession->isLogged() && ! $this->userSession->isAdmin()) {
|
||||
$project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
|
||||
return $this->tagModel->getAllByProjectIds($project_ids);
|
||||
}
|
||||
|
||||
return $this->tagModel->getAll();
|
||||
}
|
||||
|
||||
public function getTagsByProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTagsByProject', $project_id);
|
||||
return $this->tagModel->getAllByProject($project_id);
|
||||
}
|
||||
|
||||
public function createTag($project_id, $tag, $color_id = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTag', $project_id);
|
||||
return $this->tagModel->create($project_id, $tag, $color_id);
|
||||
}
|
||||
|
||||
public function updateTag($tag_id, $tag, $color_id = null)
|
||||
{
|
||||
TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTag', $tag_id);
|
||||
return $this->tagModel->update($tag_id, $tag, $color_id);
|
||||
}
|
||||
|
||||
public function removeTag($tag_id)
|
||||
{
|
||||
TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTag', $tag_id);
|
||||
return $this->tagModel->remove($tag_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkManager;
|
||||
use Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound;
|
||||
|
||||
/**
|
||||
* Task External Link API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskExternalLinkProcedure extends BaseProcedure
|
||||
{
|
||||
public function getExternalTaskLinkTypes()
|
||||
{
|
||||
return $this->externalLinkManager->getTypes();
|
||||
}
|
||||
|
||||
public function getExternalTaskLinkProviderDependencies($providerName)
|
||||
{
|
||||
try {
|
||||
return $this->externalLinkManager->getProvider($providerName)->getDependencies();
|
||||
} catch (ExternalLinkProviderNotFound $e) {
|
||||
$this->logger->error(__METHOD__.': '.$e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getExternalTaskLinkById($task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getExternalTaskLink', $task_id);
|
||||
$link = $this->taskExternalLinkModel->getById($link_id);
|
||||
|
||||
if (empty($link) || (int) $link['task_id'] !== (int) $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
public function getAllExternalTaskLinks($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getExternalTaskLinks', $task_id);
|
||||
return $this->taskExternalLinkModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function createExternalTaskLink($task_id, $url, $dependency, $type = ExternalLinkManager::TYPE_AUTO, $title = '')
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createExternalTaskLink', $task_id);
|
||||
|
||||
try {
|
||||
$provider = $this->externalLinkManager
|
||||
->setUserInputText($url)
|
||||
->setUserInputType($type)
|
||||
->find();
|
||||
|
||||
$link = $provider->getLink();
|
||||
|
||||
$values = array(
|
||||
'task_id' => $task_id,
|
||||
'title' => $title ?: $link->getTitle(),
|
||||
'url' => $link->getUrl(),
|
||||
'link_type' => $provider->getType(),
|
||||
'dependency' => $dependency,
|
||||
);
|
||||
|
||||
list($valid, $errors) = $this->externalLinkValidator->validateCreation($values);
|
||||
|
||||
if (! $valid) {
|
||||
$this->logger->error(__METHOD__.': '.var_export($errors));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->taskExternalLinkModel->create($values);
|
||||
} catch (ExternalLinkProviderNotFound $e) {
|
||||
$this->logger->error(__METHOD__.': '.$e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateExternalTaskLink($task_id, $link_id, $title = null, $url = null, $dependency = null)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateExternalTaskLink', $task_id);
|
||||
|
||||
$link = $this->taskExternalLinkModel->getById($link_id);
|
||||
|
||||
if (empty($link) || (int) $link['task_id'] !== (int) $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = $this->filterValues(array(
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'dependency' => $dependency,
|
||||
));
|
||||
|
||||
$values = array_merge($link, $values);
|
||||
list($valid, $errors) = $this->externalLinkValidator->validateModification($values);
|
||||
|
||||
if (! $valid) {
|
||||
$this->logger->error(__METHOD__.': '.var_export($errors));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->taskExternalLinkModel->update($values);
|
||||
}
|
||||
|
||||
public function removeExternalTaskLink($task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeExternalTaskLink', $task_id);
|
||||
$link = $this->taskExternalLinkModel->getById($link_id);
|
||||
|
||||
if (empty($link) || (int) $link['task_id'] !== (int) $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->taskExternalLinkModel->remove($link_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskFileAuthorization;
|
||||
use Kanboard\Core\ObjectStorage\ObjectStorageException;
|
||||
|
||||
/**
|
||||
* Task File API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFileProcedure extends BaseProcedure
|
||||
{
|
||||
public function getTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskFile', $file_id);
|
||||
return $this->taskFileModel->getById($file_id);
|
||||
}
|
||||
|
||||
public function getAllTaskFiles($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskFiles', $task_id);
|
||||
return $this->taskFileModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function downloadTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadTaskFile', $file_id);
|
||||
|
||||
try {
|
||||
$file = $this->taskFileModel->getById($file_id);
|
||||
|
||||
if (! empty($file)) {
|
||||
return base64_encode($this->objectStorage->get($file['path']));
|
||||
}
|
||||
} catch (ObjectStorageException $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function createTaskFile($project_id, $task_id, $filename, $blob)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskFile', $project_id);
|
||||
|
||||
if (!$this->taskFinderModel->exists($task_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$taskProjectID = $this->taskFinderModel->getProjectId($task_id);
|
||||
if ($taskProjectID != $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskFile', $task_id);
|
||||
|
||||
try {
|
||||
return $this->taskFileModel->uploadContent($task_id, $filename, $blob);
|
||||
} catch (ObjectStorageException $e) {
|
||||
$this->logger->error(__METHOD__.': '.$e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskFile', $file_id);
|
||||
return $this->taskFileModel->remove($file_id);
|
||||
}
|
||||
|
||||
public function removeAllTaskFiles($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllTaskFiles', $task_id);
|
||||
return $this->taskFileModel->removeAll($task_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskLinkAuthorization;
|
||||
|
||||
/**
|
||||
* TaskLink API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskLinkProcedure extends BaseProcedure
|
||||
{
|
||||
/**
|
||||
* Get a task link
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_link_id Task link id
|
||||
* @return array
|
||||
*/
|
||||
public function getTaskLinkById($task_link_id)
|
||||
{
|
||||
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskLinkById', $task_link_id);
|
||||
return $this->taskLinkModel->getById($task_link_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all links attached to a task
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_id Task id
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTaskLinks($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskLinks', $task_id);
|
||||
return $this->taskLinkModel->getAll($task_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new link
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_id Task id
|
||||
* @param integer $opposite_task_id Opposite task id
|
||||
* @param integer $link_id Link id
|
||||
* @return integer Task link id
|
||||
*/
|
||||
public function createTaskLink($task_id, $opposite_task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskLink', $task_id);
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
$opposite_task = $this->taskFinderModel->getById($opposite_task_id);
|
||||
|
||||
if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->taskLinkModel->create($task_id, $opposite_task_id, $link_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a task link
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_link_id Task link id
|
||||
* @param integer $task_id Task id
|
||||
* @param integer $opposite_task_id Opposite task id
|
||||
* @param integer $link_id Link id
|
||||
* @return boolean
|
||||
*/
|
||||
public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTaskLink', $task_id);
|
||||
|
||||
$taskLink = $this->taskLinkModel->getById($task_link_id);
|
||||
|
||||
if (empty($taskLink) || (int) $taskLink['task_id'] !== (int) $task_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
$opposite_task = $this->taskFinderModel->getById($opposite_task_id);
|
||||
|
||||
if (! $this->projectPermissionModel->isUserAllowed($opposite_task['project_id'], $this->userSession->getId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->taskLinkModel->update($task_link_id, $task_id, $opposite_task_id, $link_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a link between two tasks
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_link_id
|
||||
* @return boolean
|
||||
*/
|
||||
public function removeTaskLink($task_link_id)
|
||||
{
|
||||
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskLink', $task_link_id);
|
||||
return $this->taskLinkModel->remove($task_link_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
|
||||
/**
|
||||
* Class TaskMetadataProcedure
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskMetadataProcedure extends BaseProcedure
|
||||
{
|
||||
public function getTaskMetadata($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskMetadata', $task_id);
|
||||
return (object) $this->taskMetadataModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function getTaskMetadataByName($task_id, $name)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskMetadataByName', $task_id);
|
||||
return $this->taskMetadataModel->get($task_id, $name);
|
||||
}
|
||||
|
||||
public function saveTaskMetadata($task_id, array $values)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'saveTaskMetadata', $task_id);
|
||||
return $this->taskMetadataModel->save($task_id, $values);
|
||||
}
|
||||
|
||||
public function removeTaskMetadata($task_id, $name)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskMetadata', $task_id);
|
||||
return $this->taskMetadataModel->remove($task_id, $name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Filter\TaskProjectFilter;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Task API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskProcedure extends BaseProcedure
|
||||
{
|
||||
public function searchTasks($project_id, $query)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'searchTasks', $project_id);
|
||||
return $this->taskLexer->build($query)->withFilter(new TaskProjectFilter($project_id))->toArray();
|
||||
}
|
||||
|
||||
public function getTask($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTask', $task_id);
|
||||
$task = $this->taskFinderModel->getById($task_id);
|
||||
return $this->taskApiFormatter->withTask($task)->format();
|
||||
}
|
||||
|
||||
public function getTaskByReference($project_id, $reference)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskByReference', $project_id);
|
||||
$task = $this->taskFinderModel->getByReference($project_id, $reference);
|
||||
return $this->taskApiFormatter->withTask($task)->format();
|
||||
}
|
||||
|
||||
public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTasks', $project_id);
|
||||
$tasks = $this->taskFinderModel->getAll($project_id, $status_id);
|
||||
return $this->tasksApiFormatter->withTasks($tasks)->format();
|
||||
}
|
||||
|
||||
public function getOverdueTasks()
|
||||
{
|
||||
return $this->taskFinderModel->getOverdueTasks();
|
||||
}
|
||||
|
||||
public function getOverdueTasksByProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getOverdueTasksByProject', $project_id);
|
||||
return $this->taskFinderModel->getOverdueTasksByProject($project_id);
|
||||
}
|
||||
|
||||
public function openTask($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'openTask', $task_id);
|
||||
return $this->taskStatusModel->open($task_id);
|
||||
}
|
||||
|
||||
public function closeTask($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'closeTask', $task_id);
|
||||
return $this->taskStatusModel->close($task_id);
|
||||
}
|
||||
|
||||
public function removeTask($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTask', $task_id);
|
||||
return $this->taskModel->remove($task_id);
|
||||
}
|
||||
|
||||
public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $task_id);
|
||||
$taskProjectId = $this->taskFinderModel->getProjectId($task_id);
|
||||
|
||||
if ($taskProjectId !== (int) $project_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $project_id);
|
||||
return $this->taskPositionModel->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id, true, false);
|
||||
}
|
||||
|
||||
public function moveTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskToProject', $task_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskToProject', $project_id);
|
||||
return $this->taskProjectMoveModel->moveToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id);
|
||||
}
|
||||
|
||||
public function duplicateTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'duplicateTaskToProject', $task_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'duplicateTaskToProject', $project_id);
|
||||
return $this->taskProjectDuplicationModel->duplicateToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id);
|
||||
}
|
||||
|
||||
public function createTask(
|
||||
$title,
|
||||
$project_id,
|
||||
$color_id = '',
|
||||
$column_id = 0,
|
||||
$owner_id = 0,
|
||||
$creator_id = 0,
|
||||
$date_due = '',
|
||||
$description = '',
|
||||
$category_id = 0,
|
||||
$score = 0,
|
||||
$swimlane_id = null,
|
||||
$priority = 0,
|
||||
$recurrence_status = 0,
|
||||
$recurrence_trigger = 0,
|
||||
$recurrence_factor = 0,
|
||||
$recurrence_timeframe = 0,
|
||||
$recurrence_basedate = 0,
|
||||
$reference = '',
|
||||
array $tags = array(),
|
||||
$date_started = '',
|
||||
$time_spent = null,
|
||||
$time_estimated = null
|
||||
) {
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTask', $project_id);
|
||||
|
||||
if ($owner_id !== 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($creator_id !== 0 && ! $this->projectPermissionModel->isAssignable($project_id, $creator_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'title' => $title,
|
||||
'project_id' => $project_id,
|
||||
'color_id' => $color_id,
|
||||
'column_id' => $column_id,
|
||||
'owner_id' => $owner_id,
|
||||
'creator_id' => $creator_id,
|
||||
'date_due' => $date_due,
|
||||
'description' => $description,
|
||||
'category_id' => $category_id,
|
||||
'score' => $score,
|
||||
'swimlane_id' => $swimlane_id,
|
||||
'recurrence_status' => $recurrence_status,
|
||||
'recurrence_trigger' => $recurrence_trigger,
|
||||
'recurrence_factor' => $recurrence_factor,
|
||||
'recurrence_timeframe' => $recurrence_timeframe,
|
||||
'recurrence_basedate' => $recurrence_basedate,
|
||||
'reference' => $reference,
|
||||
'priority' => $priority,
|
||||
'tags' => $tags,
|
||||
'date_started' => $date_started,
|
||||
'time_spent' => $time_spent,
|
||||
'time_estimated' => $time_estimated,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->taskValidator->validateCreation($values);
|
||||
|
||||
return $valid ? $this->taskCreationModel->create($values) : false;
|
||||
}
|
||||
|
||||
public function updateTask(
|
||||
$id,
|
||||
$title = null,
|
||||
$color_id = null,
|
||||
$owner_id = null,
|
||||
$date_due = null,
|
||||
$description = null,
|
||||
$category_id = null,
|
||||
$score = null,
|
||||
$priority = null,
|
||||
$recurrence_status = null,
|
||||
$recurrence_trigger = null,
|
||||
$recurrence_factor = null,
|
||||
$recurrence_timeframe = null,
|
||||
$recurrence_basedate = null,
|
||||
$reference = null,
|
||||
$tags = null,
|
||||
$date_started = null,
|
||||
$time_spent = null,
|
||||
$time_estimated = null
|
||||
) {
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTask', $id);
|
||||
$project_id = $this->taskFinderModel->getProjectId($id);
|
||||
|
||||
if ($project_id === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($owner_id !== null && $owner_id != 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = $this->filterValues(array(
|
||||
'id' => $id,
|
||||
'title' => $title,
|
||||
'color_id' => $color_id,
|
||||
'owner_id' => $owner_id,
|
||||
'date_due' => $date_due,
|
||||
'description' => $description,
|
||||
'category_id' => $category_id,
|
||||
'score' => $score,
|
||||
'recurrence_status' => $recurrence_status,
|
||||
'recurrence_trigger' => $recurrence_trigger,
|
||||
'recurrence_factor' => $recurrence_factor,
|
||||
'recurrence_timeframe' => $recurrence_timeframe,
|
||||
'recurrence_basedate' => $recurrence_basedate,
|
||||
'reference' => $reference,
|
||||
'priority' => $priority,
|
||||
'tags' => $tags,
|
||||
'date_started' => $date_started,
|
||||
'time_spent' => $time_spent,
|
||||
'time_estimated' => $time_estimated,
|
||||
));
|
||||
|
||||
list($valid) = $this->taskValidator->validateApiModification($values);
|
||||
return $valid && $this->taskModificationModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
|
||||
/**
|
||||
* Class TaskTagProcedure
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskTagProcedure extends BaseProcedure
|
||||
{
|
||||
public function setTaskTags($project_id, $task_id, array $tags)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'setTaskTags', $project_id);
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setTaskTags', $task_id);
|
||||
return $this->taskTagModel->save($project_id, $task_id, $tags);
|
||||
}
|
||||
|
||||
public function getTaskTags($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskTags', $task_id);
|
||||
return (object) $this->taskTagModel->getList($task_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use LogicException;
|
||||
use Kanboard\Core\Security\Role;
|
||||
use Kanboard\Core\Ldap\Client as LdapClient;
|
||||
use Kanboard\Core\Ldap\ClientException as LdapException;
|
||||
use Kanboard\Core\Ldap\User as LdapUser;
|
||||
use Kanboard\Notification\MailNotification;
|
||||
use Kanboard\Notification\WebNotification;
|
||||
|
||||
/**
|
||||
* User API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserProcedure extends BaseProcedure
|
||||
{
|
||||
public function getUser($user_id)
|
||||
{
|
||||
return $this->userModel->getById($user_id);
|
||||
}
|
||||
|
||||
public function getUserByName($username)
|
||||
{
|
||||
return $this->userModel->getByUsername($username);
|
||||
}
|
||||
|
||||
public function getAllUsers()
|
||||
{
|
||||
return $this->userModel->getAll();
|
||||
}
|
||||
|
||||
public function removeUser($user_id)
|
||||
{
|
||||
return $this->userModel->remove($user_id);
|
||||
}
|
||||
|
||||
public function disableUser($user_id)
|
||||
{
|
||||
return $this->userModel->disable($user_id);
|
||||
}
|
||||
|
||||
public function enableUser($user_id)
|
||||
{
|
||||
return $this->userModel->enable($user_id);
|
||||
}
|
||||
|
||||
public function isActiveUser($user_id)
|
||||
{
|
||||
return $this->userModel->isActive($user_id);
|
||||
}
|
||||
|
||||
public function createUser($username, $password, $name = '', $email = '', $role = Role::APP_USER)
|
||||
{
|
||||
$values = array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'confirmation' => $password,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'role' => $role,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->userValidator->validateCreation($values);
|
||||
|
||||
if ($valid) {
|
||||
$user_id = $this->userModel->create($values);
|
||||
if ($user_id !== false && $this->configModel->get('notifications_enabled', 0) == 1) {
|
||||
$this->userNotificationTypeModel->saveSelectedTypes($user_id, [MailNotification::TYPE, WebNotification::TYPE]);
|
||||
}
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create LDAP user in the database
|
||||
*
|
||||
* Only "anonymous" and "proxy" LDAP authentication are supported by this method
|
||||
*
|
||||
* User information will be fetched from the LDAP server
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
* @return bool|int
|
||||
*/
|
||||
public function createLdapUser($username)
|
||||
{
|
||||
if (LDAP_BIND_TYPE === 'user') {
|
||||
$this->logger->error('LDAP authentication "user" is not supported by this API call');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$ldap = LdapClient::connect();
|
||||
$ldap->setLogger($this->logger);
|
||||
$user = LdapUser::getUser($ldap, $username);
|
||||
|
||||
if ($user === null) {
|
||||
$this->logger->info('User not found in LDAP server');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user->getUsername() === '') {
|
||||
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
||||
}
|
||||
|
||||
$values = array(
|
||||
'username' => $user->getUsername(),
|
||||
'name' => $user->getName(),
|
||||
'email' => $user->getEmail(),
|
||||
'role' => $user->getRole() ?: Role::APP_USER,
|
||||
'is_ldap_user' => 1,
|
||||
);
|
||||
|
||||
$user_id = $this->userModel->create($values);
|
||||
|
||||
if ($user_id !== false && $this->configModel->get('notifications_enabled', 0) == 1) {
|
||||
$this->userNotificationTypeModel->saveSelectedTypes($user_id, [MailNotification::TYPE, WebNotification::TYPE]);
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
} catch (LdapException $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUser($id, $username = null, $name = null, $email = null, $role = null)
|
||||
{
|
||||
$values = $this->filterValues(array(
|
||||
'id' => $id,
|
||||
'username' => $username,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'role' => $role,
|
||||
));
|
||||
|
||||
list($valid, ) = $this->userValidator->validateApiModification($values);
|
||||
return $valid && $this->userModel->update($values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Auth;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||
use Kanboard\Model\UserModel;
|
||||
use Kanboard\User\DatabaseUserProvider;
|
||||
|
||||
/**
|
||||
* API Access Token Authentication Provider
|
||||
*
|
||||
* @package Kanboard\Auth
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ApiAccessTokenAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||
{
|
||||
/**
|
||||
* User properties
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $userInfo = array();
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* Get authentication provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'API Access Token';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
if (session_get('scope') !== 'API') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $this->db
|
||||
->table(UserModel::TABLE)
|
||||
->columns('id', 'password')
|
||||
->eq('username', $this->username)
|
||||
->eq('api_access_token', $this->password)
|
||||
->notNull('api_access_token')
|
||||
->eq('is_active', 1)
|
||||
->findOne();
|
||||
|
||||
if (! empty($user)) {
|
||||
$this->userInfo = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user object
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\User\DatabaseUserProvider
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
if (empty($this->userInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DatabaseUserProvider($this->userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set username
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Auth;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||
use Kanboard\Core\Security\SessionCheckProviderInterface;
|
||||
use Kanboard\Model\UserModel;
|
||||
use Kanboard\User\DatabaseUserProvider;
|
||||
|
||||
/**
|
||||
* Database Authentication Provider
|
||||
*
|
||||
* @package Kanboard\Auth
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterface, SessionCheckProviderInterface
|
||||
{
|
||||
/**
|
||||
* User properties
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $userInfo = array();
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* Get authentication provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Database';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$user = $this->db
|
||||
->table(UserModel::TABLE)
|
||||
->columns('id', 'password')
|
||||
->eq('username', $this->username)
|
||||
->eq('disable_login_form', 0)
|
||||
->eq('is_ldap_user', 0)
|
||||
->eq('is_active', 1)
|
||||
->findOne();
|
||||
|
||||
if (! empty($user) && password_verify($this->password, $user['password'])) {
|
||||
$this->userInfo = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user session is valid
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValidSession()
|
||||
{
|
||||
return $this->userModel->isValidSession($this->userSession->getId(), $this->userSession->getRole());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user object
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\User\DatabaseUserProvider
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
if (empty($this->userInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DatabaseUserProvider($this->userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set username
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Auth;
|
||||
|
||||
use LogicException;
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Core\Ldap\Client as LdapClient;
|
||||
use Kanboard\Core\Ldap\ClientException as LdapException;
|
||||
use Kanboard\Core\Ldap\User as LdapUser;
|
||||
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||
|
||||
/**
|
||||
* LDAP Authentication Provider
|
||||
*
|
||||
* @package Kanboard\Auth
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||
{
|
||||
/**
|
||||
* User properties
|
||||
*
|
||||
* @access protected
|
||||
* @var \Kanboard\User\LdapUserProvider
|
||||
*/
|
||||
protected $userInfo = null;
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $username = '';
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* Get authentication provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'LDAP';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
try {
|
||||
|
||||
$client = LdapClient::connect($this->getLdapUsername(), $this->getLdapPassword());
|
||||
$client->setLogger($this->logger);
|
||||
|
||||
$user = LdapUser::getUser($client, $this->username);
|
||||
|
||||
if ($user === null) {
|
||||
$this->logger->info('User ('.$this->username.') not found in LDAP server');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user->getUsername() === '') {
|
||||
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
||||
}
|
||||
|
||||
$this->logger->info('Authenticate this user: '.$user->getDn());
|
||||
|
||||
if ($client->authenticate($user->getDn(), $this->password)) {
|
||||
$this->userInfo = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (LdapException $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user object
|
||||
*
|
||||
* @access public
|
||||
* @return \Kanboard\User\LdapUserProvider
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set username
|
||||
*
|
||||
* @access public
|
||||
* @param string $username
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LDAP username (proxy auth)
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLdapUsername()
|
||||
{
|
||||
switch ($this->getLdapBindType()) {
|
||||
case 'proxy':
|
||||
return LDAP_USERNAME;
|
||||
case 'user':
|
||||
return sprintf(LDAP_USERNAME, $this->username);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LDAP password (proxy auth)
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLdapPassword()
|
||||
{
|
||||
switch ($this->getLdapBindType()) {
|
||||
case 'proxy':
|
||||
return LDAP_PASSWORD;
|
||||
case 'user':
|
||||
return $this->password;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LDAP bind type
|
||||
*
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getLdapBindType()
|
||||
{
|
||||
if (LDAP_BIND_TYPE !== 'user' && LDAP_BIND_TYPE !== 'proxy' && LDAP_BIND_TYPE !== 'anonymous') {
|
||||
throw new LogicException('Wrong value for the parameter LDAP_BIND_TYPE');
|
||||
}
|
||||
|
||||
return LDAP_BIND_TYPE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Auth;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Core\Security\PreAuthenticationProviderInterface;
|
||||
use Kanboard\User\DatabaseUserProvider;
|
||||
|
||||
/**
|
||||
* RememberMe Cookie Authentication Provider
|
||||
*
|
||||
* @package Kanboard\Auth
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
|
||||
{
|
||||
/**
|
||||
* User properties
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $userInfo = array();
|
||||
|
||||
/**
|
||||
* Get authentication provider name
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'RememberMe';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user
|
||||
*
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$credentials = $this->rememberMeCookie->read();
|
||||
|
||||
if ($credentials !== false) {
|
||||
$session = $this->rememberMeSessionModel->find($credentials['token'], $credentials['sequence']);
|
||||
|
||||
if (! empty($session)) {
|
||||
$this->rememberMeCookie->write(
|
||||
$session['token'],
|
||||
$this->rememberMeSessionModel->updateSequence($session['token']),
|
||||
$session['expiration']
|
||||
);
|
||||
|
||||
$this->userInfo = $this->userModel->getById($session['user_id']);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user object
|
||||
*
|
||||
* @access public
|
||||
* @return DatabaseUserProvider
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
if (empty($this->userInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DatabaseUserProvider($this->userInfo);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user