mirror of
https://github.com/YunoHost-Apps/kanboard_ynh.git
synced 2024-09-03 19:36:17 +02:00
Update kanboard to v1.0.31
This commit is contained in:
parent
918986f169
commit
6cc879dffe
1229 changed files with 39417 additions and 16044 deletions
|
@ -33,7 +33,7 @@ From command line:
|
||||||
|
|
||||||
Infos
|
Infos
|
||||||
-----
|
-----
|
||||||
Kanboard v1.0.27
|
Kanboard v1.0.31
|
||||||
|
|
||||||
Yunohost forum thread: <https://forum.yunohost.org/t/kanboard-package/78>
|
Yunohost forum thread: <https://forum.yunohost.org/t/kanboard-package/78>
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ Test it
|
||||||
Test or upgrade to dev version:
|
Test or upgrade to dev version:
|
||||||
```
|
```
|
||||||
su - admin
|
su - admin
|
||||||
git clone -b dev https://github.com/mbugeia/kanboard_ynh
|
git clone -b dev https://github.com/YunoHost-Apps/kanboard_ynh
|
||||||
# to install
|
# to install
|
||||||
sudo yunohost app install -l Kanboard /home/admin/kanboard_ynh
|
sudo yunohost app install -l Kanboard /home/admin/kanboard_ynh
|
||||||
# to upgrade
|
# to upgrade
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
// Enable/Disable debug
|
// Enable/Disable debug
|
||||||
define('DEBUG', false);
|
define('DEBUG', false);
|
||||||
|
|
||||||
// Debug file path
|
// Available log drivers: syslog, stderr, stdout or file
|
||||||
define('DEBUG_FILE', __DIR__.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'debug.log');
|
define('LOG_DRIVER', '');
|
||||||
|
|
||||||
|
// Log filename if the log driver is "file"
|
||||||
|
define('LOG_FILE', __DIR__.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'debug.log');
|
||||||
|
|
||||||
// Plugins directory
|
// Plugins directory
|
||||||
define('PLUGINS_DIR', 'plugins');
|
define('PLUGINS_DIR', 'plugins');
|
||||||
|
@ -46,6 +49,15 @@ define('DB_NAME', 'yuno_dbuser');
|
||||||
// Mysql/Postgres custom port (null = default port)
|
// Mysql/Postgres custom port (null = default port)
|
||||||
define('DB_PORT', null);
|
define('DB_PORT', null);
|
||||||
|
|
||||||
|
// Mysql SSL key
|
||||||
|
define('DB_SSL_KEY', null);
|
||||||
|
|
||||||
|
// Mysql SSL certificate
|
||||||
|
define('DB_SSL_CERT', null);
|
||||||
|
|
||||||
|
// Mysql SSL CA
|
||||||
|
define('DB_SSL_CA', null);
|
||||||
|
|
||||||
// Enable LDAP authentication (false by default)
|
// Enable LDAP authentication (false by default)
|
||||||
define('LDAP_AUTH', false);
|
define('LDAP_AUTH', false);
|
||||||
|
|
||||||
|
@ -101,6 +113,13 @@ define('LDAP_USER_ATTRIBUTE_EMAIL', 'mail');
|
||||||
// LDAP attribute to find groups in user profile
|
// LDAP attribute to find groups in user profile
|
||||||
define('LDAP_USER_ATTRIBUTE_GROUPS', 'memberof');
|
define('LDAP_USER_ATTRIBUTE_GROUPS', 'memberof');
|
||||||
|
|
||||||
|
// LDAP attribute for user avatar image: thumbnailPhoto or jpegPhoto
|
||||||
|
define('LDAP_USER_ATTRIBUTE_PHOTO', '');
|
||||||
|
|
||||||
|
// LDAP attribute for user language, example: 'preferredlanguage'
|
||||||
|
// Put an empty string to disable language sync
|
||||||
|
define('LDAP_USER_ATTRIBUTE_LANGUAGE', '');
|
||||||
|
|
||||||
// Allow automatic LDAP user creation
|
// Allow automatic LDAP user creation
|
||||||
define('LDAP_USER_CREATION', true);
|
define('LDAP_USER_CREATION', true);
|
||||||
|
|
||||||
|
@ -123,6 +142,11 @@ define('LDAP_GROUP_BASE_DN', '');
|
||||||
// Example for ActiveDirectory: (&(objectClass=group)(sAMAccountName=%s*))
|
// Example for ActiveDirectory: (&(objectClass=group)(sAMAccountName=%s*))
|
||||||
define('LDAP_GROUP_FILTER', '');
|
define('LDAP_GROUP_FILTER', '');
|
||||||
|
|
||||||
|
// LDAP user group filter
|
||||||
|
// If this filter is configured, Kanboard will search user groups in LDAP_GROUP_BASE_DN with this filter
|
||||||
|
// Example for OpenLDAP: (&(objectClass=posixGroup)(memberUid=%s))
|
||||||
|
define('LDAP_GROUP_USER_FILTER', '');
|
||||||
|
|
||||||
// LDAP attribute for the group name
|
// LDAP attribute for the group name
|
||||||
define('LDAP_GROUP_ATTRIBUTE_NAME', 'cn');
|
define('LDAP_GROUP_ATTRIBUTE_NAME', 'cn');
|
||||||
|
|
||||||
|
@ -147,9 +171,6 @@ define('ENABLE_HSTS', false);
|
||||||
// Enable or disable "X-Frame-Options: DENY" HTTP header
|
// Enable or disable "X-Frame-Options: DENY" HTTP header
|
||||||
define('ENABLE_XFRAME', true);
|
define('ENABLE_XFRAME', true);
|
||||||
|
|
||||||
// Enable syslog logging
|
|
||||||
define('ENABLE_SYSLOG', true);
|
|
||||||
|
|
||||||
// Escape html inside markdown text
|
// Escape html inside markdown text
|
||||||
define('MARKDOWN_ESCAPE_HTML', true);
|
define('MARKDOWN_ESCAPE_HTML', true);
|
||||||
|
|
||||||
|
|
26
sources/.htaccess
Normal file
26
sources/.htaccess
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
Options -MultiViews
|
||||||
|
|
||||||
|
SetEnv HTTP_MOD_REWRITE On
|
||||||
|
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule ^ index.php [QSA,L]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<FilesMatch "(kanboard|config.php|config.default.php)">
|
||||||
|
<IfModule mod_version.c>
|
||||||
|
<IfVersion >= 2.3>
|
||||||
|
Require all denied
|
||||||
|
</IfVersion>
|
||||||
|
<IfVersion < 2.3>
|
||||||
|
Order allow,deny
|
||||||
|
Deny from all
|
||||||
|
</IfVersion>
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule !mod_version.c>
|
||||||
|
Order allow,deny
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
|
</FilesMatch>
|
|
@ -1,3 +1,135 @@
|
||||||
|
Version 1.0.31
|
||||||
|
--------------
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Added tags: global and specific by project
|
||||||
|
* Added application and project roles validation for API procedure calls
|
||||||
|
* Added new API call: "getProjectByIdentifier"
|
||||||
|
* Added new API calls for external task links, project attachments and subtask time tracking
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Use PHP 7 for the Docker image
|
||||||
|
* Preserve role for existing users when using ReverseProxy authentication
|
||||||
|
* Handle priority for task and project duplication
|
||||||
|
* Expose task reference field to the user interface
|
||||||
|
* Improve ICal export
|
||||||
|
* Added argument owner_id and identifier to project API calls
|
||||||
|
* Rewrite integration tests to run with Docker containers
|
||||||
|
* Use the same task form layout everywhere
|
||||||
|
* Removed some tasks dropdown menus that are now available with task edit form
|
||||||
|
* Make embedded documentation readable in multiple languages (if a translation is available)
|
||||||
|
* Added acceptance tests (browser tests)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fixed broken CSV exports
|
||||||
|
* Fixed identical background color for LetterAvatar on 32bits platforms (Hash greater than PHP_MAX_INT)
|
||||||
|
* Fixed lexer issue with non word characters
|
||||||
|
* Flush memory cache in worker to get latest config values
|
||||||
|
* Fixed empty title for web notification with only one overdue task
|
||||||
|
* Take default swimlane into consideration for SwimlaneModel::getFirstActiveSwimlane()
|
||||||
|
* Fixed "due today" highlighting
|
||||||
|
|
||||||
|
Version 1.0.30
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Show tasks that are due today in a different color
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fixed wrong controller for search in dashboard
|
||||||
|
* Fixed plural form in alert message
|
||||||
|
* Fixed CSS cosmetic issue with popover and tooltips
|
||||||
|
|
||||||
|
Version 1.0.29
|
||||||
|
--------------
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Manage plugin from the user interface and from the command line
|
||||||
|
* Added support for background workers
|
||||||
|
* Added the possibility to convert a subtask to a task
|
||||||
|
* Added menu entry to add tasks from all project views
|
||||||
|
* Add tasks in bulk from the board
|
||||||
|
* Add dropdown for projects
|
||||||
|
* Added config parameter to allow self-signed certificates for the HTTP client
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Display local date format in date picker
|
||||||
|
* Configure email settings with the user interface in addition to config file
|
||||||
|
* Upgrade Docker image to Alpine Linux 3.4
|
||||||
|
* Move task import to a separate section
|
||||||
|
* Mark web notification as read when clicking on it
|
||||||
|
* Support strtotime strings for date search
|
||||||
|
* Reset failed login counter and unlock user when changing password
|
||||||
|
* Task do not open anymore in a new window on the Gantt chart
|
||||||
|
* Do not display task progress for tasks with no start/end date
|
||||||
|
* Use Gulp and Bower to manage assets
|
||||||
|
* Controller and Middleware refactoring
|
||||||
|
* Replace jQuery mobile detection by the library isMobile
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fixed user date format parsing for dates that can be valid in multiple formats
|
||||||
|
* Do not sync user role if LDAP groups are not configured
|
||||||
|
* Fixed issue with unicode handling for letter based avatars and user initials
|
||||||
|
* Do not send notifications to disabled users
|
||||||
|
* Fixed wrong redirect when removing a task from the task view page
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
|
||||||
|
* Webhook to create tasks have been removed, use the API instead
|
||||||
|
* All controllers have been renamed, people who are not using URL rewriting will see different URLs
|
||||||
|
* All models have been renamed, plugin maintainers will have to update their plugins
|
||||||
|
|
||||||
|
Version 1.0.28
|
||||||
|
--------------
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Added automated action to change task color based on the priority
|
||||||
|
* Added support for LDAP Posix Groups (OpenLDAP with memberUid or groupOfNames)
|
||||||
|
* Added support for LDAP user photo attribute (Avatar image)
|
||||||
|
* Added support for language LDAP attribute
|
||||||
|
* Added support for Mysql SSL connection
|
||||||
|
* Search in activity stream
|
||||||
|
* Search in comments
|
||||||
|
* Search by task creator
|
||||||
|
* Added command line utility to reset user password and to disable 2FA
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Improve Avatar upload form
|
||||||
|
* User roles are now synced with LDAP at each login
|
||||||
|
* Improve web page title on the task view
|
||||||
|
* Unify task drop-down menu between different views
|
||||||
|
* Improve LDAP user group membership synchronization
|
||||||
|
* Category and user filters do not append anymore in search field
|
||||||
|
* Added more template hooks
|
||||||
|
* Added tasks search with the API
|
||||||
|
* Added priority field to API procedures
|
||||||
|
* Added API procedure "getMemberGroups"
|
||||||
|
* Added parameters for overdue tasks notifications: group by projects and send only to managers
|
||||||
|
* Allow people to install Kanboard outside of the DocumentRoot
|
||||||
|
* Allow plugins to be loaded from another folder
|
||||||
|
* Filter/Lexer/QueryBuilder refactoring
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Allow a project owner to manage his own public project
|
||||||
|
* Fixed PHP warning when removing a user with no Avatar image
|
||||||
|
* Fixed improper Markdown escaping for some tooltips
|
||||||
|
* Closing all tasks by column, also update closed tasks
|
||||||
|
* Fixed wrong task link generation within Markdown text
|
||||||
|
* Fixed wrong URL on comment toggle link for sorting
|
||||||
|
* Fixed form submission with Meta+Enter keyboard shortcut
|
||||||
|
* Removed PHP notices in comment suppression view
|
||||||
|
|
||||||
Version 1.0.27
|
Version 1.0.27
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -65,11 +65,11 @@ class CommentCreation extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return (bool) $this->comment->create(array(
|
return (bool) $this->commentModel->create(array(
|
||||||
'reference' => isset($data['reference']) ? $data['reference'] : '',
|
'reference' => isset($data['reference']) ? $data['reference'] : '',
|
||||||
'comment' => $data['comment'],
|
'comment' => $data['comment'],
|
||||||
'task_id' => $data['task_id'],
|
'task_id' => $data['task_id'],
|
||||||
'user_id' => isset($data['user_id']) && $this->projectPermission->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0,
|
'user_id' => isset($data['user_id']) && $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a comment of the triggering event to the task description.
|
* Add a comment of the triggering event to the task description.
|
||||||
|
@ -32,7 +32,7 @@ class CommentCreationMoveTaskColumn extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +71,9 @@ class CommentCreationMoveTaskColumn extends Base
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$column = $this->column->getById($data['column_id']);
|
$column = $this->columnModel->getById($data['column_id']);
|
||||||
|
|
||||||
return (bool) $this->comment->create(array(
|
return (bool) $this->commentModel->create(array(
|
||||||
'comment' => t('Moved to column %s', $column['title']),
|
'comment' => t('Moved to column %s', $column['title']),
|
||||||
'task_id' => $data['task_id'],
|
'task_id' => $data['task_id'],
|
||||||
'user_id' => $this->userSession->getId(),
|
'user_id' => $this->userSession->getId(),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a category automatically according to the color
|
* Set a category automatically according to the color
|
||||||
|
@ -32,7 +32,7 @@ class TaskAssignCategoryColor extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE_UPDATE,
|
TaskModel::EVENT_CREATE_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TaskAssignCategoryColor extends Base
|
||||||
'category_id' => $this->getParam('category_id'),
|
'category_id' => $this->getParam('category_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -74,7 +74,7 @@ class TaskAssignCategoryLabel extends Base
|
||||||
'category_id' => $this->getParam('category_id'),
|
'category_id' => $this->getParam('category_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\TaskLink;
|
use Kanboard\Model\TaskLinkModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a category automatically according to a task link
|
* Set a category automatically according to a task link
|
||||||
|
@ -33,7 +33,7 @@ class TaskAssignCategoryLink extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
TaskLink::EVENT_CREATE_UPDATE,
|
TaskLinkModel::EVENT_CREATE_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class TaskAssignCategoryLink extends Base
|
||||||
'category_id' => $this->getParam('category_id'),
|
'category_id' => $this->getParam('category_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +92,7 @@ class TaskAssignCategoryLink extends Base
|
||||||
public function hasRequiredCondition(array $data)
|
public function hasRequiredCondition(array $data)
|
||||||
{
|
{
|
||||||
if ($data['link_id'] == $this->getParam('link_id')) {
|
if ($data['link_id'] == $this->getParam('link_id')) {
|
||||||
$task = $this->taskFinder->getById($data['task_id']);
|
$task = $this->taskFinderModel->getById($data['task_id']);
|
||||||
return empty($task['category_id']);
|
return empty($task['category_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a color to a specific category
|
* Assign a color to a specific category
|
||||||
|
@ -32,7 +32,7 @@ class TaskAssignColorCategory extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE_UPDATE,
|
TaskModel::EVENT_CREATE_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TaskAssignColorCategory extends Base
|
||||||
'color_id' => $this->getParam('color_id'),
|
'color_id' => $this->getParam('color_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values, false);
|
return $this->taskModificationModel->update($values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a color to a task
|
* Assign a color to a task
|
||||||
|
@ -32,8 +32,8 @@ class TaskAssignColorColumn extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE,
|
TaskModel::EVENT_CREATE,
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class TaskAssignColorColumn extends Base
|
||||||
'color_id' => $this->getParam('color_id'),
|
'color_id' => $this->getParam('color_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values, false);
|
return $this->taskModificationModel->update($values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\TaskLink;
|
use Kanboard\Model\TaskLinkModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a color to a specific task link
|
* Assign a color to a specific task link
|
||||||
|
@ -32,7 +32,7 @@ class TaskAssignColorLink extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
TaskLink::EVENT_CREATE_UPDATE,
|
TaskLinkModel::EVENT_CREATE_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TaskAssignColorLink extends Base
|
||||||
'color_id' => $this->getParam('color_id'),
|
'color_id' => $this->getParam('color_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values, false);
|
return $this->taskModificationModel->update($values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
95
sources/app/Action/TaskAssignColorPriority.php
Normal file
95
sources/app/Action/TaskAssignColorPriority.php
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a color to a priority
|
||||||
|
*
|
||||||
|
* @package 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',
|
||||||
|
'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['priority'] == $this->getParam('priority');
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a color to a specific user
|
* Assign a color to a specific user
|
||||||
|
@ -32,8 +32,8 @@ class TaskAssignColorUser extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE,
|
TaskModel::EVENT_CREATE,
|
||||||
Task::EVENT_ASSIGNEE_CHANGE,
|
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class TaskAssignColorUser extends Base
|
||||||
'color_id' => $this->getParam('color_id'),
|
'color_id' => $this->getParam('color_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values, false);
|
return $this->taskModificationModel->update($values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a task to the logged user
|
* Assign a task to the logged user
|
||||||
|
@ -32,7 +32,7 @@ class TaskAssignCurrentUser extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE,
|
TaskModel::EVENT_CREATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TaskAssignCurrentUser extends Base
|
||||||
'owner_id' => $this->userSession->getId(),
|
'owner_id' => $this->userSession->getId(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a task to the logged user on column change
|
* Assign a task to the logged user on column change
|
||||||
|
@ -32,7 +32,7 @@ class TaskAssignCurrentUserColumn extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class TaskAssignCurrentUserColumn extends Base
|
||||||
'owner_id' => $this->userSession->getId(),
|
'owner_id' => $this->userSession->getId(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a task to a specific user
|
* Assign a task to a specific user
|
||||||
|
@ -32,8 +32,8 @@ class TaskAssignSpecificUser extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_CREATE_UPDATE,
|
TaskModel::EVENT_CREATE_UPDATE,
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class TaskAssignSpecificUser extends Base
|
||||||
'owner_id' => $this->getParam('user_id'),
|
'owner_id' => $this->getParam('user_id'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,7 +71,7 @@ class TaskAssignUser extends Base
|
||||||
'owner_id' => $data['owner_id'],
|
'owner_id' => $data['owner_id'],
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values);
|
return $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,6 +83,6 @@ class TaskAssignUser extends Base
|
||||||
*/
|
*/
|
||||||
public function hasRequiredCondition(array $data)
|
public function hasRequiredCondition(array $data)
|
||||||
{
|
{
|
||||||
return $this->projectPermission->isAssignable($this->getProjectId(), $data['owner_id']);
|
return $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['owner_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ class TaskClose extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return $this->taskStatus->close($data['task_id']);
|
return $this->taskStatusModel->close($data['task_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close automatically a task in a specific column
|
* Close automatically a task in a specific column
|
||||||
|
@ -32,7 +32,7 @@ class TaskCloseColumn extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class TaskCloseColumn extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return $this->taskStatus->close($data['task_id']);
|
return $this->taskStatusModel->close($data['task_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close automatically a task after when inactive
|
* Close automatically a task after when inactive
|
||||||
|
@ -31,7 +31,7 @@ class TaskCloseNoActivity extends Base
|
||||||
*/
|
*/
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(Task::EVENT_DAILY_CRONJOB);
|
return array(TaskModel::EVENT_DAILY_CRONJOB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +74,7 @@ class TaskCloseNoActivity extends Base
|
||||||
$duration = time() - $task['date_modification'];
|
$duration = time() - $task['date_modification'];
|
||||||
|
|
||||||
if ($duration > $max) {
|
if ($duration > $max) {
|
||||||
$results[] = $this->taskStatus->close($task['id']);
|
$results[] = $this->taskStatusModel->close($task['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ class TaskCreation extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return (bool) $this->taskCreation->create(array(
|
return (bool) $this->taskCreationModel->create(array(
|
||||||
'project_id' => $data['project_id'],
|
'project_id' => $data['project_id'],
|
||||||
'title' => $data['title'],
|
'title' => $data['title'],
|
||||||
'reference' => $data['reference'],
|
'reference' => $data['reference'],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate a task to another project
|
* Duplicate a task to another project
|
||||||
|
@ -32,8 +32,9 @@ class TaskDuplicateAnotherProject extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
Task::EVENT_CLOSE,
|
TaskModel::EVENT_CLOSE,
|
||||||
|
TaskModel::EVENT_CREATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +75,8 @@ class TaskDuplicateAnotherProject extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
$destination_column_id = $this->column->getFirstColumnId($this->getParam('project_id'));
|
$destination_column_id = $this->columnModel->getFirstColumnId($this->getParam('project_id'));
|
||||||
return (bool) $this->taskDuplication->duplicateToProject($data['task_id'], $this->getParam('project_id'), null, $destination_column_id);
|
return (bool) $this->taskProjectDuplicationModel->duplicateToProject($data['task_id'], $this->getParam('project_id'), null, $destination_column_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email a task to someone
|
* Email a task to someone
|
||||||
|
@ -32,8 +32,8 @@ class TaskEmail extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
Task::EVENT_CLOSE,
|
TaskModel::EVENT_CLOSE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,16 +75,16 @@ class TaskEmail extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
$user = $this->user->getById($this->getParam('user_id'));
|
$user = $this->userModel->getById($this->getParam('user_id'));
|
||||||
|
|
||||||
if (! empty($user['email'])) {
|
if (! empty($user['email'])) {
|
||||||
$task = $this->taskFinder->getDetails($data['task_id']);
|
$task = $this->taskFinderModel->getDetails($data['task_id']);
|
||||||
|
|
||||||
$this->emailClient->send(
|
$this->emailClient->send(
|
||||||
$user['email'],
|
$user['email'],
|
||||||
$user['name'] ?: $user['username'],
|
$user['name'] ?: $user['username'],
|
||||||
$this->getParam('subject'),
|
$this->getParam('subject'),
|
||||||
$this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->config->get('application_url')))
|
$this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->configModel->get('application_url')))
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Email a task with no activity
|
* Email a task with no activity
|
||||||
|
@ -32,7 +32,7 @@ class TaskEmailNoActivity extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_DAILY_CRONJOB,
|
TaskModel::EVENT_DAILY_CRONJOB,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class TaskEmailNoActivity extends Base
|
||||||
{
|
{
|
||||||
$results = array();
|
$results = array();
|
||||||
$max = $this->getParam('duration') * 86400;
|
$max = $this->getParam('duration') * 86400;
|
||||||
$user = $this->user->getById($this->getParam('user_id'));
|
$user = $this->userModel->getById($this->getParam('user_id'));
|
||||||
|
|
||||||
if (! empty($user['email'])) {
|
if (! empty($user['email'])) {
|
||||||
foreach ($data['tasks'] as $task) {
|
foreach ($data['tasks'] as $task) {
|
||||||
|
@ -110,13 +110,13 @@ class TaskEmailNoActivity extends Base
|
||||||
*/
|
*/
|
||||||
private function sendEmail($task_id, array $user)
|
private function sendEmail($task_id, array $user)
|
||||||
{
|
{
|
||||||
$task = $this->taskFinder->getDetails($task_id);
|
$task = $this->taskFinderModel->getDetails($task_id);
|
||||||
|
|
||||||
$this->emailClient->send(
|
$this->emailClient->send(
|
||||||
$user['email'],
|
$user['email'],
|
||||||
$user['name'] ?: $user['username'],
|
$user['name'] ?: $user['username'],
|
||||||
$this->getParam('subject'),
|
$this->getParam('subject'),
|
||||||
$this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->config->get('application_url')))
|
$this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->configModel->get('application_url')))
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a task to another project
|
* Move a task to another project
|
||||||
|
@ -32,8 +32,8 @@ class TaskMoveAnotherProject extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
Task::EVENT_CLOSE,
|
TaskModel::EVENT_CLOSE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class TaskMoveAnotherProject extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return $this->taskDuplication->moveToProject($data['task_id'], $this->getParam('project_id'));
|
return $this->taskProjectMoveModel->moveToProject($data['task_id'], $this->getParam('project_id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a task to another column when an assignee is set
|
* Move a task to another column when an assignee is set
|
||||||
|
@ -32,8 +32,8 @@ class TaskMoveColumnAssigned extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_ASSIGNEE_CHANGE,
|
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||||
Task::EVENT_UPDATE,
|
TaskModel::EVENT_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ class TaskMoveColumnAssigned extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
$original_task = $this->taskFinder->getById($data['task_id']);
|
$original_task = $this->taskFinderModel->getById($data['task_id']);
|
||||||
|
|
||||||
return $this->taskPosition->movePosition(
|
return $this->taskPositionModel->movePosition(
|
||||||
$data['project_id'],
|
$data['project_id'],
|
||||||
$data['task_id'],
|
$data['task_id'],
|
||||||
$this->getParam('dest_column_id'),
|
$this->getParam('dest_column_id'),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a task to another column when the category is changed
|
* Move a task to another column when the category is changed
|
||||||
|
@ -32,7 +32,7 @@ class TaskMoveColumnCategoryChange extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_UPDATE,
|
TaskModel::EVENT_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ class TaskMoveColumnCategoryChange extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
$original_task = $this->taskFinder->getById($data['task_id']);
|
$original_task = $this->taskFinderModel->getById($data['task_id']);
|
||||||
|
|
||||||
return $this->taskPosition->movePosition(
|
return $this->taskPositionModel->movePosition(
|
||||||
$data['project_id'],
|
$data['project_id'],
|
||||||
$data['task_id'],
|
$data['task_id'],
|
||||||
$this->getParam('dest_column_id'),
|
$this->getParam('dest_column_id'),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a task to another column when an assignee is cleared
|
* Move a task to another column when an assignee is cleared
|
||||||
|
@ -32,8 +32,8 @@ class TaskMoveColumnUnAssigned extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_ASSIGNEE_CHANGE,
|
TaskModel::EVENT_ASSIGNEE_CHANGE,
|
||||||
Task::EVENT_UPDATE,
|
TaskModel::EVENT_UPDATE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ class TaskMoveColumnUnAssigned extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
$original_task = $this->taskFinder->getById($data['task_id']);
|
$original_task = $this->taskFinderModel->getById($data['task_id']);
|
||||||
|
|
||||||
return $this->taskPosition->movePosition(
|
return $this->taskPositionModel->movePosition(
|
||||||
$data['project_id'],
|
$data['project_id'],
|
||||||
$data['task_id'],
|
$data['task_id'],
|
||||||
$this->getParam('dest_column_id'),
|
$this->getParam('dest_column_id'),
|
||||||
|
|
|
@ -63,7 +63,7 @@ class TaskOpen extends Base
|
||||||
*/
|
*/
|
||||||
public function doAction(array $data)
|
public function doAction(array $data)
|
||||||
{
|
{
|
||||||
return $this->taskStatus->open($data['task_id']);
|
return $this->taskStatusModel->open($data['task_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Action;
|
namespace Kanboard\Action;
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the start date of task
|
* Set the start date of task
|
||||||
|
@ -32,7 +32,7 @@ class TaskUpdateStartDate extends Base
|
||||||
public function getCompatibleEvents()
|
public function getCompatibleEvents()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
Task::EVENT_MOVE_COLUMN,
|
TaskModel::EVENT_MOVE_COLUMN,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class TaskUpdateStartDate extends Base
|
||||||
'date_started' => time(),
|
'date_started' => time(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->taskModification->update($values, false);
|
return $this->taskModificationModel->update($values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Kanboard\Analytic;
|
namespace Kanboard\Analytic;
|
||||||
|
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Average Lead and Cycle Time
|
* Average Lead and Cycle Time
|
||||||
|
@ -106,7 +106,7 @@ class AverageLeadCycleTimeAnalytic extends Base
|
||||||
private function getTasks($project_id)
|
private function getTasks($project_id)
|
||||||
{
|
{
|
||||||
return $this->db
|
return $this->db
|
||||||
->table(Task::TABLE)
|
->table(TaskModel::TABLE)
|
||||||
->columns('date_completed', 'date_creation', 'date_started')
|
->columns('date_completed', 'date_creation', 'date_started')
|
||||||
->eq('project_id', $project_id)
|
->eq('project_id', $project_id)
|
||||||
->desc('id')
|
->desc('id')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Kanboard\Analytic;
|
namespace Kanboard\Analytic;
|
||||||
|
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Average Time Spent by Column
|
* Average Time Spent by Column
|
||||||
|
@ -40,7 +40,7 @@ class AverageTimeSpentColumnAnalytic extends Base
|
||||||
private function initialize($project_id)
|
private function initialize($project_id)
|
||||||
{
|
{
|
||||||
$stats = array();
|
$stats = array();
|
||||||
$columns = $this->column->getList($project_id);
|
$columns = $this->columnModel->getList($project_id);
|
||||||
|
|
||||||
foreach ($columns as $column_id => $column_title) {
|
foreach ($columns as $column_id => $column_title) {
|
||||||
$stats[$column_id] = array(
|
$stats[$column_id] = array(
|
||||||
|
@ -110,7 +110,7 @@ class AverageTimeSpentColumnAnalytic extends Base
|
||||||
*/
|
*/
|
||||||
private function getTaskTimeByColumns(array &$task)
|
private function getTaskTimeByColumns(array &$task)
|
||||||
{
|
{
|
||||||
$columns = $this->transition->getTimeSpentByTask($task['id']);
|
$columns = $this->transitionModel->getTimeSpentByTask($task['id']);
|
||||||
|
|
||||||
if (! isset($columns[$task['column_id']])) {
|
if (! isset($columns[$task['column_id']])) {
|
||||||
$columns[$task['column_id']] = 0;
|
$columns[$task['column_id']] = 0;
|
||||||
|
@ -144,7 +144,7 @@ class AverageTimeSpentColumnAnalytic extends Base
|
||||||
private function getTasks($project_id)
|
private function getTasks($project_id)
|
||||||
{
|
{
|
||||||
return $this->db
|
return $this->db
|
||||||
->table(Task::TABLE)
|
->table(TaskModel::TABLE)
|
||||||
->columns('id', 'date_completed', 'date_moved', 'column_id')
|
->columns('id', 'date_completed', 'date_moved', 'column_id')
|
||||||
->eq('project_id', $project_id)
|
->eq('project_id', $project_id)
|
||||||
->desc('id')
|
->desc('id')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Kanboard\Analytic;
|
namespace Kanboard\Analytic;
|
||||||
|
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Model\Task;
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimated/Spent Time Comparison
|
* Estimated/Spent Time Comparison
|
||||||
|
@ -22,7 +22,7 @@ class EstimatedTimeComparisonAnalytic extends Base
|
||||||
*/
|
*/
|
||||||
public function build($project_id)
|
public function build($project_id)
|
||||||
{
|
{
|
||||||
$rows = $this->db->table(Task::TABLE)
|
$rows = $this->db->table(TaskModel::TABLE)
|
||||||
->columns('SUM(time_estimated) AS time_estimated', 'SUM(time_spent) AS time_spent', 'is_active')
|
->columns('SUM(time_estimated) AS time_estimated', 'SUM(time_spent) AS time_spent', 'is_active')
|
||||||
->eq('project_id', $project_id)
|
->eq('project_id', $project_id)
|
||||||
->groupBy('is_active')
|
->groupBy('is_active')
|
||||||
|
@ -40,7 +40,7 @@ class EstimatedTimeComparisonAnalytic extends Base
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$key = $row['is_active'] == Task::STATUS_OPEN ? 'open' : 'closed';
|
$key = $row['is_active'] == TaskModel::STATUS_OPEN ? 'open' : 'closed';
|
||||||
$metrics[$key]['time_spent'] = $row['time_spent'];
|
$metrics[$key]['time_spent'] = $row['time_spent'];
|
||||||
$metrics[$key]['time_estimated'] = $row['time_estimated'];
|
$metrics[$key]['time_estimated'] = $row['time_estimated'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ class TaskDistributionAnalytic extends Base
|
||||||
{
|
{
|
||||||
$metrics = array();
|
$metrics = array();
|
||||||
$total = 0;
|
$total = 0;
|
||||||
$columns = $this->column->getAll($project_id);
|
$columns = $this->columnModel->getAll($project_id);
|
||||||
|
|
||||||
foreach ($columns as $column) {
|
foreach ($columns as $column) {
|
||||||
$nb_tasks = $this->taskFinder->countByColumnId($project_id, $column['id']);
|
$nb_tasks = $this->taskFinderModel->countByColumnId($project_id, $column['id']);
|
||||||
$total += $nb_tasks;
|
$total += $nb_tasks;
|
||||||
|
|
||||||
$metrics[] = array(
|
$metrics[] = array(
|
||||||
|
|
|
@ -23,8 +23,8 @@ class UserDistributionAnalytic extends Base
|
||||||
{
|
{
|
||||||
$metrics = array();
|
$metrics = array();
|
||||||
$total = 0;
|
$total = 0;
|
||||||
$tasks = $this->taskFinder->getAll($project_id);
|
$tasks = $this->taskFinderModel->getAll($project_id);
|
||||||
$users = $this->projectUserRole->getAssignableUsersList($project_id);
|
$users = $this->projectUserRoleModel->getAssignableUsersList($project_id);
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
foreach ($tasks as $task) {
|
||||||
$user = isset($users[$task['owner_id']]) ? $users[$task['owner_id']] : $users[0];
|
$user = isset($users[$task['owner_id']]) ? $users[$task['owner_id']] : $users[0];
|
||||||
|
|
19
sources/app/Api/Authorization/ActionAuthorization.php
Normal file
19
sources/app/Api/Authorization/ActionAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/CategoryAuthorization.php
Normal file
19
sources/app/Api/Authorization/CategoryAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/ColumnAuthorization.php
Normal file
19
sources/app/Api/Authorization/ColumnAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/CommentAuthorization.php
Normal file
19
sources/app/Api/Authorization/CommentAuthorization.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Authorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
sources/app/Api/Authorization/ProcedureAuthorization.php
Normal file
32
sources/app/Api/Authorization/ProcedureAuthorization.php
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
sources/app/Api/Authorization/ProjectAuthorization.php
Normal file
35
sources/app/Api/Authorization/ProjectAuthorization.php
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/SubtaskAuthorization.php
Normal file
19
sources/app/Api/Authorization/SubtaskAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/TaskAuthorization.php
Normal file
19
sources/app/Api/Authorization/TaskAuthorization.php
Normal file
|
@ -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, $category_id)
|
||||||
|
{
|
||||||
|
if ($this->userSession->isLogged()) {
|
||||||
|
$this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($category_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/TaskFileAuthorization.php
Normal file
19
sources/app/Api/Authorization/TaskFileAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
sources/app/Api/Authorization/TaskLinkAuthorization.php
Normal file
19
sources/app/Api/Authorization/TaskLinkAuthorization.php
Normal file
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
sources/app/Api/Authorization/UserAuthorization.php
Normal file
22
sources/app/Api/Authorization/UserAuthorization.php
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,117 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
use JsonRPC\AccessDeniedException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
abstract class Base extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
private $user_allowed_procedures = array(
|
|
||||||
'getMe',
|
|
||||||
'getMyDashboard',
|
|
||||||
'getMyActivityStream',
|
|
||||||
'createMyPrivateProject',
|
|
||||||
'getMyProjectsList',
|
|
||||||
'getMyProjects',
|
|
||||||
'getMyOverdueTasks',
|
|
||||||
);
|
|
||||||
|
|
||||||
private $both_allowed_procedures = array(
|
|
||||||
'getTimezone',
|
|
||||||
'getVersion',
|
|
||||||
'getDefaultTaskColor',
|
|
||||||
'getDefaultTaskColors',
|
|
||||||
'getColorList',
|
|
||||||
'getProjectById',
|
|
||||||
'getTask',
|
|
||||||
'getTaskByReference',
|
|
||||||
'getAllTasks',
|
|
||||||
'openTask',
|
|
||||||
'closeTask',
|
|
||||||
'moveTaskPosition',
|
|
||||||
'createTask',
|
|
||||||
'updateTask',
|
|
||||||
'getBoard',
|
|
||||||
'getProjectActivity',
|
|
||||||
'getOverdueTasksByProject',
|
|
||||||
);
|
|
||||||
|
|
||||||
public function checkProcedurePermission($is_user, $procedure)
|
|
||||||
{
|
|
||||||
$is_both_procedure = in_array($procedure, $this->both_allowed_procedures);
|
|
||||||
$is_user_procedure = in_array($procedure, $this->user_allowed_procedures);
|
|
||||||
|
|
||||||
if ($is_user && ! $is_both_procedure && ! $is_user_procedure) {
|
|
||||||
throw new AccessDeniedException('Permission denied');
|
|
||||||
} elseif (! $is_user && ! $is_both_procedure && $is_user_procedure) {
|
|
||||||
throw new AccessDeniedException('Permission denied');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->logger->debug('API call: '.$procedure);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkProjectPermission($project_id)
|
|
||||||
{
|
|
||||||
if ($this->userSession->isLogged() && ! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) {
|
|
||||||
throw new AccessDeniedException('Permission denied');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkTaskPermission($task_id)
|
|
||||||
{
|
|
||||||
if ($this->userSession->isLogged()) {
|
|
||||||
$this->checkProjectPermission($this->taskFinder->getProjectId($task_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formatTask($task)
|
|
||||||
{
|
|
||||||
if (! empty($task)) {
|
|
||||||
$task['url'] = $this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), '', true);
|
|
||||||
$task['color'] = $this->color->getColorProperties($task['color_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $task;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formatTasks($tasks)
|
|
||||||
{
|
|
||||||
if (! empty($tasks)) {
|
|
||||||
foreach ($tasks as &$task) {
|
|
||||||
$task = $this->formatTask($task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formatProject($project)
|
|
||||||
{
|
|
||||||
if (! empty($project)) {
|
|
||||||
$project['url'] = array(
|
|
||||||
'board' => $this->helper->url->to('board', 'show', array('project_id' => $project['id']), '', true),
|
|
||||||
'calendar' => $this->helper->url->to('calendar', 'show', array('project_id' => $project['id']), '', true),
|
|
||||||
'list' => $this->helper->url->to('listing', 'show', array('project_id' => $project['id']), '', true),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $project;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function formatProjects($projects)
|
|
||||||
{
|
|
||||||
if (! empty($projects)) {
|
|
||||||
foreach ($projects as &$project) {
|
|
||||||
$project = $this->formatProject($project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $projects;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Board API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Board extends Base
|
|
||||||
{
|
|
||||||
public function getBoard($project_id)
|
|
||||||
{
|
|
||||||
$this->checkProjectPermission($project_id);
|
|
||||||
return $this->board->getBoard($project_id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Category API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Category extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
public function getCategory($category_id)
|
|
||||||
{
|
|
||||||
return $this->category->getById($category_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllCategories($project_id)
|
|
||||||
{
|
|
||||||
return $this->category->getAll($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeCategory($category_id)
|
|
||||||
{
|
|
||||||
return $this->category->remove($category_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createCategory($project_id, $name)
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'project_id' => $project_id,
|
|
||||||
'name' => $name,
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->categoryValidator->validateCreation($values);
|
|
||||||
return $valid ? $this->category->create($values) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateCategory($id, $name)
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'id' => $id,
|
|
||||||
'name' => $name,
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->categoryValidator->validateModification($values);
|
|
||||||
return $valid && $this->category->update($values);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Column API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Column extends Base
|
|
||||||
{
|
|
||||||
public function getColumns($project_id)
|
|
||||||
{
|
|
||||||
return $this->column->getAll($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getColumn($column_id)
|
|
||||||
{
|
|
||||||
return $this->column->getById($column_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateColumn($column_id, $title, $task_limit = 0, $description = '')
|
|
||||||
{
|
|
||||||
return $this->column->update($column_id, $title, $task_limit, $description);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addColumn($project_id, $title, $task_limit = 0, $description = '')
|
|
||||||
{
|
|
||||||
return $this->column->create($project_id, $title, $task_limit, $description);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeColumn($column_id)
|
|
||||||
{
|
|
||||||
return $this->column->remove($column_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changeColumnPosition($project_id, $column_id, $position)
|
|
||||||
{
|
|
||||||
return $this->column->changePosition($project_id, $column_id, $position);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comment API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Comment extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
public function getComment($comment_id)
|
|
||||||
{
|
|
||||||
return $this->comment->getById($comment_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllComments($task_id)
|
|
||||||
{
|
|
||||||
return $this->comment->getAll($task_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeComment($comment_id)
|
|
||||||
{
|
|
||||||
return $this->comment->remove($comment_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createComment($task_id, $user_id, $content, $reference = '')
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'task_id' => $task_id,
|
|
||||||
'user_id' => $user_id,
|
|
||||||
'comment' => $content,
|
|
||||||
'reference' => $reference,
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->commentValidator->validateCreation($values);
|
|
||||||
|
|
||||||
return $valid ? $this->comment->create($values) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateComment($id, $content)
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'id' => $id,
|
|
||||||
'comment' => $content,
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->commentValidator->validateModification($values);
|
|
||||||
return $valid && $this->comment->update($values);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
use Kanboard\Core\ObjectStorage\ObjectStorageException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class File extends Base
|
|
||||||
{
|
|
||||||
public function getTaskFile($file_id)
|
|
||||||
{
|
|
||||||
return $this->taskFile->getById($file_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllTaskFiles($task_id)
|
|
||||||
{
|
|
||||||
return $this->taskFile->getAll($task_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function downloadTaskFile($file_id)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$file = $this->taskFile->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)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return $this->taskFile->uploadContent($task_id, $filename, $blob);
|
|
||||||
} catch (ObjectStorageException $e) {
|
|
||||||
$this->logger->error($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeTaskFile($file_id)
|
|
||||||
{
|
|
||||||
return $this->taskFile->remove($file_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeAllTaskFiles($task_id)
|
|
||||||
{
|
|
||||||
return $this->taskFile->removeAll($task_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated procedures
|
|
||||||
|
|
||||||
public function getFile($file_id)
|
|
||||||
{
|
|
||||||
return $this->getTaskFile($file_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllFiles($task_id)
|
|
||||||
{
|
|
||||||
return $this->getAllTaskFiles($task_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function downloadFile($file_id)
|
|
||||||
{
|
|
||||||
return $this->downloadTaskFile($file_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createFile($project_id, $task_id, $filename, $blob)
|
|
||||||
{
|
|
||||||
return $this->createTaskFile($project_id, $task_id, $filename, $blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeFile($file_id)
|
|
||||||
{
|
|
||||||
return $this->removeTaskFile($file_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeAllFiles($task_id)
|
|
||||||
{
|
|
||||||
return $this->removeAllTaskFiles($task_id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group Member API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class GroupMember extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
public function getGroupMembers($group_id)
|
|
||||||
{
|
|
||||||
return $this->groupMember->getMembers($group_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addGroupMember($group_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->groupMember->addUser($group_id, $user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeGroupMember($group_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->groupMember->removeUser($group_id, $user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isGroupMember($group_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->groupMember->isMember($group_id, $user_id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
use Kanboard\Model\Subtask as SubtaskModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Me API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Me extends Base
|
|
||||||
{
|
|
||||||
public function getMe()
|
|
||||||
{
|
|
||||||
return $this->sessionStorage->user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMyDashboard()
|
|
||||||
{
|
|
||||||
$user_id = $this->userSession->getId();
|
|
||||||
$projects = $this->project->getQueryColumnStats($this->projectPermission->getActiveProjectIds($user_id))->findAll();
|
|
||||||
$tasks = $this->taskFinder->getUserQuery($user_id)->findAll();
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'projects' => $this->formatProjects($projects),
|
|
||||||
'tasks' => $this->formatTasks($tasks),
|
|
||||||
'subtasks' => $this->subtask->getUserQuery($user_id, array(SubTaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))->findAll(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMyActivityStream()
|
|
||||||
{
|
|
||||||
$project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId());
|
|
||||||
return $this->projectActivity->getProjects($project_ids, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createMyPrivateProject($name, $description = null)
|
|
||||||
{
|
|
||||||
if ($this->config->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->project->create($values, $this->userSession->getId(), true) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMyProjectsList()
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->getProjectsByUser($this->userSession->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMyOverdueTasks()
|
|
||||||
{
|
|
||||||
return $this->taskFinder->getOverdueTasksByUser($this->userSession->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMyProjects()
|
|
||||||
{
|
|
||||||
$project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId());
|
|
||||||
$projects = $this->project->getAllByIds($project_ids);
|
|
||||||
|
|
||||||
return $this->formatProjects($projects);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Middleware;
|
||||||
|
|
||||||
use JsonRPC\AuthenticationFailure;
|
use JsonRPC\Exception\AccessDeniedException;
|
||||||
|
use JsonRPC\Exception\AuthenticationFailureException;
|
||||||
|
use JsonRPC\MiddlewareInterface;
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class
|
* Class AuthenticationApiMiddleware
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Middleware
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Auth extends Base
|
class AuthenticationMiddleware extends Base implements MiddlewareInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Check api credentials
|
* Execute Middleware
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @param string $class
|
* @param string $procedureName
|
||||||
* @param string $method
|
* @throws AccessDeniedException
|
||||||
|
* @throws AuthenticationFailureException
|
||||||
*/
|
*/
|
||||||
public function checkCredentials($username, $password, $class, $method)
|
public function execute($username, $password, $procedureName)
|
||||||
{
|
{
|
||||||
$this->dispatcher->dispatch('app.bootstrap');
|
$this->dispatcher->dispatch('app.bootstrap');
|
||||||
|
|
||||||
if ($this->isUserAuthenticated($username, $password)) {
|
if ($this->isUserAuthenticated($username, $password)) {
|
||||||
$this->checkProcedurePermission(true, $method);
|
$this->userSession->initialize($this->userModel->getByUsername($username));
|
||||||
$this->userSession->initialize($this->user->getByUsername($username));
|
} elseif (! $this->isAppAuthenticated($username, $password)) {
|
||||||
} elseif ($this->isAppAuthenticated($username, $password)) {
|
|
||||||
$this->checkProcedurePermission(false, $method);
|
|
||||||
} else {
|
|
||||||
$this->logger->error('API authentication failure for '.$username);
|
$this->logger->error('API authentication failure for '.$username);
|
||||||
throw new AuthenticationFailure('Wrong credentials');
|
throw new AuthenticationFailureException('Wrong credentials');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ class Auth extends Base
|
||||||
private function isUserAuthenticated($username, $password)
|
private function isUserAuthenticated($username, $password)
|
||||||
{
|
{
|
||||||
return $username !== 'jsonrpc' &&
|
return $username !== 'jsonrpc' &&
|
||||||
! $this->userLocking->isLocked($username) &&
|
! $this->userLockingModel->isLocked($username) &&
|
||||||
$this->authenticationManager->passwordAuthentication($username, $password);
|
$this->authenticationManager->passwordAuthentication($username, $password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +77,6 @@ class Auth extends Base
|
||||||
return API_AUTHENTICATION_TOKEN;
|
return API_AUTHENTICATION_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->config->get('api_token');
|
return $this->configModel->get('api_token');
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\ActionAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action API controller
|
* Action API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Action extends \Kanboard\Core\Base
|
class ActionProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
public function getAvailableActions()
|
public function getAvailableActions()
|
||||||
{
|
{
|
||||||
|
@ -27,16 +30,19 @@ class Action extends \Kanboard\Core\Base
|
||||||
|
|
||||||
public function removeAction($action_id)
|
public function removeAction($action_id)
|
||||||
{
|
{
|
||||||
return $this->action->remove($action_id);
|
ActionAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAction', $action_id);
|
||||||
|
return $this->actionModel->remove($action_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getActions($project_id)
|
public function getActions($project_id)
|
||||||
{
|
{
|
||||||
return $this->action->getAllByProject($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)
|
public function createAction($project_id, $event_name, $action_name, array $params)
|
||||||
{
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createAction', $project_id);
|
||||||
$values = array(
|
$values = array(
|
||||||
'project_id' => $project_id,
|
'project_id' => $project_id,
|
||||||
'event_name' => $event_name,
|
'event_name' => $event_name,
|
||||||
|
@ -80,6 +86,6 @@ class Action extends \Kanboard\Core\Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->action->create($values);
|
return $this->actionModel->create($values);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App API controller
|
* App API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class App extends \Kanboard\Core\Base
|
class AppProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
public function getTimezone()
|
public function getTimezone()
|
||||||
{
|
{
|
||||||
return $this->config->get('application_timezone');
|
return $this->timezoneModel->getCurrentTimezone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVersion()
|
public function getVersion()
|
||||||
|
@ -22,17 +22,17 @@ class App extends \Kanboard\Core\Base
|
||||||
|
|
||||||
public function getDefaultTaskColor()
|
public function getDefaultTaskColor()
|
||||||
{
|
{
|
||||||
return $this->color->getDefaultColor();
|
return $this->colorModel->getDefaultColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultTaskColors()
|
public function getDefaultTaskColors()
|
||||||
{
|
{
|
||||||
return $this->color->getDefaultColors();
|
return $this->colorModel->getDefaultColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getColorList()
|
public function getColorList()
|
||||||
{
|
{
|
||||||
return $this->color->getList();
|
return $this->colorModel->getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getApplicationRoles()
|
public function getApplicationRoles()
|
85
sources/app/Api/Procedure/BaseProcedure.php
Normal file
85
sources/app/Api/Procedure/BaseProcedure.php
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?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 formatTask($task)
|
||||||
|
{
|
||||||
|
if (! empty($task)) {
|
||||||
|
$task['url'] = $this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), '', true);
|
||||||
|
$task['color'] = $this->colorModel->getColorProperties($task['color_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $task;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function formatTasks($tasks)
|
||||||
|
{
|
||||||
|
if (! empty($tasks)) {
|
||||||
|
foreach ($tasks as &$task) {
|
||||||
|
$task = $this->formatTask($task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function formatProject($project)
|
||||||
|
{
|
||||||
|
if (! empty($project)) {
|
||||||
|
$project['url'] = array(
|
||||||
|
'board' => $this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id']), '', true),
|
||||||
|
'calendar' => $this->helper->url->to('CalendarController', 'show', array('project_id' => $project['id']), '', true),
|
||||||
|
'list' => $this->helper->url->to('TaskListController', 'show', array('project_id' => $project['id']), '', true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function formatProjects($projects)
|
||||||
|
{
|
||||||
|
if (! empty($projects)) {
|
||||||
|
foreach ($projects as &$project) {
|
||||||
|
$project = $this->formatProject($project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
25
sources/app/Api/Procedure/BoardProcedure.php
Normal file
25
sources/app/Api/Procedure/BoardProcedure.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||||
|
use Kanboard\Formatter\BoardFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 BoardFormatter::getInstance($this->container)
|
||||||
|
->withProjectId($project_id)
|
||||||
|
->withQuery($this->taskFinderModel->getExtendedQuery())
|
||||||
|
->format();
|
||||||
|
}
|
||||||
|
}
|
59
sources/app/Api/Procedure/CategoryProcedure.php
Normal file
59
sources/app/Api/Procedure/CategoryProcedure.php
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?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)
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createCategory', $project_id);
|
||||||
|
|
||||||
|
$values = array(
|
||||||
|
'project_id' => $project_id,
|
||||||
|
'name' => $name,
|
||||||
|
);
|
||||||
|
|
||||||
|
list($valid, ) = $this->categoryValidator->validateCreation($values);
|
||||||
|
return $valid ? $this->categoryModel->create($values) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateCategory($id, $name)
|
||||||
|
{
|
||||||
|
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateCategory', $id);
|
||||||
|
|
||||||
|
$values = array(
|
||||||
|
'id' => $id,
|
||||||
|
'name' => $name,
|
||||||
|
);
|
||||||
|
|
||||||
|
list($valid, ) = $this->categoryValidator->validateModification($values);
|
||||||
|
return $valid && $this->categoryModel->update($values);
|
||||||
|
}
|
||||||
|
}
|
51
sources/app/Api/Procedure/ColumnProcedure.php
Normal file
51
sources/app/Api/Procedure/ColumnProcedure.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\ColumnAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
return $this->columnModel->remove($column_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeColumnPosition($project_id, $column_id, $position)
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeColumnPosition', $project_id);
|
||||||
|
return $this->columnModel->changePosition($project_id, $column_id, $position);
|
||||||
|
}
|
||||||
|
}
|
62
sources/app/Api/Procedure/CommentProcedure.php
Normal file
62
sources/app/Api/Procedure/CommentProcedure.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\CommentAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
return $this->commentModel->getAll($task_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeComment($comment_id)
|
||||||
|
{
|
||||||
|
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeComment', $comment_id);
|
||||||
|
return $this->commentModel->remove($comment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createComment($task_id, $user_id, $content, $reference = '')
|
||||||
|
{
|
||||||
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createComment', $task_id);
|
||||||
|
|
||||||
|
$values = array(
|
||||||
|
'task_id' => $task_id,
|
||||||
|
'user_id' => $user_id,
|
||||||
|
'comment' => $content,
|
||||||
|
'reference' => $reference,
|
||||||
|
);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
$values = array(
|
||||||
|
'id' => $id,
|
||||||
|
'comment' => $content,
|
||||||
|
);
|
||||||
|
|
||||||
|
list($valid, ) = $this->commentValidator->validateModification($values);
|
||||||
|
return $valid && $this->commentModel->update($values);
|
||||||
|
}
|
||||||
|
}
|
37
sources/app/Api/Procedure/GroupMemberProcedure.php
Normal file
37
sources/app/Api/Procedure/GroupMemberProcedure.php
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Group API controller
|
* Group API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Group extends \Kanboard\Core\Base
|
class GroupProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
public function createGroup($name, $external_id = '')
|
public function createGroup($name, $external_id = '')
|
||||||
{
|
{
|
||||||
return $this->group->create($name, $external_id);
|
return $this->groupModel->create($name, $external_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateGroup($group_id, $name = null, $external_id = null)
|
public function updateGroup($group_id, $name = null, $external_id = null)
|
||||||
|
@ -29,21 +29,21 @@ class Group extends \Kanboard\Core\Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->group->update($values);
|
return $this->groupModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeGroup($group_id)
|
public function removeGroup($group_id)
|
||||||
{
|
{
|
||||||
return $this->group->remove($group_id);
|
return $this->groupModel->remove($group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGroup($group_id)
|
public function getGroup($group_id)
|
||||||
{
|
{
|
||||||
return $this->group->getById($group_id);
|
return $this->groupModel->getById($group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllGroups()
|
public function getAllGroups()
|
||||||
{
|
{
|
||||||
return $this->group->getAll();
|
return $this->groupModel->getAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link API controller
|
* Link API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Link extends \Kanboard\Core\Base
|
class LinkProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get a link by id
|
* Get a link by id
|
||||||
|
@ -19,7 +19,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getLinkById($link_id)
|
public function getLinkById($link_id)
|
||||||
{
|
{
|
||||||
return $this->link->getById($link_id);
|
return $this->linkModel->getById($link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +31,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getLinkByLabel($label)
|
public function getLinkByLabel($label)
|
||||||
{
|
{
|
||||||
return $this->link->getByLabel($label);
|
return $this->linkModel->getByLabel($label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getOppositeLinkId($link_id)
|
public function getOppositeLinkId($link_id)
|
||||||
{
|
{
|
||||||
return $this->link->getOppositeLinkId($link_id);
|
return $this->linkModel->getOppositeLinkId($link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getAllLinks()
|
public function getAllLinks()
|
||||||
{
|
{
|
||||||
return $this->link->getAll();
|
return $this->linkModel->getAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +73,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
);
|
);
|
||||||
|
|
||||||
list($valid, ) = $this->linkValidator->validateCreation($values);
|
list($valid, ) = $this->linkValidator->validateCreation($values);
|
||||||
return $valid ? $this->link->create($label, $opposite_label) : false;
|
return $valid ? $this->linkModel->create($label, $opposite_label) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ class Link extends \Kanboard\Core\Base
|
||||||
);
|
);
|
||||||
|
|
||||||
list($valid, ) = $this->linkValidator->validateModification($values);
|
list($valid, ) = $this->linkValidator->validateModification($values);
|
||||||
return $valid && $this->link->update($values);
|
return $valid && $this->linkModel->update($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,6 +106,6 @@ class Link extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function removeLink($link_id)
|
public function removeLink($link_id)
|
||||||
{
|
{
|
||||||
return $this->link->remove($link_id);
|
return $this->linkModel->remove($link_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
72
sources/app/Api/Procedure/MeProcedure.php
Normal file
72
sources/app/Api/Procedure/MeProcedure.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Model\SubtaskModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Me API controller
|
||||||
|
*
|
||||||
|
* @package Kanboard\Api\Procedure
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class MeProcedure extends BaseProcedure
|
||||||
|
{
|
||||||
|
public function getMe()
|
||||||
|
{
|
||||||
|
return $this->sessionStorage->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMyDashboard()
|
||||||
|
{
|
||||||
|
$user_id = $this->userSession->getId();
|
||||||
|
$projects = $this->projectModel->getQueryColumnStats($this->projectPermissionModel->getActiveProjectIds($user_id))->findAll();
|
||||||
|
$tasks = $this->taskFinderModel->getUserQuery($user_id)->findAll();
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'projects' => $this->formatProjects($projects),
|
||||||
|
'tasks' => $this->formatTasks($tasks),
|
||||||
|
'subtasks' => $this->subtaskModel->getUserQuery($user_id, array(SubtaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))->findAll(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 $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->formatProjects($projects);
|
||||||
|
}
|
||||||
|
}
|
68
sources/app/Api/Procedure/ProjectFileProcedure.php
Normal file
68
sources/app/Api/Procedure/ProjectFileProcedure.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?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);
|
||||||
|
return $this->projectFileModel->getById($file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
69
sources/app/Api/Procedure/ProjectPermissionProcedure.php
Normal file
69
sources/app/Api/Procedure/ProjectPermissionProcedure.php
Normal file
|
@ -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 $this->projectUserRoleModel->getAllUsers($project_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAssignableUsers($project_id, $prepend_unassigned = false)
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAssignableUsers', $project_id);
|
||||||
|
return $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);
|
||||||
|
}
|
||||||
|
}
|
113
sources/app/Api/Procedure/ProjectProcedure.php
Normal file
113
sources/app/Api/Procedure/ProjectProcedure.php
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
<?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);
|
||||||
|
return $this->formatProject($this->projectModel->getById($project_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProjectByName($name)
|
||||||
|
{
|
||||||
|
$project = $this->projectModel->getByName($name);
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByName', $project['id']);
|
||||||
|
return $this->formatProject($project);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProjectByIdentifier($identifier)
|
||||||
|
{
|
||||||
|
$project = $this->formatProject($this->projectModel->getByIdentifier($identifier));
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByIdentifier', $project['id']);
|
||||||
|
return $this->formatProject($project);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllProjects()
|
||||||
|
{
|
||||||
|
return $this->formatProjects($this->projectModel->getAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
$values = $this->filterValues(array(
|
||||||
|
'name' => $name,
|
||||||
|
'description' => $description,
|
||||||
|
'identifier' => $identifier,
|
||||||
|
));
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
));
|
||||||
|
|
||||||
|
list($valid, ) = $this->projectValidator->validateModification($values);
|
||||||
|
return $valid && $this->projectModel->update($values);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,40 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\SubtaskAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtask API controller
|
* Subtask API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Subtask extends \Kanboard\Core\Base
|
class SubtaskProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
public function getSubtask($subtask_id)
|
public function getSubtask($subtask_id)
|
||||||
{
|
{
|
||||||
return $this->subtask->getById($subtask_id);
|
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtask', $subtask_id);
|
||||||
|
return $this->subtaskModel->getById($subtask_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllSubtasks($task_id)
|
public function getAllSubtasks($task_id)
|
||||||
{
|
{
|
||||||
return $this->subtask->getAll($task_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSubtasks', $task_id);
|
||||||
|
return $this->subtaskModel->getAll($task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeSubtask($subtask_id)
|
public function removeSubtask($subtask_id)
|
||||||
{
|
{
|
||||||
return $this->subtask->remove($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)
|
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(
|
$values = array(
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'task_id' => $task_id,
|
'task_id' => $task_id,
|
||||||
|
@ -37,11 +45,13 @@ class Subtask extends \Kanboard\Core\Base
|
||||||
);
|
);
|
||||||
|
|
||||||
list($valid, ) = $this->subtaskValidator->validateCreation($values);
|
list($valid, ) = $this->subtaskValidator->validateCreation($values);
|
||||||
return $valid ? $this->subtask->create($values) : false;
|
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)
|
public function updateSubtask($id, $task_id, $title = null, $user_id = null, $time_estimated = null, $time_spent = null, $status = null)
|
||||||
{
|
{
|
||||||
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateSubtask', $task_id);
|
||||||
|
|
||||||
$values = array(
|
$values = array(
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'task_id' => $task_id,
|
'task_id' => $task_id,
|
||||||
|
@ -59,6 +69,6 @@ class Subtask extends \Kanboard\Core\Base
|
||||||
}
|
}
|
||||||
|
|
||||||
list($valid, ) = $this->subtaskValidator->validateApiModification($values);
|
list($valid, ) = $this->subtaskValidator->validateApiModification($values);
|
||||||
return $valid && $this->subtask->update($values);
|
return $valid && $this->subtaskModel->update($values);
|
||||||
}
|
}
|
||||||
}
|
}
|
39
sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php
Normal file
39
sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
91
sources/app/Api/Procedure/SwimlaneProcedure.php
Normal file
91
sources/app/Api/Procedure/SwimlaneProcedure.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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->getSwimlanes($project_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return $this->swimlaneModel->getById($swimlane_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultSwimlane($project_id)
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getDefaultSwimlane', $project_id);
|
||||||
|
return $this->swimlaneModel->getDefault($project_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addSwimlane($project_id, $name, $description = '')
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addSwimlane', $project_id);
|
||||||
|
return $this->swimlaneModel->create(array('project_id' => $project_id, 'name' => $name, 'description' => $description));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateSwimlane($swimlane_id, $name, $description = null)
|
||||||
|
{
|
||||||
|
$values = array('id' => $swimlane_id, 'name' => $name);
|
||||||
|
|
||||||
|
if (!is_null($description)) {
|
||||||
|
$values['description'] = $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->swimlaneModel->update($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeSwimlane($project_id, $swimlane_id)
|
||||||
|
{
|
||||||
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSwimlane', $project_id);
|
||||||
|
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);
|
||||||
|
return $this->swimlaneModel->changePosition($project_id, $swimlane_id, $position);
|
||||||
|
}
|
||||||
|
}
|
106
sources/app/Api/Procedure/TaskExternalLinkProcedure.php
Normal file
106
sources/app/Api/Procedure/TaskExternalLinkProcedure.php
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<?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);
|
||||||
|
return $this->taskExternalLinkModel->getById($link_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
$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);
|
||||||
|
return $this->taskExternalLinkModel->remove($link_id);
|
||||||
|
}
|
||||||
|
}
|
70
sources/app/Api/Procedure/TaskFileProcedure.php
Normal file
70
sources/app/Api/Procedure/TaskFileProcedure.php
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
|
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\TaskLinkAuthorization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TaskLink API controller
|
* TaskLink API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class TaskLink extends \Kanboard\Core\Base
|
class TaskLinkProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get a task link
|
* Get a task link
|
||||||
|
@ -19,7 +22,8 @@ class TaskLink extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getTaskLinkById($task_link_id)
|
public function getTaskLinkById($task_link_id)
|
||||||
{
|
{
|
||||||
return $this->taskLink->getById($task_link_id);
|
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskLinkById', $task_link_id);
|
||||||
|
return $this->taskLinkModel->getById($task_link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +35,8 @@ class TaskLink extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getAllTaskLinks($task_id)
|
public function getAllTaskLinks($task_id)
|
||||||
{
|
{
|
||||||
return $this->taskLink->getAll($task_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskLinks', $task_id);
|
||||||
|
return $this->taskLinkModel->getAll($task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +50,8 @@ class TaskLink extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function createTaskLink($task_id, $opposite_task_id, $link_id)
|
public function createTaskLink($task_id, $opposite_task_id, $link_id)
|
||||||
{
|
{
|
||||||
return $this->taskLink->create($task_id, $opposite_task_id, $link_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskLink', $task_id);
|
||||||
|
return $this->taskLinkModel->create($task_id, $opposite_task_id, $link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +66,8 @@ class TaskLink extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id)
|
public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id)
|
||||||
{
|
{
|
||||||
return $this->taskLink->update($task_link_id, $task_id, $opposite_task_id, $link_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTaskLink', $task_id);
|
||||||
|
return $this->taskLinkModel->update($task_link_id, $task_id, $opposite_task_id, $link_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,6 +79,7 @@ class TaskLink extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function removeTaskLink($task_link_id)
|
public function removeTaskLink($task_link_id)
|
||||||
{
|
{
|
||||||
return $this->taskLink->remove($task_link_id);
|
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskLink', $task_link_id);
|
||||||
|
return $this->taskLinkModel->remove($task_link_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,87 +1,99 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
use Kanboard\Model\Task as TaskModel;
|
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||||
|
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||||
|
use Kanboard\Filter\TaskProjectFilter;
|
||||||
|
use Kanboard\Model\TaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task API controller
|
* Task API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Task extends Base
|
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)
|
public function getTask($task_id)
|
||||||
{
|
{
|
||||||
$this->checkTaskPermission($task_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTask', $task_id);
|
||||||
return $this->formatTask($this->taskFinder->getById($task_id));
|
return $this->formatTask($this->taskFinderModel->getById($task_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTaskByReference($project_id, $reference)
|
public function getTaskByReference($project_id, $reference)
|
||||||
{
|
{
|
||||||
$this->checkProjectPermission($project_id);
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskByReference', $project_id);
|
||||||
return $this->formatTask($this->taskFinder->getByReference($project_id, $reference));
|
return $this->formatTask($this->taskFinderModel->getByReference($project_id, $reference));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN)
|
public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN)
|
||||||
{
|
{
|
||||||
$this->checkProjectPermission($project_id);
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTasks', $project_id);
|
||||||
return $this->formatTasks($this->taskFinder->getAll($project_id, $status_id));
|
return $this->formatTasks($this->taskFinderModel->getAll($project_id, $status_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOverdueTasks()
|
public function getOverdueTasks()
|
||||||
{
|
{
|
||||||
return $this->taskFinder->getOverdueTasks();
|
return $this->taskFinderModel->getOverdueTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOverdueTasksByProject($project_id)
|
public function getOverdueTasksByProject($project_id)
|
||||||
{
|
{
|
||||||
$this->checkProjectPermission($project_id);
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getOverdueTasksByProject', $project_id);
|
||||||
return $this->taskFinder->getOverdueTasksByProject($project_id);
|
return $this->taskFinderModel->getOverdueTasksByProject($project_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function openTask($task_id)
|
public function openTask($task_id)
|
||||||
{
|
{
|
||||||
$this->checkTaskPermission($task_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'openTask', $task_id);
|
||||||
return $this->taskStatus->open($task_id);
|
return $this->taskStatusModel->open($task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function closeTask($task_id)
|
public function closeTask($task_id)
|
||||||
{
|
{
|
||||||
$this->checkTaskPermission($task_id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'closeTask', $task_id);
|
||||||
return $this->taskStatus->close($task_id);
|
return $this->taskStatusModel->close($task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeTask($task_id)
|
public function removeTask($task_id)
|
||||||
{
|
{
|
||||||
return $this->task->remove($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 = 0)
|
public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0)
|
||||||
{
|
{
|
||||||
$this->checkProjectPermission($project_id);
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $project_id);
|
||||||
return $this->taskPosition->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id);
|
return $this->taskPositionModel->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function moveTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
public function moveTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||||
{
|
{
|
||||||
return $this->taskDuplication->moveToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_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)
|
public function duplicateTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||||
{
|
{
|
||||||
return $this->taskDuplication->duplicateToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_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,
|
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 = 0,
|
$date_due = '', $description = '', $category_id = 0, $score = 0, $swimlane_id = 0, $priority = 0,
|
||||||
$recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
|
$recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
|
||||||
$recurrence_basedate = 0, $reference = '')
|
$recurrence_basedate = 0, $reference = '')
|
||||||
{
|
{
|
||||||
$this->checkProjectPermission($project_id);
|
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTask', $project_id);
|
||||||
|
|
||||||
if ($owner_id !== 0 && ! $this->projectPermission->isAssignable($project_id, $owner_id)) {
|
if ($owner_id !== 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,31 +119,31 @@ class Task extends Base
|
||||||
'recurrence_timeframe' => $recurrence_timeframe,
|
'recurrence_timeframe' => $recurrence_timeframe,
|
||||||
'recurrence_basedate' => $recurrence_basedate,
|
'recurrence_basedate' => $recurrence_basedate,
|
||||||
'reference' => $reference,
|
'reference' => $reference,
|
||||||
|
'priority' => $priority,
|
||||||
);
|
);
|
||||||
|
|
||||||
list($valid, ) = $this->taskValidator->validateCreation($values);
|
list($valid, ) = $this->taskValidator->validateCreation($values);
|
||||||
|
|
||||||
return $valid ? $this->taskCreation->create($values) : false;
|
return $valid ? $this->taskCreationModel->create($values) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateTask($id, $title = null, $color_id = null, $owner_id = null,
|
public function updateTask($id, $title = null, $color_id = null, $owner_id = null,
|
||||||
$date_due = null, $description = null, $category_id = null, $score = null,
|
$date_due = null, $description = null, $category_id = null, $score = null, $priority = null,
|
||||||
$recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null,
|
$recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null,
|
||||||
$recurrence_timeframe = null, $recurrence_basedate = null, $reference = null)
|
$recurrence_timeframe = null, $recurrence_basedate = null, $reference = null)
|
||||||
{
|
{
|
||||||
$this->checkTaskPermission($id);
|
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTask', $id);
|
||||||
|
$project_id = $this->taskFinderModel->getProjectId($id);
|
||||||
$project_id = $this->taskFinder->getProjectId($id);
|
|
||||||
|
|
||||||
if ($project_id === 0) {
|
if ($project_id === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($owner_id !== null && $owner_id != 0 && ! $this->projectPermission->isAssignable($project_id, $owner_id)) {
|
if ($owner_id !== null && $owner_id != 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = array(
|
$values = $this->filterValues(array(
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'color_id' => $color_id,
|
'color_id' => $color_id,
|
||||||
|
@ -146,15 +158,10 @@ class Task extends Base
|
||||||
'recurrence_timeframe' => $recurrence_timeframe,
|
'recurrence_timeframe' => $recurrence_timeframe,
|
||||||
'recurrence_basedate' => $recurrence_basedate,
|
'recurrence_basedate' => $recurrence_basedate,
|
||||||
'reference' => $reference,
|
'reference' => $reference,
|
||||||
);
|
'priority' => $priority,
|
||||||
|
));
|
||||||
foreach ($values as $key => $value) {
|
|
||||||
if (is_null($value)) {
|
|
||||||
unset($values[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list($valid) = $this->taskValidator->validateApiModification($values);
|
list($valid) = $this->taskValidator->validateApiModification($values);
|
||||||
return $valid && $this->taskModification->update($values);
|
return $valid && $this->taskModificationModel->update($values);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
namespace Kanboard\Api\Procedure;
|
||||||
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
@ -11,44 +11,44 @@ use Kanboard\Core\Ldap\User as LdapUser;
|
||||||
/**
|
/**
|
||||||
* User API controller
|
* User API controller
|
||||||
*
|
*
|
||||||
* @package api
|
* @package Kanboard\Api\Procedure
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class User extends \Kanboard\Core\Base
|
class UserProcedure extends BaseProcedure
|
||||||
{
|
{
|
||||||
public function getUser($user_id)
|
public function getUser($user_id)
|
||||||
{
|
{
|
||||||
return $this->user->getById($user_id);
|
return $this->userModel->getById($user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserByName($username)
|
public function getUserByName($username)
|
||||||
{
|
{
|
||||||
return $this->user->getByUsername($username);
|
return $this->userModel->getByUsername($username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllUsers()
|
public function getAllUsers()
|
||||||
{
|
{
|
||||||
return $this->user->getAll();
|
return $this->userModel->getAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeUser($user_id)
|
public function removeUser($user_id)
|
||||||
{
|
{
|
||||||
return $this->user->remove($user_id);
|
return $this->userModel->remove($user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function disableUser($user_id)
|
public function disableUser($user_id)
|
||||||
{
|
{
|
||||||
return $this->user->disable($user_id);
|
return $this->userModel->disable($user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enableUser($user_id)
|
public function enableUser($user_id)
|
||||||
{
|
{
|
||||||
return $this->user->enable($user_id);
|
return $this->userModel->enable($user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isActiveUser($user_id)
|
public function isActiveUser($user_id)
|
||||||
{
|
{
|
||||||
return $this->user->isActive($user_id);
|
return $this->userModel->isActive($user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createUser($username, $password, $name = '', $email = '', $role = Role::APP_USER)
|
public function createUser($username, $password, $name = '', $email = '', $role = Role::APP_USER)
|
||||||
|
@ -63,7 +63,7 @@ class User extends \Kanboard\Core\Base
|
||||||
);
|
);
|
||||||
|
|
||||||
list($valid, ) = $this->userValidator->validateCreation($values);
|
list($valid, ) = $this->userValidator->validateCreation($values);
|
||||||
return $valid ? $this->user->create($values) : false;
|
return $valid ? $this->userModel->create($values) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +107,7 @@ class User extends \Kanboard\Core\Base
|
||||||
'is_ldap_user' => 1,
|
'is_ldap_user' => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->user->create($values);
|
return $this->userModel->create($values);
|
||||||
|
|
||||||
} catch (LdapException $e) {
|
} catch (LdapException $e) {
|
||||||
$this->logger->error($e->getMessage());
|
$this->logger->error($e->getMessage());
|
||||||
|
@ -117,21 +117,15 @@ class User extends \Kanboard\Core\Base
|
||||||
|
|
||||||
public function updateUser($id, $username = null, $name = null, $email = null, $role = null)
|
public function updateUser($id, $username = null, $name = null, $email = null, $role = null)
|
||||||
{
|
{
|
||||||
$values = array(
|
$values = $this->filterValues(array(
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'role' => $role,
|
'role' => $role,
|
||||||
);
|
));
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
|
||||||
if (is_null($value)) {
|
|
||||||
unset($values[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list($valid, ) = $this->userValidator->validateApiModification($values);
|
list($valid, ) = $this->userValidator->validateApiModification($values);
|
||||||
return $valid && $this->user->update($values);
|
return $valid && $this->userModel->update($values);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Project API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Project extends Base
|
|
||||||
{
|
|
||||||
public function getProjectById($project_id)
|
|
||||||
{
|
|
||||||
$this->checkProjectPermission($project_id);
|
|
||||||
return $this->formatProject($this->project->getById($project_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProjectByName($name)
|
|
||||||
{
|
|
||||||
return $this->formatProject($this->project->getByName($name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllProjects()
|
|
||||||
{
|
|
||||||
return $this->formatProjects($this->project->getAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeProject($project_id)
|
|
||||||
{
|
|
||||||
return $this->project->remove($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enableProject($project_id)
|
|
||||||
{
|
|
||||||
return $this->project->enable($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function disableProject($project_id)
|
|
||||||
{
|
|
||||||
return $this->project->disable($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enableProjectPublicAccess($project_id)
|
|
||||||
{
|
|
||||||
return $this->project->enablePublicAccess($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function disableProjectPublicAccess($project_id)
|
|
||||||
{
|
|
||||||
return $this->project->disablePublicAccess($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProjectActivities(array $project_ids)
|
|
||||||
{
|
|
||||||
return $this->projectActivity->getProjects($project_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProjectActivity($project_id)
|
|
||||||
{
|
|
||||||
$this->checkProjectPermission($project_id);
|
|
||||||
return $this->projectActivity->getProject($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createProject($name, $description = null)
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'name' => $name,
|
|
||||||
'description' => $description
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->projectValidator->validateCreation($values);
|
|
||||||
return $valid ? $this->project->create($values) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateProject($id, $name, $description = null)
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'id' => $id,
|
|
||||||
'name' => $name,
|
|
||||||
'description' => $description
|
|
||||||
);
|
|
||||||
|
|
||||||
list($valid, ) = $this->projectValidator->validateModification($values);
|
|
||||||
return $valid && $this->project->update($values);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
use Kanboard\Core\Security\Role;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Project Permission API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class ProjectPermission extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
public function getProjectUsers($project_id)
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->getAllUsers($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAssignableUsers($project_id, $prepend_unassigned = false)
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->getAssignableUsersList($project_id, $prepend_unassigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addProjectUser($project_id, $user_id, $role = Role::PROJECT_MEMBER)
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->addUser($project_id, $user_id, $role);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addProjectGroup($project_id, $group_id, $role = Role::PROJECT_MEMBER)
|
|
||||||
{
|
|
||||||
return $this->projectGroupRole->addGroup($project_id, $group_id, $role);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeProjectUser($project_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->removeUser($project_id, $user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeProjectGroup($project_id, $group_id)
|
|
||||||
{
|
|
||||||
return $this->projectGroupRole->removeGroup($project_id, $group_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changeProjectUserRole($project_id, $user_id, $role)
|
|
||||||
{
|
|
||||||
return $this->projectUserRole->changeUserRole($project_id, $user_id, $role);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changeProjectGroupRole($project_id, $group_id, $role)
|
|
||||||
{
|
|
||||||
return $this->projectGroupRole->changeGroupRole($project_id, $group_id, $role);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
public function getMembers($project_id)
|
|
||||||
{
|
|
||||||
return $this->getProjectUsers($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
public function revokeUser($project_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->removeProjectUser($project_id, $user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
public function allowUser($project_id, $user_id)
|
|
||||||
{
|
|
||||||
return $this->addProjectUser($project_id, $user_id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Api;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swimlane API controller
|
|
||||||
*
|
|
||||||
* @package api
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*/
|
|
||||||
class Swimlane extends \Kanboard\Core\Base
|
|
||||||
{
|
|
||||||
public function getActiveSwimlanes($project_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getSwimlanes($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllSwimlanes($project_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getAll($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSwimlaneById($swimlane_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getById($swimlane_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSwimlaneByName($project_id, $name)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getByName($project_id, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSwimlane($swimlane_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getById($swimlane_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDefaultSwimlane($project_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->getDefault($project_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addSwimlane($project_id, $name, $description = '')
|
|
||||||
{
|
|
||||||
return $this->swimlane->create(array('project_id' => $project_id, 'name' => $name, 'description' => $description));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateSwimlane($swimlane_id, $name, $description = null)
|
|
||||||
{
|
|
||||||
$values = array('id' => $swimlane_id, 'name' => $name);
|
|
||||||
|
|
||||||
if (!is_null($description)) {
|
|
||||||
$values['description'] = $description;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->swimlane->update($values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeSwimlane($project_id, $swimlane_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->remove($project_id, $swimlane_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function disableSwimlane($project_id, $swimlane_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->disable($project_id, $swimlane_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enableSwimlane($project_id, $swimlane_id)
|
|
||||||
{
|
|
||||||
return $this->swimlane->enable($project_id, $swimlane_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changeSwimlanePosition($project_id, $swimlane_id, $position)
|
|
||||||
{
|
|
||||||
return $this->swimlane->changePosition($project_id, $swimlane_id, $position);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@ namespace Kanboard\Auth;
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||||
use Kanboard\Core\Security\SessionCheckProviderInterface;
|
use Kanboard\Core\Security\SessionCheckProviderInterface;
|
||||||
use Kanboard\Model\User;
|
use Kanboard\Model\UserModel;
|
||||||
use Kanboard\User\DatabaseUserProvider;
|
use Kanboard\User\DatabaseUserProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterfa
|
||||||
public function authenticate()
|
public function authenticate()
|
||||||
{
|
{
|
||||||
$user = $this->db
|
$user = $this->db
|
||||||
->table(User::TABLE)
|
->table(UserModel::TABLE)
|
||||||
->columns('id', 'password')
|
->columns('id', 'password')
|
||||||
->eq('username', $this->username)
|
->eq('username', $this->username)
|
||||||
->eq('disable_login_form', 0)
|
->eq('disable_login_form', 0)
|
||||||
|
@ -84,7 +84,7 @@ class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterfa
|
||||||
*/
|
*/
|
||||||
public function isValidSession()
|
public function isValidSession()
|
||||||
{
|
{
|
||||||
return $this->user->isActive($this->userSession->getId());
|
return $this->userModel->isActive($this->userSession->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -76,7 +76,7 @@ class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||||
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->info('Authenticate user: '.$user->getDn());
|
$this->logger->info('Authenticate this user: '.$user->getDn());
|
||||||
|
|
||||||
if ($client->authenticate($user->getDn(), $this->password)) {
|
if ($client->authenticate($user->getDn(), $this->password)) {
|
||||||
$this->userInfo = $user;
|
$this->userInfo = $user;
|
||||||
|
|
|
@ -44,16 +44,16 @@ class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
|
||||||
$credentials = $this->rememberMeCookie->read();
|
$credentials = $this->rememberMeCookie->read();
|
||||||
|
|
||||||
if ($credentials !== false) {
|
if ($credentials !== false) {
|
||||||
$session = $this->rememberMeSession->find($credentials['token'], $credentials['sequence']);
|
$session = $this->rememberMeSessionModel->find($credentials['token'], $credentials['sequence']);
|
||||||
|
|
||||||
if (! empty($session)) {
|
if (! empty($session)) {
|
||||||
$this->rememberMeCookie->write(
|
$this->rememberMeCookie->write(
|
||||||
$session['token'],
|
$session['token'],
|
||||||
$this->rememberMeSession->updateSequence($session['token']),
|
$this->rememberMeSessionModel->updateSequence($session['token']),
|
||||||
$session['expiration']
|
$session['expiration']
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->userInfo = $this->user->getById($session['user_id']);
|
$this->userInfo = $this->userModel->getById($session['user_id']);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,8 @@ class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterfac
|
||||||
$username = $this->request->getRemoteUser();
|
$username = $this->request->getRemoteUser();
|
||||||
|
|
||||||
if (! empty($username)) {
|
if (! empty($username)) {
|
||||||
$this->userInfo = new ReverseProxyUserProvider($username);
|
$userProfile = $this->userModel->getByUsername($username);
|
||||||
|
$this->userInfo = new ReverseProxyUserProvider($username, $userProfile ?: array());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Console;
|
|
||||||
|
|
||||||
use Pimple\Container;
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base command class
|
|
||||||
*
|
|
||||||
* @package console
|
|
||||||
* @author Frederic Guillot
|
|
||||||
*
|
|
||||||
* @property \Kanboard\Export\SubtaskExport $subtaskExport
|
|
||||||
* @property \Kanboard\Export\TaskExport $taskExport
|
|
||||||
* @property \Kanboard\Export\TransitionExport $transitionExport
|
|
||||||
* @property \Kanboard\Model\Notification $notification
|
|
||||||
* @property \Kanboard\Model\Project $project
|
|
||||||
* @property \Kanboard\Model\ProjectPermission $projectPermission
|
|
||||||
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
|
|
||||||
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
|
|
||||||
* @property \Kanboard\Model\Task $task
|
|
||||||
* @property \Kanboard\Model\TaskFinder $taskFinder
|
|
||||||
* @property \Kanboard\Model\UserNotification $userNotification
|
|
||||||
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
|
|
||||||
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
|
||||||
*/
|
|
||||||
abstract class Base extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Container instance
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @var \Pimple\Container
|
|
||||||
*/
|
|
||||||
protected $container;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param \Pimple\Container $container
|
|
||||||
*/
|
|
||||||
public function __construct(Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->container = $container;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load automatically models
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param string $name Model name
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function __get($name)
|
|
||||||
{
|
|
||||||
return $this->container[$name];
|
|
||||||
}
|
|
||||||
}
|
|
67
sources/app/Console/BaseCommand.php
Normal file
67
sources/app/Console/BaseCommand.php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Pimple\Container;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base command class
|
||||||
|
*
|
||||||
|
* @package console
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*
|
||||||
|
* @property \Kanboard\Validator\PasswordResetValidator $passwordResetValidator
|
||||||
|
* @property \Kanboard\Export\SubtaskExport $subtaskExport
|
||||||
|
* @property \Kanboard\Export\TaskExport $taskExport
|
||||||
|
* @property \Kanboard\Export\TransitionExport $transitionExport
|
||||||
|
* @property \Kanboard\Model\NotificationModel $notificationModel
|
||||||
|
* @property \Kanboard\Model\ProjectModel $projectModel
|
||||||
|
* @property \Kanboard\Model\ProjectPermissionModel $projectPermissionModel
|
||||||
|
* @property \Kanboard\Model\ProjectDailyColumnStatsModel $projectDailyColumnStatsModel
|
||||||
|
* @property \Kanboard\Model\ProjectDailyStatsModel $projectDailyStatsModel
|
||||||
|
* @property \Kanboard\Model\TaskModel $taskModel
|
||||||
|
* @property \Kanboard\Model\TaskFinderModel $taskFinderModel
|
||||||
|
* @property \Kanboard\Model\UserModel $userModel
|
||||||
|
* @property \Kanboard\Model\UserNotificationModel $userNotificationModel
|
||||||
|
* @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel
|
||||||
|
* @property \Kanboard\Model\ProjectUserRoleModel $projectUserRoleModel
|
||||||
|
* @property \Kanboard\Core\Plugin\Loader $pluginLoader
|
||||||
|
* @property \Kanboard\Core\Http\Client $httpClient
|
||||||
|
* @property \Kanboard\Core\Queue\QueueManager $queueManager
|
||||||
|
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
||||||
|
*/
|
||||||
|
abstract class BaseCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Container instance
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var \Pimple\Container
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param \Pimple\Container $container
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->container = $container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load automatically models
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $name Model name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
return $this->container[$name];
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Output\NullOutput;
|
use Symfony\Component\Console\Output\NullOutput;
|
||||||
|
|
||||||
class Cronjob extends Base
|
class CronjobCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
private $commands = array(
|
private $commands = array(
|
||||||
'projects:daily-stats',
|
'projects:daily-stats',
|
|
@ -7,7 +7,7 @@ use RecursiveDirectoryIterator;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class LocaleComparator extends Base
|
class LocaleComparatorCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
const REF_LOCALE = 'fr_FR';
|
const REF_LOCALE = 'fr_FR';
|
||||||
|
|
|
@ -6,7 +6,7 @@ use DirectoryIterator;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class LocaleSync extends Base
|
class LocaleSyncCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
const REF_LOCALE = 'fr_FR';
|
const REF_LOCALE = 'fr_FR';
|
||||||
|
|
36
sources/app/Console/PluginInstallCommand.php
Normal file
36
sources/app/Console/PluginInstallCommand.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Kanboard\Core\Plugin\Installer;
|
||||||
|
use Kanboard\Core\Plugin\PluginInstallerException;
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class PluginInstallCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('plugin:install')
|
||||||
|
->setDescription('Install a plugin from a remote Zip archive')
|
||||||
|
->addArgument('url', InputArgument::REQUIRED, 'Archive URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
if (!Installer::isConfigured()) {
|
||||||
|
throw new LogicException('Kanboard is not configured to install plugins itself');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$installer = new Installer($this->container);
|
||||||
|
$installer->install($input->getArgument('url'));
|
||||||
|
$output->writeln('<info>Plugin installed successfully</info>');
|
||||||
|
} catch (PluginInstallerException $e) {
|
||||||
|
$output->writeln('<error>'.$e->getMessage().'</error>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
sources/app/Console/PluginUninstallCommand.php
Normal file
36
sources/app/Console/PluginUninstallCommand.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Kanboard\Core\Plugin\Installer;
|
||||||
|
use Kanboard\Core\Plugin\PluginInstallerException;
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class PluginUninstallCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('plugin:uninstall')
|
||||||
|
->setDescription('Remove a plugin')
|
||||||
|
->addArgument('pluginId', InputArgument::REQUIRED, 'Plugin directory name');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
if (!Installer::isConfigured()) {
|
||||||
|
throw new LogicException('Kanboard is not configured to install plugins itself');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$installer = new Installer($this->container);
|
||||||
|
$installer->uninstall($input->getArgument('pluginId'));
|
||||||
|
$output->writeln('<info>Plugin removed successfully</info>');
|
||||||
|
} catch (PluginInstallerException $e) {
|
||||||
|
$output->writeln('<error>'.$e->getMessage().'</error>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
sources/app/Console/PluginUpgradeCommand.php
Normal file
55
sources/app/Console/PluginUpgradeCommand.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Kanboard\Core\Plugin\Base as BasePlugin;
|
||||||
|
use Kanboard\Core\Plugin\Directory;
|
||||||
|
use Kanboard\Core\Plugin\Installer;
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class PluginUpgradeCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('plugin:upgrade')
|
||||||
|
->setDescription('Update all installed plugins')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
if (!Installer::isConfigured()) {
|
||||||
|
throw new LogicException('Kanboard is not configured to install plugins itself');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installer = new Installer($this->container);
|
||||||
|
$availablePlugins = Directory::getInstance($this->container)->getAvailablePlugins();
|
||||||
|
|
||||||
|
foreach ($this->pluginLoader->getPlugins() as $installedPlugin) {
|
||||||
|
$pluginDetails = $this->getPluginDetails($availablePlugins, $installedPlugin);
|
||||||
|
|
||||||
|
if ($pluginDetails === null) {
|
||||||
|
$output->writeln('<error>* Plugin not available in the directory: '.$installedPlugin->getPluginName().'</error>');
|
||||||
|
} elseif ($pluginDetails['version'] > $installedPlugin->getPluginVersion()) {
|
||||||
|
$output->writeln('<comment>* Updating plugin: '.$installedPlugin->getPluginName().'</comment>');
|
||||||
|
$installer->update($pluginDetails['download']);
|
||||||
|
} else {
|
||||||
|
$output->writeln('<info>* Plugin up to date: '.$installedPlugin->getPluginName().'</info>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPluginDetails(array $availablePlugins, BasePlugin $installedPlugin)
|
||||||
|
{
|
||||||
|
foreach ($availablePlugins as $availablePlugin) {
|
||||||
|
if ($availablePlugin['title'] === $installedPlugin->getPluginName()) {
|
||||||
|
return $availablePlugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class ProjectDailyColumnStatsExport extends Base
|
class ProjectDailyColumnStatsExportCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ class ProjectDailyColumnStatsExport extends Base
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$data = $this->projectDailyColumnStats->getAggregatedMetrics(
|
$data = $this->projectDailyColumnStatsModel->getAggregatedMetrics(
|
||||||
$input->getArgument('project_id'),
|
$input->getArgument('project_id'),
|
||||||
$input->getArgument('start_date'),
|
$input->getArgument('start_date'),
|
||||||
$input->getArgument('end_date')
|
$input->getArgument('end_date')
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
namespace Kanboard\Console;
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
use Kanboard\Model\Project;
|
use Kanboard\Model\ProjectModel;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class ProjectDailyStatsCalculation extends Base
|
class ProjectDailyStatsCalculationCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
|
@ -17,12 +17,12 @@ class ProjectDailyStatsCalculation extends Base
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$projects = $this->project->getAllByStatus(Project::ACTIVE);
|
$projects = $this->projectModel->getAllByStatus(ProjectModel::ACTIVE);
|
||||||
|
|
||||||
foreach ($projects as $project) {
|
foreach ($projects as $project) {
|
||||||
$output->writeln('Run calculation for '.$project['name']);
|
$output->writeln('Run calculation for '.$project['name']);
|
||||||
$this->projectDailyColumnStats->updateTotals($project['id'], date('Y-m-d'));
|
$this->projectDailyColumnStatsModel->updateTotals($project['id'], date('Y-m-d'));
|
||||||
$this->projectDailyStats->updateTotals($project['id'], date('Y-m-d'));
|
$this->projectDailyStatsModel->updateTotals($project['id'], date('Y-m-d'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
79
sources/app/Console/ResetPasswordCommand.php
Normal file
79
sources/app/Console/ResetPasswordCommand.php
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
|
||||||
|
class ResetPasswordCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('user:reset-password')
|
||||||
|
->setDescription('Change user password')
|
||||||
|
->addArgument('username', InputArgument::REQUIRED, 'Username')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$helper = $this->getHelper('question');
|
||||||
|
$username = $input->getArgument('username');
|
||||||
|
|
||||||
|
$passwordQuestion = new Question('What is the new password for '.$username.'? (characters are not printed)'.PHP_EOL);
|
||||||
|
$passwordQuestion->setHidden(true);
|
||||||
|
$passwordQuestion->setHiddenFallback(false);
|
||||||
|
|
||||||
|
$password = $helper->ask($input, $output, $passwordQuestion);
|
||||||
|
|
||||||
|
$confirmationQuestion = new Question('Confirmation:'.PHP_EOL);
|
||||||
|
$confirmationQuestion->setHidden(true);
|
||||||
|
$confirmationQuestion->setHiddenFallback(false);
|
||||||
|
|
||||||
|
$confirmation = $helper->ask($input, $output, $confirmationQuestion);
|
||||||
|
|
||||||
|
if ($this->validatePassword($output, $password, $confirmation)) {
|
||||||
|
$this->resetPassword($output, $username, $password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validatePassword(OutputInterface $output, $password, $confirmation)
|
||||||
|
{
|
||||||
|
list($valid, $errors) = $this->passwordResetValidator->validateModification(array(
|
||||||
|
'password' => $password,
|
||||||
|
'confirmation' => $confirmation,
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!$valid) {
|
||||||
|
foreach ($errors as $error_list) {
|
||||||
|
foreach ($error_list as $error) {
|
||||||
|
$output->writeln('<error>'.$error.'</error>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resetPassword(OutputInterface $output, $username, $password)
|
||||||
|
{
|
||||||
|
$userId = $this->userModel->getIdByUsername($username);
|
||||||
|
|
||||||
|
if (empty($userId)) {
|
||||||
|
$output->writeln('<error>User not found</error>');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->userModel->update(array('id' => $userId, 'password' => $password))) {
|
||||||
|
$output->writeln('<error>Unable to update password</error>');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln('<info>Password updated successfully</info>');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
38
sources/app/Console/ResetTwoFactorCommand.php
Normal file
38
sources/app/Console/ResetTwoFactorCommand.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class ResetTwoFactorCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('user:reset-2fa')
|
||||||
|
->setDescription('Remove two-factor authentication for a user')
|
||||||
|
->addArgument('username', InputArgument::REQUIRED, 'Username');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$username = $input->getArgument('username');
|
||||||
|
$userId = $this->userModel->getIdByUsername($username);
|
||||||
|
|
||||||
|
if (empty($userId)) {
|
||||||
|
$output->writeln('<error>User not found</error>');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->userModel->update(array('id' => $userId, 'twofactor_activated' => 0, 'twofactor_secret' => ''))) {
|
||||||
|
$output->writeln('<error>Unable to update user profile</error>');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln('<info>Two-factor authentication disabled</info>');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class SubtaskExport extends Base
|
class SubtaskExportCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
|
@ -7,7 +7,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class TaskExport extends Base
|
class TaskExportCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
|
@ -1,116 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Kanboard\Console;
|
|
||||||
|
|
||||||
use Kanboard\Model\Task;
|
|
||||||
use Symfony\Component\Console\Helper\Table;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
|
|
||||||
class TaskOverdueNotification extends Base
|
|
||||||
{
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this
|
|
||||||
->setName('notification:overdue-tasks')
|
|
||||||
->setDescription('Send notifications for overdue tasks')
|
|
||||||
->addOption('show', null, InputOption::VALUE_NONE, 'Show sent overdue tasks');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
|
||||||
{
|
|
||||||
$tasks = $this->sendOverdueTaskNotifications();
|
|
||||||
|
|
||||||
if ($input->getOption('show')) {
|
|
||||||
$this->showTable($output, $tasks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function showTable(OutputInterface $output, array $tasks)
|
|
||||||
{
|
|
||||||
$rows = array();
|
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
|
||||||
$rows[] = array(
|
|
||||||
$task['id'],
|
|
||||||
$task['title'],
|
|
||||||
date('Y-m-d', $task['date_due']),
|
|
||||||
$task['project_id'],
|
|
||||||
$task['project_name'],
|
|
||||||
$task['assignee_name'] ?: $task['assignee_username'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$table = new Table($output);
|
|
||||||
$table
|
|
||||||
->setHeaders(array('Id', 'Title', 'Due date', 'Project Id', 'Project name', 'Assignee'))
|
|
||||||
->setRows($rows)
|
|
||||||
->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send overdue tasks
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function sendOverdueTaskNotifications()
|
|
||||||
{
|
|
||||||
$tasks = $this->taskFinder->getOverdueTasks();
|
|
||||||
|
|
||||||
foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) {
|
|
||||||
$users = $this->userNotification->getUsersWithNotificationEnabled($project_id);
|
|
||||||
|
|
||||||
foreach ($users as $user) {
|
|
||||||
$this->sendUserOverdueTaskNotifications($user, $project_tasks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send overdue tasks for a given user
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $user
|
|
||||||
* @param array $tasks
|
|
||||||
*/
|
|
||||||
public function sendUserOverdueTaskNotifications(array $user, array $tasks)
|
|
||||||
{
|
|
||||||
$user_tasks = array();
|
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
|
||||||
if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) {
|
|
||||||
$user_tasks[] = $task;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($user_tasks)) {
|
|
||||||
$this->userNotification->sendUserNotification(
|
|
||||||
$user,
|
|
||||||
Task::EVENT_OVERDUE,
|
|
||||||
array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group a collection of records by a column
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $collection
|
|
||||||
* @param string $column
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function groupByColumn(array $collection, $column)
|
|
||||||
{
|
|
||||||
$result = array();
|
|
||||||
|
|
||||||
foreach ($collection as $item) {
|
|
||||||
$result[$item[$column]][] = $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue