summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Action/TaskAssignColorOnDueDate.php100
-rw-r--r--app/Helper/TextHelper.php13
-rw-r--r--app/Locale/pt_PT/translations.php60
-rw-r--r--app/Schema/Migration.php3
-rw-r--r--app/ServiceProvider/ActionProvider.php2
-rw-r--r--app/Template/board/table_column.php29
-rw-r--r--app/Template/project_overview/information.php4
-rw-r--r--app/Template/project_user_overview/tooltip_users.php2
-rw-r--r--app/User/Avatar/LetterAvatarProvider.php2
9 files changed, 171 insertions, 44 deletions
diff --git a/app/Action/TaskAssignColorOnDueDate.php b/app/Action/TaskAssignColorOnDueDate.php
new file mode 100644
index 00000000..06b70a18
--- /dev/null
+++ b/app/Action/TaskAssignColorOnDueDate.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Kanboard\Action;
+
+use Kanboard\Model\TaskModel;
+
+
+/**
+ * Assign a color to a priority
+ *
+ * @package Kanboard\Action
+ * @author Julien Buratto
+ */
+class TaskAssignColorOnDueDate extends Base
+{
+ /**
+ * Get action description
+ *
+ * @access public
+ * @return string
+ */
+ public function getDescription()
+ {
+ return t('Assign automatically a color when due date is expired');
+ }
+
+ /**
+ * Get the list of compatible events
+ *
+ * @access public
+ * @return array
+ */
+ public function getCompatibleEvents()
+ {
+ return array(
+ TaskModel::EVENT_DAILY_CRONJOB,
+ );
+ }
+
+ /**
+ * Get the required parameter for the action
+ *
+ * @access public
+ * @return array
+ */
+ public function getActionRequiredParameters()
+ {
+ return array(
+ 'color_id' => t('Color'),
+ );
+ }
+
+ /**
+ * Get all tasks
+ *
+ * @access public
+ * @return array
+ */
+
+ public function getEventRequiredParameters()
+ {
+ return array('tasks');
+ }
+
+ /**
+ * Execute the action (change the task color)
+ *
+ * @access public
+ * @param array $data Event data dictionary
+ * @return bool True if the action was executed or false when not executed
+ */
+ public function doAction(array $data)
+ {
+ $results = array();
+
+ foreach ($data['tasks'] as $task) {
+ if ($task['date_due'] <= time() && $task['date_due'] > 0) {
+ $values = array(
+ 'id' => $task['id'],
+ 'color_id' => $this->getParam('color_id'),
+ );
+ $results[] = $this->taskModificationModel->update($values, false);
+ }
+ }
+
+ return in_array(true, $results, true);
+ }
+
+ /**
+ * Check if the event data meet the action condition
+ *
+ * @access public
+ * @param array $data Event data dictionary
+ * @return bool
+ */
+ public function hasRequiredCondition(array $data)
+ {
+ return count($data['tasks']) > 0;
+ }
+}
diff --git a/app/Helper/TextHelper.php b/app/Helper/TextHelper.php
index 66583cd1..89c1a8f3 100644
--- a/app/Helper/TextHelper.php
+++ b/app/Helper/TextHelper.php
@@ -25,6 +25,19 @@ class TextHelper extends Base
}
/**
+ * Join with HTML escaping
+ *
+ * @param $glue
+ * @param array $list
+ * @return string
+ */
+ public function implode($glue, array $list)
+ {
+ array_walk($list, function (&$value) { $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); });
+ return implode($glue, $list);
+ }
+
+ /**
* Markdown transformation
*
* @param string $text
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index 7aa39b2e..cb6873cd 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -1302,34 +1302,34 @@ return array(
'Do you really want to reopen this project: "%s"?' => 'Deseja mesmo reabrir este projecto?: "%s"?',
'This project is open' => 'Este projeto está aberto',
'This project is closed' => 'Este projecto está fechado',
- // 'Unable to upload files, check the permissions of your data folder.' => '',
- // 'Another category with the same name exists in this project' => '',
- // 'Comment sent by email successfully.' => '',
- // 'Sent by email to [%s](mailto:%s) (%s)' => '',
- // 'Unable to read uploaded file.' => '',
- // 'Database uploaded successfully.' => '',
- // 'Task sent by email successfully.' => '',
- // 'There is no category in this project.' => '',
- // 'Send by email' => '',
- // 'Create and send a comment by email' => '',
- // 'Subject' => '',
- // 'Upload the database' => '',
- // 'You could upload the previously downloaded Sqlite database (Gzip format).' => '',
- // 'Database file' => '',
- // 'Upload' => '',
- // 'Remove this user from group' => '',
- // 'Your project must have at least one active swimlane.' => '',
- // 'Project: %s' => '',
- // 'Automatic action not found: "%s"' => '',
- // '%d projects' => '',
- // '%d project' => '',
- // 'There is no project.' => '',
- // 'Sort' => '',
- // 'Project ID' => '',
- // 'Project name' => '',
- // 'Public' => '',
- // 'Private' => '',
- // '%d tasks' => '',
- // '%d task' => '',
- // 'Task ID' => '',
+ 'Unable to upload files, check the permissions of your data folder.' => 'Impossivel enviar ficheiros, verifique as permissões da pasta data',
+ 'Another category with the same name exists in this project' => 'Outra categoria com o mesmo nome já existe neste projecto',
+ 'Comment sent by email successfully.' => 'Comentário enviado por email com sucesso.',
+ 'Sent by email to [%s](mailto:%s) (%s)' => 'Enviado por email para [%s](mailto:%s) (%s)',
+ 'Unable to read uploaded file.' => 'Não foi possivel ler ficheiro enviado.',
+ 'Database uploaded successfully.' => 'Base de dados enviada com sucesso.',
+ 'Task sent by email successfully.' => 'Tarefa enviada por email com sucesso.',
+ 'There is no category in this project.' => 'Não existe categorias neste projecto.',
+ 'Send by email' => 'Enviar por email',
+ 'Create and send a comment by email' => 'Criar e enviar um comentário por email',
+ 'Subject' => 'Assunto',
+ 'Upload the database' => 'Enviar a base de dados',
+ 'You could upload the previously downloaded Sqlite database (Gzip format).' => 'Poderia enviar a base de dados Sqlite transferida anteriormente (formato Gzip).',
+ 'Database file' => 'Ficheiro base de dados',
+ 'Upload' => 'Enviar',
+ 'Remove this user from group' => 'Remover este utilizador do grupo',
+ 'Your project must have at least one active swimlane.' => 'O seu projecto deve ter pelo menos uma swimlane activa.',
+ 'Project: %s' => 'Projecto: %s',
+ 'Automatic action not found: "%s"' => 'Acção automática não encontrada: "%s"',
+ '%d projects' => '%d projetos',
+ '%d project' => '%d projecto',
+ 'There is no project.' => 'Não existe projecto.',
+ 'Sort' => 'Ordenar',
+ 'Project ID' => 'ID do Projecto',
+ 'Project name' => 'Nome do Projecto',
+ 'Public' => 'Público',
+ 'Private' => 'Privado',
+ '%d tasks' => '%d tarefas',
+ '%d task' => '%d tarefa',
+ 'Task ID' => 'ID da Tarefa',
);
diff --git a/app/Schema/Migration.php b/app/Schema/Migration.php
index 91838efa..654303f4 100644
--- a/app/Schema/Migration.php
+++ b/app/Schema/Migration.php
@@ -9,6 +9,9 @@ function migrate_default_swimlane(PDO $pdo)
$projects = get_all_projects($pdo);
foreach ($projects as $project) {
+ if (empty($project['default_swimlane'])) {
+ $project['default_swimlane'] = 'Default swimlane';
+ }
// Create new default swimlane
$rq = $pdo->prepare('INSERT INTO swimlanes (project_id, name, is_active, position) VALUES (?, ?, ?, ?)');
diff --git a/app/ServiceProvider/ActionProvider.php b/app/ServiceProvider/ActionProvider.php
index 81f2b39e..a7e8040e 100644
--- a/app/ServiceProvider/ActionProvider.php
+++ b/app/ServiceProvider/ActionProvider.php
@@ -4,6 +4,7 @@ namespace Kanboard\ServiceProvider;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
+use Kanboard\Action\TaskAssignColorOnDueDate;
use Kanboard\Action\TaskAssignColorPriority;
use Kanboard\Action\TaskAssignDueDateOnCreation;
use Kanboard\Action\TaskMoveColumnClosed;
@@ -92,6 +93,7 @@ class ActionProvider implements ServiceProviderInterface
$container['actionManager']->register(new TaskAssignDueDateOnCreation($container));
$container['actionManager']->register(new TaskAssignColorSwimlane($container));
$container['actionManager']->register(new TaskAssignPrioritySwimlane($container));
+ $container['actionManager']->register(new TaskAssignColorOnDueDate($container));
return $container;
}
diff --git a/app/Template/board/table_column.php b/app/Template/board/table_column.php
index df16715f..c2d6b9fc 100644
--- a/app/Template/board/table_column.php
+++ b/app/Template/board/table_column.php
@@ -53,17 +53,26 @@
<?php endif ?>
</span>
- <?php if (! $not_editable && ! empty($column['description'])): ?>
- <span class="tooltip pull-right" title="<?= $this->text->markdownAttribute($column['description']) ?>">
- &nbsp;<i class="fa fa-info-circle"></i>
- </span>
- <?php endif ?>
+ <span class="pull-right">
+ <?php if ($swimlane['nb_swimlanes'] > 1 && ! empty($column['column_score'])): ?>
+ <span title="<?= t('Total score in this column across all swimlanes') ?>">
+ (<span><?= $column['column_score'] ?></span>)
+ </span>
+ <?php endif ?>
- <?php if (! empty($column['score'])): ?>
- <span class="pull-right" title="<?= t('Score') ?>">
- <?= $column['score'] ?>
- </span>
- <?php endif ?>
+ <?php if (! empty($column['score'])): ?>
+ <span title="<?= t('Score') ?>">
+ <?= $column['score'] ?>
+ </span>
+ <?php endif ?>
+
+ <?php if (! $not_editable && ! empty($column['description'])): ?>
+ <span class="tooltip" title="<?= $this->text->markdownAttribute($column['description']) ?>">
+ &nbsp;<i class="fa fa-info-circle"></i>
+ </span>
+ <?php endif ?>
+
+ </span>
<?php if ($column['task_limit']): ?>
<span title="<?= t('Task limit') ?>">
diff --git a/app/Template/project_overview/information.php b/app/Template/project_overview/information.php
index 0fe53e08..e8c20903 100644
--- a/app/Template/project_overview/information.php
+++ b/app/Template/project_overview/information.php
@@ -13,8 +13,8 @@
<?php foreach ($roles as $role => $role_name): ?>
<?php if (isset($users[$role])): ?>
<li>
- <?= $role_name ?>:
- <strong><?= implode(', ', $users[$role]) ?></strong>
+ <?= $this->text->e($role_name) ?>:
+ <strong><?= $this->text->implode(', ', $users[$role]) ?></strong>
</li>
<?php endif ?>
<?php endforeach ?>
diff --git a/app/Template/project_user_overview/tooltip_users.php b/app/Template/project_user_overview/tooltip_users.php
index 99b00030..8bc821e7 100644
--- a/app/Template/project_user_overview/tooltip_users.php
+++ b/app/Template/project_user_overview/tooltip_users.php
@@ -4,7 +4,7 @@
<table class="table-small">
<?php foreach ($roles as $role => $role_name): ?>
<?php if (isset($users[$role])): ?>
- <tr><th><?= $role_name ?></th></tr>
+ <tr><th><?= $this->text->e($role_name) ?></th></tr>
<?php foreach ($users[$role] as $user_id => $user): ?>
<tr><td>
<?= $this->url->link($this->text->e($user), 'ProjectUserOverviewController', 'opens', array('user_id' => $user_id)) ?>
diff --git a/app/User/Avatar/LetterAvatarProvider.php b/app/User/Avatar/LetterAvatarProvider.php
index 727f9109..cc417a86 100644
--- a/app/User/Avatar/LetterAvatarProvider.php
+++ b/app/User/Avatar/LetterAvatarProvider.php
@@ -39,7 +39,7 @@ class LetterAvatarProvider extends Base implements AvatarProviderInterface
$rgb[1],
$rgb[2],
$this->helper->text->e($user['name'] ?: $user['username']),
- $initials
+ $this->helper->text->e($initials)
);
}