summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Api/Auth.php4
-rw-r--r--app/Api/Base.php3
-rw-r--r--app/Api/GroupMember.php5
-rw-r--r--app/Api/Task.php13
-rw-r--r--app/Console/BaseCommand.php1
-rw-r--r--app/Console/TaskOverdueNotificationCommand.php81
-rw-r--r--app/Controller/Comment.php2
-rw-r--r--app/Core/Plugin/Loader.php8
-rw-r--r--app/Core/Template.php2
-rw-r--r--app/Locale/bs_BA/translations.php10
-rw-r--r--app/Locale/cs_CZ/translations.php2
-rw-r--r--app/Locale/da_DK/translations.php2
-rw-r--r--app/Locale/de_DE/translations.php6
-rw-r--r--app/Locale/el_GR/translations.php2
-rw-r--r--app/Locale/es_ES/translations.php2
-rw-r--r--app/Locale/fi_FI/translations.php2
-rw-r--r--app/Locale/fr_FR/translations.php2
-rw-r--r--app/Locale/hu_HU/translations.php2
-rw-r--r--app/Locale/id_ID/translations.php2
-rw-r--r--app/Locale/it_IT/translations.php2
-rw-r--r--app/Locale/ja_JP/translations.php2
-rw-r--r--app/Locale/ko_KR/translations.php2
-rw-r--r--app/Locale/my_MY/translations.php2
-rw-r--r--app/Locale/nb_NO/translations.php2
-rw-r--r--app/Locale/nl_NL/translations.php2
-rw-r--r--app/Locale/pl_PL/translations.php2
-rw-r--r--app/Locale/pt_BR/translations.php2
-rw-r--r--app/Locale/pt_PT/translations.php2
-rw-r--r--app/Locale/ru_RU/translations.php30
-rw-r--r--app/Locale/sr_Latn_RS/translations.php2
-rw-r--r--app/Locale/sv_SE/translations.php2
-rw-r--r--app/Locale/th_TH/translations.php2
-rw-r--r--app/Locale/tr_TR/translations.php2
-rw-r--r--app/Locale/zh_CN/translations.php2
-rw-r--r--app/Model/GroupMember.php17
-rw-r--r--app/Model/TaskFinder.php2
-rw-r--r--app/Template/app/notifications.php2
-rw-r--r--app/Template/app/tasks.php8
-rw-r--r--app/Template/notification/task_overdue.php43
-rw-r--r--app/Template/project/sidebar.php2
-rw-r--r--app/Template/project_header/search.php8
-rw-r--r--app/Template/task/details.php12
-rw-r--r--app/Template/task/dropdown.php2
-rw-r--r--app/Template/task/layout.php3
-rw-r--r--app/Template/task/show.php2
-rw-r--r--app/Template/task/sidebar.php6
-rw-r--r--app/Template/task_creation/form.php4
-rw-r--r--app/Template/task_modification/edit_task.php6
-rw-r--r--app/check_setup.php4
-rw-r--r--app/common.php12
-rw-r--r--app/constants.php19
51 files changed, 260 insertions, 101 deletions
diff --git a/app/Api/Auth.php b/app/Api/Auth.php
index 6c6e1ebe..1cc6627f 100644
--- a/app/Api/Auth.php
+++ b/app/Api/Auth.php
@@ -2,7 +2,7 @@
namespace Kanboard\Api;
-use JsonRPC\AuthenticationFailure;
+use JsonRPC\Exception\AuthenticationFailureException;
/**
* Base class
@@ -32,7 +32,7 @@ class Auth extends Base
$this->checkProcedurePermission(false, $method);
} else {
$this->logger->error('API authentication failure for '.$username);
- throw new AuthenticationFailure('Wrong credentials');
+ throw new AuthenticationFailureException('Wrong credentials');
}
}
diff --git a/app/Api/Base.php b/app/Api/Base.php
index 0959817e..ea817f7d 100644
--- a/app/Api/Base.php
+++ b/app/Api/Base.php
@@ -2,7 +2,7 @@
namespace Kanboard\Api;
-use JsonRPC\AccessDeniedException;
+use JsonRPC\Exception\AccessDeniedException;
/**
* Base class
@@ -40,6 +40,7 @@ abstract class Base extends \Kanboard\Core\Base
'getBoard',
'getProjectActivity',
'getOverdueTasksByProject',
+ 'searchTasks',
);
public function checkProcedurePermission($is_user, $procedure)
diff --git a/app/Api/GroupMember.php b/app/Api/GroupMember.php
index de62f0c6..9d2a4796 100644
--- a/app/Api/GroupMember.php
+++ b/app/Api/GroupMember.php
@@ -10,6 +10,11 @@ namespace Kanboard\Api;
*/
class GroupMember extends \Kanboard\Core\Base
{
+ public function getMemberGroups($user_id)
+ {
+ return $this->groupMember->getGroups($user_id);
+ }
+
public function getGroupMembers($group_id)
{
return $this->groupMember->getMembers($group_id);
diff --git a/app/Api/Task.php b/app/Api/Task.php
index 177a09c6..1d1211f2 100644
--- a/app/Api/Task.php
+++ b/app/Api/Task.php
@@ -2,6 +2,7 @@
namespace Kanboard\Api;
+use Kanboard\Filter\TaskProjectFilter;
use Kanboard\Model\Task as TaskModel;
/**
@@ -12,6 +13,12 @@ use Kanboard\Model\Task as TaskModel;
*/
class Task extends Base
{
+ public function searchTasks($project_id, $query)
+ {
+ $this->checkProjectPermission($project_id);
+ return $this->taskLexer->build($query)->withFilter(new TaskProjectFilter($project_id))->toArray();
+ }
+
public function getTask($task_id)
{
$this->checkTaskPermission($task_id);
@@ -75,7 +82,7 @@ class Task extends Base
}
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_basedate = 0, $reference = '')
{
@@ -107,6 +114,7 @@ class Task extends Base
'recurrence_timeframe' => $recurrence_timeframe,
'recurrence_basedate' => $recurrence_basedate,
'reference' => $reference,
+ 'priority' => $priority,
);
list($valid, ) = $this->taskValidator->validateCreation($values);
@@ -115,7 +123,7 @@ class Task extends Base
}
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_timeframe = null, $recurrence_basedate = null, $reference = null)
{
@@ -146,6 +154,7 @@ class Task extends Base
'recurrence_timeframe' => $recurrence_timeframe,
'recurrence_basedate' => $recurrence_basedate,
'reference' => $reference,
+ 'priority' => $priority,
);
foreach ($values as $key => $value) {
diff --git a/app/Console/BaseCommand.php b/app/Console/BaseCommand.php
index 23cdcc9c..4444ceba 100644
--- a/app/Console/BaseCommand.php
+++ b/app/Console/BaseCommand.php
@@ -25,6 +25,7 @@ use Symfony\Component\Console\Command\Command;
* @property \Kanboard\Model\User $user
* @property \Kanboard\Model\UserNotification $userNotification
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
+ * @property \Kanboard\Model\ProjectUserRole $projectUserRole
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
*/
abstract class BaseCommand extends Command
diff --git a/app/Console/TaskOverdueNotificationCommand.php b/app/Console/TaskOverdueNotificationCommand.php
index 7d176ab1..7e8484c8 100644
--- a/app/Console/TaskOverdueNotificationCommand.php
+++ b/app/Console/TaskOverdueNotificationCommand.php
@@ -3,6 +3,7 @@
namespace Kanboard\Console;
use Kanboard\Model\Task;
+use Kanboard\Core\Security\Role;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -15,12 +16,20 @@ class TaskOverdueNotificationCommand extends BaseCommand
$this
->setName('notification:overdue-tasks')
->setDescription('Send notifications for overdue tasks')
- ->addOption('show', null, InputOption::VALUE_NONE, 'Show sent overdue tasks');
+ ->addOption('show', null, InputOption::VALUE_NONE, 'Show sent overdue tasks')
+ ->addOption('group', null, InputOption::VALUE_NONE, 'Group all overdue tasks for one user (from all projects) in one email')
+ ->addOption('manager', null, InputOption::VALUE_NONE, 'Send all overdue tasks to project manager(s) in one email');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
- $tasks = $this->sendOverdueTaskNotifications();
+ if ($input->getOption('group')) {
+ $tasks = $this->sendGroupOverdueTaskNotifications();
+ } elseif ($input->getOption('manager')) {
+ $tasks = $this->sendOverdueTaskNotificationsToManagers();
+ } else {
+ $tasks = $this->sendOverdueTaskNotifications();
+ }
if ($input->getOption('show')) {
$this->showTable($output, $tasks);
@@ -50,6 +59,54 @@ class TaskOverdueNotificationCommand extends BaseCommand
}
/**
+ * Send all overdue tasks for one user in one email
+ *
+ * @access public
+ */
+ public function sendGroupOverdueTaskNotifications()
+ {
+ $tasks = $this->taskFinder->getOverdueTasks();
+
+ foreach ($this->groupByColumn($tasks, 'owner_id') as $user_tasks) {
+ $users = $this->userNotification->getUsersWithNotificationEnabled($user_tasks[0]['project_id']);
+
+ foreach ($users as $user) {
+ $this->sendUserOverdueTaskNotifications($user, $user_tasks);
+ }
+ }
+
+ return $tasks;
+ }
+
+ /**
+ * Send all overdue tasks in one email to project manager(s)
+ *
+ * @access public
+ */
+ public function sendOverdueTaskNotificationsToManagers()
+ {
+ $tasks = $this->taskFinder->getOverdueTasks();
+
+ foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) {
+ $users = $this->userNotification->getUsersWithNotificationEnabled($project_id);
+ $managers = array();
+
+ foreach ($users as $user) {
+ $role = $this->projectUserRole->getUserRole($project_id, $user['id']);
+ if($role == Role::PROJECT_MANAGER) {
+ $managers[] = $user;
+ }
+ }
+
+ foreach ($managers as $manager) {
+ $this->sendUserOverdueTaskNotificationsToManagers($manager, $project_tasks);
+ }
+ }
+
+ return $tasks;
+ }
+
+ /**
* Send overdue tasks
*
* @access public
@@ -79,10 +136,12 @@ class TaskOverdueNotificationCommand extends BaseCommand
public function sendUserOverdueTaskNotifications(array $user, array $tasks)
{
$user_tasks = array();
+ $project_names = array();
foreach ($tasks as $task) {
if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) {
$user_tasks[] = $task;
+ $project_names[$task['project_id']] = $task['project_name'];
}
}
@@ -90,12 +149,28 @@ class TaskOverdueNotificationCommand extends BaseCommand
$this->userNotification->sendUserNotification(
$user,
Task::EVENT_OVERDUE,
- array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name'])
+ array('tasks' => $user_tasks, 'project_name' => implode(", ", $project_names))
);
}
}
/**
+ * Send overdue tasks for a project manager(s)
+ *
+ * @access public
+ * @param array $manager
+ * @param array $tasks
+ */
+ public function sendUserOverdueTaskNotificationsToManagers(array $manager, array $tasks)
+ {
+ $this->userNotification->sendUserNotification(
+ $manager,
+ Task::EVENT_OVERDUE,
+ array('tasks' => $tasks, 'project_name' => $tasks[0]['project_name'])
+ );
+ }
+
+ /**
* Group a collection of records by a column
*
* @access public
diff --git a/app/Controller/Comment.php b/app/Controller/Comment.php
index ff7ec305..0b39f390 100644
--- a/app/Controller/Comment.php
+++ b/app/Controller/Comment.php
@@ -173,6 +173,6 @@ class Comment extends Base
$order = $this->userSession->getCommentSorting() === 'ASC' ? 'DESC' : 'ASC';
$this->userSession->setCommentSorting($order);
- $this->response->redirect($this->helper->url->href('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'comments'));
+ $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'));
}
}
diff --git a/app/Core/Plugin/Loader.php b/app/Core/Plugin/Loader.php
index 775673de..799024ad 100644
--- a/app/Core/Plugin/Loader.php
+++ b/app/Core/Plugin/Loader.php
@@ -2,6 +2,7 @@
namespace Kanboard\Core\Plugin;
+use Composer\Autoload\ClassLoader;
use DirectoryIterator;
use PDOException;
use LogicException;
@@ -39,6 +40,10 @@ class Loader extends \Kanboard\Core\Base
public function scan()
{
if (file_exists(PLUGINS_DIR)) {
+ $loader = new ClassLoader();
+ $loader->addPsr4('Kanboard\Plugin\\', PLUGINS_DIR);
+ $loader->register();
+
$dir = new DirectoryIterator(PLUGINS_DIR);
foreach ($dir as $fileinfo) {
@@ -68,8 +73,7 @@ class Loader extends \Kanboard\Core\Base
$instance = new $class($this->container);
- Tool::buildDic($this->container, $instance->getClasses());
-
+ Tool::buildDIC($this->container, $instance->getClasses());
Tool::buildDICHelpers($this->container, $instance->getHelpers());
$instance->initialize();
diff --git a/app/Core/Template.php b/app/Core/Template.php
index 1874d44a..d3ec26d5 100644
--- a/app/Core/Template.php
+++ b/app/Core/Template.php
@@ -116,7 +116,7 @@ class Template
}
if ($plugin !== 'kanboard' && $plugin !== '') {
- return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', '..', 'plugins', ucfirst($plugin), 'Template', $template.'.php'));
+ return implode(DIRECTORY_SEPARATOR, array(PLUGINS_DIR, ucfirst($plugin), 'Template', $template.'.php'));
}
return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'Template', $template.'.php'));
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index fadf0a1b..e689f07a 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'pregled ploče na Kanboard-u',
'The task have been moved to the first swimlane' => 'Zadatak je premješten u prvu swimline traku',
'The task have been moved to another swimlane:' => 'Zadatak je premješten u drugu swimline traku',
- 'Overdue tasks for the project "%s"' => 'Zadaci u kašnjenju za projekat "%s"',
+ 'Overdue tasks for the project(s) "%s"' => 'Zadaci u kašnjenju za projekat(te) "%s"',
'New title: %s' => 'Novi naslov: %s',
'The task is not assigned anymore' => 'Zadatak nema više izvršioca',
'New assignee: %s' => 'Novi izvršilac: %s',
@@ -1163,8 +1163,8 @@ return array(
'Search by task status: ' => 'Pretraga po statusu zadatka: ',
'Search by task title: ' => 'Pretraga po naslovu zadatka: ',
'Activity stream search' => 'Pretraga aktivnosti',
- // 'Projects where "%s" is manager' => '',
- // 'Projects where "%s" is member' => '',
- // 'Open tasks assigned to "%s"' => '',
- // 'Closed tasks assigned to "%s"' => '',
+ 'Projects where "%s" is manager' => 'Projekti gdje je "%s" menadžer',
+ 'Projects where "%s" is member' => 'Projekti gdje je "%s" član',
+ 'Open tasks assigned to "%s"' => 'Otvoreni zadaci dodijeljeni "%s"',
+ 'Closed tasks assigned to "%s"' => 'Zatvoreni zadaci dodijeljeni "%s"',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index 777e9b42..a8fbdead 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'Pinnwand in Kanboard anzeigen',
'The task have been moved to the first swimlane' => 'Die Aufgabe wurde in die erste Swimlane verschoben',
'The task have been moved to another swimlane:' => 'Die Aufgaben wurde in ene andere Swimlane verschoben',
- 'Overdue tasks for the project "%s"' => 'Überfällige Aufgaben für das Projekt "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Überfällige Aufgaben für das Projekt "%s"',
'New title: %s' => 'Neuer Titel: %s',
'The task is not assigned anymore' => 'Die Aufgabe ist nicht mehr zugewiesen',
'New assignee: %s' => 'Neue Zuordnung: %s',
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 7c255561..aa53e382 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 43b80561..160cd51f 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -558,8 +558,8 @@ return array(
'is blocked by' => 'ist blockiert von',
'duplicates' => 'doppelt',
'is duplicated by' => 'ist gedoppelt von',
- 'is a child of' => 'ist untergeordnet',
- 'is a parent of' => 'ist übergeordnet',
+ 'is a child of' => 'ist ein untergeordnetes Element von',
+ 'is a parent of' => 'ist ein übergeordnetes Element von',
'targets milestone' => 'betrifft Meilenstein',
'is a milestone of' => 'ist ein Meilenstein von',
'fixes' => 'behebt',
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'Pinnwand in Kanboard anzeigen',
'The task have been moved to the first swimlane' => 'Die Aufgabe wurde in die erste Swimlane verschoben',
'The task have been moved to another swimlane:' => 'Die Aufgaben wurde in ene andere Swimlane verschoben',
- 'Overdue tasks for the project "%s"' => 'Überfällige Aufgaben für das Projekt "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Überfällige Aufgaben für das Projekt "%s"',
'New title: %s' => 'Neuer Titel: %s',
'The task is not assigned anymore' => 'Die Aufgabe ist nicht mehr zugewiesen',
'New assignee: %s' => 'Neue Zuordnung: %s',
diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php
index 664bf328..f70742a3 100644
--- a/app/Locale/el_GR/translations.php
+++ b/app/Locale/el_GR/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'δείτε τον πίνακα στο Kanboard',
'The task have been moved to the first swimlane' => 'Η εργασία αυτή έχει μετακινηθεί στην πρώτη λωρίδα',
'The task have been moved to another swimlane:' => 'Η εργασία αυτή έχει μετακινηθεί σε άλλη λωρίδα:',
- 'Overdue tasks for the project "%s"' => 'Εκπρόθεσμες εργασίες για το έργο « %s »',
+ // 'Overdue tasks for the project(s) "%s"' => 'Εκπρόθεσμες εργασίες για το έργο « %s »',
'New title: %s' => 'Νέος τίτλος: %s',
'The task is not assigned anymore' => 'Η εργασία δεν έχει ανατεθεί πλέον',
'New assignee: %s' => 'Καινούργια ανάθεση: %s',
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 6b4dda42..240a04fe 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'ver el tablero en Kanboard',
'The task have been moved to the first swimlane' => 'Se ha movido la tarea a la primera calle',
'The task have been moved to another swimlane:' => 'Se ha movido la tarea a otra calle',
- 'Overdue tasks for the project "%s"' => 'Tareas atrasadas para el proyecto "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Tareas atrasadas para el proyecto "%s"',
'New title: %s' => 'Nuevo título: %s',
'The task is not assigned anymore' => 'La tarea ya no está asignada',
'New assignee: %s' => 'Nuevo concesionario: %s',
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index f30b7b4c..147713a5 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index ed4638cd..8f4bb5da 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'voir le tableau sur Kanboard',
'The task have been moved to the first swimlane' => 'La tâche a été déplacée dans la première swimlane',
'The task have been moved to another swimlane:' => 'La tâche a été déplacée dans une autre swimlane :',
- 'Overdue tasks for the project "%s"' => 'Tâches en retard pour le projet « %s »',
+ // 'Overdue tasks for the project(s) "%s"' => 'Tâches en retard pour le projet « %s »',
'New title: %s' => 'Nouveau titre : %s',
'The task is not assigned anymore' => 'La tâche n\'est plus assignée maintenant',
'New assignee: %s' => 'Nouvel assigné : %s',
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index 394f89a0..920fda74 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index bd1dd684..59fd75d4 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'lihat papan di Kanboard',
'The task have been moved to the first swimlane' => 'Tugas telah dipindahkan ke swimlane pertama',
'The task have been moved to another swimlane:' => 'Tugas telah dipindahkan ke swimlane lain:',
- 'Overdue tasks for the project "%s"' => 'Tugas terlambat untuk proyek « %s »',
+ // 'Overdue tasks for the project(s) "%s"' => 'Tugas terlambat untuk proyek « %s »',
'New title: %s' => 'Judul baru : %s',
'The task is not assigned anymore' => 'Tugas tidak ditugaskan lagi',
'New assignee: %s' => 'Penerima baru : %s',
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index cee1c16a..bd85b6c2 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'guarda la bacheca su Kanboard',
'The task have been moved to the first swimlane' => 'Il task è stato spostato nella prima corsia',
'The task have been moved to another swimlane:' => 'Il task è stato spostato in un\'altra corsia:',
- 'Overdue tasks for the project "%s"' => 'Task scaduti per il progetto "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Task scaduti per il progetto "%s"',
'New title: %s' => 'Nuovo titolo: %s',
'The task is not assigned anymore' => 'Il task non è più assegnato a nessuno',
'New assignee: %s' => 'Nuovo assegnatario: %s',
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 89769edd..e3cf662c 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php
index ed9e3b86..0cd0d93c 100644
--- a/app/Locale/ko_KR/translations.php
+++ b/app/Locale/ko_KR/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
'New title: %s' => '제목 변경: %s',
'The task is not assigned anymore' => '담당자 없음',
'New assignee: %s' => '담당자 변경: %s',
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index 4537f38c..d6109be9 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'lihat papan di Kanboard',
'The task have been moved to the first swimlane' => 'Tugas telah dipindahkan ke swimlane pertama',
'The task have been moved to another swimlane:' => 'Tugas telah dipindahkan ke swimlane lain:',
- 'Overdue tasks for the project "%s"' => 'Tugas terlambat untuk projek « %s »',
+ 'Overdue tasks for the project(s) "%s"' => 'Tugas terlambat untuk projek « %s »',
'New title: %s' => 'Judul baru : %s',
'The task is not assigned anymore' => 'Tugas tidak ditugaskan lagi',
'New assignee: %s' => 'Penerima baru : %s',
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index 8c6a56f2..4bdbc250 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 18155816..0cf8ae6d 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
'New title: %s' => 'Nieuw titel: %s',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index d9427d80..4aab974d 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
'New title: %s' => 'Nowy tytuł: %s',
'The task is not assigned anymore' => 'Brak osoby odpowiedzialnej za zadanie',
'New assignee: %s' => 'Nowy odpowiedzialny: %s',
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index e0cdb17d..b0aba4db 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'ver o painel no Kanboard',
'The task have been moved to the first swimlane' => 'A tarefa foi movida para a primeira swimlane',
'The task have been moved to another swimlane:' => 'A tarefa foi movida para outra swimlane:',
- 'Overdue tasks for the project "%s"' => 'Tarefas atrasadas para o projeto "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Tarefas atrasadas para o projeto "%s"',
'New title: %s' => 'Novo título: %s',
'The task is not assigned anymore' => 'Agora a tarefa não está mais atribuída',
'New assignee: %s' => 'Novo designado: %s',
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index aa51534b..f8ace69d 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'ver o painel no Kanboard',
'The task have been moved to the first swimlane' => 'A tarefa foi movida para o primeiro Swimlane',
'The task have been moved to another swimlane:' => 'A tarefa foi movida para outro Swimlane:',
- 'Overdue tasks for the project "%s"' => 'Tarefas atrasadas para o projecto "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Tarefas atrasadas para o projecto "%s"',
'New title: %s' => 'Novo título: %s',
'The task is not assigned anymore' => 'Tarefa já não está atribuída',
'New assignee: %s' => 'Novo assignado: %s',
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index bf2bc559..322126e3 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'посмотреть доску на Kanboard',
'The task have been moved to the first swimlane' => 'Эта задача была перемещена в первую дорожку',
'The task have been moved to another swimlane:' => 'Эта задача была перемещена в другую дорожку:',
- 'Overdue tasks for the project "%s"' => 'Просроченные задачи для проекта "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Просроченные задачи для проекта "%s"',
'New title: %s' => 'Новый заголовок: %s',
'The task is not assigned anymore' => 'Задача больше не назначена',
'New assignee: %s' => 'Новый назначенный: %s',
@@ -1153,18 +1153,18 @@ return array(
'Upload my avatar image' => 'Загрузить моё изображение для аватара',
'Remove my image' => 'Удалить моё изображение',
'The OAuth2 state parameter is invalid' => 'Параметр состояние OAuth2 неправильный',
- // 'User not found.' => '',
- // 'Search in activity stream' => '',
- // 'My activities' => '',
- // 'Activity until yesterday' => '',
- // 'Activity until today' => '',
- // 'Search by creator: ' => '',
- // 'Search by creation date: ' => '',
- // 'Search by task status: ' => '',
- // 'Search by task title: ' => '',
- // 'Activity stream search' => '',
- // 'Projects where "%s" is manager' => '',
- // 'Projects where "%s" is member' => '',
- // 'Open tasks assigned to "%s"' => '',
- // 'Closed tasks assigned to "%s"' => '',
+ 'User not found.' => 'Пользователь не найден',
+ 'Search in activity stream' => 'Поиск в потоке активности',
+ 'My activities' => 'Мои активности',
+ 'Activity until yesterday' => 'Активности до вчерашнего дня',
+ 'Activity until today' => 'Активности до сегодня',
+ 'Search by creator: ' => 'Поиск по создателю: ',
+ 'Search by creation date: ' => 'Поиск по дате создания: ',
+ 'Search by task status: ' => 'Поиск по статусу задачи: ',
+ 'Search by task title: ' => 'Поиск по заголоску задачи: ',
+ 'Activity stream search' => 'Поиск в потоке активности; ',
+ 'Projects where "%s" is manager' => 'Проекты, где менеджером является "%s"',
+ 'Projects where "%s" is member' => 'Проекты, где членом является "%s"',
+ 'Open tasks assigned to "%s"' => 'Открытые задачи, назначенные на "%s"',
+ 'Closed tasks assigned to "%s"' => 'Закрытые задачи, назначенные на "%s"',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 0399530e..304b91dc 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -709,7 +709,7 @@ return array(
// 'view the board on Kanboard' => '',
// 'The task have been moved to the first swimlane' => '',
// 'The task have been moved to another swimlane:' => '',
- // 'Overdue tasks for the project "%s"' => '',
+ // 'Overdue tasks for the project(s) "%s"' => '',
// 'New title: %s' => '',
// 'The task is not assigned anymore' => '',
// 'New assignee: %s' => '',
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 7e738e70..6fca58a1 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'visa tavlan på Kanboard',
'The task have been moved to the first swimlane' => 'Uppgiften har flyttats till första swimlane',
'The task have been moved to another swimlane:' => 'Uppgiften har flyttats till en annan swimlane:',
- 'Overdue tasks for the project "%s"' => 'Försenade uppgifter för projektet "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'Försenade uppgifter för projektet "%s"',
'New title: %s' => 'Ny titel: %s',
'The task is not assigned anymore' => 'Uppgiften är inte länge tilldelad',
'New assignee: %s' => 'Ny tilldelning: %s',
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index 6765e8ea..2cdc870c 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'แสดงบอร์ดบนคังบอร์ด',
'The task have been moved to the first swimlane' => 'งานถูกย้านไปสวิมเลนแรก',
'The task have been moved to another swimlane:' => 'งานถูกย้านไปสวิมเลนอื่น:',
- 'Overdue tasks for the project "%s"' => 'งานที่เกินกำหนดสำหรับโปรเจค "%s"',
+ // 'Overdue tasks for the project(s) "%s"' => 'งานที่เกินกำหนดสำหรับโปรเจค "%s"',
'New title: %s' => 'ชื่อเรื่องใหม่: %s',
'The task is not assigned anymore' => 'ไม่กำหนดผู้รับผิดชอบ',
'New assignee: %s' => 'ผู้รับผิดชอบใหม่: %s',
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index f771b106..ee9242a9 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => 'Tabloyu Kanboard\'da görüntüle',
'The task have been moved to the first swimlane' => 'Görev birinci kulvara taşındı',
'The task have been moved to another swimlane:' => 'Görev başka bir kulvara taşındı:',
- 'Overdue tasks for the project "%s"' => '"%s" projesi için gecikmiş görevler',
+ // 'Overdue tasks for the project(s) "%s"' => '"%s" projesi için gecikmiş görevler',
'New title: %s' => 'Yeni başlık: %s',
'The task is not assigned anymore' => 'Görev artık atanmamış',
'New assignee: %s' => 'Yeni atanan: %s',
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index baa7693a..fc3fcbfc 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -709,7 +709,7 @@ return array(
'view the board on Kanboard' => '在看板上查看面板',
'The task have been moved to the first swimlane' => '该任务已被移动到首个里程碑',
'The task have been moved to another swimlane:' => '该任务已被移动到别的里程碑:',
- 'Overdue tasks for the project "%s"' => '"%s"项目下的超期任务',
+ // 'Overdue tasks for the project(s) "%s"' => '"%s"项目下的超期任务',
'New title: %s' => '新标题:%s',
'The task is not assigned anymore' => '该任务没有指派人',
'New assignee: %s' => '新指派到:%s',
diff --git a/app/Model/GroupMember.php b/app/Model/GroupMember.php
index 7ed5f733..14041704 100644
--- a/app/Model/GroupMember.php
+++ b/app/Model/GroupMember.php
@@ -108,4 +108,21 @@ class GroupMember extends Base
->eq('user_id', $user_id)
->exists();
}
+
+ /**
+ * Get all groups for a given user
+ *
+ * @access public
+ * @param integer $user_id
+ * @return array
+ */
+ public function getGroups($user_id)
+ {
+ return $this->db->table(self::TABLE)
+ ->columns(Group::TABLE.'.id', Group::TABLE.'.name')
+ ->join(Group::TABLE, 'id', 'group_id')
+ ->eq(self::TABLE.'.user_id', $user_id)
+ ->asc(Group::TABLE.'.name')
+ ->findAll();
+ }
}
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index d406b794..0b2cbb84 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -35,6 +35,7 @@ class TaskFinder extends Base
Task::TABLE.'.date_started',
Task::TABLE.'.project_id',
Task::TABLE.'.color_id',
+ Task::TABLE.'.priority',
Task::TABLE.'.time_spent',
Task::TABLE.'.time_estimated',
Project::TABLE.'.name AS project_name',
@@ -67,6 +68,7 @@ class TaskFinder extends Base
'tasks.date_creation',
'tasks.project_id',
'tasks.color_id',
+ 'tasks.priority',
'tasks.time_spent',
'tasks.time_estimated',
'projects.name AS project_name'
diff --git a/app/Template/app/notifications.php b/app/Template/app/notifications.php
index 4cb3c571..b64eb0b7 100644
--- a/app/Template/app/notifications.php
+++ b/app/Template/app/notifications.php
@@ -2,8 +2,8 @@
<h2><?= t('My notifications') ?></h2>
<?php if (empty($notifications)): ?>
- <p class="alert"><?= t('No new notifications.') ?></p>
</div>
+<p class="alert"><?= t('No new notifications.') ?></p>
<?php else: ?>
<ul>
<li>
diff --git a/app/Template/app/tasks.php b/app/Template/app/tasks.php
index d7826fb7..f0ed61e0 100644
--- a/app/Template/app/tasks.php
+++ b/app/Template/app/tasks.php
@@ -9,6 +9,7 @@
<th class="column-5"><?= $paginator->order('Id', 'tasks.id') ?></th>
<th class="column-20"><?= $paginator->order(t('Project'), 'project_name') ?></th>
<th><?= $paginator->order(t('Task'), 'title') ?></th>
+ <th class="column-5"><?= $paginator->order('Priority', 'tasks.priority') ?></th>
<th class="column-20"><?= t('Time tracking') ?></th>
<th class="column-20"><?= $paginator->order(t('Due date'), 'date_due') ?></th>
</tr>
@@ -24,6 +25,11 @@
<?= $this->url->link($this->text->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</td>
<td>
+ <?php if ($task['priority'] >= 0): ?>
+ P<?= $this->text->e($task['priority'])?>
+ <?php endif?>
+ </td>
+ <td>
<?php if (! empty($task['time_spent'])): ?>
<strong><?= $this->text->e($task['time_spent']).'h' ?></strong> <?= t('spent') ?>
<?php endif ?>
@@ -40,4 +46,4 @@
</table>
<?= $paginator ?>
-<?php endif ?> \ No newline at end of file
+<?php endif ?>
diff --git a/app/Template/notification/task_overdue.php b/app/Template/notification/task_overdue.php
index ac0665a2..ee2ff379 100644
--- a/app/Template/notification/task_overdue.php
+++ b/app/Template/notification/task_overdue.php
@@ -1,18 +1,31 @@
-<h2><?= t('Overdue tasks for the project "%s"', $project_name) ?></h2>
+<h2><?= t('Overdue tasks for the project(s) "%s"', $project_name) ?></h2>
+
+<table style="font-size: .8em; table-layout: fixed; width: 100%; border-collapse: collapse; border-spacing: 0; margin-bottom: 20px;" cellpadding=5 cellspacing=1>
+ <tr style="background: #fbfbfb; text-align: left; padding-top: .5em; padding-bottom: .5em; padding-left: 3px; padding-right: 3px;">
+ <th style="border: 1px solid #eee;"><?= t('ID') ?></th>
+ <th style="border: 1px solid #eee;"><?= t('Title') ?></th>
+ <th style="border: 1px solid #eee;"><?= t('Due date') ?></th>
+ <th style="border: 1px solid #eee;"><?= t('Project') ?></th>
+ <th style="border: 1px solid #eee;"><?= t('Assignee') ?></th>
+ </tr>
-<ul>
<?php foreach ($tasks as $task): ?>
- <li>
- (<strong>#<?= $task['id'] ?></strong>)
- <?php if ($application_url): ?>
- <a href="<?= $this->url->href('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', true) ?>"><?= $this->text->e($task['title']) ?></a>
- <?php else: ?>
- <?= $this->text->e($task['title']) ?>
- <?php endif ?>
- (<?= $this->dt->date($task['date_due']) ?>)
- <?php if ($task['assignee_username']): ?>
- (<strong><?= t('Assigned to %s', $task['assignee_name'] ?: $task['assignee_username']) ?></strong>)
- <?php endif ?>
- </li>
+ <tr style="overflow: hidden; background: #fff; text-align: left; padding-top: .5em; padding-bottom: .5em; padding-left: 3px; padding-right: 3px;">
+ <td style="border: 1px solid #eee;">#<?= $task['id'] ?></td>
+ <td style="border: 1px solid #eee;">
+ <?php if ($application_url): ?>
+ <a href="<?= $this->url->href('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', true) ?>"><?= $this->text->e($task['title']) ?></a>
+ <?php else: ?>
+ <?= $this->text->e($task['title']) ?>
+ <?php endif ?>
+ </td>
+ <td style="border: 1px solid #eee;"><?= $this->dt->date($task['date_due']) ?></td>
+ <td style="border: 1px solid #eee;"><?= $task['project_name'] ?></td>
+ <td style="border: 1px solid #eee;">
+ <?php if ($task['assignee_username']): ?>
+ <?= t('%s', $task['assignee_name'] ?: $task['assignee_username']) ?>
+ <?php endif ?>
+ </td>
+ </tr>
<?php endforeach ?>
-</ul>
+</table>
diff --git a/app/Template/project/sidebar.php b/app/Template/project/sidebar.php
index 304b4aee..7fb7718d 100644
--- a/app/Template/project/sidebar.php
+++ b/app/Template/project/sidebar.php
@@ -11,7 +11,7 @@
<?php endif ?>
<?php if ($this->user->hasProjectAccess('ProjectEdit', 'edit', $project['id'])): ?>
- <li <?= $this->app->checkMenuSelection('ProjectEdit', 'edit') ?>>
+ <li <?= $this->app->checkMenuSelection('ProjectEdit') ?>>
<?= $this->url->link(t('Edit project'), 'ProjectEdit', 'edit', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('project', 'share') ?>>
diff --git a/app/Template/project_header/search.php b/app/Template/project_header/search.php
index 42216352..8885d9c9 100644
--- a/app/Template/project_header/search.php
+++ b/app/Template/project_header/search.php
@@ -22,9 +22,9 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon" title="<?= t('User filters') ?>"><i class="fa fa-users fa-fw"></i> <i class="fa fa-caret-down"></i></a>
<ul>
- <li><a href="#" class="filter-helper" data-append-filter="assignee:nobody"><?= t('Not assigned') ?></a></li>
+ <li><a href="#" class="filter-helper" data-unique-filter="assignee:nobody"><?= t('Not assigned') ?></a></li>
<?php foreach ($users_list as $user): ?>
- <li><a href="#" class="filter-helper" data-append-filter='assignee:"<?= $this->text->e($user) ?>"'><?= $this->text->e($user) ?></a></li>
+ <li><a href="#" class="filter-helper" data-unique-filter='assignee:"<?= $this->text->e($user) ?>"'><?= $this->text->e($user) ?></a></li>
<?php endforeach ?>
</ul>
</div>
@@ -34,9 +34,9 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon" title="<?= t('Category filters') ?>"><i class="fa fa-tags fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
- <li><a href="#" class="filter-helper" data-append-filter="category:none"><?= t('No category') ?></a></li>
+ <li><a href="#" class="filter-helper" data-unique-filter="category:none"><?= t('No category') ?></a></li>
<?php foreach ($categories_list as $category): ?>
- <li><a href="#" class="filter-helper" data-append-filter='category:"<?= $this->text->e($category) ?>"'><?= $this->text->e($category) ?></a></li>
+ <li><a href="#" class="filter-helper" data-unique-filter='category:"<?= $this->text->e($category) ?>"'><?= $this->text->e($category) ?></a></li>
<?php endforeach ?>
</ul>
</div>
diff --git a/app/Template/task/details.php b/app/Template/task/details.php
index 6093c157..5b8b7c6d 100644
--- a/app/Template/task/details.php
+++ b/app/Template/task/details.php
@@ -1,6 +1,8 @@
<section id="task-summary">
<h2><?= $this->text->e($task['title']) ?></h2>
+ <?= $this->hook->render('template:task:details:top', array('task' => $task)) ?>
+
<div class="task-summary-container color-<?= $task['color_id'] ?>">
<div class="task-summary-column">
<ul class="no-bullet">
@@ -40,6 +42,8 @@
</li>
<?php endif ?>
<li class="smaller">
+
+ <?= $this->hook->render('template:task:details:first-column', array('task' => $task)) ?>
</ul>
</div>
<div class="task-summary-column">
@@ -64,6 +68,8 @@
<strong><?= t('Position:') ?></strong>
<span><?= $task['position'] ?></span>
</li>
+
+ <?= $this->hook->render('template:task:details:second-column', array('task' => $task)) ?>
</ul>
</div>
<div class="task-summary-column">
@@ -102,6 +108,8 @@
<span><?= t('%s hours', $task['time_spent']) ?></span>
</li>
<?php endif ?>
+
+ <?= $this->hook->render('template:task:details:third-column', array('task' => $task)) ?>
</ul>
</div>
<div class="task-summary-column">
@@ -132,6 +140,8 @@
<span><?= $this->dt->datetime($task['date_moved']) ?></span>
</li>
<?php endif ?>
+
+ <?= $this->hook->render('template:task:details:fourth-column', array('task' => $task)) ?>
</ul>
</div>
</div>
@@ -141,4 +151,6 @@
<?= $this->url->button('fa-play', t('Set start date'), 'taskmodification', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div>
<?php endif ?>
+
+ <?= $this->hook->render('template:task:details:bottom', array('task' => $task)) ?>
</section>
diff --git a/app/Template/task/dropdown.php b/app/Template/task/dropdown.php
index f98f5172..6fea3728 100644
--- a/app/Template/task/dropdown.php
+++ b/app/Template/task/dropdown.php
@@ -55,6 +55,6 @@
</li>
<?php endif ?>
- <?= $this->hook->render('template:task:dropdown') ?>
+ <?= $this->hook->render('template:task:dropdown', array('task' => $task)) ?>
</ul>
</div>
diff --git a/app/Template/task/layout.php b/app/Template/task/layout.php
index 52db5d1b..ba2cd8d5 100644
--- a/app/Template/task/layout.php
+++ b/app/Template/task/layout.php
@@ -1,5 +1,6 @@
<section id="main">
<?= $this->projectHeader->render($project, 'Listing', 'show') ?>
+ <?= $this->hook->render('template:task:layout:top', array('task' => $task)) ?>
<section
class="sidebar-container" id="task-view"
data-edit-url="<?= $this->url->href('taskmodification', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"
@@ -14,4 +15,4 @@
<?= $content_for_sublayout ?>
</div>
</section>
-</section> \ No newline at end of file
+</section>
diff --git a/app/Template/task/show.php b/app/Template/task/show.php
index 86422941..8f41d653 100644
--- a/app/Template/task/show.php
+++ b/app/Template/task/show.php
@@ -34,7 +34,7 @@
'project' => $project,
)) ?>
-<?= $this->hook->render('template:task:show:before-attachements', array('task' => $task, 'project' => $project)) ?>
+<?= $this->hook->render('template:task:show:before-attachments', array('task' => $task, 'project' => $project)) ?>
<?= $this->render('task_file/show', array(
'task' => $task,
'files' => $files,
diff --git a/app/Template/task/sidebar.php b/app/Template/task/sidebar.php
index 773b28dc..a2d73b8c 100644
--- a/app/Template/task/sidebar.php
+++ b/app/Template/task/sidebar.php
@@ -23,6 +23,8 @@
<?= $this->url->link(t('Time tracking'), 'task', 'timetracking', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php endif ?>
+
+ <?= $this->hook->render('template:task:sidebar:information', array('task' => $task)) ?>
</ul>
<?php if ($this->user->hasProjectAccess('taskmodification', 'edit', $task['project_id'])): ?>
@@ -91,8 +93,8 @@
<?= $this->url->link(t('Remove'), 'task', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
</li>
<?php endif ?>
+
+ <?= $this->hook->render('template:task:sidebar:actions', array('task' => $task)) ?>
</ul>
<?php endif ?>
-
- <?= $this->hook->render('template:task:sidebar', array('task' => $task)) ?>
</div>
diff --git a/app/Template/task_creation/form.php b/app/Template/task_creation/form.php
index 9bfd839f..c963bdcf 100644
--- a/app/Template/task_creation/form.php
+++ b/app/Template/task_creation/form.php
@@ -29,7 +29,7 @@
<?= $this->form->checkbox('another_task', t('Create another task'), 1, isset($values['another_task']) && $values['another_task'] == 1) ?>
<?php endif ?>
- <?= $this->hook->render('template:task:form:left-column', array('values'=>$values, 'errors'=>$errors)) ?>
+ <?= $this->hook->render('template:task:form:left-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
<div class="form-column">
@@ -43,7 +43,7 @@
<?= $this->task->selectTimeEstimated($values, $errors) ?>
<?= $this->task->selectDueDate($values, $errors) ?>
- <?= $this->hook->render('template:task:form:right-column', array('values'=>$values, 'errors'=>$errors)) ?>
+ <?= $this->hook->render('template:task:form:right-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
<div class="form-actions">
diff --git a/app/Template/task_modification/edit_task.php b/app/Template/task_modification/edit_task.php
index b5891c15..5ddec5ea 100644
--- a/app/Template/task_modification/edit_task.php
+++ b/app/Template/task_modification/edit_task.php
@@ -14,6 +14,8 @@
<?= $this->task->selectCategory($categories_list, $values, $errors) ?>
<?= $this->task->selectPriority($project, $values) ?>
<?= $this->task->selectScore($values, $errors) ?>
+
+ <?= $this->hook->render('template:task:form:left-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
<div class="form-column">
@@ -21,6 +23,8 @@
<?= $this->task->selectTimeSpent($values, $errors) ?>
<?= $this->task->selectStartDate($values, $errors) ?>
<?= $this->task->selectDueDate($values, $errors) ?>
+
+ <?= $this->hook->render('template:task:form:right-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
<div class="form-clear">
@@ -32,4 +36,4 @@
<?= t('or') ?>
<?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
</div>
-</form> \ No newline at end of file
+</form>
diff --git a/app/check_setup.php b/app/check_setup.php
index af830de7..d962a6f8 100644
--- a/app/check_setup.php
+++ b/app/check_setup.php
@@ -15,8 +15,8 @@ if (version_compare(PHP_VERSION, '5.4.0', '<')) {
}
// Check data folder if sqlite
-if (DB_DRIVER === 'sqlite' && ! is_writable('data')) {
- throw new Exception('The directory "data" must be writeable by your web server user');
+if (DB_DRIVER === 'sqlite' && ! is_writable(dirname(DB_FILENAME))) {
+ throw new Exception('The directory "'.dirname(DB_FILENAME).'" must be writeable by your web server user');
}
// Check PDO extensions
diff --git a/app/common.php b/app/common.php
index da624844..aed07a50 100644
--- a/app/common.php
+++ b/app/common.php
@@ -14,12 +14,16 @@ if (getenv('DATABASE_URL')) {
define('DB_NAME', ltrim($dbopts["path"], '/'));
}
-if (file_exists('config.php')) {
- require 'config.php';
+$config_file = implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'config.php'));
+
+if (file_exists($config_file)) {
+ require $config_file;
}
-if (file_exists('data'.DIRECTORY_SEPARATOR.'config.php')) {
- require 'data'.DIRECTORY_SEPARATOR.'config.php';
+$config_file = implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'data', 'config.php'));
+
+if (file_exists($config_file)) {
+ require $config_file;
}
require __DIR__.'/constants.php';
diff --git a/app/constants.php b/app/constants.php
index a09aac19..3dd827b3 100644
--- a/app/constants.php
+++ b/app/constants.php
@@ -1,11 +1,17 @@
<?php
+// Data directory location
+defined('DATA_DIR') or define('DATA_DIR', implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'data')));
+
+// Files directory (attachments)
+defined('FILES_DIR') or define('FILES_DIR', DATA_DIR.DIRECTORY_SEPARATOR.'files');
+
+// Plugins directory
+defined('PLUGINS_DIR') or define('PLUGINS_DIR', implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'plugins')));
+
// Enable/disable debug
defined('DEBUG') or define('DEBUG', getenv('DEBUG'));
-defined('DEBUG_FILE') or define('DEBUG_FILE', getenv('DEBUG_FILE') ?: __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'debug.log');
-
-// Plugin directory
-defined('PLUGINS_DIR') or define('PLUGINS_DIR', __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'plugins');
+defined('DEBUG_FILE') or define('DEBUG_FILE', getenv('DEBUG_FILE') ?: DATA_DIR.DIRECTORY_SEPARATOR.'debug.log');
// Application version
defined('APP_VERSION') or define('APP_VERSION', build_app_version('$Format:%d$', '$Format:%H$'));
@@ -14,7 +20,7 @@ defined('APP_VERSION') or define('APP_VERSION', build_app_version('$Format:%d$',
defined('DB_DRIVER') or define('DB_DRIVER', 'sqlite');
// Sqlite configuration
-defined('DB_FILENAME') or define('DB_FILENAME', 'data'.DIRECTORY_SEPARATOR.'db.sqlite');
+defined('DB_FILENAME') or define('DB_FILENAME', DATA_DIR.DIRECTORY_SEPARATOR.'db.sqlite');
// Mysql/Postgres configuration
defined('DB_USERNAME') or define('DB_USERNAME', 'root');
@@ -82,9 +88,6 @@ defined('ENABLE_XFRAME') or define('ENABLE_XFRAME', true);
// Syslog
defined('ENABLE_SYSLOG') or define('ENABLE_SYSLOG', getenv('ENABLE_SYSLOG'));
-// Default files directory
-defined('FILES_DIR') or define('FILES_DIR', 'data'.DIRECTORY_SEPARATOR.'files');
-
// Escape html inside markdown text
defined('MARKDOWN_ESCAPE_HTML') or define('MARKDOWN_ESCAPE_HTML', true);