diff options
Diffstat (limited to 'app')
32 files changed, 180 insertions, 49 deletions
diff --git a/app/Controller/CommentMailController.php b/app/Controller/CommentMailController.php new file mode 100644 index 00000000..e30d6a55 --- /dev/null +++ b/app/Controller/CommentMailController.php @@ -0,0 +1,74 @@ +<?php + +namespace Kanboard\Controller; + +/** + * Class CommentMailController + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class CommentMailController extends BaseController +{ + public function create(array $values = array(), array $errors = array()) + { + $project = $this->getProject(); + $task = $this->getTask(); + + $this->response->html($this->helper->layout->task('comment_mail/create', array( + 'values' => $values, + 'errors' => $errors, + 'task' => $task, + 'project' => $project, + ))); + } + + public function save() + { + $task = $this->getTask(); + $values = $this->request->getValues(); + $values['task_id'] = $task['id']; + $values['user_id'] = $this->userSession->getId(); + + list($valid, $errors) = $this->commentValidator->validateEmailCreation($values); + + if ($valid) { + $this->sendByEmail($values); + $values = $this->prepareComment($values); + + if ($this->commentModel->create($values) !== false) { + $this->flash->success(t('Comment sent by email successfully.')); + } else { + $this->flash->failure(t('Unable to create your comment.')); + } + + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true); + } else { + $this->create($values, $errors); + } + } + + protected function sendByEmail(array $values) + { + $html = $this->template->render('comment_mail/email', array( + 'email' => $values, + )); + + $this->emailClient->send( + $values['email'], + $values['email'], + $values['subject'], + $html + ); + } + + protected function prepareComment(array $values) + { + $values['comment'] .= "\n\n_".t('Sent by email to [%s](mailto:%s) (%s)', $values['email'], $values['email'], $values['subject']).'_'; + + unset($values['subject']); + unset($values['email']); + + return $values; + } +} diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php index 7ca6e5df..6e7fcdd3 100644 --- a/app/Locale/bs_BA/translations.php +++ b/app/Locale/bs_BA/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Dodaj', 'Replace' => 'Zamijeni', 'Import' => 'Uvoz', - 'change sorting' => 'Promijeni sortiranje', + 'Change sorting' => 'Promijeni sortiranje', 'Tasks Importation' => 'Uvoz zadataka', 'Delimiter' => 'Djelilac', 'Enclosure' => 'Prilog', diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php index 2b594585..2013834e 100644 --- a/app/Locale/cs_CZ/translations.php +++ b/app/Locale/cs_CZ/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index 478d71fe..61d135c1 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 02880efb..7ff21e8e 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Anhängen', 'Replace' => 'Ersetzen', 'Import' => 'Import', - 'change sorting' => 'Sortierung ändern', + 'Change sorting' => 'Sortierung ändern', 'Tasks Importation' => 'Aufgaben Import', 'Delimiter' => 'Trennzeichen', 'Enclosure' => 'Textbegrenzer', diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php index 3897b67b..07b216e3 100644 --- a/app/Locale/el_GR/translations.php +++ b/app/Locale/el_GR/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Προσθήκη', 'Replace' => 'Αντικατάσταση', 'Import' => 'Εισαγωγή', - 'change sorting' => 'Αλλαγή ταξινόμησης', + 'Change sorting' => 'Αλλαγή ταξινόμησης', 'Tasks Importation' => 'Εισαγωγή εργασιών', 'Delimiter' => 'Delimiter', 'Enclosure' => 'Enclosure', diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index 4f2da41d..cea867ec 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Añadir', 'Replace' => 'Reemplazar', 'Import' => 'Importar', - 'change sorting' => 'Cambiar orden', + 'Change sorting' => 'Cambiar orden', 'Tasks Importation' => 'Importación de tareas', 'Delimiter' => 'Delimitador', 'Enclosure' => 'Recinto', diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index c6276e27..bee32a2c 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index 4b17b674..38d35def 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Ajouter', 'Replace' => 'Remplaçer', 'Import' => 'Importation', - 'change sorting' => 'changer l\'ordre', + 'Change sorting' => 'changer l\'ordre', 'Tasks Importation' => 'Importation des tâches', 'Delimiter' => 'Délimiteur', 'Enclosure' => 'Caractère d\'encadrement', diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index 4211ba3b..1a12d0c0 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Hozzáfűz', 'Replace' => 'Helyettesít', 'Import' => 'Importál', - 'change sorting' => 'rendezési sorrend megváltoztatása', + 'Change sorting' => 'rendezési sorrend megváltoztatása', 'Tasks Importation' => 'Feladat importálás', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php index 4f4580cf..6b51a76b 100644 --- a/app/Locale/id_ID/translations.php +++ b/app/Locale/id_ID/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Tambahkan', 'Replace' => 'Ganti', 'Import' => 'Impor', - 'change sorting' => 'ubah pengurutan', + 'Change sorting' => 'ubah pengurutan', 'Tasks Importation' => 'Importasi Tugas', 'Delimiter' => 'Pembatas', 'Enclosure' => 'Lampiran', diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index de901550..a77e01f5 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Aggiungi', 'Replace' => 'Sostituisci', 'Import' => 'Importa', - 'change sorting' => 'cambia ordinamento', + 'Change sorting' => 'cambia ordinamento', 'Tasks Importation' => 'Importazione task', 'Delimiter' => 'Delimitatore', // 'Enclosure' => '', diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index 147159a2..a85df1df 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php index b42e728f..5c7c174c 100644 --- a/app/Locale/ko_KR/translations.php +++ b/app/Locale/ko_KR/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => '추가', 'Replace' => '변경', 'Import' => '가져오기', - 'change sorting' => '정렬 변경', + 'Change sorting' => '정렬 변경', 'Tasks Importation' => '할일 가져오기', 'Delimiter' => '구분자', 'Enclosure' => '동봉', diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php index 727506bd..f44411e8 100644 --- a/app/Locale/my_MY/translations.php +++ b/app/Locale/my_MY/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php index 2e290048..a6a92313 100644 --- a/app/Locale/nb_NO/translations.php +++ b/app/Locale/nb_NO/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php index 001964b6..93b4262f 100644 --- a/app/Locale/nl_NL/translations.php +++ b/app/Locale/nl_NL/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index 7f8887d7..56154adc 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Dołącz', 'Replace' => 'Zastąp', 'Import' => 'Importuj', - 'change sorting' => 'odwróć sortowanie', + 'Change sorting' => 'odwróć sortowanie', 'Tasks Importation' => 'Import zadań', 'Delimiter' => 'Separator pola', 'Enclosure' => 'Separator tekstu', diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index eef50b17..1203caa0 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Adicionar', 'Replace' => 'Substituir', 'Import' => 'Importar', - 'change sorting' => 'alterar ordenação', + 'Change sorting' => 'alterar ordenação', 'Tasks Importation' => 'Importação de Tarefas', 'Delimiter' => 'Separador', 'Enclosure' => 'Delimitador de campos', diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php index 44e0cf6a..3fdc56cd 100644 --- a/app/Locale/pt_PT/translations.php +++ b/app/Locale/pt_PT/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Acrescentar', 'Replace' => 'Substituir', 'Import' => 'Importar', - 'change sorting' => 'alterar ordernação', + 'Change sorting' => 'alterar ordernação', 'Tasks Importation' => 'Importação de Tarefas', 'Delimiter' => 'Delimitador', 'Enclosure' => 'Clausura', diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index 6b4f7fb5..5ba1b2af 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Добавление', 'Replace' => 'Замена', 'Import' => 'Импорт', - 'change sorting' => 'изменить сортировку', + 'Change sorting' => 'изменить сортировку', 'Tasks Importation' => 'Импортирование задач', 'Delimiter' => 'Разделитель', 'Enclosure' => 'Тип кавычек', diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php index cfd6286d..36fa8a90 100644 --- a/app/Locale/sr_Latn_RS/translations.php +++ b/app/Locale/sr_Latn_RS/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index 59948bb5..63977737 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -844,7 +844,7 @@ return array( // 'Append' => '', // 'Replace' => '', // 'Import' => '', - // 'change sorting' => '', + // 'Change sorting' => '', // 'Tasks Importation' => '', // 'Delimiter' => '', // 'Enclosure' => '', diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index 33579591..38b1706a 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'เพิ่มเติม', 'Replace' => 'แทนที่', 'Import' => 'นำเข้า', - 'change sorting' => 'เปลี่ยนการเรียง', + 'Change sorting' => 'เปลี่ยนการเรียง', 'Tasks Importation' => 'การนำเข้างาน', 'Delimiter' => 'คั่น', 'Enclosure' => 'กำหนดข้อความ', diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php index 98331ae4..1d97ba02 100644 --- a/app/Locale/tr_TR/translations.php +++ b/app/Locale/tr_TR/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => 'Ekle', 'Replace' => 'Üzerine yaz', 'Import' => 'İçeri aktar', - 'change sorting' => 'sıralamayı değiştir', + 'Change sorting' => 'sıralamayı değiştir', 'Tasks Importation' => 'Görevleri içeri aktar', 'Delimiter' => 'Ayırıcı', 'Enclosure' => 'Enclosure', diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index 358bce93..53e21ce6 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -844,7 +844,7 @@ return array( 'Append' => '追加', 'Replace' => '替换', 'Import' => '导入', - 'change sorting' => '改变排序', + 'Change sorting' => '改变排序', 'Tasks Importation' => '任务重要性', 'Delimiter' => '分隔符', 'Enclosure' => '附件', diff --git a/app/Template/comment/show.php b/app/Template/comment/show.php index d8470c24..5f15ffd6 100644 --- a/app/Template/comment/show.php +++ b/app/Template/comment/show.php @@ -8,26 +8,28 @@ <?php endif ?> <small class="comment-date"><?= t('Created at:') ?> <?= $this->dt->datetime($comment['date_creation']) ?></small> - <small class="comment-date"><?= t('Updated at:')?> <?= $this->dt->datetime($comment['date_modification']) ?></small> + <small class="comment-date"><?= t('Updated at:') ?> <?= $this->dt->datetime($comment['date_modification']) ?></small> </div> <?php if (! isset($hide_actions)): ?> - <div class="comment-actions"> + <div class="comment-actions"> + <div class="dropdown"> + <a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog"></i><i class="fa fa-caret-down"></i></a> <ul> <li> - <i class="fa fa-link fa-fw"></i> - <a href="#comment-<?= $comment['id'] ?>"><?= t('link') ?></a> + <?= $this->url->icon('link', t('Link'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', '', $this->app->isAjax(), 'comment-'.$comment['id']) ?> </li> <?php if ($editable && ($this->user->isAdmin() || $this->user->isCurrentUser($comment['user_id']))): ?> <li> - <?= $this->modal->medium('edit', t('edit'), 'CommentController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?> + <?= $this->modal->medium('edit', t('Edit'), 'CommentController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?> </li> <li> - <?= $this->modal->confirm('trash-o', t('remove'), 'CommentController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?> + <?= $this->modal->confirm('trash-o', t('Remove'), 'CommentController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?> </li> <?php endif ?> </ul> </div> + </div> <?php endif ?> <div class="comment-content"> diff --git a/app/Template/comment_list/show.php b/app/Template/comment_list/show.php index 6e362560..4b6b765d 100644 --- a/app/Template/comment_list/show.php +++ b/app/Template/comment_list/show.php @@ -1,20 +1,25 @@ <div class="page-header"> - <h2><?= $this->text->e($task['title']) ?> > <?= t('Comments') ?></h2> + <h2><?= $this->text->e($task['title']) ?></h2> <?php if (!isset($is_public) || !$is_public): ?> - <div class="comment-sorting"> - <small> - <?= $this->url->icon('sort', t('change sorting'), 'CommentListController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'js-modal-replace') ?> - </small> - </div> + <ul> + <li> + <?= $this->url->icon('sort', t('Change sorting'), 'CommentListController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'js-modal-replace') ?> + </li> + <?php if ($editable): ?> + <li> + <?= $this->modal->medium('paper-plane', t('Send by email'), 'CommentMailController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> + </li> + <?php endif ?> + </ul> <?php endif ?> </div> <div class="comments"> <?php foreach ($comments as $comment): ?> <?= $this->render('comment/show', array( - 'comment' => $comment, - 'task' => $task, - 'project' => $project, - 'editable' => $editable, + 'comment' => $comment, + 'task' => $task, + 'project' => $project, + 'editable' => $editable, 'is_public' => isset($is_public) && $is_public, )) ?> <?php endforeach ?> diff --git a/app/Template/comment_mail/create.php b/app/Template/comment_mail/create.php new file mode 100644 index 00000000..57ddeb39 --- /dev/null +++ b/app/Template/comment_mail/create.php @@ -0,0 +1,21 @@ +<div class="page-header"> + <h2><?= t('Create and send comment by email') ?></h2> +</div> +<form method="post" action="<?= $this->url->href('CommentMailController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off"> + <?= $this->form->csrf() ?> + <?= $this->form->hidden('task_id', $values) ?> + <?= $this->form->hidden('user_id', $values) ?> + + <?= $this->form->label(t('Email'), 'email') ?> + <?= $this->form->email('email', $values, $errors, array('autofocus', 'required', 'tabindex="1"')) ?> + + <?= $this->form->label(t('Subject'), 'subject') ?> + <?= $this->form->text('subject', $values, $errors, array('required', 'tabindex="2"')) ?> + + <?= $this->form->textEditor('comment', $values, $errors, array('required' => true, 'tabindex' => 3)) ?> + + <?= $this->modal->submitButtons(array( + 'submitLabel' => t('Send by email'), + 'tabindex' => 4, + )) ?> +</form> diff --git a/app/Template/comment_mail/email.php b/app/Template/comment_mail/email.php new file mode 100644 index 00000000..a89284f4 --- /dev/null +++ b/app/Template/comment_mail/email.php @@ -0,0 +1 @@ +<?= $this->text->markdown($email['comment'], true) ?> diff --git a/app/Template/task_comments/show.php b/app/Template/task_comments/show.php index 18200bc8..d34e5e95 100644 --- a/app/Template/task_comments/show.php +++ b/app/Template/task_comments/show.php @@ -6,25 +6,28 @@ <?php if (!isset($is_public) || !$is_public): ?> <div class="comment-sorting"> <small> - <?= $this->url->icon('sort', t('change sorting'), 'CommentController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> + <?= $this->url->icon('sort', t('Change sorting'), 'CommentController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> + <?php if ($editable): ?> + <?= $this->modal->medium('paper-plane', t('Send by email'), 'CommentMailController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> + <?php endif ?> </small> </div> <?php endif ?> <?php foreach ($comments as $comment): ?> <?= $this->render('comment/show', array( - 'comment' => $comment, - 'task' => $task, - 'project' => $project, - 'editable' => $editable, + 'comment' => $comment, + 'task' => $task, + 'project' => $project, + 'editable' => $editable, 'is_public' => isset($is_public) && $is_public, )) ?> <?php endforeach ?> <?php if ($editable): ?> <?= $this->render('task_comments/create', array( - 'values' => array(), - 'errors' => array(), - 'task' => $task, + 'values' => array(), + 'errors' => array(), + 'task' => $task, )) ?> <?php endif ?> </div> diff --git a/app/Validator/CommentValidator.php b/app/Validator/CommentValidator.php index fc8e6da8..29994afc 100644 --- a/app/Validator/CommentValidator.php +++ b/app/Validator/CommentValidator.php @@ -14,6 +14,31 @@ use SimpleValidator\Validators; class CommentValidator extends BaseValidator { /** + * Validate comment email creation + * + * @access public + * @param array $values Required parameters to save an action + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateEmailCreation(array $values) + { + $rules = array( + new Validators\Required('task_id', t('This value is required')), + new Validators\Required('user_id', t('This value is required')), + new Validators\Required('subject', t('This field is required')), + new Validators\Required('email', t('This field is required')), + new Validators\Email('email', t('Email address invalid')), + ); + + $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** * Validate comment creation * * @access public |