diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index 462529b17..2739c5ac0 100644
--- a/app/Controller/Base.php
+++ b/app/Controller/Base.php
@@ -151,6 +151,7 @@ abstract class Base
// Attach events
$this->action->attachEvents();
$this->project->attachEvents();
+ $this->webhook->attachEvents();
}
/**
diff --git a/app/Event/TaskModification.php b/app/Event/ProjectModificationDate.php
similarity index 85%
rename from app/Event/TaskModification.php
rename to app/Event/ProjectModificationDate.php
index b1d412c74..8fbaee73c 100644
--- a/app/Event/TaskModification.php
+++ b/app/Event/ProjectModificationDate.php
@@ -6,12 +6,14 @@ use Core\Listener;
use Model\Project;
/**
- * Task modification listener
+ * Project modification date listener
*
- * @package events
+ * Update the last modified field for a project
+ *
+ * @package event
* @author Frederic Guillot
*/
-class TaskModification implements Listener
+class ProjectModificationDate implements Listener
{
/**
* Project model
diff --git a/app/Event/WebhookListener.php b/app/Event/WebhookListener.php
new file mode 100644
index 000000000..f97766538
--- /dev/null
+++ b/app/Event/WebhookListener.php
@@ -0,0 +1,49 @@
+url = $url;
+ $this->webhook = $webhook;
+ }
+
+ /**
+ * Execute the action
+ *
+ * @access public
+ * @param array $data Event data dictionary
+ * @return bool True if the action was executed or false when not executed
+ */
+ public function execute(array $data)
+ {
+ $this->webhook->notify($this->url, $data);
+ return true;
+ }
+}
diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php
index 01be45c77..cc62bbe3a 100644
--- a/app/Locales/de_DE/translations.php
+++ b/app/Locales/de_DE/translations.php
@@ -396,4 +396,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php
index 2b7420d98..7306526f3 100644
--- a/app/Locales/es_ES/translations.php
+++ b/app/Locales/es_ES/translations.php
@@ -395,4 +395,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php
index 3d1d313b6..9399fd14b 100644
--- a/app/Locales/fr_FR/translations.php
+++ b/app/Locales/fr_FR/translations.php
@@ -393,4 +393,6 @@ return array(
'Creator' => 'Créateur',
'Modification date' => 'Date de modification',
'Completion date' => 'Date de complétion',
+ 'Webhook URL for task creation' => 'URL du webhook pour la création de tâche',
+ 'Webhook URL for task modification' => 'URL du webhook pour la modification de tâche',
);
diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php
index eaafe7c5e..c961ac2ea 100644
--- a/app/Locales/pl_PL/translations.php
+++ b/app/Locales/pl_PL/translations.php
@@ -396,4 +396,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php
index a422a6602..bb7a37190 100644
--- a/app/Locales/pt_BR/translations.php
+++ b/app/Locales/pt_BR/translations.php
@@ -393,4 +393,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php
index d69f66046..8113477cd 100644
--- a/app/Locales/sv_SE/translations.php
+++ b/app/Locales/sv_SE/translations.php
@@ -395,4 +395,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php
index de12c4248..22678f197 100644
--- a/app/Locales/zh_CN/translations.php
+++ b/app/Locales/zh_CN/translations.php
@@ -401,4 +401,6 @@ return array(
// 'Creator' => '',
// 'Modification date' => '',
// 'Completion date' => '',
+ // 'Webhook URL for task creation' => '',
+ // 'Webhook URL for task modification' => '',
);
diff --git a/app/Model/Project.php b/app/Model/Project.php
index 51a23967f..5d3f01b9d 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -4,7 +4,7 @@ namespace Model;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
-use Event\TaskModification;
+use Event\ProjectModificationDate;
use Core\Security;
/**
@@ -575,7 +575,7 @@ class Project extends Base
Task::EVENT_OPEN,
);
- $listener = new TaskModification($this);
+ $listener = new ProjectModificationDate($this);
foreach ($events as $event_name) {
$this->event->attach($event_name, $listener);
diff --git a/app/Model/Webhook.php b/app/Model/Webhook.php
new file mode 100644
index 000000000..679d3edc7
--- /dev/null
+++ b/app/Model/Webhook.php
@@ -0,0 +1,154 @@
+db, $this->event);
+
+ $this->url_task_creation = $config->get('webhooks_url_task_creation');
+ $this->url_task_modification = $config->get('webhooks_url_task_modification');
+ $this->token = $config->get('webhooks_token');
+
+ if ($this->url_task_creation) {
+ $this->attachCreateEvents();
+ }
+
+ if ($this->url_task_modification) {
+ $this->attachUpdateEvents();
+ }
+ }
+
+ /**
+ * Attach events for task modification
+ *
+ * @access public
+ */
+ public function attachUpdateEvents()
+ {
+ $events = array(
+ Task::EVENT_UPDATE,
+ Task::EVENT_CLOSE,
+ Task::EVENT_OPEN,
+ );
+
+ $listener = new WebhookListener($this->url_task_modification, $this);
+
+ foreach ($events as $event_name) {
+ $this->event->attach($event_name, $listener);
+ }
+ }
+
+ /**
+ * Attach events for task creation
+ *
+ * @access public
+ */
+ public function attachCreateEvents()
+ {
+ $events = array(
+ Task::EVENT_CREATE,
+ );
+
+ $listener = new WebhookListener($this->url_task_creation, $this);
+
+ foreach ($events as $event_name) {
+ $this->event->attach($event_name, $listener);
+ }
+ }
+
+ /**
+ * Call the external URL
+ *
+ * @access public
+ * @param string $url URL to call
+ * @param array $task Task data
+ */
+ public function notify($url, array $task)
+ {
+ $headers = array(
+ 'Connection: close',
+ 'User-Agent: '.self::HTTP_USER_AGENT,
+ );
+
+ $context = stream_context_create(array(
+ 'http' => array(
+ 'method' => 'POST',
+ 'protocol_version' => 1.1,
+ 'timeout' => self::HTTP_TIMEOUT,
+ 'max_redirects' => self::HTTP_MAX_REDIRECTS,
+ 'header' => implode("\r\n", $headers),
+ 'content' => json_encode($task)
+ )
+ ));
+
+ if (strpos($url, '?') !== false) {
+ $url .= '&token='.$this->token;
+ }
+ else {
+ $url .= '?token='.$this->token;
+ }
+
+ @file_get_contents($url, false, $context);
+ }
+}
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index b9c35efc6..46fc6d430 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -4,7 +4,13 @@ namespace Schema;
use Core\Security;
-const VERSION = 21;
+const VERSION = 22;
+
+function version_22($pdo)
+{
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification VARCHAR(255)");
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation VARCHAR(255)");
+}
function version_21($pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index bc18bdcab..a9eea531c 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -4,7 +4,13 @@ namespace Schema;
use Core\Security;
-const VERSION = 2;
+const VERSION = 3;
+
+function version_3($pdo)
+{
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification VARCHAR(255)");
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation VARCHAR(255)");
+}
function version_2($pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index 5ab42a6ed..4660251f6 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -4,7 +4,13 @@ namespace Schema;
use Core\Security;
-const VERSION = 21;
+const VERSION = 22;
+
+function version_22($pdo)
+{
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification TEXT");
+ $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation TEXT");
+}
function version_21($pdo)
{
diff --git a/app/Templates/config_index.php b/app/Templates/config_index.php
index b242d16ff..919197768 100644
--- a/app/Templates/config_index.php
+++ b/app/Templates/config_index.php
@@ -15,6 +15,12 @@
= Helper\form_label(t('Timezone'), 'timezone') ?>
= Helper\form_select('timezone', $timezones, $values, $errors) ?>
+ = Helper\form_label(t('Webhook URL for task creation'), 'webhooks_url_task_creation') ?>
+ = Helper\form_text('webhooks_url_task_creation', $values, $errors) ?>
+
+ = Helper\form_label(t('Webhook URL for task modification'), 'webhooks_url_task_modification') ?>
+ = Helper\form_text('webhooks_url_task_modification', $values, $errors) ?>
+