summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2016-07-26 22:23:58 -0400
committerFrederic Guillot <fred@kanboard.net>2016-07-26 22:23:58 -0400
commit9649f7ba82ba7fe6a470abfe9f65e214cc68fa34 (patch)
tree386cdf7a8d7bf7ad2d80d938333bafbaf0fedcbc
parent3c228b4e2aa7969dda17586708c64315fcd362f1 (diff)
Use the library PicoFeed to generate RSS/Atom feeds
-rw-r--r--ChangeLog1
-rw-r--r--app/Controller/FeedController.php60
-rw-r--r--app/Template/feed/project.php27
-rw-r--r--app/Template/feed/user.php27
-rw-r--r--composer.json1
-rw-r--r--composer.lock97
6 files changed, 149 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 0eb07f55..36f40461 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,7 @@ Improvements:
* Make search attributes not case sensitive
* Display TOTP issuer for 2FA
* Make sure that the table schema_version use InnoDB for Mysql
+* Use the library PicoFeed to generate RSS/Atom feeds
Bug fixes:
diff --git a/app/Controller/FeedController.php b/app/Controller/FeedController.php
index cf2b1088..f9b0ed7c 100644
--- a/app/Controller/FeedController.php
+++ b/app/Controller/FeedController.php
@@ -2,7 +2,11 @@
namespace Kanboard\Controller;
+use DateTime;
use Kanboard\Core\Controller\AccessForbiddenException;
+use PicoFeed\Syndication\AtomFeedBuilder;
+use PicoFeed\Syndication\AtomItemBuilder;
+use PicoFeed\Syndication\FeedBuilder;
/**
* Atom/RSS Feed controller
@@ -27,10 +31,15 @@ class FeedController extends BaseController
throw AccessForbiddenException::getInstance()->withoutLayout();
}
- $this->response->xml($this->template->render('feed/user', array(
- 'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id'])),
- 'user' => $user,
- )));
+ $events = $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id']));
+
+ $feedBuilder = AtomFeedBuilder::create()
+ ->withTitle(e('Project activities for %s', $this->helper->user->getFullname($user)))
+ ->withFeedUrl($this->helper->url->to('FeedController', 'user', array('token' => $user['token']), '', true))
+ ->withSiteUrl($this->helper->url->base())
+ ->withDate(new DateTime());
+
+ $this->response->xml($this->buildFeedItems($events, $feedBuilder)->build());
}
/**
@@ -47,9 +56,44 @@ class FeedController extends BaseController
throw AccessForbiddenException::getInstance()->withoutLayout();
}
- $this->response->xml($this->template->render('feed/project', array(
- 'events' => $this->helper->projectActivity->getProjectEvents($project['id']),
- 'project' => $project,
- )));
+ $events = $this->helper->projectActivity->getProjectEvents($project['id']);
+
+ $feedBuilder = AtomFeedBuilder::create()
+ ->withTitle(e('%s\'s activity', $project['name']))
+ ->withFeedUrl($this->helper->url->to('FeedController', 'project', array('token' => $project['token']), '', true))
+ ->withSiteUrl($this->helper->url->base())
+ ->withDate(new DateTime());
+
+ $this->response->xml($this->buildFeedItems($events, $feedBuilder)->build());
+ }
+
+ /**
+ * Build feed items
+ *
+ * @access protected
+ * @param array $events
+ * @param FeedBuilder $feedBuilder
+ * @return FeedBuilder
+ */
+ protected function buildFeedItems(array $events, FeedBuilder $feedBuilder)
+ {
+ foreach ($events as $event) {
+ $itemDate = new DateTime();
+ $itemDate->setTimestamp($event['date_creation']);
+
+ $itemUrl = $this->helper->url->to('TaskViewController', 'show', array('task_id' => $event['task_id']), '', true);
+
+ $feedBuilder
+ ->withItem(AtomItemBuilder::create($feedBuilder)
+ ->withTitle($event['event_title'])
+ ->withUrl($itemUrl.'#event-'.$event['id'])
+ ->withAuthor($event['author'])
+ ->withPublishedDate($itemDate)
+ ->withUpdatedDate($itemDate)
+ ->withContent($event['event_content'])
+ );
+ }
+
+ return $feedBuilder;
}
}
diff --git a/app/Template/feed/project.php b/app/Template/feed/project.php
deleted file mode 100644
index 213a04d4..00000000
--- a/app/Template/feed/project.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?= '<?xml version="1.0" encoding="utf-8"?>' ?>
-<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
- <title><?= t('%s\'s activity', $project['name']) ?></title>
- <link rel="alternate" type="text/html" href="<?= $this->url->base() ?>"/>
- <link rel="self" type="application/atom+xml" href="<?= $this->url->href('FeedController', 'project', array('token' => $project['token']), false, '', true) ?>"/>
- <updated><?= date(DATE_ATOM) ?></updated>
- <id><?= $this->url->href('FeedController', 'project', array('token' => $project['token']), false, '', true) ?></id>
- <icon><?= $this->url->base() ?>assets/img/favicon.png</icon>
-
- <?php foreach ($events as $e): ?>
- <entry>
- <title type="text"><?= $e['event_title'] ?></title>
- <link rel="alternate" href="<?= $this->url->href('TaskViewController', 'show', array('task_id' => $e['task_id']), false, '', true) ?>"/>
- <id><?= $e['id'].'-'.$e['event_name'].'-'.$e['task_id'].'-'.$e['date_creation'] ?></id>
- <published><?= date(DATE_ATOM, $e['date_creation']) ?></published>
- <updated><?= date(DATE_ATOM, $e['date_creation']) ?></updated>
- <author>
- <name><?= $this->text->e($e['author']) ?></name>
- </author>
- <content type="html">
- <![CDATA[
- <?= $e['event_content'] ?>
- ]]>
- </content>
- </entry>
- <?php endforeach ?>
-</feed>
diff --git a/app/Template/feed/user.php b/app/Template/feed/user.php
deleted file mode 100644
index 0c45f03c..00000000
--- a/app/Template/feed/user.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?= '<?xml version="1.0" encoding="utf-8"?>' ?>
-<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
- <title><?= t('Project activities for %s', $user['name'] ?: $user['username']) ?></title>
- <link rel="alternate" type="text/html" href="<?= $this->url->base() ?>"/>
- <link rel="self" type="application/atom+xml" href="<?= $this->url->href('FeedController', 'user', array('token' => $user['token']), false, '', true) ?>"/>
- <updated><?= date(DATE_ATOM) ?></updated>
- <id><?= $this->url->href('FeedController', 'user', array('token' => $user['token']), false, '', true) ?></id>
- <icon><?= $this->url->base() ?>assets/img/favicon.png</icon>
-
- <?php foreach ($events as $e): ?>
- <entry>
- <title type="text"><?= $e['event_title'] ?></title>
- <link rel="alternate" href="<?= $this->url->href('TaskViewController', 'show', array('task_id' => $e['task_id']), false, '', true) ?>"/>
- <id><?= $e['id'].'-'.$e['event_name'].'-'.$e['task_id'].'-'.$e['date_creation'] ?></id>
- <published><?= date(DATE_ATOM, $e['date_creation']) ?></published>
- <updated><?= date(DATE_ATOM, $e['date_creation']) ?></updated>
- <author>
- <name><?= $this->text->e($e['author']) ?></name>
- </author>
- <content type="html">
- <![CDATA[
- <?= $e['event_content'] ?>
- ]]>
- </content>
- </entry>
- <?php endforeach ?>
-</feed>
diff --git a/composer.json b/composer.json
index 443fb826..a49f263b 100644
--- a/composer.json
+++ b/composer.json
@@ -28,6 +28,7 @@
"erusev/parsedown" : "1.6.0",
"fguillot/json-rpc" : "1.2.1",
"fguillot/picodb" : "1.0.14",
+ "fguillot/picofeed": "0.1.24",
"fguillot/simpleLogger" : "1.0.1",
"fguillot/simple-validator" : "1.0.1",
"fguillot/simple-queue" : "1.0.1",
diff --git a/composer.lock b/composer.lock
index 33c2ca71..64feaa9c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "daa76b43d528f87e3bed91133fdb9259",
- "content-hash": "dde1b92fc6f9ca106cf927f4cd141a21",
+ "hash": "5111a8477b4462a68a9a93af931fbfeb",
+ "content-hash": "8609029c4ce32c3b3aec0778320a729a",
"packages": [
{
"name": "christian-riesen/base32",
@@ -284,6 +284,54 @@
"time": "2016-07-16 22:59:59"
},
{
+ "name": "fguillot/picofeed",
+ "version": "v0.1.24",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fguillot/picoFeed.git",
+ "reference": "25f9653ca663e098f51eabbdf495eb9a130c041b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/25f9653ca663e098f51eabbdf495eb9a130c041b",
+ "reference": "25f9653ca663e098f51eabbdf495eb9a130c041b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "php": ">=5.3.0",
+ "zendframework/zendxml": "^1.0"
+ },
+ "suggest": {
+ "ext-curl": "PicoFeed will use cURL if present"
+ },
+ "bin": [
+ "picofeed"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "PicoFeed": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frédéric Guillot"
+ }
+ ],
+ "description": "Modern library to handle RSS/Atom feeds",
+ "homepage": "https://github.com/fguillot/picoFeed",
+ "time": "2016-07-03 00:02:03"
+ },
+ {
"name": "fguillot/simple-queue",
"version": "v1.0.1",
"source": {
@@ -861,6 +909,51 @@
"shim"
],
"time": "2016-05-18 14:26:46"
+ },
+ {
+ "name": "zendframework/zendxml",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/ZendXml.git",
+ "reference": "7b64507bc35d841c9c5802d67f6f87ef8e1a58c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/ZendXml/zipball/7b64507bc35d841c9c5802d67f6f87ef8e1a58c9",
+ "reference": "7b64507bc35d841c9c5802d67f6f87ef8e1a58c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^3.7 || ^4.0",
+ "squizlabs/php_codesniffer": "^1.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "ZendXml\\": "library/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Utility library for XML usage, best practices, and security in PHP",
+ "homepage": "http://packages.zendframework.com/",
+ "keywords": [
+ "security",
+ "xml",
+ "zf2"
+ ],
+ "time": "2016-02-04 21:02:08"
}
],
"packages-dev": [