summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-07-21 20:32:12 -0230
committerFrédéric Guillot <fred@kanboard.net>2014-07-21 20:32:12 -0230
commit9e1dcf21dc5d65bcc4195f1ae4caedbe57835415 (patch)
tree7fa9a2a08e24de7d16c0196b61e7c1bf8540f486 /app
parent4ae655ced334bb48342274caaf15f2b3d8b444f6 (diff)
Improve webhooks to call external url on task creation/modification
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Base.php1
-rw-r--r--app/Event/ProjectModificationDate.php (renamed from app/Event/TaskModification.php)8
-rw-r--r--app/Event/WebhookListener.php49
-rw-r--r--app/Locales/de_DE/translations.php2
-rw-r--r--app/Locales/es_ES/translations.php2
-rw-r--r--app/Locales/fr_FR/translations.php2
-rw-r--r--app/Locales/pl_PL/translations.php2
-rw-r--r--app/Locales/pt_BR/translations.php2
-rw-r--r--app/Locales/sv_SE/translations.php2
-rw-r--r--app/Locales/zh_CN/translations.php2
-rw-r--r--app/Model/Project.php4
-rw-r--r--app/Model/Webhook.php154
-rw-r--r--app/Schema/Mysql.php8
-rw-r--r--app/Schema/Postgres.php8
-rw-r--r--app/Schema/Sqlite.php8
-rw-r--r--app/Templates/config_index.php6
16 files changed, 252 insertions, 8 deletions
diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index 462529b1..2739c5ac 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
index b1d412c7..8fbaee73 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 00000000..f9776653
--- /dev/null
+++ b/app/Event/WebhookListener.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Event;
+
+use Core\Listener;
+use Model\Webhook;
+
+/**
+ * Webhook task events
+ *
+ * @package event
+ * @author Frederic Guillot
+ */
+class WebhookListener implements Listener
+{
+ /**
+ * Webhook model
+ *
+ * @accesss private
+ * @var \Model\Webhook
+ */
+ private $webhook;
+
+ /**
+ * Constructor
+ *
+ * @access public
+ * @param string $url URL to call
+ * @param \Model\Webhook $webhook Webhook model instance
+ */
+ public function __construct($url, Webhook $webhook)
+ {
+ $this->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 01be45c7..cc62bbe3 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 2b7420d9..7306526f 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 3d1d313b..9399fd14 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 eaafe7c5..c961ac2e 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 a422a660..bb7a3719 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 d69f6604..8113477c 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 de12c424..22678f19 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 51a23967..5d3f01b9 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 00000000..679d3edc
--- /dev/null
+++ b/app/Model/Webhook.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace Model;
+
+use Event\WebhookListener;
+
+/**
+ * Webhook model
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
+class Webhook extends Base
+{
+ /**
+ * HTTP connection timeout in seconds
+ *
+ * @var integer
+ */
+ const HTTP_TIMEOUT = 1;
+
+ /**
+ * Number of maximum redirections for the HTTP client
+ *
+ * @var integer
+ */
+ const HTTP_MAX_REDIRECTS = 3;
+
+ /**
+ * HTTP client user agent
+ *
+ * @var string
+ */
+ const HTTP_USER_AGENT = 'Kanboard Webhook';
+
+ /**
+ * URL to call for task creation
+ *
+ * @access private
+ * @var string
+ */
+ private $url_task_creation = '';
+
+ /**
+ * URL to call for task modification
+ *
+ * @access private
+ * @var string
+ */
+ private $url_task_modification = '';
+
+ /**
+ * Webook token
+ *
+ * @access private
+ * @var string
+ */
+ private $token = '';
+
+ /**
+ * Attach events
+ *
+ * @access public
+ */
+ public function attachEvents()
+ {
+ $config = new Config($this->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 b9c35efc..46fc6d43 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 bc18bdca..a9eea531 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 5ab42a6e..4660251f 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 b242d16f..91919776 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) ?><br/>
+ <?= Helper\form_label(t('Webhook URL for task creation'), 'webhooks_url_task_creation') ?>
+ <?= Helper\form_text('webhooks_url_task_creation', $values, $errors) ?><br/>
+
+ <?= Helper\form_label(t('Webhook URL for task modification'), 'webhooks_url_task_modification') ?>
+ <?= Helper\form_text('webhooks_url_task_modification', $values, $errors) ?><br/>
+
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
</div>