diff --git a/blocks/rss_client/block_rss_client.php b/blocks/rss_client/block_rss_client.php
index 68a13ac2320e7..e41e68c6c5fac 100644
--- a/blocks/rss_client/block_rss_client.php
+++ b/blocks/rss_client/block_rss_client.php
@@ -14,6 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Contains block_rss_client
+ * @package block_rss_client
+ * @copyright Daryl Hawes
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL
+ */
+
/**
* A block which displays Remote feeds
*
@@ -45,6 +52,31 @@ function specialization() {
}
}
+ /**
+ * Gets the footer, which is the channel link of the last feed in our list of feeds
+ *
+ * @param array $feedrecords The feed records from the database.
+ * @return block_rss_client\output\footer|null The renderable footer or null if none should be displayed.
+ */
+ protected function get_footer($feedrecords) {
+ $footer = null;
+
+ if ($this->config->block_rss_client_show_channel_link) {
+ global $CFG;
+ require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
+
+ $feedrecord = array_pop($feedrecords);
+ $feed = new moodle_simplepie($feedrecord->url);
+ $channellink = new moodle_url($feed->get_link());
+
+ if (!empty($channellink)) {
+ $footer = new block_rss_client\output\footer($channellink);
+ }
+ }
+
+ return $footer;
+ }
+
function get_content() {
global $CFG, $DB;
@@ -80,31 +112,38 @@ function get_content() {
$maxentries = intval($CFG->block_rss_client_num_entries);
}
-
/* ---------------------------------
* Begin Normal Display of Block Content
* --------------------------------- */
- $output = '';
-
+ $renderer = $this->page->get_renderer('block_rss_client');
+ $block = new \block_rss_client\output\block();
if (!empty($this->config->rssid)) {
- list($rss_ids_sql, $params) = $DB->get_in_or_equal($this->config->rssid);
-
- $rss_feeds = $DB->get_records_select('block_rss_client', "id $rss_ids_sql", $params);
+ list($rssidssql, $params) = $DB->get_in_or_equal($this->config->rssid);
+ $rssfeeds = $DB->get_records_select('block_rss_client', "id $rssidssql", $params);
+
+ if (!empty($rssfeeds)) {
+ $showtitle = false;
+ if (count($rssfeeds) > 1) {
+ // When many feeds show the title for each feed.
+ $showtitle = true;
+ }
- $showtitle = false;
- if (count($rss_feeds) > 1) {
- // when many feeds show the title for each feed
- $showtitle = true;
- }
+ foreach ($rssfeeds as $feed) {
+ if ($renderablefeed = $this->get_feed($feed, $maxentries, $showtitle)) {
+ $block->add_feed($renderablefeed);
+ }
+ }
- foreach($rss_feeds as $feed){
- $output.= $this->get_feed_html($feed, $maxentries, $showtitle);
+ $footer = $this->get_footer($rssfeeds);
}
}
- $this->content->text = $output;
+ $this->content->text = $renderer->render_block($block);
+ if (isset($footer)) {
+ $this->content->footer = $renderer->render_footer($footer);
+ }
return $this->content;
}
@@ -128,136 +167,80 @@ function instance_allow_config() {
* @param mixed feedrecord The feed record from the database
* @param int maxentries The maximum number of entries to be displayed
* @param boolean showtitle Should the feed title be displayed in html
- * @return string html representing the rss feed content
+ * @return block_rss_client\output\feed|null The renderable feed or null of there is an error
*/
- function get_feed_html($feedrecord, $maxentries, $showtitle){
+ public function get_feed($feedrecord, $maxentries, $showtitle) {
global $CFG;
require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
- $feed = new moodle_simplepie($feedrecord->url);
+ $simplepiefeed = new moodle_simplepie($feedrecord->url);
if(isset($CFG->block_rss_client_timeout)){
- $feed->set_cache_duration($CFG->block_rss_client_timeout*60);
- }
-
- if ($CFG->debugdeveloper && $feed->error()) {
- return '
'. $feedrecord->url .' Failed with code: '.$feed->error().'
';
+ $simplepiefeed->set_cache_duration($CFG->block_rss_client_timeout * 60);
}
- $r = ''; // return string
-
- if($this->config->block_rss_client_show_channel_image){
- if($image = $feed->get_image_url()){
- $imagetitle = s($feed->get_image_title());
- $imagelink = $feed->get_image_link();
-
- $r.='';
- }
+ if ($simplepiefeed->error()) {
+ debugging($feedrecord->url .' Failed with code: '.$simplepiefeed->error());
+ return null;
}
if(empty($feedrecord->preferredtitle)){
- $feedtitle = $this->format_title($feed->get_title());
+ $feedtitle = $this->format_title($simplepiefeed->get_title());
}else{
$feedtitle = $this->format_title($feedrecord->preferredtitle);
}
- if($showtitle){
- $r.=''.$feedtitle.'
';
- }
-
-
- $r.=''."\n";
-
- $feeditems = $feed->get_items(0, $maxentries);
- foreach($feeditems as $item){
- $r.= $this->get_item_html($item);
- }
-
- $r.='
';
-
-
- if ($this->config->block_rss_client_show_channel_link) {
-
- $channellink = $feed->get_link();
-
- if (!empty($channellink)){
- //NOTE: this means the 'last feed' display wins the block title - but
- //this is exiting behaviour..
- $this->content->footer = ''. get_string('clientchannellink', 'block_rss_client') .'';
- }
- }
-
if (empty($this->config->title)){
//NOTE: this means the 'last feed' displayed wins the block title - but
//this is exiting behaviour..
$this->title = strip_tags($feedtitle);
}
- return $r;
- }
-
-
- /**
- * Returns the html list item of a feed item
- *
- * @param mixed item simplepie_item representing the feed item
- * @return string html li representing the rss feed item
- */
- function get_item_html($item){
-
- $link = $item->get_link();
- $title = $item->get_title();
- $description = $item->get_description();
-
-
- if(empty($title)){
- // no title present, use portion of description
- $title = core_text::substr(strip_tags($description), 0, 20) . '...';
- }else{
- $title = break_up_long_words($title, 30);
+ $feed = new \block_rss_client\output\feed($feedtitle, $showtitle, $this->config->block_rss_client_show_channel_image);
+
+ if ($simplepieitems = $simplepiefeed->get_items(0, $maxentries)) {
+ foreach ($simplepieitems as $simplepieitem) {
+ try {
+ $item = new \block_rss_client\output\item(
+ $simplepieitem->get_id(),
+ new moodle_url($simplepieitem->get_link()),
+ $simplepieitem->get_title(),
+ $simplepieitem->get_description(),
+ new moodle_url($simplepieitem->get_permalink()),
+ $simplepieitem->get_date('U'),
+ $this->config->display_description
+ );
+
+ $feed->add_item($item);
+ } catch (moodle_exception $e) {
+ // If there is an error with the RSS item, we don't
+ // want to crash the page. Specifically, moodle_url can
+ // throw an exception of the param is an extremely
+ // malformed url.
+ debugging($e->getMessage());
+ }
+ }
}
- if(empty($link)){
- $link = $item->get_id();
- } else {
+ // Feed image.
+ if ($imageurl = $simplepiefeed->get_image_url()) {
try {
- // URLs in our RSS cache will be escaped (correctly as theyre store in XML)
- // html_writer::link() will re-escape them. To prevent double escaping unescape here.
- // This can by done using htmlspecialchars_decode() but moodle_url also has that effect.
- $link = new moodle_url($link);
+ $image = new \block_rss_client\output\channel_image(
+ new moodle_url($imageurl),
+ $simplepiefeed->get_image_title(),
+ new moodle_url($simplepiefeed->get_image_link())
+ );
+
+ $feed->set_image($image);
} catch (moodle_exception $e) {
- // Catching the exception to prevent the whole site to crash in case of malformed RSS feed
- $link = '';
+ // If there is an error with the RSS image, we don'twant to
+ // crash the page. Specifically, moodle_url can throw an
+ // exception if the param is an extremely malformed url.
+ debugging($e->getMessage());
}
}
- $r = html_writer::start_tag('li');
- $r.= html_writer::start_tag('div',array('class'=>'link'));
- $r.= html_writer::link($link, s($title), array('onclick'=>'this.target="_blank"'));
- $r.= html_writer::end_tag('div');
-
- if($this->config->display_description && !empty($description)){
-
- $formatoptions = new stdClass();
- $formatoptions->para = false;
-
- $r.= html_writer::start_tag('div',array('class'=>'description'));
- $description = format_text($description, FORMAT_HTML, $formatoptions, $this->page->course->id);
- $description = break_up_long_words($description, 30);
- $r.= $description;
- $r.= html_writer::end_tag('div');
- }
- $r.= html_writer::end_tag('li');
-
- return $r;
+ return $feed;
}
/**
@@ -378,5 +361,3 @@ protected function calculate_skiptime($currentskip) {
return $newskiptime;
}
}
-
-
diff --git a/blocks/rss_client/classes/output/block.php b/blocks/rss_client/classes/output/block.php
new file mode 100644
index 0000000000000..7789f0c7bc914
--- /dev/null
+++ b/blocks/rss_client/classes/output/block.php
@@ -0,0 +1,104 @@
+.
+
+/**
+ * Contains class block_rss_client\output\block
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class to help display an RSS Feeds block
+ *
+ * @package block_rss_client
+ * @copyright 2016 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block implements \renderable, \templatable {
+
+ /**
+ * An array of renderable feeds
+ *
+ * @var array
+ */
+ protected $feeds;
+
+ /**
+ * Contruct
+ *
+ * @param array $feeds An array of renderable feeds
+ */
+ public function __construct(array $feeds = array()) {
+ $this->feeds = $feeds;
+ }
+
+ /**
+ * Prepare data for use in a template
+ *
+ * @param \renderer_base $output
+ * @return array
+ */
+ public function export_for_template(\renderer_base $output) {
+ $data = array('feeds' => array());
+
+ foreach ($this->feeds as $feed) {
+ $data['feeds'][] = $feed->export_for_template($output);
+ }
+
+ return $data;
+ }
+
+ /**
+ * Add a feed
+ *
+ * @param \block_rss_client\output\feed $feed
+ * @return \block_rss_client\output\block
+ */
+ public function add_feed(feed $feed) {
+ $this->feeds[] = $feed;
+
+ return $this;
+ }
+
+ /**
+ * Set the feeds
+ *
+ * @param array $feeds
+ * @return \block_rss_client\output\block
+ */
+ public function set_feeds(array $feeds) {
+ $this->feeds = $feeds;
+
+ return $this;
+ }
+
+ /**
+ * Get feeds
+ *
+ * @return array
+ */
+ public function get_feeds() {
+ return $this->feeds;
+ }
+}
diff --git a/blocks/rss_client/classes/output/channel_image.php b/blocks/rss_client/classes/output/channel_image.php
new file mode 100644
index 0000000000000..af9e22fef142b
--- /dev/null
+++ b/blocks/rss_client/classes/output/channel_image.php
@@ -0,0 +1,151 @@
+.
+
+/**
+ * Contains class block_rss_client\output\channel_image
+ *
+ * @package block_rss_client
+ * @copyright 2016 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class to display RSS channel images
+ *
+ * @package block_rss_client
+ * @copyright 2016 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class channel_image implements \renderable, \templatable {
+
+ /**
+ * The URL location of the image
+ *
+ * @var string
+ */
+ protected $url;
+
+ /**
+ * The title of the image
+ *
+ * @var string
+ */
+ protected $title;
+
+ /**
+ * The URL of the image link
+ *
+ * @var string
+ */
+ protected $link;
+
+ /**
+ * Contructor
+ *
+ * @param \moodle_url $url The URL location of the image
+ * @param string $title The title of the image
+ * @param \moodle_url $link The URL of the image link
+ */
+ public function __construct(\moodle_url $url, $title, \moodle_url $link = null) {
+ $this->url = $url;
+ $this->title = $title;
+ $this->link = $link;
+ }
+
+ /**
+ * Export this for use in a mustache template context.
+ *
+ * @see templatable::export_for_template()
+ * @param renderer_base $output
+ * @return array The data for the template
+ */
+ public function export_for_template(\renderer_base $output) {
+ return array(
+ 'url' => clean_param($this->url, PARAM_URL),
+ 'title' => $this->title,
+ 'link' => clean_param($this->link, PARAM_URL),
+ );
+ }
+
+ /**
+ * Set the URL
+ *
+ * @param \moodle_url $url
+ * @return \block_rss_client\output\channel_image
+ */
+ public function set_url(\moodle_url $url) {
+ $this->url = $url;
+
+ return $this;
+ }
+
+ /**
+ * Get the URL
+ *
+ * @return \moodle_url
+ */
+ public function get_url() {
+ return $this->url;
+ }
+
+ /**
+ * Set the title
+ *
+ * @param string $title
+ * @return \block_rss_client\output\channel_image
+ */
+ public function set_title($title) {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ /**
+ * Get the title
+ *
+ * @return string
+ */
+ public function get_title() {
+ return $this->title;
+ }
+
+ /**
+ * Set the link
+ *
+ * @param \moodle_url $link
+ * @return \block_rss_client\output\channel_image
+ */
+ public function set_link($link) {
+ $this->link = $link;
+
+ return $this;
+ }
+
+ /**
+ * Get the link
+ *
+ * @return \moodle_url
+ */
+ public function get_link() {
+ return $this->link;
+ }
+}
diff --git a/blocks/rss_client/classes/output/feed.php b/blocks/rss_client/classes/output/feed.php
new file mode 100644
index 0000000000000..02f7e2db95b72
--- /dev/null
+++ b/blocks/rss_client/classes/output/feed.php
@@ -0,0 +1,224 @@
+.
+
+/**
+ * Contains class block_rss_client\output\feed
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class to help display an RSS Feed
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class feed implements \renderable, \templatable {
+
+ /**
+ * The feed's title
+ *
+ * @var string
+ */
+ protected $title = null;
+
+ /**
+ * An array of renderable feed items
+ *
+ * @var array
+ */
+ protected $items = array();
+
+ /**
+ * The channel image
+ *
+ * @var channel_image
+ */
+ protected $image = null;
+
+ /**
+ * Whether or not to show the title
+ *
+ * @var boolean
+ */
+ protected $showtitle;
+
+ /**
+ * Whether or not to show the channel image
+ *
+ * @var boolean
+ */
+ protected $showimage;
+
+ /**
+ * Contructor
+ *
+ * @param string $title The title of the RSS feed
+ * @param boolean $showtitle Whether to show the title
+ * @param boolean $showimage Whether to show the channel image
+ */
+ public function __construct($title, $showtitle = true, $showimage = true) {
+ $this->title = $title;
+ $this->showtitle = $showtitle;
+ $this->showimage = $showimage;
+ }
+
+ /**
+ * Export this for use in a mustache template context.
+ *
+ * @see templatable::export_for_template()
+ * @param renderer_base $output
+ * @return stdClass
+ */
+ public function export_for_template(\renderer_base $output) {
+ $data = array(
+ 'title' => $this->showtitle ? $this->title : null,
+ 'image' => null,
+ 'items' => array(),
+ );
+
+ if ($this->showimage && $this->image) {
+ $data['image'] = $this->image->export_for_template($output);
+ }
+
+ foreach ($this->items as $item) {
+ $data['items'][] = $item->export_for_template($output);
+ }
+
+ return $data;
+ }
+
+ /**
+ * Set the feed title
+ *
+ * @param string $title
+ * @return \block_rss_client\output\feed
+ */
+ public function set_title($title) {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ /**
+ * Get the feed title
+ *
+ * @return string
+ */
+ public function get_title() {
+ return $this->title;
+ }
+
+ /**
+ * Add an RSS item
+ *
+ * @param \block_rss_client\output\item $item
+ */
+ public function add_item(item $item) {
+ $this->items[] = $item;
+
+ return $this;
+ }
+
+ /**
+ * Set the RSS items
+ *
+ * @param array $items An array of renderable RSS items
+ */
+ public function set_items(array $items) {
+ $this->items = $items;
+
+ return $this;
+ }
+
+ /**
+ * Get the RSS items
+ *
+ * @return array An array of renderable RSS items
+ */
+ public function get_items() {
+ return $this->items;
+ }
+
+ /**
+ * Set the channel image
+ *
+ * @param \block_rss_client\output\channel_image $image
+ */
+ public function set_image(channel_image $image) {
+ $this->image = $image;
+ }
+
+ /**
+ * Get the channel image
+ *
+ * @return channel_image
+ */
+ public function get_image() {
+ return $this->image;
+ }
+
+ /**
+ * Set showtitle
+ *
+ * @param boolean $showtitle
+ * @return \block_rss_client\output\feed
+ */
+ public function set_showtitle($showtitle) {
+ $this->showtitle = boolval($showtitle);
+
+ return $this;
+ }
+
+ /**
+ * Get showtitle
+ *
+ * @return boolean
+ */
+ public function get_showtitle() {
+ return $this->showtitle;
+ }
+
+ /**
+ * Set showimage
+ *
+ * @param boolean $showimage
+ * @return \block_rss_client\output\feed
+ */
+ public function set_showimage($showimage) {
+ $this->showimage = boolval($showimage);
+
+ return $this;
+ }
+
+ /**
+ * Get showimage
+ *
+ * @return boolean
+ */
+ public function get_showimage() {
+ return $this->showimage;
+ }
+}
diff --git a/blocks/rss_client/classes/output/footer.php b/blocks/rss_client/classes/output/footer.php
new file mode 100644
index 0000000000000..3da20398b598a
--- /dev/null
+++ b/blocks/rss_client/classes/output/footer.php
@@ -0,0 +1,90 @@
+.
+
+/**
+ * Contains class block_rss_client\output\footer
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class to help display an RSS Block footer
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class footer implements \renderable, \templatable {
+
+ /**
+ * The link provided in the RSS channel
+ *
+ * @var \moodle_url
+ */
+ protected $channelurl;
+
+ /**
+ * Constructor
+ *
+ * @param \moodle_url $channelurl The link provided in the RSS channel
+ */
+ public function __construct(\moodle_url $channelurl) {
+ $this->channelurl = $channelurl;
+ }
+
+ /**
+ * Set the channel url
+ *
+ * @param \moodle_url $channelurl
+ * @return \block_rss_client\output\footer
+ */
+ public function set_channelurl(\moodle_url $channelurl) {
+ $this->channelurl = $channelurl;
+
+ return $this;
+ }
+
+ /**
+ * Get the channel url
+ *
+ * @return \moodle_url
+ */
+ public function get_channelurl() {
+ return $this->channelurl;
+ }
+
+ /**
+ * Export context for use in mustache templates
+ *
+ * @see templatable::export_for_template()
+ * @param renderer_base $output
+ * @return stdClass
+ */
+ public function export_for_template(\renderer_base $output) {
+ $data = new \stdClass();
+ $data->channellink = clean_param($this->channelurl, PARAM_URL);
+
+ return $data;
+ }
+}
diff --git a/blocks/rss_client/classes/output/item.php b/blocks/rss_client/classes/output/item.php
new file mode 100644
index 0000000000000..71a71dc7547c6
--- /dev/null
+++ b/blocks/rss_client/classes/output/item.php
@@ -0,0 +1,286 @@
+.
+
+/**
+ * Contains class block_rss_client\output\feed
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class to help display an RSS Item
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class item implements \renderable, \templatable {
+
+ /**
+ * The unique id of the item
+ *
+ * @var string
+ */
+ protected $id;
+
+ /**
+ * The link to the item
+ *
+ * @var \moodle_url
+ */
+ protected $link;
+
+ /**
+ * The title of the item
+ *
+ * @var string
+ */
+ protected $title;
+
+ /**
+ * The description of the item
+ *
+ * @var string
+ */
+ protected $description;
+
+ /**
+ * The item's permalink
+ *
+ * @var \moodle_url
+ */
+ protected $permalink;
+
+ /**
+ * The publish date of the item in Unix timestamp format
+ *
+ * @var int
+ */
+ protected $timestamp;
+
+ /**
+ * Whether or not to show the item's description
+ *
+ * @var string
+ */
+ protected $showdescription;
+
+ /**
+ * Contructor
+ *
+ * @param string $id The id of the RSS item
+ * @param \moodle_url $link The URL of the RSS item
+ * @param string $title The title pf the RSS item
+ * @param string $description The description of the RSS item
+ * @param \moodle_url $permalink The permalink of the RSS item
+ * @param int $timestamp The Unix timestamp that represents the published date
+ * @param boolean $showdescription Whether or not to show the description
+ */
+ public function __construct($id, \moodle_url $link, $title, $description, \moodle_url $permalink, $timestamp,
+ $showdescription = true) {
+ $this->id = $id;
+ $this->link = $link;
+ $this->title = $title;
+ $this->description = $description;
+ $this->permalink = $permalink;
+ $this->timestamp = $timestamp;
+ $this->showdescription = $showdescription;
+ }
+
+ /**
+ * Export context for use in mustache templates
+ *
+ * @see templatable::export_for_template()
+ * @param renderer_base $output
+ * @return array
+ */
+ public function export_for_template(\renderer_base $output) {
+ $data = array(
+ 'id' => $this->id,
+ 'permalink' => clean_param($this->permalink, PARAM_URL),
+ 'datepublished' => $output->format_published_date($this->timestamp),
+ 'link' => clean_param($this->link, PARAM_URL),
+ );
+
+ // If the item does not have a title, create one from the description.
+ $title = $this->title;
+ if (!$title) {
+ $title = strip_tags($this->description);
+ $title = core_text::substr($title, 0, 20) . '...';
+ }
+
+ // Allow the renderer to format the title and description.
+ $data['title'] = $output->format_title($title);
+ $data['description'] = $this->showdescription ? $output->format_description($this->description) : null;
+
+ return $data;
+ }
+
+ /**
+ * Set id
+ *
+ * @param string $id
+ * @return \block_rss_client\output\item
+ */
+ public function set_id($id) {
+ $this->id = $id;
+
+ return $this;
+ }
+
+ /**
+ * Get id
+ *
+ * @return string
+ */
+ public function get_id() {
+ return $this->id;
+ }
+
+ /**
+ * Set link
+ *
+ * @param \moodle_url $link
+ * @return \block_rss_client\output\item
+ */
+ public function set_link(\moodle_url $link) {
+ $this->link = $link;
+
+ return $this;
+ }
+
+ /**
+ * Get link
+ *
+ * @return \moodle_url
+ */
+ public function get_link() {
+ return $this->link;
+ }
+
+ /**
+ * Set title
+ *
+ * @param string $title
+ * @return \block_rss_client\output\item
+ */
+ public function set_title($title) {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ /**
+ * Get title
+ *
+ * @return string
+ */
+ public function get_title() {
+ return $this->title;
+ }
+
+ /**
+ * Set description
+ *
+ * @param string $description
+ * @return \block_rss_client\output\item
+ */
+ public function set_description($description) {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Get description
+ *
+ * @return string
+ */
+ public function get_description() {
+ return $this->description;
+ }
+
+ /**
+ * Set permalink
+ *
+ * @param string $permalink
+ * @return \block_rss_client\output\item
+ */
+ public function set_permalink($permalink) {
+ $this->permalink = $permalink;
+
+ return $this;
+ }
+
+ /**
+ * Get permalink
+ *
+ * @return string
+ */
+ public function get_permalink() {
+ return $this->permalink;
+ }
+
+ /**
+ * Set timestamp
+ *
+ * @param int $timestamp
+ * @return \block_rss_client\output\item
+ */
+ public function set_timestamp($timestamp) {
+ $this->timestamp = $timestamp;
+
+ return $this;
+ }
+
+ /**
+ * Get timestamp
+ *
+ * @return string
+ */
+ public function get_timestamp() {
+ return $this->timestamp;
+ }
+
+ /**
+ * Set showdescription
+ *
+ * @param boolean $showdescription
+ * @return \block_rss_client\output\item
+ */
+ public function set_showdescription($showdescription) {
+ $this->showdescription = boolval($showdescription);
+
+ return $this;
+ }
+
+ /**
+ * Get showdescription
+ *
+ * @return boolean
+ */
+ public function get_showdescription() {
+ return $this->showdescription;
+ }
+}
diff --git a/blocks/rss_client/classes/output/renderer.php b/blocks/rss_client/classes/output/renderer.php
new file mode 100644
index 0000000000000..7a03280fbdc8c
--- /dev/null
+++ b/blocks/rss_client/classes/output/renderer.php
@@ -0,0 +1,121 @@
+.
+
+/**
+ * Contains class block_rss_client\output\block_renderer_html
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace block_rss_client\output;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Renderer for RSS Client block
+ *
+ * @package block_rss_client
+ * @copyright 2015 Howard County Public School System
+ * @author Brendan Anderson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class renderer extends \plugin_renderer_base {
+
+ /**
+ * Render an RSS Item
+ *
+ * @param templatable $item
+ * @return string|boolean
+ */
+ public function render_item(\templatable $item) {
+ $data = $item->export_for_template($this);
+
+ return $this->render_from_template('block_rss_client/item', $data);
+ }
+
+ /**
+ * Render an RSS Feed
+ *
+ * @param templatable $feed
+ * @return string|boolean
+ */
+ public function render_feed(\templatable $feed) {
+ $data = $feed->export_for_template($this);
+
+ return $this->render_from_template('block_rss_client/feed', $data);
+ }
+
+ /**
+ * Render an RSS feeds block
+ *
+ * @param \templatable $block
+ * @return string|boolean
+ */
+ public function render_block(\templatable $block) {
+ $data = $block->export_for_template($this);
+
+ return $this->render_from_template('block_rss_client/block', $data);
+ }
+
+ /**
+ * Render the block footer
+ *
+ * @param templatable $footer
+ * @return string|boolean
+ */
+ public function render_footer(\templatable $footer) {
+ $data = $footer->export_for_template($this);
+
+ return $this->render_from_template('block_rss_client/footer', $data);
+ }
+
+ /**
+ * Format a timestamp to use as a published date
+ *
+ * @param int $timestamp Unix timestamp
+ * @return string
+ */
+ public function format_published_date($timestamp) {
+ return strftime(get_string('strftimerecentfull', 'langconfig'), $timestamp);
+ return date('j F Y, g:i a', $timestamp);
+ }
+
+ /**
+ * Format an RSS item title
+ *
+ * @param string $title
+ * @return string
+ */
+ public function format_title($title) {
+ return break_up_long_words($title, 30);
+ }
+
+ /**
+ * Format an RSS item description
+ *
+ * @param string $description
+ * @return string
+ */
+ public function format_description($description) {
+ $description = format_text($description, FORMAT_HTML, array('para' => false));
+ $description = break_up_long_words($description, 30);
+
+ return $description;
+ }
+}
diff --git a/blocks/rss_client/templates/block.mustache b/blocks/rss_client/templates/block.mustache
new file mode 100644
index 0000000000000..6cc2c71ea0770
--- /dev/null
+++ b/blocks/rss_client/templates/block.mustache
@@ -0,0 +1,91 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template block_rss_client/block
+
+ Template which defines an RSS Feeds block
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * feeds - array: An array of RSS feeds.
+
+ Example context (json):
+ {
+ "feeds": [
+ {
+ "title": "News from around my living room",
+ "image": {
+ "url": "https://www.example.com/feeds/news/poster.jpg",
+ "title": "Example News Logo",
+ "link": "https://www.example.com/feeds/news/"
+ },
+ "items": [
+ {
+ "id": "https://www.example.com/node/12",
+ "link": "https://www.example.com/my-turtle-story.html",
+ "title": "My Turtle Story",
+ "description": "This is a story about my turtle.",
+ "permalink": "https://www.example.com/my-turtle-story.html",
+ "datepublished": "11 January 2016, 7:11 pm"
+ },
+ {
+ "id": "https://www.example.com/node/12",
+ "link": "https://www.example.com/my-cat-story.html",
+ "title": "My Story",
+ "description": "This is a story about my cats.",
+ "permalink": "https://www.example.com/my-cat-story.html",
+ "datepublished": "12 January 2016, 9:12 pm"
+ }
+ ]
+ },
+ {
+ "title": "News from around my kitchen",
+ "image": {
+ "url": "https://www.example.com/feeds/news/kitchen.jpg",
+ "title": "Picture of My Kitchen",
+ "link": "https://www.example.com/feeds/news/kitchen/"
+ },
+ "items": [
+ {
+ "id": "https://www.example.com/node/10",
+ "link": "https://www.example.com/oven-smoke.html",
+ "title": "Why is the Oven Smoking?",
+ "description": "There is something smoking in the oven.",
+ "permalink": "https://www.example.com/oven-smoke.html",
+ "datepublished": "10 January 2016, 1:13 pm"
+ },
+ {
+ "id": "https://www.example.com/node/13",
+ "link": "https://www.example.com/coffee-is-good.html",
+ "title": "Why My Coffee Machine is So Great!",
+ "description": "Don't be fancy; drips are best.",
+ "permalink": "https://www.example.com/oven-smoke.html",
+ "datepublished": "13 January 2016, 8:25 pm"
+ }
+ ]
+ }
+ ]
+ }
+}}
+{{#feeds}}
+ {{> block_rss_client/feed}}
+{{/feeds}}
diff --git a/blocks/rss_client/templates/channel_image.mustache b/blocks/rss_client/templates/channel_image.mustache
new file mode 100644
index 0000000000000..f20166e53d7af
--- /dev/null
+++ b/blocks/rss_client/templates/channel_image.mustache
@@ -0,0 +1,50 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template block_rss_client/channel_image
+
+ Template which defines an item in an RSS Feed
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * url - string: The escaped URL of the image.
+ * title - string: The title of the image.
+ * link - string: Optionally, a URL to link the image to. Must be escaped.
+
+ Example context (json):
+ {
+ "url": "http://www.example.com/images/catpic.jpg",
+ "title": "A picture of my cat",
+ "link": "http://www.example.com/cat-news/"
+ }
+}}
+
diff --git a/blocks/rss_client/templates/feed.mustache b/blocks/rss_client/templates/feed.mustache
new file mode 100644
index 0000000000000..ad9ae3e29e594
--- /dev/null
+++ b/blocks/rss_client/templates/feed.mustache
@@ -0,0 +1,79 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template block_rss_client/feed
+
+ Template which defines an item in an RSS Feed
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * channel_image - object: URL, title and link for the channel image.
+ * title - string: The title of the feed.
+ * items - array: An array of feed items.
+
+ Example context (json):
+ {
+ "title": "News from around my living room",
+ "image": {
+ "url": "https://www.example.com/feeds/news/poster.jpg",
+ "title": "Example News Logo",
+ "link": "https://www.example.com/feeds/news/"
+ },
+ "feeditems": [
+ {
+ "id": "https://www.example.com/node/12",
+ "link": "https://www.example.com/my-turtle-story.html",
+ "title": "My Turtle Story",
+ "description": "This is a story about my turtle.",
+ "permalink": "https://www.example.com/my-turtle-story.html",
+ "datepublished": "11 January 2016, 7:11 pm"
+ },
+ {
+ "id": "https://www.example.com/node/12",
+ "link": "https://www.example.com/my-cat-story.html",
+ "title": "My Story",
+ "description": "This is a story about my cats.",
+ "permalink": "https://www.example.com/my-cat-story.html",
+ "datepublished": "12 January 2016, 9:12 pm"
+ }
+ ]
+ }
+}}
+{{$image}}
+ {{#image}}
+ {{> block_rss_client/channel_image}}
+ {{/image}}
+{{/image}}
+
+{{$title}}
+ {{#title}}
+ {{feedtitle}}
+ {{/title}}
+{{/title}}
+
+{{$items}}
+
+ {{#items}}
+ {{> block_rss_client/item}}
+ {{/items}}
+
+{{/items}}
diff --git a/blocks/rss_client/templates/footer.mustache b/blocks/rss_client/templates/footer.mustache
new file mode 100644
index 0000000000000..b1aa3733edf29
--- /dev/null
+++ b/blocks/rss_client/templates/footer.mustache
@@ -0,0 +1,36 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template block_rss_client/footer
+
+ Template which defines an item in an RSS Feed
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * channellink - string: The channel URL. Must be escaped.
+
+ Example context (json):
+ {
+ "channellink": "https://www.example.com/feeds/rss"
+ }
+}}
+{{#str}} clientchannellink, block_rss_client {{/str}}
diff --git a/blocks/rss_client/templates/item.mustache b/blocks/rss_client/templates/item.mustache
new file mode 100644
index 0000000000000..b21bf11f00aca
--- /dev/null
+++ b/blocks/rss_client/templates/item.mustache
@@ -0,0 +1,60 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template block_rss_client/item
+
+ Template which defines an item in an RSS Feed
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * id - string: A unique id for the feed item.
+ * link - string: The URL of the feed item. Must already be escaped.
+ * title - string: The title of the feed item.
+ * description - string: The text description of the feed item.
+ * permalink - string: The permalink of the feed item. Must already be escaped.
+ * datepublished - string: The date the feed item was published.
+
+ Example context (json):
+ {
+ "id": "https://www.example.com/node",
+ "link": "https://www.example.com/my-cat-story.html",
+ "title": "My Story",
+ "description": "This is a story about my cats.",
+ "permalink": "https://www.example.com/my-cat-story.html",
+ "datepublished": "12 January 2016, 9:12 pm"
+ }
+}}
+
+ {{$title}}
+
+ {{/title}}
+
+ {{$content}}
+ {{#description}}
+
+ {{{description}}}
+
+ {{/description}}
+ {{/content}}
+