summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Controller/Config.php2
-rw-r--r--app/Controller/Project.php37
-rw-r--r--app/Controller/User.php22
-rw-r--r--app/Core/Base.php8
-rw-r--r--app/Integration/HipchatWebhook.php93
-rw-r--r--app/Integration/Jabber.php126
-rw-r--r--app/Integration/SlackWebhook.php126
-rw-r--r--app/Locale/cs_CZ/translations.php17
-rw-r--r--app/Locale/da_DK/translations.php17
-rw-r--r--app/Locale/de_DE/translations.php17
-rw-r--r--app/Locale/es_ES/translations.php17
-rw-r--r--app/Locale/fi_FI/translations.php17
-rw-r--r--app/Locale/fr_FR/translations.php17
-rw-r--r--app/Locale/hu_HU/translations.php17
-rw-r--r--app/Locale/id_ID/translations.php17
-rw-r--r--app/Locale/it_IT/translations.php17
-rw-r--r--app/Locale/ja_JP/translations.php17
-rw-r--r--app/Locale/nb_NO/translations.php17
-rw-r--r--app/Locale/nl_NL/translations.php17
-rw-r--r--app/Locale/pl_PL/translations.php17
-rw-r--r--app/Locale/pt_BR/translations.php17
-rw-r--r--app/Locale/pt_PT/translations.php17
-rw-r--r--app/Locale/ru_RU/translations.php17
-rw-r--r--app/Locale/sr_Latn_RS/translations.php17
-rw-r--r--app/Locale/sv_SE/translations.php17
-rw-r--r--app/Locale/th_TH/translations.php17
-rw-r--r--app/Locale/tr_TR/translations.php17
-rw-r--r--app/Locale/zh_CN/translations.php17
-rw-r--r--app/Model/Acl.php2
-rw-r--r--app/Model/Notification.php142
-rw-r--r--app/Model/NotificationType.php16
-rw-r--r--app/Model/ProjectActivity.php52
-rw-r--r--app/Model/ProjectIntegration.php66
-rw-r--r--app/Model/ProjectNotification.php38
-rw-r--r--app/Model/ProjectNotificationType.php6
-rw-r--r--app/Model/UserNotificationType.php5
-rw-r--r--app/Model/UserUnreadNotification.php63
-rw-r--r--app/Notification/ActivityStream.php11
-rw-r--r--app/Schema/Mysql.php17
-rw-r--r--app/Schema/Postgres.php17
-rw-r--r--app/Schema/Sqlite.php17
-rw-r--r--app/ServiceProvider/ClassProvider.php5
-rw-r--r--app/Template/config/integrations.php54
-rw-r--r--app/Template/project/integrations.php74
-rw-r--r--app/Template/project/notifications.php20
-rw-r--r--app/Template/project/sidebar.php7
-rw-r--r--app/Template/user/integrations.php13
-rw-r--r--app/Template/user/sidebar.php3
-rw-r--r--assets/img/hipchat-icon.pngbin1373 -> 0 bytes
-rw-r--r--assets/img/jabber-icon.pngbin1275 -> 0 bytes
-rw-r--r--doc/fr/notifications.markdown11
-rw-r--r--doc/hipchat.markdown38
-rw-r--r--doc/index.markdown3
-rw-r--r--doc/jabber.markdown34
-rw-r--r--doc/notifications.markdown9
-rw-r--r--doc/plugin-hooks.markdown2
-rw-r--r--doc/plugin-notifications.markdown60
-rw-r--r--doc/plugin-registration.markdown4
-rw-r--r--doc/plugins.markdown4
-rw-r--r--doc/slack.markdown38
-rw-r--r--tests/units/Base.php2
-rw-r--r--tests/units/Integration/SlackWebhookTest.php377
-rw-r--r--tests/units/Model/NotificationTest.php69
-rw-r--r--tests/units/Model/ProjectActivityTest.php40
-rw-r--r--tests/units/Model/ProjectNotificationTypeTest.php11
-rw-r--r--tests/units/Model/UserNotificationTest.php23
-rw-r--r--tests/units/Model/UserNotificationTypeTest.php21
-rw-r--r--tests/units/Model/UserUnreadNotificationTest.php43
68 files changed, 544 insertions, 1644 deletions
diff --git a/app/Controller/Config.php b/app/Controller/Config.php
index 9a376b36..47b844e4 100644
--- a/app/Controller/Config.php
+++ b/app/Controller/Config.php
@@ -44,7 +44,7 @@ class Config extends Base
$values += array('subtask_restriction' => 0, 'subtask_time_tracking' => 0, 'cfd_include_closed_tasks' => 0);
break;
case 'integrations':
- $values += array('integration_slack_webhook' => 0, 'integration_hipchat' => 0, 'integration_gravatar' => 0, 'integration_jabber' => 0);
+ $values += array('integration_gravatar' => 0);
break;
case 'calendar':
$values += array('calendar_user_subtasks_time_tracking' => 0);
diff --git a/app/Controller/Project.php b/app/Controller/Project.php
index af01ea77..f30d70e2 100644
--- a/app/Controller/Project.php
+++ b/app/Controller/Project.php
@@ -89,29 +89,50 @@ class Project extends Base
*
* @access public
*/
- public function integration()
+ public function integrations()
{
$project = $this->getProject();
if ($this->request->isPost()) {
- $params = $this->request->getValues();
- $params += array('hipchat' => 0, 'slack' => 0, 'jabber' => 0);
- $this->projectIntegration->saveParameters($project['id'], $params);
+ $this->projectMetadata->save($project['id'], $this->request->getValues());
+ $this->session->flash(t('Project updated successfully.'));
+ $this->response->redirect($this->helper->url->to('project', 'integrations', array('project_id' => $project['id'])));
}
- $values = $this->projectIntegration->getParameters($project['id']);
- $values += array('hipchat_api_url' => 'https://api.hipchat.com');
-
$this->response->html($this->projectLayout('project/integrations', array(
'project' => $project,
'title' => t('Integrations'),
'webhook_token' => $this->config->get('webhook_token'),
- 'values' => $values,
+ 'values' => $this->projectMetadata->getAll($project['id']),
'errors' => array(),
)));
}
/**
+ * Display project notifications
+ *
+ * @access public
+ */
+ public function notifications()
+ {
+ $project = $this->getProject();
+
+ if ($this->request->isPost()) {
+ $values = $this->request->getValues();
+ $this->projectNotification->saveSettings($project['id'], $values);
+ $this->session->flash(t('Project updated successfully.'));
+ $this->response->redirect($this->helper->url->to('project', 'notifications', array('project_id' => $project['id'])));
+ }
+
+ $this->response->html($this->projectLayout('project/notifications', array(
+ 'notifications' => $this->projectNotification->readSettings($project['id']),
+ 'types' => $this->projectNotificationType->getTypes(),
+ 'project' => $project,
+ 'title' => t('Notifications'),
+ )));
+ }
+
+ /**
* Display a form to edit a project
*
* @access public
diff --git a/app/Controller/User.php b/app/Controller/User.php
index 85b80d79..b5f4edeb 100644
--- a/app/Controller/User.php
+++ b/app/Controller/User.php
@@ -214,6 +214,28 @@ class User extends Base
}
/**
+ * Display user integrations
+ *
+ * @access public
+ */
+ public function integrations()
+ {
+ $user = $this->getUser();
+
+ if ($this->request->isPost()) {
+ $values = $this->request->getValues();
+ $this->userMetadata->save($user['id'], $values);
+ $this->session->flash(t('User updated successfully.'));
+ $this->response->redirect($this->helper->url->to('user', 'integrations', array('user_id' => $user['id'])));
+ }
+
+ $this->response->html($this->layout('user/integrations', array(
+ 'user' => $user,
+ 'values' => $this->userMetadata->getall($user['id']),
+ )));
+ }
+
+ /**
* Display external accounts
*
* @access public
diff --git a/app/Core/Base.php b/app/Core/Base.php
index 74f29508..b7be45d1 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -27,9 +27,6 @@ use Pimple\Container;
* @property \Kanboard\Integration\BitbucketWebhook $bitbucketWebhook
* @property \Kanboard\Integration\GithubWebhook $githubWebhook
* @property \Kanboard\Integration\GitlabWebhook $gitlabWebhook
- * @property \Kanboard\Integration\HipchatWebhook $hipchatWebhook
- * @property \Kanboard\Integration\Jabber $jabber
- * @property \Kanboard\Integration\SlackWebhook $slackWebhook
* @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter
* @property \Kanboard\Formatter\TaskFilterGanttFormatter $taskFilterGanttFormatter
* @property \Kanboard\Formatter\TaskFilterAutoCompleteFormatter $taskFilterAutoCompleteFormatter
@@ -49,6 +46,7 @@ use Pimple\Container;
* @property \Kanboard\Model\File $file
* @property \Kanboard\Model\LastLogin $lastLogin
* @property \Kanboard\Model\Link $link
+ * @property \Kanboard\Model\Notification $notification
* @property \Kanboard\Model\OverdueNotification $overdueNotification
* @property \Kanboard\Model\Project $project
* @property \Kanboard\Model\ProjectActivity $projectActivity
@@ -56,7 +54,7 @@ use Pimple\Container;
* @property \Kanboard\Model\ProjectDuplication $projectDuplication
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
- * @property \Kanboard\Model\ProjectIntegration $projectIntegration
+ * @property \Kanboard\Model\ProjectMetadata $projectMetadata
* @property \Kanboard\Model\ProjectPermission $projectPermission
* @property \Kanboard\Model\Subtask $subtask
* @property \Kanboard\Model\SubtaskExport $subtaskExport
@@ -76,6 +74,7 @@ use Pimple\Container;
* @property \Kanboard\Model\TaskPosition $taskPosition
* @property \Kanboard\Model\TaskStatus $taskStatus
* @property \Kanboard\Model\TaskValidator $taskValidator
+ * @property \Kanboard\Model\TaskMetadata $taskMetadata
* @property \Kanboard\Model\Transition $transition
* @property \Kanboard\Model\User $user
* @property \Kanboard\Model\UserImport $userImport
@@ -84,6 +83,7 @@ use Pimple\Container;
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
* @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification
* @property \Kanboard\Model\UserSession $userSession
+ * @property \Kanboard\Model\UserMetadata $userMetadata
* @property \Kanboard\Model\Webhook $webhook
* @property \Psr\Log\LoggerInterface $logger
* @property \League\HTMLToMarkdown\HtmlConverter $htmlConverter
diff --git a/app/Integration/HipchatWebhook.php b/app/Integration/HipchatWebhook.php
deleted file mode 100644
index 6f789718..00000000
--- a/app/Integration/HipchatWebhook.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-namespace Kanboard\Integration;
-
-/**
- * Hipchat webhook
- *
- * @package integration
- * @author Frederic Guillot
- */
-class HipchatWebhook extends \Kanboard\Core\Base
-{
- /**
- * Return true if Hipchat is enabled for this project or globally
- *
- * @access public
- * @param integer $project_id
- * @return boolean
- */
- public function isActivated($project_id)
- {
- return $this->config->get('integration_hipchat') == 1 || $this->projectIntegration->hasValue($project_id, 'hipchat', 1);
- }
-
- /**
- * Get API parameters
- *
- * @access public
- * @param integer $project_id
- * @return array
- */
- public function getParameters($project_id)
- {
- if ($this->config->get('integration_hipchat') == 1) {
- return array(
- 'api_url' => $this->config->get('integration_hipchat_api_url'),
- 'room_id' => $this->config->get('integration_hipchat_room_id'),
- 'room_token' => $this->config->get('integration_hipchat_room_token'),
- );
- }
-
- $options = $this->projectIntegration->getParameters($project_id);
-
- return array(
- 'api_url' => $options['hipchat_api_url'],
- 'room_id' => $options['hipchat_room_id'],
- 'room_token' => $options['hipchat_room_token'],
- );
- }
-
- /**
- * Send the notification if activated
- *
- * @access public
- * @param integer $project_id Project id
- * @param integer $task_id Task id
- * @param string $event_name Event name
- * @param array $event Event data
- */
- public function notify($project_id, $task_id, $event_name, array $event)
- {
- if ($this->isActivated($project_id)) {
- $params = $this->getParameters($project_id);
- $project = $this->project->getbyId($project_id);
-
- $event['event_name'] = $event_name;
- $event['author'] = $this->user->getFullname($this->session['user']);
-
- $html = '<img src="http://kanboard.net/assets/img/favicon-32x32.png"/>';
- $html .= '<strong>'.$project['name'].'</strong>'.(isset($event['task']['title']) ? '<br/>'.$event['task']['title'] : '').'<br/>';
- $html .= $this->projectActivity->getTitle($event);
-
- if ($this->config->get('application_url')) {
- $html .= '<br/><a href="'.$this->helper->url->href('task', 'show', array('task_id' => $task_id, 'project_id' => $project_id), false, '', true).'">';
- $html .= t('view the task on Kanboard').'</a>';
- }
-
- $payload = array(
- 'message' => $html,
- 'color' => 'yellow',
- );
-
- $url = sprintf(
- '%s/v2/room/%s/notification?auth_token=%s',
- $params['api_url'],
- $params['room_id'],
- $params['room_token']
- );
-
- $this->httpClient->postJson($url, $payload);
- }
- }
-}
diff --git a/app/Integration/Jabber.php b/app/Integration/Jabber.php
deleted file mode 100644
index d776e560..00000000
--- a/app/Integration/Jabber.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-
-namespace Kanboard\Integration;
-
-use Exception;
-use Fabiang\Xmpp\Options;
-use Fabiang\Xmpp\Client;
-use Fabiang\Xmpp\Protocol\Message;
-use Fabiang\Xmpp\Protocol\Presence;
-
-/**
- * Jabber
- *
- * @package integration
- * @author Frederic Guillot
- */
-class Jabber extends \Kanboard\Core\Base
-{
- /**
- * Return true if Jabber is enabled for this project or globally
- *
- * @access public
- * @param integer $project_id
- * @return boolean
- */
- public function isActivated($project_id)
- {
- return $this->config->get('integration_jabber') == 1 || $this->projectIntegration->hasValue($project_id, 'jabber', 1);
- }
-
- /**
- * Get connection parameters
- *
- * @access public
- * @param integer $project_id
- * @return array
- */
- public function getParameters($project_id)
- {
- if ($this->config->get('integration_jabber') == 1) {
- return array(
- 'server' => $this->config->get('integration_jabber_server'),
- 'domain' => $this->config->get('integration_jabber_domain'),
- 'username' => $this->config->get('integration_jabber_username'),
- 'password' => $this->config->get('integration_jabber_password'),
- 'nickname' => $this->config->get('integration_jabber_nickname'),
- 'room' => $this->config->get('integration_jabber_room'),
- );
- }
-
- $options = $this->projectIntegration->getParameters($project_id);
-
- return array(
- 'server' => $options['jabber_server'],
- 'domain' => $options['jabber_domain'],
- 'username' => $options['jabber_username'],
- 'password' => $options['jabber_password'],
- 'nickname' => $options['jabber_nickname'],
- 'room' => $options['jabber_room'],
- );
- }
-
- /**
- * Build and send the message
- *
- * @access public
- * @param integer $project_id Project id
- * @param integer $task_id Task id
- * @param string $event_name Event name
- * @param array $event Event data
- */
- public function notify($project_id, $task_id, $event_name, array $event)
- {
- if ($this->isActivated($project_id)) {
- $project = $this->project->getbyId($project_id);
-
- $event['event_name'] = $event_name;
- $event['author'] = $this->user->getFullname($this->session['user']);
-
- $payload = '['.$project['name'].'] '.str_replace('&quot;', '"', $this->projectActivity->getTitle($event)).(isset($event['task']['title']) ? ' ('.$event['task']['title'].')' : '');
-
- if ($this->config->get('application_url')) {
- $payload .= ' '.$this->helper->url->to('task', 'show', array('task_id' => $task_id, 'project_id' => $project_id), '', true);
- }
-
- $this->sendMessage($project_id, $payload);
- }
- }
-
- /**
- * Send message to the XMPP server
- *
- * @access public
- * @param integer $project_id
- * @param string $payload
- */
- public function sendMessage($project_id, $payload)
- {
- try {
- $params = $this->getParameters($project_id);
-
- $options = new Options($params['server']);
- $options->setUsername($params['username']);
- $options->setPassword($params['password']);
- $options->setTo($params['domain']);
- $options->setLogger($this->container['logger']);
-
- $client = new Client($options);
-
- $channel = new Presence;
- $channel->setTo($params['room'])->setNickName($params['nickname']);
- $client->send($channel);
-
- $message = new Message;
- $message->setMessage($payload)
- ->setTo($params['room'])
- ->setType(Message::TYPE_GROUPCHAT);
-
- $client->send($message);
-
- $client->disconnect();
- } catch (Exception $e) {
- $this->container['logger']->error('Jabber error: '.$e->getMessage());
- }
- }
-}
diff --git a/app/Integration/SlackWebhook.php b/app/Integration/SlackWebhook.php
deleted file mode 100644
index 8f4eb422..00000000
--- a/app/Integration/SlackWebhook.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-
-namespace Kanboard\Integration;
-
-/**
- * Slack Webhook
- *
- * @package integration
- * @author Frederic Guillot
- */
-class SlackWebhook extends \Kanboard\Core\Base
-{
- /**
- * Return true if Slack is enabled for this project or globally
- *
- * @access public
- * @param integer $project_id
- * @return boolean
- */
- public function isActivated($project_id)
- {
- return $this->config->get('integration_slack_webhook') == 1 || $this->projectIntegration->hasValue($project_id, 'slack', 1);
- }
-
- /**
- * Get wehbook url
- *
- * @access public
- * @param integer $project_id
- * @return string
- */
- public function getWebhookUrl($project_id)
- {
- if ($this->config->get('integration_slack_webhook') == 1) {
- return $this->config->get('integration_slack_webhook_url');
- }
-
- $options = $this->projectIntegration->getParameters($project_id);
- return isset($options['slack_webhook_url']) ? $options['slack_webhook_url'] : '';
- }
-
- /**
- * Get optional Slack channel
- *
- * @access public
- * @param integer $project_id
- * @return string
- */
- public function getChannel($project_id)
- {
- $channel = $this->config->get('integration_slack_webhook_channel');
-
- if (! empty($channel)) {
- return $channel;
- }
-
- $options = $this->projectIntegration->getParameters($project_id);
- return isset($options['slack_webhook_channel']) ? $options['slack_webhook_channel'] : '';
- }
-
- /**
- * Send notification to Slack
- *
- * @access public
- * @param integer $project_id Project id
- * @param integer $task_id Task id
- * @param string $event_name Event name
- * @param array $event Event data
- */
- public function notify($project_id, $task_id, $event_name, array $event)
- {
- if ($this->isActivated($project_id)) {
- $project = $this->project->getbyId($project_id);
-
- $event['event_name'] = $event_name;
- $event['author'] = $this->user->getFullname($this->session['user']);
-
- $message = '*['.$project['name'].']* ';
- $message .= str_replace('&quot;', '"', $this->projectActivity->getTitle($event));
- $message .= isset($event['task']['title']) ? ' ('.$event['task']['title'].')' : '';
-
- if ($this->config->get('application_url')) {
- $message .= ' - <'.$this->helper->url->href('task', 'show', array('task_id' => $task_id, 'project_id' => $project_id), false, '', true);
- $message .= '|'.t('view the task on Kanboard').'>';
- }
-
- $this->sendMessage($project_id, $message);
- }
- }
-
- /**
- * Send message to Slack
- *
- * @access public
- * @param integer $project_id
- * @param string $message
- */
- public function sendMessage($project_id, $message)
- {
- $payload = array(
- 'text' => $message,
- 'username' => 'Kanboard',
- 'icon_url' => 'http://kanboard.net/assets/img/favicon.png',
- );
-
- $this->sendPayload($project_id, $payload);
- }
-
- /**
- * Send payload to Slack
- *
- * @access public
- * @param integer $project_id
- * @param array $payload
- */
- public function sendPayload($project_id, array $payload)
- {
- $channel = $this->getChannel($project_id);
-
- if (! empty($channel)) {
- $payload['channel'] = $channel;
- }
-
- $this->httpClient->postJson($this->getWebhookUrl($project_id), $payload);
- }
-}
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index 0ea35a9b..4b872c1d 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Referenční měna',
'The currency rate have been added successfully.' => 'Směnný kurz byl úspěšně přidán.',
'Unable to add this currency rate.' => 'Nelze přidat tento směnný kurz',
- 'Send notifications to a Slack channel' => 'Zaslání upozornění do Slack kanálu',
'Webhook URL' => 'Webhook URL',
- 'Help on Slack integration' => 'Nápověda pro Slack integraci.',
'%s remove the assignee of the task %s' => '%s odstranil přiřazení úkolu %s ',
- 'Send notifications to Hipchat' => 'Odeslat upozornění přes Hipchat',
'API URL' => 'API URL',
- 'Room API ID or name' => 'Raum API ID oder Name',
- 'Room notification token' => 'Raum Benachrichtigungstoken',
- 'Help on Hipchat integration' => 'Hilfe bei Hipchat Integration',
'Enable Gravatar images' => 'Aktiviere Gravatar Bilder',
'Information' => 'Informace',
'Check two factor authentication code' => 'Prüfe Zwei-Faktor-Authentifizierungscode',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
'Calendar settings' => 'Nastavení kalendáře',
// 'Project calendar view' => '',
'Project settings' => 'Nastavení projektu',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s hat die Aufgabe #%d in die Swimlane "%s" verschoben',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
'%s moved the task %s to the first swimlane' => '%s hat die Aufgabe %s in die erste Swimlane verschoben',
'%s moved the task %s to the swimlane "%s"' => '%s hat die Aufgaben %s in die Swimlane "%s" verschoben',
'This report contains all subtasks information for the given date range.' => 'Report obsahuje všechny informace o dílčích úkolech pro daný časový úsek',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Nápověda k ověřování pomocí služby Google',
'Github Authentication' => 'Ověřování pomocí služby Github',
'Help on Github authentication' => 'Nápověda k ověřování pomocí služby Github',
- 'Channel/Group/User (Optional)' => 'Kanál/Skupina/Uživatel (volitelně)',
'Lead time: ' => 'Dodací lhůta: ',
'Cycle time: ' => 'Doba cyklu: ',
'Time spent into each column' => 'Čas strávený v každé fázi',
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index a0578120..a8addf6f 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 13d88b11..4e451f22 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Referenzwährung',
'The currency rate have been added successfully.' => 'Der Währungskurs wurde erfolgreich hinzugefügt.',
'Unable to add this currency rate.' => 'Währungskurs konnte nicht hinzugefügt werden',
- 'Send notifications to a Slack channel' => 'Benachrichtigung an einen Slack-Kanal senden',
'Webhook URL' => 'Webhook-URL',
- 'Help on Slack integration' => 'Hilfe für Slack-Integration.',
'%s remove the assignee of the task %s' => '%s Zuordnung für die Aufgabe %s entfernen',
- 'Send notifications to Hipchat' => 'Sende Benachrichtigung an Hipchat',
'API URL' => 'API-URL',
- 'Room API ID or name' => 'Raum-API-ID oder -Name',
- 'Room notification token' => 'Raum-Benachrichtigungstoken',
- 'Help on Hipchat integration' => 'Hilfe bei Hipchat-Integration',
'Enable Gravatar images' => 'Aktiviere Gravatar-Bilder',
'Information' => 'Information',
'Check two factor authentication code' => 'Prüfe Zwei-Faktor-Authentifizierungscode',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Wenn Aufgabe von erster Spalte verschoben wird',
'When task is moved to last column' => 'Wenn Aufgabe in letzte Spalte verschoben wird',
'Year(s)' => 'Jahr(e)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Benachrichtigungen an Jabber senden',
- 'XMPP server address' => 'XMPP-Server-Adresse',
- 'Jabber domain' => 'Jabber-Domain',
- 'Jabber nickname' => 'Jabber-Nickname',
- 'Multi-user chat room' => 'Multi-User-Chatroom',
- 'Help on Jabber integration' => 'Hilfe zur Jabber-Integration',
- 'The server address must use this format: "tcp://hostname:5222"' => 'Die Server-Adresse muss in diesem Format sein: "tcp://hostname:5222"',
'Calendar settings' => 'Kalender-Einstellungen',
'Project calendar view' => 'Projekt-Kalendarsicht',
'Project settings' => 'Projekteinstellungen',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s hat die Aufgabe #%d in die Swimlane "%s" verschoben',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s hat die Aufgabe %s in die erste Swimlane verschoben',
'%s moved the task %s to the swimlane "%s"' => '%s hat die Aufgaben %s in die Swimlane "%s" verschoben',
'This report contains all subtasks information for the given date range.' => 'Der Bericht beinhaltet alle Teilaufgaben im gewählten Zeitraum',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Hilfe bei Google-Authentifizierung',
'Github Authentication' => 'Github-Authentifizierung',
'Help on Github authentication' => 'Hilfe bei Github-Authentifizierung',
- 'Channel/Group/User (Optional)' => 'Kanal/Gruppe/Benutzer (optional)',
'Lead time: ' => 'Durchlaufzeit:',
'Cycle time: ' => 'Zykluszeit:',
'Time spent into each column' => 'zeit verbracht in jeder Spalte',
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 7e951471..527151f5 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Moneda de referencia',
'The currency rate have been added successfully.' => 'Se ha añadido el cambio de moneda con éxito',
'Unable to add this currency rate.' => 'No pude añadir este cambio de moneda.',
- 'Send notifications to a Slack channel' => 'Enviar notificaciones a un canal Desatendido',
'Webhook URL' => 'URL de Disparador Web (webhook)',
- 'Help on Slack integration' => 'Ayuda sobre integración Desatendida',
'%s remove the assignee of the task %s' => '%s quita el concesionario de la tarea %s',
- 'Send notifications to Hipchat' => 'Enviar notificaciones a Hipchat',
'API URL' => 'URL de API',
- 'Room API ID or name' => 'ID de API de habitación o nombre',
- 'Room notification token' => 'Notificación de ficha de Habitación',
- 'Help on Hipchat integration' => 'Ayuda sobre integración de Hipchat',
'Enable Gravatar images' => 'Activar imágenes Gravatar',
'Information' => 'Información',
'Check two factor authentication code' => 'Revisar código de autenticación de dos factores',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Cuando la tarea es movida desde la primera columna',
'When task is moved to last column' => 'Cuando la tarea es movida a la última columna',
'Year(s)' => 'Año(s)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Enviar notificaciones a Jabber',
- 'XMPP server address' => 'Dirección del servidor XMPP',
- 'Jabber domain' => 'Dominio Jabber',
- 'Jabber nickname' => 'Apodo Jabber',
- 'Multi-user chat room' => 'Sala de chat multiusuario',
- 'Help on Jabber integration' => 'Ayuda para la integración con Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'La dirección del servidor debe usar este formato: "tcp://hostname:5222"',
'Calendar settings' => 'Parámetros del Calendario',
'Project calendar view' => 'Vista de Calendario para el Proyecto',
'Project settings' => 'Parámetros del Proyecto',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s movió la tarea #%d a la calle "%s"',
'Swimlane' => 'Calle',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Desatendida',
'%s moved the task %s to the first swimlane' => '%s movió la tarea %s a la primera calle',
'%s moved the task %s to the swimlane "%s"' => '%s movió la tarea %s a la calle "%s"',
'This report contains all subtasks information for the given date range.' => 'Este informe contiene todas la información de las subtareas para el rango proporcionado de fechas.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Ayuda con la aAutenticación de Google',
'Github Authentication' => 'Autenticación de Github',
'Help on Github authentication' => 'Ayuda con la autenticación de Github',
- 'Channel/Group/User (Optional)' => 'Canal/Grupo/Usuario (Opcional)',
'Lead time: ' => 'Plazo de entrega: ',
'Cycle time: ' => 'Tiempo de Ciclo: ',
'Time spent into each column' => 'Tiempo empleado en cada columna',
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index be4d2275..3bba8bea 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 1afdeab3..d7c0148a 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -699,15 +699,9 @@ return array(
'Reference currency' => 'Devise de référence',
'The currency rate have been added successfully.' => 'Le taux de change a été ajouté avec succès.',
'Unable to add this currency rate.' => 'Impossible d\'ajouter ce taux de change',
- 'Send notifications to a Slack channel' => 'Envoyer les notifications sur un salon de discussion Slack',
'Webhook URL' => 'URL du webhook',
- 'Help on Slack integration' => 'Aide sur l\'intégration avec Slack',
'%s remove the assignee of the task %s' => '%s a enlevé la personne assignée à la tâche %s',
- 'Send notifications to Hipchat' => 'Envoyer les notifications vers Hipchat',
'API URL' => 'URL de l\'api',
- 'Room API ID or name' => 'Nom ou identifiant du salon de discussion',
- 'Room notification token' => 'Jeton de sécurité du salon de discussion',
- 'Help on Hipchat integration' => 'Aide sur l\'intégration avec Hipchat',
'Enable Gravatar images' => 'Activer les images Gravatar',
'Information' => 'Informations',
'Check two factor authentication code' => 'Vérification du code pour l\'authentification à deux-facteurs',
@@ -770,14 +764,6 @@ return array(
'When task is moved from first column' => 'Lorsque la tâche est déplacée en dehors de la première colonne',
'When task is moved to last column' => 'Lorsque la tâche est déplacée dans la dernière colonne',
'Year(s)' => 'Année(s)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Envoyer les notifications vers Jabber',
- 'XMPP server address' => 'Adresse du serveur XMPP',
- 'Jabber domain' => 'Nom de domaine Jabber',
- 'Jabber nickname' => 'Pseudonyme Jabber',
- 'Multi-user chat room' => 'Salon de discussion multi-utilisateurs',
- 'Help on Jabber integration' => 'Aide sur l\'intégration avec Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'L\'adresse du serveur doit utiliser le format suivant : « tcp://hostname:5222 »',
'Calendar settings' => 'Paramètres du calendrier',
'Project calendar view' => 'Vue en mode projet du calendrier',
'Project settings' => 'Paramètres du projet',
@@ -822,8 +808,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s a déplacé la tâche n°%d dans la swimlane « %s »',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s a déplacé la tâche %s dans la première swimlane',
'%s moved the task %s to the swimlane "%s"' => '%s a déplacé la tâche %s dans la swimlane « %s »',
'This report contains all subtasks information for the given date range.' => 'Ce rapport contient les informations de toutes les sous-tâches pour la période sélectionnée.',
@@ -920,7 +904,6 @@ return array(
'Help on Google authentication' => 'Aide sur l\'authentification Google',
'Github Authentication' => 'Authentification Github',
'Help on Github authentication' => 'Aide sur l\'authentification Github',
- 'Channel/Group/User (Optional)' => 'Canal/Groupe/Utilisateur (Optionnel)',
'Lead time: ' => 'Lead time : ',
'Cycle time: ' => 'Temps de cycle : ',
'Time spent into each column' => 'Temps passé dans chaque colonne',
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index bd9ac9b5..b63ce202 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index ef4eefee..a32e2a7a 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Referensi mata uang',
'The currency rate have been added successfully.' => 'Nilai tukar mata uang berhasil ditambahkan.',
'Unable to add this currency rate.' => 'Tidak dapat menambahkan nilai tukar mata uang',
- 'Send notifications to a Slack channel' => 'Kirim pemberitahuan ke saluran Slack',
'Webhook URL' => 'URL webhook',
- 'Help on Slack integration' => 'Bantuan pada integrasi Slack',
'%s remove the assignee of the task %s' => '%s menghapus penugasan dari tugas %s',
- 'Send notifications to Hipchat' => 'Kirim pemberitahuan ke Hipchat',
'API URL' => 'API URL',
- 'Room API ID or name' => 'Id kamar API atau nama ',
- 'Room notification token' => 'Token notifikasi kamar',
- 'Help on Hipchat integration' => 'Bantuan pada integrasi Hipchat',
'Enable Gravatar images' => 'Mengaktifkan gambar Gravatar',
'Information' => 'Informasi',
'Check two factor authentication code' => 'Cek dua faktor kode otentifikasi',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Ketika tugas dipindahkan dari kolom pertama',
'When task is moved to last column' => 'Ketika tugas dipindahkan ke kolom terakhir',
'Year(s)' => 'Tahun',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Kirim pemberitahuan ke Jabber',
- 'XMPP server address' => 'alamat server XMPP',
- 'Jabber domain' => 'Domain Jabber',
- 'Jabber nickname' => 'Nickname Jabber',
- 'Multi-user chat room' => 'Multi-pengguna kamar obrolan',
- 'Help on Jabber integration' => 'Bantuan pada integrasi Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'Alamat server harus menggunakan format ini : « tcp://hostname:5222 »',
'Calendar settings' => 'Pengaturan kalender',
'Project calendar view' => 'Tampilan kalender proyek',
'Project settings' => 'Pengaturan proyek',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s memindahkan tugas n°%d ke swimlane « %s »',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s memindahkan tugas %s ke swimlane pertama',
'%s moved the task %s to the swimlane "%s"' => '%s memindahkan tugas %s ke swimlane « %s »',
'This report contains all subtasks information for the given date range.' => 'Laporan ini berisi semua informasi subtugas untuk rentang tanggal tertentu.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Bantuan pada otentifikasi Google',
'Github Authentication' => 'Otentifikasi Github',
'Help on Github authentication' => 'Bantuan pada otentifikasi Github',
- 'Channel/Group/User (Optional)' => 'Kanal/Grup/Pengguna (pilihan)',
'Lead time: ' => 'Lead time : ',
'Cycle time: ' => 'Siklus waktu : ',
'Time spent into each column' => 'Waktu yang dihabiskan di setiap kolom',
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index e906888a..10c85548 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Valuta di riferimento',
'The currency rate have been added successfully.' => 'Il tasso di cambio è stato aggiunto con successo.',
'Unable to add this currency rate.' => 'Impossibile aggiungere questo tasso di cambio.',
- 'Send notifications to a Slack channel' => 'Invia notifiche al canale Slack',
'Webhook URL' => 'URL Webhook',
- 'Help on Slack integration' => 'Guida all\'integrazione con Slack',
'%s remove the assignee of the task %s' => '%s rimuove l\'assegnatario del compito %s',
- 'Send notifications to Hipchat' => 'Invia notifiche a Hipchat',
'API URL' => 'URL API',
- 'Room API ID or name' => 'Nome o ID API della Room',
- 'Room notification token' => 'Token per le notifiche della Room',
- 'Help on Hipchat integration' => 'Guida all\'integrazione di Hipchat',
'Enable Gravatar images' => 'Abilita immagini Gravatar',
'Information' => 'Informazioni',
'Check two factor authentication code' => 'Controlla il codice di autenticazione a due fattori',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 7bf174ed..b2097280 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => '基軸通貨',
// 'The currency rate have been added successfully.' => '',
'Unable to add this currency rate.' => 'この通貨レートを追加できません。',
- 'Send notifications to a Slack channel' => 'Slack チャンネルに通知を送信',
'Webhook URL' => 'Webhook URL',
- 'Help on Slack integration' => 'Slack 連携のヘルプ',
'%s remove the assignee of the task %s' => '%s がタスク「%s」の担当を解除しました。',
- 'Send notifications to Hipchat' => 'Hipchat に通知を送信',
'API URL' => 'API URL',
- 'Room API ID or name' => 'Room API ID または名前',
- 'Room notification token' => 'Room 通知トークン',
- 'Help on Hipchat integration' => 'Hipchat 連携のヘルプ',
'Enable Gravatar images' => 'Gravatar イメージを有効化',
'Information' => '情報 ',
'Check two factor authentication code' => '2 段認証をチェックする',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index ba4a06d5..e329252b 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Når oppgaven er flyttet fra første kolon',
'When task is moved to last column' => 'Når oppgaven er flyttet til siste kolonne',
'Year(s)' => 'år',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
'Calendar settings' => 'Kalenderinstillinger',
'Project calendar view' => 'Visning prosjektkalender',
'Project settings' => 'Prosjektinnstillinger',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
'Swimlane' => 'Svømmebane',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 09076565..cb0eb422 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 92ad4c26..ffaed8bc 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Waluta referencyjna',
'The currency rate have been added successfully.' => 'Dodano kurs waluty',
'Unable to add this currency rate.' => 'Nie można dodać kursu waluty',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
'%s remove the assignee of the task %s' => '%s usunął osobę przypisaną do zadania %s',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
'Information' => 'Informacje',
'Check two factor authentication code' => 'Sprawdź kod weryfikujący',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Przeniesienie zadania z pierwszej kolumny',
'When task is moved to last column' => 'Przeniesienie zadania do ostatniej kolumny',
'Year(s)' => 'Lat',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
'Calendar settings' => 'Ustawienia kalendarza',
'Project calendar view' => 'Widok kalendarza projektu',
'Project settings' => 'Ustawienia Projektu',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index fdad50ba..0950ef35 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Moeda de Referência',
'The currency rate have been added successfully.' => 'A taxa de câmbio foi adicionada com sucesso.',
'Unable to add this currency rate.' => 'Impossível de adicionar essa taxa de câmbio.',
- 'Send notifications to a Slack channel' => 'Enviar as notificações em um canal Slack',
'Webhook URL' => 'URL do webhook',
- 'Help on Slack integration' => 'Ajuda sobre integração com o Slack',
'%s remove the assignee of the task %s' => '%s removeu a pessoa designada para a tarefa %s',
- 'Send notifications to Hipchat' => 'Enviar as notificações para o Hipchat',
'API URL' => 'URL da API',
- 'Room API ID or name' => 'Nome ou ID da sala de discussão',
- 'Room notification token' => 'Código de segurança da sala de discussão',
- 'Help on Hipchat integration' => 'Ajuda sobre integração com o Hipchat',
'Enable Gravatar images' => 'Ativar imagens do Gravatar',
'Information' => 'Informações',
'Check two factor authentication code' => 'Verificação do código de autenticação à fator duplo',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Quando a tarefa é movida fora da primeira coluna',
'When task is moved to last column' => 'Quando a tarefa é movida para a última coluna',
'Year(s)' => 'Ano(s)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Enviar notificações para o Jabber',
- 'XMPP server address' => 'Endereço do servidor XMPP',
- 'Jabber domain' => 'Nome de domínio Jabber',
- 'Jabber nickname' => 'Apelido Jabber',
- 'Multi-user chat room' => 'Sala de chat multi-usuário',
- 'Help on Jabber integration' => 'Ajuda sobre integração com o Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'O endereço do servidor deve usar o seguinte formato: "tcp://hostname:5222"',
'Calendar settings' => 'Configurações do calendário',
'Project calendar view' => 'Vista em modo projeto do calendário',
'Project settings' => 'Configurações dos projetos',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s moveu a tarefa #%d para a swimlane "%s"',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s moveu a tarefa %s para a primeira swimlane',
'%s moved the task %s to the swimlane "%s"' => '%s moveu a tarefa %s para a swimlane "%s"',
'This report contains all subtasks information for the given date range.' => 'Este relatório contém informações de todas as sub-tarefas para o período selecionado.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Ajuda com a autenticação Google',
'Github Authentication' => 'Autenticação Github',
'Help on Github authentication' => 'Ajuda com a autenticação Github',
- 'Channel/Group/User (Optional)' => 'Canal/Grupo/Utilizador (Opcional)',
'Lead time: ' => 'Lead time: ',
'Cycle time: ' => 'Cycle time: ',
'Time spent into each column' => 'Tempo gasto em cada coluna',
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index 800e5ee3..24366d92 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Moeda de Referência',
'The currency rate have been added successfully.' => 'A taxa de câmbio foi adicionada com sucesso.',
'Unable to add this currency rate.' => 'Impossível adicionar essa taxa de câmbio.',
- 'Send notifications to a Slack channel' => 'Enviar as notificações por canal Slack',
'Webhook URL' => 'URL do webhook',
- 'Help on Slack integration' => 'Ajuda na integração com o Slack',
'%s remove the assignee of the task %s' => '%s removeu a pessoa assignada à tarefa %s',
- 'Send notifications to Hipchat' => 'Enviar as notificações para o Hipchat',
'API URL' => 'URL da API',
- 'Room API ID or name' => 'Nome ou ID da sala de discussão',
- 'Room notification token' => 'Código de segurança da sala de discussão',
- 'Help on Hipchat integration' => 'Ajuda na integração com o Hipchat',
'Enable Gravatar images' => 'Activar imagem Gravatar',
'Information' => 'Informações',
'Check two factor authentication code' => 'Verificação do código de autenticação com factor duplo',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Quando a tarefa é movida fora da primeira coluna',
'When task is moved to last column' => 'Quando a tarefa é movida para a última coluna',
'Year(s)' => 'Ano(s)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Enviar notificações para o Jabber',
- 'XMPP server address' => 'Endereço do servidor XMPP',
- 'Jabber domain' => 'Nome de domínio Jabber',
- 'Jabber nickname' => 'Apelido Jabber',
- 'Multi-user chat room' => 'Sala de chat multi-utilizador',
- 'Help on Jabber integration' => 'Ajuda na integração com Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'O endereço do servidor deve usar o seguinte formato: "tcp://hostname:5222"',
'Calendar settings' => 'Configurações do calendário',
'Project calendar view' => 'Vista em modo projecto do calendário',
'Project settings' => 'Configurações dos projectos',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s moveu a tarefa n° %d no swimlane "%s"',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s moveu a tarefa %s no primeiro swimlane',
'%s moved the task %s to the swimlane "%s"' => '%s moveu a tarefa %s no swimlane "%s"',
'This report contains all subtasks information for the given date range.' => 'Este relatório contém informações de todas as sub-tarefas para o período selecionado.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Ajuda com autenticação Google',
'Github Authentication' => 'Autenticação Github',
'Help on Github authentication' => 'Ajuda com autenticação Github',
- 'Channel/Group/User (Optional)' => 'Canal/Grupo/Utilizador (Opcional)',
'Lead time: ' => 'Tempo de Espera: ',
'Cycle time: ' => 'Tempo de Ciclo: ',
'Time spent into each column' => 'Tempo gasto em cada coluna',
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index fd0540e0..d16e95f3 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Справочник валют',
'The currency rate have been added successfully.' => 'Курс валюты был успешно добавлен.',
'Unable to add this currency rate.' => 'Невозможно добавить этот курс валюты.',
- 'Send notifications to a Slack channel' => 'Отправлять уведомления в канал Slack',
'Webhook URL' => 'Webhook URL',
- 'Help on Slack integration' => 'Помощь по интеграции Slack',
'%s remove the assignee of the task %s' => '%s удалить назначенную задачу %s',
- 'Send notifications to Hipchat' => 'Отправлять уведомления в Hipchat',
'API URL' => 'API URL',
- 'Room API ID or name' => 'API ID комнаты или имя',
- 'Room notification token' => 'Ключь комнаты для уведомлений',
- 'Help on Hipchat integration' => 'Помощь по интеграции Hipchat',
'Enable Gravatar images' => 'Включить Gravatar изображения',
'Information' => 'Информация',
'Check two factor authentication code' => 'Проверка кода двухфакторной авторизации',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'Когда задача перемещается из первой колонки',
'When task is moved to last column' => 'Когда задача перемещается в последнюю колонку',
'Year(s)' => 'Год(а)',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Отправлять уведомления в Jabber',
- 'XMPP server address' => 'Адрес Jabber сервера',
- 'Jabber domain' => 'Домен Jabber',
- 'Jabber nickname' => 'Имя пользователя Jabber',
- 'Multi-user chat room' => 'Многопользовательский чат',
- 'Help on Jabber integration' => 'Помощь по интеграции Jabber',
- 'The server address must use this format: "tcp://hostname:5222"' => 'Адрес сервера должен быть в формате: tcp://hostname:5222',
'Calendar settings' => 'Настройки календаря',
'Project calendar view' => 'Вид календаря проекта',
'Project settings' => 'Настройки проекта',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s задач перемещено #%d в дорожке "%s"',
'Swimlane' => 'Дорожки',
'Gravatar' => 'Граватар',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
'This report contains all subtasks information for the given date range.' => 'Этот отчет содержит всю информацию подзадач в заданном диапазоне дат.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Помощь в авторизации Google',
'Github Authentication' => 'Авторизация Github',
'Help on Github authentication' => 'Помощь в авторизации Github',
- 'Channel/Group/User (Optional)' => 'Канал/Группа/Пользователь (опционально)',
'Lead time: ' => 'Время выполнения:',
'Cycle time: ' => 'Время цикла:',
'Time spent into each column' => 'Время, проведенное в каждой колонке',
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index a1eac165..34dca50b 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 6faf7f60..aac3fac7 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => 'Referensvaluta',
'The currency rate have been added successfully.' => 'Valutakursen har lagts till.',
'Unable to add this currency rate.' => 'Kunde inte lägga till valutakursen.',
- 'Send notifications to a Slack channel' => 'Skicka notiser till en Slack kanal',
'Webhook URL' => 'Webhook URL',
- 'Help on Slack integration' => 'Hjälp för Slack integration',
'%s remove the assignee of the task %s' => '%s ta bort tilldelningen av uppgiften %s',
- 'Send notifications to Hipchat' => 'Skicka notiser till Hipchat',
'API URL' => 'API URL',
- 'Room API ID or name' => 'Room API ID eller namn',
- 'Room notification token' => 'Room notistoken',
- 'Help on Hipchat integration' => 'Hjälp för Hipchat integration',
'Enable Gravatar images' => 'Aktivera Gravatar bilder',
'Information' => 'Information',
'Check two factor authentication code' => 'Kolla tvåfaktorsverifieringskod',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'När uppgiften flyttas från första kolumnen',
'When task is moved to last column' => 'När uppgiften flyttas till sista kolumnen',
'Year(s)' => 'År',
- 'Jabber (XMPP)' => 'Jabber (XMPP)',
- 'Send notifications to Jabber' => 'Skicka notiser till Jabber',
- 'XMPP server address' => 'XMPP serveradress',
- 'Jabber domain' => 'Jabber domän',
- 'Jabber nickname' => 'Jabber smeknamn',
- 'Multi-user chat room' => 'Multi-user chatrum',
- 'Help on Jabber integration' => 'Hjälp för Jabber integration',
- 'The server address must use this format: "tcp://hostname:5222"' => 'Serveradressen måste använda detta format: "tcp://hostname:5222"',
'Calendar settings' => 'Inställningar för kalendern',
'Project calendar view' => 'Projektkalendervy',
'Project settings' => 'Projektinställningar',
@@ -820,8 +806,6 @@ return array(
'%s moved the task #%d to the swimlane "%s"' => '%s flyttade uppgiften #%d till swimlane "%s"',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
- 'Hipchat' => 'Hipchat',
- 'Slack' => 'Slack',
'%s moved the task %s to the first swimlane' => '%s flyttade uppgiften %s till första swimlane',
'%s moved the task %s to the swimlane "%s"' => '%s flyttade uppgiften %s till swimlane "%s"',
'This report contains all subtasks information for the given date range.' => 'Denna rapport innehåller all deluppgiftsinformation för det givna datumintervallet.',
@@ -918,7 +902,6 @@ return array(
'Help on Google authentication' => 'Hjälp för Google autentisering',
'Github Authentication' => 'Github autentisering',
'Help on Github authentication' => 'Hjälp för Github autentisering',
- 'Channel/Group/User (Optional)' => 'Kanal/Grupp/Användare (valfri)',
'Lead time: ' => 'Ledtid',
'Cycle time: ' => 'Cykeltid',
'Time spent into each column' => 'Tidsåtgång per kolumn',
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index b2918ae2..1f7f2dd4 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- 'Send notifications to a Slack channel' => 'ส่งการแจ้งเตือนไปทาง Slack channel',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
'Enable Gravatar images' => 'สามารถใช้งานภาพ Gravatar',
'Information' => 'ข้อมูลสารสนเทศ',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
'When task is moved from first column' => 'เมื่องานถูกย้ายจากคอลัมน์แรก',
'When task is moved to last column' => 'เมื่องานถูกย้ายไปคอลัมน์สุดท้าย',
'Year(s)' => 'ปี',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
'Calendar settings' => 'ตั้งค่าปฏิทิน',
'Project calendar view' => 'มุมมองปฏิทินของโปรเจค',
'Project settings' => 'ตั้งค่าโปรเจค',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 54cb165d..47afc9a5 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -697,15 +697,9 @@ return array(
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
- // 'Send notifications to a Slack channel' => '',
// 'Webhook URL' => '',
- // 'Help on Slack integration' => '',
// '%s remove the assignee of the task %s' => '',
- // 'Send notifications to Hipchat' => '',
// 'API URL' => '',
- // 'Room API ID or name' => '',
- // 'Room notification token' => '',
- // 'Help on Hipchat integration' => '',
// 'Enable Gravatar images' => '',
// 'Information' => '',
// 'Check two factor authentication code' => '',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- // 'Multi-user chat room' => '',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
// 'Calendar settings' => '',
// 'Project calendar view' => '',
// 'Project settings' => '',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index 02e0572c..22612b59 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -697,15 +697,9 @@ return array(
'Reference currency' => '参考货币',
'The currency rate have been added successfully.' => '成功添加汇率。',
'Unable to add this currency rate.' => '无法添加此汇率',
- 'Send notifications to a Slack channel' => '发送通知到 Slack 频道',
'Webhook URL' => '网络钩子 URL',
- 'Help on Slack integration' => 'Slack 整合帮助',
'%s remove the assignee of the task %s' => '%s删除了任务%s的负责人',
- 'Send notifications to Hipchat' => '发送通知到 Hipchat',
'API URL' => 'API URL',
- 'Room API ID or name' => '房间 API ID 或名称',
- 'Room notification token' => '房间通知令牌',
- 'Help on Hipchat integration' => 'Hipchat 整合帮助',
'Enable Gravatar images' => '启用 Gravatar 图像',
'Information' => '信息',
'Check two factor authentication code' => '检查双重认证码',
@@ -768,14 +762,6 @@ return array(
// 'When task is moved from first column' => '',
// 'When task is moved to last column' => '',
// 'Year(s)' => '',
- // 'Jabber (XMPP)' => '',
- // 'Send notifications to Jabber' => '',
- // 'XMPP server address' => '',
- // 'Jabber domain' => '',
- // 'Jabber nickname' => '',
- 'Multi-user chat room' => '多用户聊天室',
- // 'Help on Jabber integration' => '',
- // 'The server address must use this format: "tcp://hostname:5222"' => '',
'Calendar settings' => '日程设置',
// 'Project calendar view' => '',
'Project settings' => '项目设置',
@@ -820,8 +806,6 @@ return array(
// '%s moved the task #%d to the swimlane "%s"' => '',
// 'Swimlane' => '',
// 'Gravatar' => '',
- // 'Hipchat' => '',
- // 'Slack' => '',
// '%s moved the task %s to the first swimlane' => '',
// '%s moved the task %s to the swimlane "%s"' => '',
// 'This report contains all subtasks information for the given date range.' => '',
@@ -918,7 +902,6 @@ return array(
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
- // 'Channel/Group/User (Optional)' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index 92ce0c5a..62f850cb 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -64,7 +64,7 @@ class Acl extends Base
'column' => '*',
'export' => '*',
'taskimport' => '*',
- 'project' => array('edit', 'update', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
+ 'project' => array('edit', 'update', 'share', 'integrations', 'notifications', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
'swimlane' => '*',
'gantt' => array('project', 'savetaskdate', 'task', 'savetask'),
);
diff --git a/app/Model/Notification.php b/app/Model/Notification.php
new file mode 100644
index 00000000..f1122993
--- /dev/null
+++ b/app/Model/Notification.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace Kanboard\Model;
+
+/**
+ * Notification
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
+class Notification extends Base
+{
+ /**
+ * Get the event title with author
+ *
+ * @access public
+ * @param string $event_author
+ * @param string $event_name
+ * @param array $event_data
+ * @return string
+ */
+ public function getTitleWithAuthor($event_author, $event_name, array $event_data)
+ {
+ switch ($event_name) {
+ case Task::EVENT_ASSIGNEE_CHANGE:
+ $assignee = $event_data['task']['assignee_name'] ?: $event_data['task']['assignee_username'];
+
+ if (! empty($assignee)) {
+ return e('%s change the assignee of the task #%d to %s', $event_author, $event_data['task']['id'], $assignee);
+ }
+
+ return e('%s remove the assignee of the task %s', $event_author, e('#%d', $event_data['task']['id']));
+ case Task::EVENT_UPDATE:
+ return e('%s updated the task #%d', $event_author, $event_data['task']['id']);
+ case Task::EVENT_CREATE:
+ return e('%s created the task #%d', $event_author, $event_data['task']['id']);
+ case Task::EVENT_CLOSE:
+ return e('%s closed the task #%d', $event_author, $event_data['task']['id']);
+ case Task::EVENT_OPEN:
+ return e('%s open the task #%d', $event_author, $event_data['task']['id']);
+ case Task::EVENT_MOVE_COLUMN:
+ return e(
+ '%s moved the task #%d to the column "%s"',
+ $event_author,
+ $event_data['task']['id'],
+ $event_data['task']['column_title']
+ );
+ case Task::EVENT_MOVE_POSITION:
+ return e(
+ '%s moved the task #%d to the position %d in the column "%s"',
+ $event_author,
+ $event_data['task']['id'],
+ $event_data['task']['position'],
+ $event_data['task']['column_title']
+ );
+ case Task::EVENT_MOVE_SWIMLANE:
+ if ($event_data['task']['swimlane_id'] == 0) {
+ return e('%s moved the task #%d to the first swimlane', $event_author, $event_data['task']['id']);
+ }
+
+ return e(
+ '%s moved the task #%d to the swimlane "%s"',
+ $event_author,
+ $event_data['task']['id'],
+ $event_data['task']['swimlane_name']
+ );
+ case Subtask::EVENT_UPDATE:
+ return e('%s updated a subtask for the task #%d', $event_author, $event_data['task']['id']);
+ case Subtask::EVENT_CREATE:
+ return e('%s created a subtask for the task #%d', $event_author, $event_data['task']['id']);
+ case Comment::EVENT_UPDATE:
+ return e('%s updated a comment on the task #%d', $event_author, $event_data['task']['id']);
+ case Comment::EVENT_CREATE:
+ return e('%s commented on the task #%d', $event_author, $event_data['task']['id']);
+ case File::EVENT_CREATE:
+ return e('%s attached a file to the task #%d', $event_author, $event_data['task']['id']);
+ default:
+ return e('Notification');
+ }
+ }
+
+ /**
+ * Get the event title without author
+ *
+ * @access public
+ * @param string $event_name
+ * @param array $event_data
+ * @return string
+ */
+ public function getTitleWithoutAuthor($event_name, array $event_data)
+ {
+ switch ($event_name) {
+ case File::EVENT_CREATE:
+ $title = e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']);
+ break;
+ case Comment::EVENT_CREATE:
+ $title = e('New comment on task #%d', $event_data['comment']['task_id']);
+ break;
+ case Comment::EVENT_UPDATE:
+ $title = e('Comment updated on task #%d', $event_data['comment']['task_id']);
+ break;
+ case Subtask::EVENT_CREATE:
+ $title = e('New subtask on task #%d', $event_data['subtask']['task_id']);
+ break;
+ case Subtask::EVENT_UPDATE:
+ $title = e('Subtask updated on task #%d', $event_data['subtask']['task_id']);
+ break;
+ case Task::EVENT_CREATE:
+ $title = e('New task #%d: %s', $event_data['task']['id'], $event_data['task']['title']);
+ break;
+ case Task::EVENT_UPDATE:
+ $title = e('Task updated #%d', $event_data['task']['id']);
+ break;
+ case Task::EVENT_CLOSE:
+ $title = e('Task #%d closed', $event_data['task']['id']);
+ break;
+ case Task::EVENT_OPEN:
+ $title = e('Task #%d opened', $event_data['task']['id']);
+ break;
+ case Task::EVENT_MOVE_COLUMN:
+ $title = e('Column changed for task #%d', $event_data['task']['id']);
+ break;
+ case Task::EVENT_MOVE_POSITION:
+ $title = e('New position for task #%d', $event_data['task']['id']);
+ break;
+ case Task::EVENT_MOVE_SWIMLANE:
+ $title = e('Swimlane changed for task #%d', $event_data['task']['id']);
+ break;
+ case Task::EVENT_ASSIGNEE_CHANGE:
+ $title = e('Assignee changed on task #%d', $event_data['task']['id']);
+ break;
+ case Task::EVENT_OVERDUE:
+ $nb = count($event_data['tasks']);
+ $title = $nb > 1 ? e('%d overdue tasks', $nb) : e('Task #%d is overdue', $event_data['tasks'][0]['id']);
+ break;
+ default:
+ $title = e('Notification');
+ }
+
+ return $title;
+ }
+}
diff --git a/app/Model/NotificationType.php b/app/Model/NotificationType.php
index e05cc686..bc9c6fdc 100644
--- a/app/Model/NotificationType.php
+++ b/app/Model/NotificationType.php
@@ -108,4 +108,20 @@ abstract class NotificationType extends Base
{
return $this->hiddens;
}
+
+ /**
+ * Keep only loaded notification types
+ *
+ * @access public
+ * @param string[] $types
+ * @return array
+ */
+ public function filterTypes(array $types)
+ {
+ $classes = $this->classes;
+
+ return array_filter($types, function($type) use ($classes) {
+ return isset($classes[$type]);
+ });
+ }
}
diff --git a/app/Model/ProjectActivity.php b/app/Model/ProjectActivity.php
index 032c1fa6..309bab9a 100644
--- a/app/Model/ProjectActivity.php
+++ b/app/Model/ProjectActivity.php
@@ -153,7 +153,7 @@ class ProjectActivity extends Base
unset($event['data']);
$event['author'] = $event['author_name'] ?: $event['author_username'];
- $event['event_title'] = $this->getTitle($event);
+ $event['event_title'] = $this->notification->getTitleWithAuthor($event['author'], $event['event_name'], $event);
$event['event_content'] = $this->getContent($event);
}
@@ -196,56 +196,6 @@ class ProjectActivity extends Base
}
/**
- * Get the event title (translated)
- *
- * @access public
- * @param array $event Event properties
- * @return string
- */
- public function getTitle(array $event)
- {
- switch ($event['event_name']) {
- case Task::EVENT_ASSIGNEE_CHANGE:
- $assignee = $event['task']['assignee_name'] ?: $event['task']['assignee_username'];
-
- if (! empty($assignee)) {
- return t('%s change the assignee of the task #%d to %s', $event['author'], $event['task']['id'], $assignee);
- }
-
- return t('%s remove the assignee of the task %s', $event['author'], e('#%d', $event['task']['id']));
- case Task::EVENT_UPDATE:
- return t('%s updated the task #%d', $event['author'], $event['task']['id']);
- case Task::EVENT_CREATE:
- return t('%s created the task #%d', $event['author'], $event['task']['id']);
- case Task::EVENT_CLOSE:
- return t('%s closed the task #%d', $event['author'], $event['task']['id']);
- case Task::EVENT_OPEN:
- return t('%s open the task #%d', $event['author'], $event['task']['id']);
- case Task::EVENT_MOVE_COLUMN:
- return t('%s moved the task #%d to the column "%s"', $event['author'], $event['task']['id'], $event['task']['column_title']);
- case Task::EVENT_MOVE_POSITION:
- return t('%s moved the task #%d to the position %d in the column "%s"', $event['author'], $event['task']['id'], $event['task']['position'], $event['task']['column_title']);
- case Task::EVENT_MOVE_SWIMLANE:
- if ($event['task']['swimlane_id'] == 0) {
- return t('%s moved the task #%d to the first swimlane', $event['author'], $event['task']['id']);
- }
- return t('%s moved the task #%d to the swimlane "%s"', $event['author'], $event['task']['id'], $event['task']['swimlane_name']);
- case Subtask::EVENT_UPDATE:
- return t('%s updated a subtask for the task #%d', $event['author'], $event['task']['id']);
- case Subtask::EVENT_CREATE:
- return t('%s created a subtask for the task #%d', $event['author'], $event['task']['id']);
- case Comment::EVENT_UPDATE:
- return t('%s updated a comment on the task #%d', $event['author'], $event['task']['id']);
- case Comment::EVENT_CREATE:
- return t('%s commented on the task #%d', $event['author'], $event['task']['id']);
- case File::EVENT_CREATE:
- return t('%s attached a file to the task #%d', $event['author'], $event['task']['id']);
- default:
- return '';
- }
- }
-
- /**
* Decode event data, supports unserialize() and json_decode()
*
* @access public
diff --git a/app/Model/ProjectIntegration.php b/app/Model/ProjectIntegration.php
deleted file mode 100644
index d07e4167..00000000
--- a/app/Model/ProjectIntegration.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-namespace Kanboard\Model;
-
-/**
- * Project integration
- *
- * @package model
- * @author Frederic Guillot
- */
-class ProjectIntegration extends Base
-{
- /**
- * SQL table name
- *
- * @var string
- */
- const TABLE = 'project_integrations';
-
- /**
- * Get all parameters for a project
- *
- * @access public
- * @param integer $project_id
- * @return array
- */
- public function getParameters($project_id)
- {
- return $this->db->table(self::TABLE)->eq('project_id', $project_id)->findOne() ?: array();
- }
-
- /**
- * Save parameters for a project
- *
- * @access public
- * @param integer $project_id
- * @param array $values
- * @return boolean
- */
- public function saveParameters($project_id, array $values)
- {
- if ($this->db->table(self::TABLE)->eq('project_id', $project_id)->exists()) {
- return $this->db->table(self::TABLE)->eq('project_id', $project_id)->update($values);
- }
-
- return $this->db->table(self::TABLE)->insert($values + array('project_id' => $project_id));
- }
-
- /**
- * Check if a project has the given parameter/value
- *
- * @access public
- * @param integer $project_id
- * @param string $option
- * @param string $value
- * @return boolean
- */
- public function hasValue($project_id, $option, $value)
- {
- return $this->db
- ->table(self::TABLE)
- ->eq('project_id', $project_id)
- ->eq($option, $value)
- ->exists();
- }
-}
diff --git a/app/Model/ProjectNotification.php b/app/Model/ProjectNotification.php
index 49fcc61d..a355902f 100644
--- a/app/Model/ProjectNotification.php
+++ b/app/Model/ProjectNotification.php
@@ -22,8 +22,44 @@ class ProjectNotification extends Base
{
$project = $this->project->getById($project_id);
- foreach ($this->projectNotificationType->getSelectedTypes($project_id) as $type) {
+ $types = array_merge(
+ $this->projectNotificationType->getHiddenTypes(),
+ $this->projectNotificationType->getSelectedTypes($project_id)
+ );
+
+ foreach ($types as $type) {
$this->projectNotificationType->getType($type)->notifyProject($project, $event_name, $event_data);
}
}
+
+ /**
+ * Save settings for the given project
+ *
+ * @access public
+ * @param integer $project_id
+ * @param array $values
+ */
+ public function saveSettings($project_id, array $values)
+ {
+ $this->db->startTransaction();
+
+ $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']);
+ $this->projectNotificationType->saveSelectedTypes($project_id, $types);
+
+ $this->db->closeTransaction();
+ }
+
+ /**
+ * Read user settings to display the form
+ *
+ * @access public
+ * @param integer $project_id
+ * @return array
+ */
+ public function readSettings($project_id)
+ {
+ return array(
+ 'notification_types' => $this->projectNotificationType->getSelectedTypes($project_id),
+ );
+ }
}
diff --git a/app/Model/ProjectNotificationType.php b/app/Model/ProjectNotificationType.php
index d8568589..a4719598 100644
--- a/app/Model/ProjectNotificationType.php
+++ b/app/Model/ProjectNotificationType.php
@@ -26,13 +26,13 @@ class ProjectNotificationType extends NotificationType
*/
public function getSelectedTypes($project_id)
{
- $selectedTypes = $this->db
+ $types = $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->asc('notification_type')
->findAllByColumn('notification_type');
- return array_merge($this->getHiddenTypes(), $selectedTypes);
+ return $this->filterTypes($types);
}
/**
@@ -52,6 +52,6 @@ class ProjectNotificationType extends NotificationType
$results[] = $this->db->table(self::TABLE)->insert(array('project_id' => $project_id, 'notification_type' => $type));
}
- return ! in_array(false, $results);
+ return ! in_array(false, $results, true);
}
}
diff --git a/app/Model/UserNotificationType.php b/app/Model/UserNotificationType.php
index d2613440..89beb480 100644
--- a/app/Model/UserNotificationType.php
+++ b/app/Model/UserNotificationType.php
@@ -26,7 +26,8 @@ class UserNotificationType extends NotificationType
*/
public function getSelectedTypes($user_id)
{
- return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('notification_type')->findAllByColumn('notification_type');
+ $types = $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('notification_type')->findAllByColumn('notification_type');
+ return $this->filterTypes($types);
}
/**
@@ -46,6 +47,6 @@ class UserNotificationType extends NotificationType
$results[] = $this->db->table(self::TABLE)->insert(array('user_id' => $user_id, 'notification_type' => $type));
}
- return ! in_array(false, $results);
+ return ! in_array(false, $results, true);
}
}
diff --git a/app/Model/UserUnreadNotification.php b/app/Model/UserUnreadNotification.php
index 98a337a2..cc0f326a 100644
--- a/app/Model/UserUnreadNotification.php
+++ b/app/Model/UserUnreadNotification.php
@@ -48,7 +48,7 @@ class UserUnreadNotification extends Base
foreach ($events as &$event) {
$event['event_data'] = json_decode($event['event_data'], true);
- $event['title'] = $this->getTitleFromEvent($event['event_name'], $event['event_data']);
+ $event['title'] = $this->notification->getTitleWithoutAuthor($event['event_name'], $event['event_data']);
}
return $events;
@@ -90,65 +90,4 @@ class UserUnreadNotification extends Base
{
return $this->db->table(self::TABLE)->eq('user_id', $user_id)->exists();
}
-
- /**
- * Get title from event
- *
- * @access public
- * @param string $event_name
- * @param array $event_data
- * @return string
- */
- public function getTitleFromEvent($event_name, array $event_data)
- {
- switch ($event_name) {
- case File::EVENT_CREATE:
- $title = t('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']);
- break;
- case Comment::EVENT_CREATE:
- $title = t('New comment on task #%d', $event_data['comment']['task_id']);
- break;
- case Comment::EVENT_UPDATE:
- $title = t('Comment updated on task #%d', $event_data['comment']['task_id']);
- break;
- case Subtask::EVENT_CREATE:
- $title = t('New subtask on task #%d', $event_data['subtask']['task_id']);
- break;
- case Subtask::EVENT_UPDATE:
- $title = t('Subtask updated on task #%d', $event_data['subtask']['task_id']);
- break;
- case Task::EVENT_CREATE:
- $title = t('New task #%d: %s', $event_data['task']['id'], $event_data['task']['title']);
- break;
- case Task::EVENT_UPDATE:
- $title = t('Task updated #%d', $event_data['task']['id']);
- break;
- case Task::EVENT_CLOSE:
- $title = t('Task #%d closed', $event_data['task']['id']);
- break;
- case Task::EVENT_OPEN:
- $title = t('Task #%d opened', $event_data['task']['id']);
- break;
- case Task::EVENT_MOVE_COLUMN:
- $title = t('Column changed for task #%d', $event_data['task']['id']);
- break;
- case Task::EVENT_MOVE_POSITION:
- $title = t('New position for task #%d', $event_data['task']['id']);
- break;
- case Task::EVENT_MOVE_SWIMLANE:
- $title = t('Swimlane changed for task #%d', $event_data['task']['id']);
- break;
- case Task::EVENT_ASSIGNEE_CHANGE:
- $title = t('Assignee changed on task #%d', $event_data['task']['id']);
- break;
- case Task::EVENT_OVERDUE:
- $nb = count($event_data['tasks']);
- $title = $nb > 1 ? t('%d overdue tasks', $nb) : t('Task #%d is overdue', $event_data['tasks'][0]['id']);
- break;
- default:
- $title = e('Notification');
- }
-
- return $title;
- }
}
diff --git a/app/Notification/ActivityStream.php b/app/Notification/ActivityStream.php
index 65ae64b1..325732ec 100644
--- a/app/Notification/ActivityStream.php
+++ b/app/Notification/ActivityStream.php
@@ -35,7 +35,6 @@ class ActivityStream extends Base implements NotificationInterface
public function notifyProject(array $project, $event_name, array $event_data)
{
if ($this->userSession->isLogged()) {
-
$this->projectActivity->createEvent(
$project['id'],
$event_data['task']['id'],
@@ -43,16 +42,6 @@ class ActivityStream extends Base implements NotificationInterface
$event_name,
$event_data
);
-
- // TODO: need to be moved to external plugins
- foreach (array('slackWebhook', 'hipchatWebhook', 'jabber') as $model) {
- $this->$model->notify(
- $project['id'],
- $event_data['task']['id'],
- $event_name,
- $event_data
- );
- }
}
}
}
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index b85c185e..d3c0d3b6 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -39,6 +39,23 @@ function version_93($pdo)
UNIQUE(task_id, name)
) ENGINE=InnoDB CHARSET=utf8
");
+
+ $pdo->exec("DROP TABLE project_integrations");
+
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_server'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_domain'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_username'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_password'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_nickname'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_room'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_api_url'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_room_id'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_room_token'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook_url'");
+ $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook_channel'");
}
function version_92($pdo)
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index 1a399cfc..165b11d2 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -39,6 +39,23 @@ function version_73($pdo)
UNIQUE(task_id, name)
)
");
+
+ $pdo->exec("DROP TABLE project_integrations");
+
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_server'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_domain'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_username'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_password'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_nickname'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_room'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_api_url'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_id'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_token'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_url'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_channel'");
}
function version_72($pdo)
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index 1a60443f..e8dcf50e 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -39,6 +39,23 @@ function version_88($pdo)
UNIQUE(task_id, name)
)
");
+
+ $pdo->exec("DROP TABLE project_integrations");
+
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_server'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_domain'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_username'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_password'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_nickname'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_room'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_api_url'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_id'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_token'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_url'");
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_channel'");
}
function version_87($pdo)
diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php
index e50a6297..c103d639 100644
--- a/app/ServiceProvider/ClassProvider.php
+++ b/app/ServiceProvider/ClassProvider.php
@@ -31,6 +31,7 @@ class ClassProvider implements ServiceProviderInterface
'File',
'LastLogin',
'Link',
+ 'Notification',
'OverdueNotification',
'Project',
'ProjectActivity',
@@ -38,7 +39,6 @@ class ClassProvider implements ServiceProviderInterface
'ProjectDuplication',
'ProjectDailyColumnStats',
'ProjectDailyStats',
- 'ProjectIntegration',
'ProjectPermission',
'ProjectNotification',
'ProjectMetadata',
@@ -98,9 +98,6 @@ class ClassProvider implements ServiceProviderInterface
'BitbucketWebhook',
'GithubWebhook',
'GitlabWebhook',
- 'HipchatWebhook',
- 'Jabber',
- 'SlackWebhook',
)
);
diff --git a/app/Template/config/integrations.php b/app/Template/config/integrations.php
index b454fa86..bba85672 100644
--- a/app/Template/config/integrations.php
+++ b/app/Template/config/integrations.php
@@ -31,60 +31,6 @@
<?= $this->form->checkbox('integration_gravatar', t('Enable Gravatar images'), 1, $values['integration_gravatar'] == 1) ?>
</div>
- <h3><img src="<?= $this->url->dir() ?>assets/img/jabber-icon.png"/> <?= t('Jabber (XMPP)') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('integration_jabber', t('Send notifications to Jabber'), 1, $values['integration_jabber'] == 1) ?>
-
- <?= $this->form->label(t('XMPP server address'), 'integration_jabber_server') ?>
- <?= $this->form->text('integration_jabber_server', $values, $errors, array('placeholder="tcp://myserver:5222"')) ?>
- <p class="form-help"><?= t('The server address must use this format: "tcp://hostname:5222"') ?></p>
-
- <?= $this->form->label(t('Jabber domain'), 'integration_jabber_domain') ?>
- <?= $this->form->text('integration_jabber_domain', $values, $errors, array('placeholder="example.com"')) ?>
-
- <?= $this->form->label(t('Username'), 'integration_jabber_username') ?>
- <?= $this->form->text('integration_jabber_username', $values, $errors) ?>
-
- <?= $this->form->label(t('Password'), 'integration_jabber_password') ?>
- <?= $this->form->password('integration_jabber_password', $values, $errors) ?>
-
- <?= $this->form->label(t('Jabber nickname'), 'integration_jabber_nickname') ?>
- <?= $this->form->text('integration_jabber_nickname', $values, $errors) ?>
-
- <?= $this->form->label(t('Multi-user chat room'), 'integration_jabber_room') ?>
- <?= $this->form->text('integration_jabber_room', $values, $errors, array('placeholder="myroom@conference.example.com"')) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Jabber integration'), 'jabber') ?></p>
- </div>
-
- <h3><img src="<?= $this->url->dir() ?>assets/img/hipchat-icon.png"/> <?= t('Hipchat') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('integration_hipchat', t('Send notifications to Hipchat'), 1, $values['integration_hipchat'] == 1) ?>
-
- <?= $this->form->label(t('API URL'), 'integration_hipchat_api_url') ?>
- <?= $this->form->text('integration_hipchat_api_url', $values, $errors) ?>
-
- <?= $this->form->label(t('Room API ID or name'), 'integration_hipchat_room_id') ?>
- <?= $this->form->text('integration_hipchat_room_id', $values, $errors) ?>
-
- <?= $this->form->label(t('Room notification token'), 'integration_hipchat_room_token') ?>
- <?= $this->form->text('integration_hipchat_room_token', $values, $errors) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Hipchat integration'), 'hipchat') ?></p>
- </div>
-
- <h3><i class="fa fa-slack fa-fw"></i>&nbsp;<?= t('Slack') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('integration_slack_webhook', t('Send notifications to a Slack channel'), 1, $values['integration_slack_webhook'] == 1) ?>
-
- <?= $this->form->label(t('Webhook URL'), 'integration_slack_webhook_url') ?>
- <?= $this->form->text('integration_slack_webhook_url', $values, $errors) ?>
- <?= $this->form->label(t('Channel/Group/User (Optional)'), 'integration_slack_webhook_channel') ?>
- <?= $this->form->text('integration_slack_webhook_channel', $values, $errors) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Slack integration'), 'slack') ?></p>
- </div>
-
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
</div>
diff --git a/app/Template/project/integrations.php b/app/Template/project/integrations.php
index eb5faddf..c4d9385b 100644
--- a/app/Template/project/integrations.php
+++ b/app/Template/project/integrations.php
@@ -2,9 +2,10 @@
<h2><?= t('Integration with third-party services') ?></h2>
</div>
-<form method="post" action="<?= $this->url->href('project', 'integration', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('project', 'integrations', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
+ <?= $this->hook->render('template:project:integrations', array('values' => $values)) ?>
<h3><i class="fa fa-github fa-fw"></i>&nbsp;<?= t('Github webhooks') ?></h3>
<div class="listing">
@@ -12,86 +13,15 @@
<p class="form-help"><?= $this->url->doc(t('Help on Github webhooks'), 'github-webhooks') ?></p>
</div>
-
<h3><img src="<?= $this->url->dir() ?>assets/img/gitlab-icon.png"/>&nbsp;<?= t('Gitlab webhooks') ?></h3>
<div class="listing">
<input type="text" class="auto-select" readonly="readonly" value="<?= $this->url->href('webhook', 'gitlab', array('token' => $webhook_token, 'project_id' => $project['id']), false, '', true) ?>"/><br/>
<p class="form-help"><?= $this->url->doc(t('Help on Gitlab webhooks'), 'gitlab-webhooks') ?></p>
</div>
-
<h3><i class="fa fa-bitbucket fa-fw"></i>&nbsp;<?= t('Bitbucket webhooks') ?></h3>
<div class="listing">
<input type="text" class="auto-select" readonly="readonly" value="<?= $this->url->href('webhook', 'bitbucket', array('token' => $webhook_token, 'project_id' => $project['id']), false, '', true) ?>"/><br/>
<p class="form-help"><?= $this->url->doc(t('Help on Bitbucket webhooks'), 'bitbucket-webhooks') ?></p>
</div>
-
-
- <h3><img src="<?= $this->url->dir() ?>assets/img/jabber-icon.png"/> <?= t('Jabber (XMPP)') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('jabber', t('Send notifications to Jabber'), 1, isset($values['jabber']) && $values['jabber'] == 1) ?>
-
- <?= $this->form->label(t('XMPP server address'), 'jabber_server') ?>
- <?= $this->form->text('jabber_server', $values, $errors, array('placeholder="tcp://myserver:5222"')) ?>
- <p class="form-help"><?= t('The server address must use this format: "tcp://hostname:5222"') ?></p>
-
- <?= $this->form->label(t('Jabber domain'), 'jabber_domain') ?>
- <?= $this->form->text('jabber_domain', $values, $errors, array('placeholder="example.com"')) ?>
-
- <?= $this->form->label(t('Username'), 'jabber_username') ?>
- <?= $this->form->text('jabber_username', $values, $errors) ?>
-
- <?= $this->form->label(t('Password'), 'jabber_password') ?>
- <?= $this->form->password('jabber_password', $values, $errors) ?>
-
- <?= $this->form->label(t('Jabber nickname'), 'jabber_nickname') ?>
- <?= $this->form->text('jabber_nickname', $values, $errors) ?>
-
- <?= $this->form->label(t('Multi-user chat room'), 'jabber_room') ?>
- <?= $this->form->text('jabber_room', $values, $errors, array('placeholder="myroom@conference.example.com"')) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Jabber integration'), 'jabber') ?></p>
-
- <div class="form-actions">
- <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
- </div>
- </div>
-
-
- <h3><img src="<?= $this->url->dir() ?>assets/img/hipchat-icon.png"/> <?= t('Hipchat') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('hipchat', t('Send notifications to Hipchat'), 1, isset($values['hipchat']) && $values['hipchat'] == 1) ?>
-
- <?= $this->form->label(t('API URL'), 'hipchat_api_url') ?>
- <?= $this->form->text('hipchat_api_url', $values, $errors) ?>
-
- <?= $this->form->label(t('Room API ID or name'), 'hipchat_room_id') ?>
- <?= $this->form->text('hipchat_room_id', $values, $errors) ?>
-
- <?= $this->form->label(t('Room notification token'), 'hipchat_room_token') ?>
- <?= $this->form->text('hipchat_room_token', $values, $errors) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Hipchat integration'), 'hipchat') ?></a></p>
-
- <div class="form-actions">
- <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
- </div>
- </div>
-
-
- <h3><i class="fa fa-slack fa-fw"></i>&nbsp;<?= t('Slack') ?></h3>
- <div class="listing">
- <?= $this->form->checkbox('slack', t('Send notifications to a Slack channel'), 1, isset($values['slack']) && $values['slack'] == 1) ?>
-
- <?= $this->form->label(t('Webhook URL'), 'slack_webhook_url') ?>
- <?= $this->form->text('slack_webhook_url', $values, $errors) ?>
- <?= $this->form->label(t('Channel/Group/User (Optional)'), 'slack_webhook_channel') ?>
- <?= $this->form->text('slack_webhook_channel', $values, $errors) ?>
-
- <p class="form-help"><?= $this->url->doc(t('Help on Slack integration'), 'slack') ?></p>
-
- <div class="form-actions">
- <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
- </div>
- </div>
</form> \ No newline at end of file
diff --git a/app/Template/project/notifications.php b/app/Template/project/notifications.php
new file mode 100644
index 00000000..ac743087
--- /dev/null
+++ b/app/Template/project/notifications.php
@@ -0,0 +1,20 @@
+<div class="page-header">
+ <h2><?= t('Notifications') ?></h2>
+</div>
+<?php if (empty($types)): ?>
+ <p class="alert"><?= t('There is no notification method registered.') ?></p>
+<?php else: ?>
+ <form method="post" action="<?= $this->url->href('project', 'notifications', array('project_id' => $project['id'])) ?>" autocomplete="off">
+
+ <?= $this->form->csrf() ?>
+
+ <h4><?= t('Notification methods:') ?></h4>
+ <?= $this->form->checkboxes('notification_types', $types, $notifications) ?>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'project', 'show', array('project_id' => $project['id'])) ?>
+ </div>
+ </form>
+<?php endif ?> \ No newline at end of file
diff --git a/app/Template/project/sidebar.php b/app/Template/project/sidebar.php
index 971ed950..fb5dd3bd 100644
--- a/app/Template/project/sidebar.php
+++ b/app/Template/project/sidebar.php
@@ -12,8 +12,11 @@
<li <?= $this->app->getRouterController() === 'project' && $this->app->getRouterAction() === 'share' ? 'class="active"' : '' ?>>
<?= $this->url->link(t('Public access'), 'project', 'share', array('project_id' => $project['id'])) ?>
</li>
- <li <?= $this->app->getRouterController() === 'project' && $this->app->getRouterAction() === 'integration' ? 'class="active"' : '' ?>>
- <?= $this->url->link(t('Integrations'), 'project', 'integration', array('project_id' => $project['id'])) ?>
+ <li <?= $this->app->getRouterController() === 'project' && $this->app->getRouterAction() === 'notifications' ? 'class="active"' : '' ?>>
+ <?= $this->url->link(t('Notifications'), 'project', 'notifications', array('project_id' => $project['id'])) ?>
+ </li>
+ <li <?= $this->app->getRouterController() === 'project' && $this->app->getRouterAction() === 'integrations' ? 'class="active"' : '' ?>>
+ <?= $this->url->link(t('Integrations'), 'project', 'integrations', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->getRouterController() === 'project' && $this->app->getRouterAction() === 'edit' ? 'class="active"' : '' ?>>
<?= $this->url->link(t('Edit project'), 'project', 'edit', array('project_id' => $project['id'])) ?>
diff --git a/app/Template/user/integrations.php b/app/Template/user/integrations.php
new file mode 100644
index 00000000..ef9d8e71
--- /dev/null
+++ b/app/Template/user/integrations.php
@@ -0,0 +1,13 @@
+<div class="page-header">
+ <h2><?= t('Integrations') ?></h2>
+</div>
+
+<form method="post" action="<?= $this->url->href('user', 'integrations', array('user_id' => $user['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?php $hooks = $this->hook->render('template:user:integrations', array('values' => $values)) ?>
+ <?php if (! empty($hooks)): ?>
+ <?= $hooks ?>
+ <?php else: ?>
+ <p class="alert"><?= t('No external integration registered.') ?></p>
+ <?php endif ?>
+</form>
diff --git a/app/Template/user/sidebar.php b/app/Template/user/sidebar.php
index ca1e0621..167c8054 100644
--- a/app/Template/user/sidebar.php
+++ b/app/Template/user/sidebar.php
@@ -56,6 +56,9 @@
<li <?= $this->app->getRouterController() === 'user' && $this->app->getRouterAction() === 'external' ? 'class="active"' : '' ?>>
<?= $this->url->link(t('External accounts'), 'user', 'external', array('user_id' => $user['id'])) ?>
</li>
+ <li <?= $this->app->getRouterController() === 'user' && $this->app->getRouterAction() === 'integrations' ? 'class="active"' : '' ?>>
+ <?= $this->url->link(t('Integrations'), 'user', 'integrations', array('user_id' => $user['id'])) ?>
+ </li>
<?php endif ?>
<?php if ($this->user->isAdmin()): ?>
diff --git a/assets/img/hipchat-icon.png b/assets/img/hipchat-icon.png
deleted file mode 100644
index 1b0a825f..00000000
--- a/assets/img/hipchat-icon.png
+++ /dev/null
Binary files differ
diff --git a/assets/img/jabber-icon.png b/assets/img/jabber-icon.png
deleted file mode 100644
index 00832279..00000000
--- a/assets/img/jabber-icon.png
+++ /dev/null
Binary files differ
diff --git a/doc/fr/notifications.markdown b/doc/fr/notifications.markdown
index 7d85087a..2190f317 100644
--- a/doc/fr/notifications.markdown
+++ b/doc/fr/notifications.markdown
@@ -4,12 +4,9 @@ Notifications
Kanboard est capable d'envoyer des notifications via différents canaux :
- Email
-- Jabber/XMPP
-- Hipchat
-- Slack
+- Web (Liste de message non lus)
-En fait, pour Jabber/Hipchat/Slack les notifications sont envoyées dans des salons de discussion car ils sont configurés au niveau projet.
-Cependant, les notifications par email sont envoyées à un individu.
+Vous pouvez ajouter d'autres cannaux an ajoutant des extensions comme par exemple Hipchat, Slack ou encore Jabber.
Configuration
--------------
@@ -26,7 +23,7 @@ Vous pouvez choisir votre méthode favorite de notification :
- Web
Pour chaque projet dont vous êtes membre, vous pouvez choisir de recevoir des notifications pour :
-
+
- Toutes les tâches
- Seulement les tâches qui vous sont assignées
- Seulement les tâches que vous avez créées
@@ -41,7 +38,7 @@ Les notifications web sont accéssibles depuis le tableau de bord ou depuis l'ic
![Icône des notifications web](http://kanboard.net/screenshots/documentation/web-notifications-icon.png)
-Les notifications sont affichés sous forme de liste. Vous pouvez marquer comme lu chacune d'entre-elle ou toutes en même temps.
+Les notifications sont affichés sous forme de liste. Vous pouvez marquer comme lu chacune d'entre-elle ou toutes en même temps.
![Notifications web](http://kanboard.net/screenshots/documentation/web-notifications.png)
diff --git a/doc/hipchat.markdown b/doc/hipchat.markdown
deleted file mode 100644
index 66cf9fdc..00000000
--- a/doc/hipchat.markdown
+++ /dev/null
@@ -1,38 +0,0 @@
-Hipchat integration
-===================
-
-You can send notifications to Hipchat for all projects or only for specific projects.
-
-- To send notifications for all projects, go to **Settings > Integrations > Hipchat**
-- To send notifications for only some projects, go to **Project settings > Integrations > Hipchat**
-
-Each project can send notifications to a separate room.
-
-Send notifications to a room
------------------------------
-
-Example of notifications:
-
-![Hipchat notification](http://kanboard.net/screenshots/documentation/hipchat-notification.png)
-
-This feature use the room notification token system of Hipchat.
-
-### Hipchat configuration
-
-![Hipchat room token](http://kanboard.net/screenshots/documentation/hipchat-room-token.png)
-
-1. Go to to **My account**
-2. Click on the tab **Rooms** and select the room you want to send the notifications
-3. On the left, choose **Tokens**
-4. Enter a label, by example "Kanboard" and save
-
-### Kanboard configuration
-
-![Hipchat settings](http://kanboard.net/screenshots/documentation/hipchat-settings.png)
-
-1. Go to **Settings > Integrations > Hipchat** or **Project settings > Integrations > Hipchat**
-2. Replace the API url if you use the self-hosted version of Hipchat
-3. Set the room name or the room API ID
-4. Copy and paste the token generated previously
-
-Now, Kanboard events will be sent to the Hipchat room.
diff --git a/doc/index.markdown b/doc/index.markdown
index 86b5b7fc..3c0cae97 100644
--- a/doc/index.markdown
+++ b/doc/index.markdown
@@ -66,9 +66,6 @@ Using Kanboard
- [Bitbucket webhooks](bitbucket-webhooks.markdown)
- [Github webhooks](github-webhooks.markdown)
- [Gitlab webhooks](gitlab-webhooks.markdown)
-- [Hipchat](hipchat.markdown)
-- [Jabber](jabber.markdown)
-- [Slack](slack.markdown)
- [iCalendar subscriptions](ical.markdown)
- [RSS/Atom subscriptions](rss.markdown)
- [Json-RPC API](api-json-rpc.markdown)
diff --git a/doc/jabber.markdown b/doc/jabber.markdown
deleted file mode 100644
index fe365168..00000000
--- a/doc/jabber.markdown
+++ /dev/null
@@ -1,34 +0,0 @@
-Jabber/XMPP integration
-=======================
-
-You can send notifications to a Jabber room for all projects or only for specific projects.
-
-- To send notifications for all projects, go to **Settings > Integrations > Jabber**
-- To send notifications for only some projects, go to **Project settings > Integrations > Jabber**
-
-Each project can send notifications to a separate room.
-
-## Example of notification
-
-Here an example with the Jabber client Adium:
-
-![Jabber notification](http://kanboard.net/screenshots/documentation/jabber-notification.png)
-
-## Configuration
-
-![Jabber settings](http://kanboard.net/screenshots/documentation/jabber-settings.png)
-
-1. Go to **Settings > Integrations > Jabber** or **Project settings > Integrations > Jabber**
-2. **XMPP server address**: URL of the XMPP server, example: **tcp://172.28.128.3:5222**
-3. **Jabber domain**: The **"to"** attribute of the XMPP protocol, example: **example.com**
-4. **Username**: The Jabber username used by Kanboard, example: **kanboard**
-5. **Password**: The Jabber password
-6. **Jabber nickname**: The nickname used to connect to the room
-7. **Multi-user chat room**: The address of the room, example: **demo@conference.example.com**
-
-Now, Kanboard events will be sent to the Jabber conference room.
-
-## Troubleshooting
-
-- Enable the debug mode
-- All connection errors with the XMPP server are recorded in the log files `data/debug.log` or syslog
diff --git a/doc/notifications.markdown b/doc/notifications.markdown
index 937060da..55ba94bb 100644
--- a/doc/notifications.markdown
+++ b/doc/notifications.markdown
@@ -4,14 +4,9 @@ Notifications
Kanboard is able to send notifications through several channels:
- Email
-- Web
-- Jabber/XMPP
-- Hipchat
-- Slack
+- Web (List of unread messages)
-Actually, Jabber/Hipchat/Slack notifications are sent to a room or group channel because they are configured at the project level.
-
-However, email or web notifications are sent to an individual person.
+External plugins allow you to send notifications to Slack, Hipchat, Jabber or any chat system.
Configuration
-------------
diff --git a/doc/plugin-hooks.markdown b/doc/plugin-hooks.markdown
index eca8c14a..95d1a55f 100644
--- a/doc/plugin-hooks.markdown
+++ b/doc/plugin-hooks.markdown
@@ -134,6 +134,8 @@ List of template hooks:
- `template:dashboard:sidebar`
- `template:config:sidebar`
- `template:config:integrations`
+- `template:project:integrations`
+- `template:user:integrations`
- `template:export:sidebar`
- `template:layout:head`
- `template:layout:top`
diff --git a/doc/plugin-notifications.markdown b/doc/plugin-notifications.markdown
new file mode 100644
index 00000000..83fdb5e3
--- /dev/null
+++ b/doc/plugin-notifications.markdown
@@ -0,0 +1,60 @@
+Add Notification Types with Plugins
+===================================
+
+You can send notifications to almost any system by adding a new type.
+There are two kinds of notifications: project and user.
+
+- Project: Notifications configured at the project level
+- User: Notifications sent individually and configured at the user profile
+
+Register a new notification type
+--------------------------------
+
+In your plugin registration file call the method `setType()`:
+
+```php
+$this->userNotificationType->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
+$this->projectNotificationType->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
+```
+
+Your handler can be registered for user or project notification. You don't necessary need to support both.
+
+When your handler is registered, the end-user can choose to receive the new notification type or not.
+
+Notification Handler
+--------------------
+
+Your notification handler must implements the interface `Kanboard\Notification\NotificationInterface`:
+
+```php
+interface NotificationInterface
+{
+ /**
+ * Send notification to a user
+ *
+ * @access public
+ * @param array $user
+ * @param string $event_name
+ * @param array $event_data
+ */
+ public function notifyUser(array $user, $event_name, array $event_data);
+
+ /**
+ * Send notification to a project
+ *
+ * @access public
+ * @param array $project
+ * @param string $event_name
+ * @param array $event_data
+ */
+ public function notifyProject(array $project, $event_name, array $event_data);
+}
+```
+
+Example of notification plugins
+-------------------------------
+
+- [Slack](https://github.com/kanboard/plugin-slack)
+- [Hipchat](https://github.com/kanboard/plugin-hipchat)
+- [Jabber](https://github.com/kanboard/plugin-jabber)
+
diff --git a/doc/plugin-registration.markdown b/doc/plugin-registration.markdown
index 50bfaff2..312f61b9 100644
--- a/doc/plugin-registration.markdown
+++ b/doc/plugin-registration.markdown
@@ -156,8 +156,8 @@ class Plugin extends Base
public function initialize()
{
$this->action->extendActions(
- '\Kanboard\Plugin\AutomaticAction\Action\SendSlackMessage', // Use absolute namespace
- t('Send a message to Slack when the task color change')
+ '\Kanboard\Plugin\AutomaticAction\Action\DoSomething', // Use absolute namespace
+ t('Do something when the task color change')
);
}
}
diff --git a/doc/plugins.markdown b/doc/plugins.markdown
index 39a1caec..89629a35 100644
--- a/doc/plugins.markdown
+++ b/doc/plugins.markdown
@@ -12,10 +12,14 @@ Plugin creators should specify explicitly the compatible versions of Kanboard. I
- [Override default application behaviors](plugin-overrides.markdown)
- [Add schema migrations for plugins](plugin-schema-migrations.markdown)
- [Add mail transports](plugin-mail-transports.markdown)
+- [Add notification types](plugin-notifications.markdown)
Examples of plugins
-------------------
+- [Slack](https://github.com/kanboard/plugin-slack)
+- [Hipchat](https://github.com/kanboard/plugin-hipchat)
+- [Jabber](https://github.com/kanboard/plugin-jabber)
- [Sendgrid](https://github.com/kanboard/plugin-sendgrid)
- [Mailgun](https://github.com/kanboard/plugin-mailgun)
- [Postmark](https://github.com/kanboard/plugin-postmark)
diff --git a/doc/slack.markdown b/doc/slack.markdown
deleted file mode 100644
index f90464e8..00000000
--- a/doc/slack.markdown
+++ /dev/null
@@ -1,38 +0,0 @@
-Slack integration
-=================
-
-You can send notifications to Slack for all projects or only for specific projects.
-
-- To send notifications for all projects, go to **Settings > Integrations > Slack**
-- To send notifications for only some projects, go to **Project settings > Integrations > Slack**
-
-Each project can send notifications to a separate channel.
-
-Send notifications to a channel
--------------------------------
-
-Example of notifications:
-
-![Slack notification](http://kanboard.net/screenshots/documentation/slack-notification.png)
-
-This feature use the [Incoming webhook](https://api.slack.com/incoming-webhooks) system of Slack.
-
-### Slack configuration
-
-![Slack webhook creation](http://kanboard.net/screenshots/documentation/slack-add-incoming-webhook.png)
-
-1. Click on the Team dropdown and choose **Configure Integrations**
-2. On the list of services, scroll-down and choose **DIY Integrations & Customizations > Incoming WebHooks**
-3. Copy the webhook url to the Kanboard settings page: **Settings > Integrations > Slack** or **Project settings > Integrations > Slack**
-
-Now, Kanboard events will be sent to the Slack channel.
-
-### Overriding Channel (Optional)
-
-Optionally you can override the channel, private group or send direct messages by filling up **Channel/Group/User** text box. Leaving it empty will post to the channel configured during webhook configuration.
-
-Examples:
-
-- Send messages to another channel: **#mychannel1**
-- Send messages to a private group: **#myprivategroup1**
-- Send messages directly to someone: **@anotheruser1**
diff --git a/tests/units/Base.php b/tests/units/Base.php
index 4a5b303f..89d0e2bf 100644
--- a/tests/units/Base.php
+++ b/tests/units/Base.php
@@ -91,7 +91,7 @@ abstract class Base extends PHPUnit_Framework_TestCase
$this->container['userNotificationType'] = $this
->getMockBuilder('\Kanboard\Model\UserNotificationType')
->setConstructorArgs(array($this->container))
- ->setMethods(array('getType'))
+ ->setMethods(array('getType', 'getSelectedTypes'))
->getMock();
}
diff --git a/tests/units/Integration/SlackWebhookTest.php b/tests/units/Integration/SlackWebhookTest.php
deleted file mode 100644
index cf8c8645..00000000
--- a/tests/units/Integration/SlackWebhookTest.php
+++ /dev/null
@@ -1,377 +0,0 @@
-<?php
-
-require_once __DIR__.'/../Base.php';
-
-use Kanboard\Integration\SlackWebhook;
-use Kanboard\Model\Project;
-use Kanboard\Model\Task;
-
-class SlackWebhookTest extends Base
-{
- public function testIsActivatedFromGlobalConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook'))
- ->will($this->returnValue(1));
-
- $this->assertTrue($slack->isActivated(1));
- }
-
- public function testIsActivatedFromProjectConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['projectIntegration'] = $this
- ->getMockBuilder('\Kanboard\Model\ProjectIntegration')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'hasValue',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook'))
- ->will($this->returnValue(0));
-
- $this->container['projectIntegration']
- ->expects($this->once())
- ->method('hasValue')
- ->with(
- $this->equalTo(1),
- $this->equalTo('slack'),
- $this->equalTo(1)
- )
- ->will($this->returnValue(true));
-
- $this->assertTrue($slack->isActivated(1));
- }
-
- public function testIsNotActivated()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['projectIntegration'] = $this
- ->getMockBuilder('\Kanboard\Model\ProjectIntegration')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'hasValue',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook'))
- ->will($this->returnValue(0));
-
- $this->container['projectIntegration']
- ->expects($this->once())
- ->method('hasValue')
- ->with(
- $this->equalTo(1),
- $this->equalTo('slack'),
- $this->equalTo(1)
- )
- ->will($this->returnValue(false));
-
- $this->assertFalse($slack->isActivated(1));
- }
-
- public function testGetChannelFromGlobalConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook_channel'))
- ->will($this->returnValue('mychannel'));
-
- $this->assertEquals('mychannel', $slack->getChannel(1));
- }
-
- public function testGetChannelFromProjectConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['projectIntegration'] = $this
- ->getMockBuilder('\Kanboard\Model\ProjectIntegration')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'getParameters',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook_channel'))
- ->will($this->returnValue(''));
-
- $this->container['projectIntegration']
- ->expects($this->once())
- ->method('getParameters')
- ->with($this->equalTo(1))
- ->will($this->returnValue(array('slack_webhook_channel' => 'my_project_channel')));
-
- $this->assertEquals('my_project_channel', $slack->getChannel(1));
- }
-
- public function testGetWebhoookUrlFromGlobalConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->at(0))
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook'))
- ->will($this->returnValue(1));
-
- $this->container['config']
- ->expects($this->at(1))
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook_url'))
- ->will($this->returnValue('url'));
-
- $this->assertEquals('url', $slack->getWebhookUrl(1));
- }
-
- public function testGetWebhookUrlFromProjectConfig()
- {
- $slack = new SlackWebhook($this->container);
-
- $this->container['config'] = $this
- ->getMockBuilder('\Kanboard\Model\Config')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'get',
- ))
- ->getMock();
-
- $this->container['projectIntegration'] = $this
- ->getMockBuilder('\Kanboard\Model\ProjectIntegration')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'getParameters',
- ))
- ->getMock();
-
- $this->container['config']
- ->expects($this->once())
- ->method('get')
- ->with($this->equalTo('integration_slack_webhook'))
- ->will($this->returnValue(0));
-
- $this->container['projectIntegration']
- ->expects($this->once())
- ->method('getParameters')
- ->with($this->equalTo(1))
- ->will($this->returnValue(array('slack_webhook_url' => 'my_project_url')));
-
- $this->assertEquals('my_project_url', $slack->getWebhookUrl(1));
- }
-
- public function testSendPayloadWithChannel()
- {
- $this->container['httpClient'] = $this
- ->getMockBuilder('\Kanboard\Core\HttpClient')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'postJson',
- ))
- ->getMock();
-
- $slack = $this
- ->getMockBuilder('\Kanboard\Integration\SlackWebhook')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'getChannel',
- 'getWebhookUrl',
- ))
- ->getMock();
-
- $slack
- ->expects($this->at(0))
- ->method('getChannel')
- ->with(
- $this->equalTo(1)
- )
- ->will($this->returnValue('mychannel'));
-
- $slack
- ->expects($this->at(1))
- ->method('getWebhookUrl')
- ->with(
- $this->equalTo(1)
- )
- ->will($this->returnValue('url'));
-
- $this->container['httpClient']
- ->expects($this->once())
- ->method('postJson')
- ->with(
- $this->equalTo('url'),
- $this->equalTo(array('text' => 'test', 'channel' => 'mychannel'))
- );
-
- $slack->sendPayload(1, array('text' => 'test'));
- }
-
- public function testSendPayloadWithoutChannel()
- {
- $this->container['httpClient'] = $this
- ->getMockBuilder('\Kanboard\Core\HttpClient')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'postJson',
- ))
- ->getMock();
-
- $slack = $this
- ->getMockBuilder('\Kanboard\Integration\SlackWebhook')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'getChannel',
- 'getWebhookUrl',
- ))
- ->getMock();
-
- $slack
- ->expects($this->at(0))
- ->method('getChannel')
- ->with(
- $this->equalTo(1)
- )
- ->will($this->returnValue(''));
-
- $slack
- ->expects($this->at(1))
- ->method('getWebhookUrl')
- ->with(
- $this->equalTo(1)
- )
- ->will($this->returnValue('url'));
-
- $this->container['httpClient']
- ->expects($this->once())
- ->method('postJson')
- ->with(
- $this->equalTo('url'),
- $this->equalTo(array('text' => 'test'))
- );
-
- $slack->sendPayload(1, array('text' => 'test'));
- }
-
- public function testSendMessage()
- {
- $message = 'test';
-
- $payload = array(
- 'text' => $message,
- 'username' => 'Kanboard',
- 'icon_url' => 'http://kanboard.net/assets/img/favicon.png',
- );
-
- $slack = $this
- ->getMockBuilder('\Kanboard\Integration\SlackWebhook')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'sendPayload',
- ))
- ->getMock();
-
- $slack
- ->expects($this->once())
- ->method('sendPayload')
- ->with(
- $this->equalTo(1),
- $this->equalTo($payload)
- );
-
- $slack->sendMessage(1, $message);
- }
-
- public function testNotify()
- {
- $message = '*[foobar]* FooBar created the task #1 (task #1)';
-
- $this->container['session']['user'] = array('username' => 'foobar', 'name' => 'FooBar');
-
- $p = new Project($this->container);
- $this->assertEquals(1, $p->create(array('name' => 'foobar')));
- $this->assertTrue($this->container['config']->save(array('integration_slack_webhook' => 1)));
-
- $slack = $this
- ->getMockBuilder('\Kanboard\Integration\SlackWebhook')
- ->setConstructorArgs(array($this->container))
- ->setMethods(array(
- 'sendMessage',
- ))
- ->getMock();
-
- $slack
- ->expects($this->once())
- ->method('sendMessage')
- ->with(
- $this->equalTo(1),
- $this->equalTo($message)
- );
-
- $slack->notify(1, 1, Task::EVENT_CREATE, array('task' => array('id' => 1, 'title' => 'task #1')));
- }
-}
diff --git a/tests/units/Model/NotificationTest.php b/tests/units/Model/NotificationTest.php
new file mode 100644
index 00000000..7f9977ce
--- /dev/null
+++ b/tests/units/Model/NotificationTest.php
@@ -0,0 +1,69 @@
+<?php
+
+require_once __DIR__.'/../Base.php';
+
+use Kanboard\Model\TaskFinder;
+use Kanboard\Model\TaskCreation;
+use Kanboard\Model\Subtask;
+use Kanboard\Model\Comment;
+use Kanboard\Model\User;
+use Kanboard\Model\File;
+use Kanboard\Model\Task;
+use Kanboard\Model\Project;
+use Kanboard\Model\Notification;
+use Kanboard\Subscriber\NotificationSubscriber;
+
+class NotificationTest extends Base
+{
+ public function testGetTitle()
+ {
+ $wn = new Notification($this->container);
+ $p = new Project($this->container);
+ $tf = new TaskFinder($this->container);
+ $tc = new TaskCreation($this->container);
+ $s = new Subtask($this->container);
+ $c = new Comment($this->container);
+ $f = new File($this->container);
+
+ $this->assertEquals(1, $p->create(array('name' => 'test')));
+ $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));
+ $this->assertEquals(1, $s->create(array('title' => 'test', 'task_id' => 1)));
+ $this->assertEquals(1, $c->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1)));
+ $this->assertEquals(1, $f->create(1, 'test', 'blah', 123));
+
+ $task = $tf->getDetails(1);
+ $subtask = $s->getById(1, true);
+ $comment = $c->getById(1);
+ $file = $c->getById(1);
+
+ $this->assertNotEmpty($task);
+ $this->assertNotEmpty($subtask);
+ $this->assertNotEmpty($comment);
+ $this->assertNotEmpty($file);
+
+ foreach (NotificationSubscriber::getSubscribedEvents() as $event_name => $values) {
+ $title = $wn->getTitleWithoutAuthor($event_name, array(
+ 'task' => $task,
+ 'comment' => $comment,
+ 'subtask' => $subtask,
+ 'file' => $file,
+ 'changes' => array()
+ ));
+
+ $this->assertNotEmpty($title);
+
+ $title = $wn->getTitleWithAuthor('foobar', $event_name, array(
+ 'task' => $task,
+ 'comment' => $comment,
+ 'subtask' => $subtask,
+ 'file' => $file,
+ 'changes' => array()
+ ));
+
+ $this->assertNotEmpty($title);
+ }
+
+ $this->assertNotEmpty($wn->getTitleWithoutAuthor(Task::EVENT_OVERDUE, array('tasks' => array(array('id' => 1)))));
+ $this->assertNotEmpty($wn->getTitleWithoutAuthor('unkown', array()));
+ }
+}
diff --git a/tests/units/Model/ProjectActivityTest.php b/tests/units/Model/ProjectActivityTest.php
index ead74e08..5a242cb2 100644
--- a/tests/units/Model/ProjectActivityTest.php
+++ b/tests/units/Model/ProjectActivityTest.php
@@ -10,49 +10,9 @@ use Kanboard\Model\Project;
use Kanboard\Model\Subtask;
use Kanboard\Model\Comment;
use Kanboard\Model\File;
-use Kanboard\Subscriber\NotificationSubscriber;
class ProjectActivityTest extends Base
{
- public function testGetTitle()
- {
- $pa = new ProjectActivity($this->container);
- $p = new Project($this->container);
- $tf = new TaskFinder($this->container);
- $tc = new TaskCreation($this->container);
- $s = new Subtask($this->container);
- $c = new Comment($this->container);
- $f = new File($this->container);
-
- $this->assertEquals(1, $p->create(array('name' => 'test')));
- $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));
- $this->assertEquals(1, $s->create(array('title' => 'test', 'task_id' => 1)));
- $this->assertEquals(1, $c->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1)));
- $this->assertEquals(1, $f->create(1, 'test', 'blah', 123));
-
- $task = $tf->getDetails(1);
- $subtask = $s->getById(1, true);
- $comment = $c->getById(1);
- $file = $c->getById(1);
-
- $this->assertNotEmpty($task);
- $this->assertNotEmpty($subtask);
- $this->assertNotEmpty($comment);
- $this->assertNotEmpty($file);
-
- foreach (NotificationSubscriber::getSubscribedEvents() as $event_name => $listeners) {
- $this->assertNotEmpty($pa->getTitle(array(
- 'event_name' => $event_name,
- 'task' => $task,
- 'comment' => $comment,
- 'subtask' => $subtask,
- 'file' => $file,
- 'author' => 'bob',
- 'changes' => array())
- ));
- }
- }
-
public function testDecode()
{
$e = new ProjectActivity($this->container);
diff --git a/tests/units/Model/ProjectNotificationTypeTest.php b/tests/units/Model/ProjectNotificationTypeTest.php
index d03bffe0..71e2b964 100644
--- a/tests/units/Model/ProjectNotificationTypeTest.php
+++ b/tests/units/Model/ProjectNotificationTypeTest.php
@@ -32,10 +32,15 @@ class ProjectNotificationTypeTest extends Base
// Hidden type
$nt->setType('baz', 'Baz', 'Something3', true);
- $this->assertEquals(array('baz'), $nt->getSelectedTypes(1));
+ $this->assertEmpty($nt->getSelectedTypes(1));
- // User defined types
+ // User defined types but not registered
$this->assertTrue($nt->saveSelectedTypes(1, array('foo', 'bar')));
- $this->assertEquals(array('baz', 'bar', 'foo'), $nt->getSelectedTypes(1));
+ $this->assertEmpty($nt->getSelectedTypes(1));
+
+ // User defined types and registered
+ $nt->setType('bar', 'Bar', 'Something4');
+ $nt->setType('foo', 'Foo', 'Something3');
+ $this->assertEquals(array('bar', 'foo'), $nt->getSelectedTypes(1));
}
}
diff --git a/tests/units/Model/UserNotificationTest.php b/tests/units/Model/UserNotificationTest.php
index 8d7dec60..729667de 100644
--- a/tests/units/Model/UserNotificationTest.php
+++ b/tests/units/Model/UserNotificationTest.php
@@ -50,6 +50,22 @@ class UserNotificationTest extends Base
'notification_projects' => array(),
));
+ $this->container['userNotificationType']
+ ->expects($this->at(0))
+ ->method('getSelectedTypes')
+ ->will($this->returnValue(array('email')));
+
+ $this->container['userNotificationType']
+ ->expects($this->at(1))
+ ->method('getSelectedTypes')
+ ->will($this->returnValue(array('email')));
+
+ $this->container['userNotificationType']
+ ->expects($this->at(2))
+ ->method('getSelectedTypes')
+ ->with($this->equalTo(1))
+ ->will($this->returnValue(array('email', 'web')));
+
$settings = $n->readSettings(1);
$this->assertNotEmpty($settings);
$this->assertEquals(1, $settings['notifications_enabled']);
@@ -183,12 +199,17 @@ class UserNotificationTest extends Base
$this->container['userNotificationType']
->expects($this->at(0))
+ ->method('getSelectedTypes')
+ ->will($this->returnValue(array('email', 'web')));
+
+ $this->container['userNotificationType']
+ ->expects($this->at(1))
->method('getType')
->with($this->equalTo('email'))
->will($this->returnValue($notifier));
$this->container['userNotificationType']
- ->expects($this->at(1))
+ ->expects($this->at(2))
->method('getType')
->with($this->equalTo('web'))
->will($this->returnValue($notifier));
diff --git a/tests/units/Model/UserNotificationTypeTest.php b/tests/units/Model/UserNotificationTypeTest.php
index 6982e890..da22afef 100644
--- a/tests/units/Model/UserNotificationTypeTest.php
+++ b/tests/units/Model/UserNotificationTypeTest.php
@@ -19,12 +19,21 @@ class UserNotificationTypeTest extends Base
public function testGetSelectedTypes()
{
$nt = new UserNotificationType($this->container);
- $types = $nt->getSelectedTypes(1);
- $this->assertEmpty($types);
- $this->assertTrue($nt->saveSelectedTypes(1, array('email', 'web')));
- $types = $nt->getSelectedTypes(1);
- $this->assertNotEmpty($types);
- $this->assertEquals(array('email', 'web'), $types);
+ // No type defined
+ $this->assertEmpty($nt->getSelectedTypes(1));
+
+ // Hidden type
+ $nt->setType('baz', 'Baz', 'Something3', true);
+ $this->assertEmpty($nt->getSelectedTypes(1));
+
+ // User defined types but not registered
+ $this->assertTrue($nt->saveSelectedTypes(1, array('foo', 'bar')));
+ $this->assertEmpty($nt->getSelectedTypes(1));
+
+ // User defined types and registered
+ $nt->setType('bar', 'Bar', 'Something4');
+ $nt->setType('foo', 'Foo', 'Something3');
+ $this->assertEquals(array('bar', 'foo'), $nt->getSelectedTypes(1));
}
}
diff --git a/tests/units/Model/UserUnreadNotificationTest.php b/tests/units/Model/UserUnreadNotificationTest.php
index 130a6eba..bf274d95 100644
--- a/tests/units/Model/UserUnreadNotificationTest.php
+++ b/tests/units/Model/UserUnreadNotificationTest.php
@@ -11,52 +11,9 @@ use Kanboard\Model\File;
use Kanboard\Model\Task;
use Kanboard\Model\Project;
use Kanboard\Model\UserUnreadNotification;
-use Kanboard\Subscriber\NotificationSubscriber;
class UserUnreadNotificationTest extends Base
{
- public function testGetTitle()
- {
- $wn = new UserUnreadNotification($this->container);
- $p = new Project($this->container);
- $tf = new TaskFinder($this->container);
- $tc = new TaskCreation($this->container);
- $s = new Subtask($this->container);
- $c = new Comment($this->container);
- $f = new File($this->container);
-
- $this->assertEquals(1, $p->create(array('name' => 'test')));
- $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));
- $this->assertEquals(1, $s->create(array('title' => 'test', 'task_id' => 1)));
- $this->assertEquals(1, $c->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1)));
- $this->assertEquals(1, $f->create(1, 'test', 'blah', 123));
-
- $task = $tf->getDetails(1);
- $subtask = $s->getById(1, true);
- $comment = $c->getById(1);
- $file = $c->getById(1);
-
- $this->assertNotEmpty($task);
- $this->assertNotEmpty($subtask);
- $this->assertNotEmpty($comment);
- $this->assertNotEmpty($file);
-
- foreach (NotificationSubscriber::getSubscribedEvents() as $event_name => $values) {
- $title = $wn->getTitleFromEvent($event_name, array(
- 'task' => $task,
- 'comment' => $comment,
- 'subtask' => $subtask,
- 'file' => $file,
- 'changes' => array()
- ));
-
- $this->assertNotEmpty($title);
- }
-
- $this->assertNotEmpty($wn->getTitleFromEvent(Task::EVENT_OVERDUE, array('tasks' => array(array('id' => 1)))));
- $this->assertNotEmpty($wn->getTitleFromEvent('unkown', array()));
- }
-
public function testHasNotification()
{
$wn = new UserUnreadNotification($this->container);