first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Provides support for the conversion of moodle1 backup to the moodle2 format
*
* @package block_rss_client
* @copyright 2012 Paul Nicholls
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Block conversion handler for rss_client
*/
class moodle1_block_rss_client_handler extends moodle1_block_handler {
public function process_block(array $data) {
parent::process_block($data);
$instanceid = $data['id'];
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);
// Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml
// for the restore process to find
$this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");
$this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));
$this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));
$this->xmlwriter->full_tag('feeds', '');
$this->xmlwriter->end_tag('rss_client');
$this->xmlwriter->end_tag('block');
$this->close_xml_writer();
return $data;
}
}
@@ -0,0 +1,54 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* @package block_rss_client
* @subpackage backup-moodle2
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/blocks/rss_client/backup/moodle2/backup_rss_client_stepslib.php'); // We have structure steps
/**
* Specialised backup task for the rss_client block
* (has own DB structures to backup)
*
* TODO: Finish phpdocs
*/
class backup_rss_client_block_task extends backup_block_task {
protected function define_my_settings() {
}
protected function define_my_steps() {
// rss_client has one structure step
$this->add_step(new backup_rss_client_block_structure_step('rss_client_structure', 'rss_client.xml'));
}
public function get_fileareas() {
return array(); // No associated fileareas
}
public function get_configdata_encoded_attributes() {
return array(); // No special handling of configdata
}
public static function encode_content_links($content) {
return $content; // No special encoding of links
}
}
@@ -0,0 +1,83 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* @package block_rss_client
* @subpackage backup-moodle2
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Define all the backup steps that wll be used by the backup_rss_client_block_task
*/
/**
* Define the complete forum structure for backup, with file and id annotations
*/
class backup_rss_client_block_structure_step extends backup_block_structure_step {
protected function define_structure() {
global $DB;
// Get the block
$block = $DB->get_record('block_instances', array('id' => $this->task->get_blockid()));
// Extract configdata
$config = unserialize_object(base64_decode($block->configdata));
// Get array of used rss feeds
if (!empty($config->rssid)) {
$feedids = $config->rssid;
// Get the IN corresponding query
list($in_sql, $in_params) = $DB->get_in_or_equal($feedids);
// Define all the in_params as sqlparams
foreach ($in_params as $key => $value) {
$in_params[$key] = backup_helper::is_sqlparam($value);
}
}
// Define each element separated
$rss_client = new backup_nested_element('rss_client', array('id'), null);
$feeds = new backup_nested_element('feeds');
$feed = new backup_nested_element('feed', array('id'), array(
'title', 'preferredtitle', 'description', 'shared',
'url'));
// Build the tree
$rss_client->add_child($feeds);
$feeds->add_child($feed);
// Define sources
$rss_client->set_source_array(array((object)array('id' => $this->task->get_blockid())));
// Only if there are feeds
if (!empty($config->rssid)) {
$feed->set_source_sql("
SELECT *
FROM {block_rss_client}
WHERE id $in_sql", $in_params);
}
// Annotations (none)
// Return the root element (rss_client), wrapped into standard block structure
return $this->prepare_block_structure($rss_client);
}
}
@@ -0,0 +1,58 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* @package block_rss_client
* @subpackage backup-moodle2
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/blocks/rss_client/backup/moodle2/restore_rss_client_stepslib.php'); // We have structure steps
/**
* Specialised restore task for the rss_client block
* (has own DB structures to backup)
*
* TODO: Finish phpdocs
*/
class restore_rss_client_block_task extends restore_block_task {
protected function define_my_settings() {
}
protected function define_my_steps() {
// rss_client has one structure step
$this->add_step(new restore_rss_client_block_structure_step('rss_client_structure', 'rss_client.xml'));
}
public function get_fileareas() {
return array(); // No associated fileareas
}
public function get_configdata_encoded_attributes() {
return array(); // No special handling of configdata
}
public static function define_decode_contents() {
return array();
}
public static function define_decode_rules() {
return array();
}
}
@@ -0,0 +1,87 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* @package block_rss_client
* @subpackage backup-moodle2
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Define all the restore steps that wll be used by the restore_rss_client_block_task
*/
/**
* Define the complete rss_client structure for restore
*/
class restore_rss_client_block_structure_step extends restore_structure_step {
protected function define_structure() {
$paths = array();
$paths[] = new restore_path_element('block', '/block', true);
$paths[] = new restore_path_element('rss_client', '/block/rss_client');
$paths[] = new restore_path_element('feed', '/block/rss_client/feeds/feed');
return $paths;
}
public function process_block($data) {
global $DB;
$data = (object)$data;
$feedsarr = array(); // To accumulate feeds
// For any reason (non multiple, dupe detected...) block not restored, return
if (!$this->task->get_blockid()) {
return;
}
// Iterate over all the feed elements, creating them if needed
if (isset($data->rss_client['feeds']['feed'])) {
foreach ($data->rss_client['feeds']['feed'] as $feed) {
$feed = (object)$feed;
// Look if the same feed is available by url and (shared or userid)
$select = 'url = :url AND (shared = 1 OR userid = :userid)';
$params = array('url' => $feed->url, 'userid' => $this->task->get_userid());
// The feed already exists, use it
if ($feedid = $DB->get_field_select('block_rss_client', 'id', $select, $params, IGNORE_MULTIPLE)) {
$feedsarr[] = $feedid;
// The feed doesn't exist, create it
} else {
$feed->userid = $this->task->get_userid();
$feedid = $DB->insert_record('block_rss_client', $feed);
$feedsarr[] = $feedid;
}
}
}
// Adjust the serialized configdata->rssid to the created/mapped feeds
// Get the configdata
$configdata = $DB->get_field('block_instances', 'configdata', array('id' => $this->task->get_blockid()));
// Extract configdata
$config = unserialize_object(base64_decode($configdata));
// Set array of used rss feeds
$config->rssid = $feedsarr;
// Serialize back the configdata
$configdata = base64_encode(serialize($config));
// Set the configdata back
$DB->set_field('block_instances', 'configdata', $configdata, array('id' => $this->task->get_blockid()));
}
}
+304
View File
@@ -0,0 +1,304 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* 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
*
* @package block_rss_client
* @copyright Daryl Hawes
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
*/
class block_rss_client extends block_base {
/** @var bool track whether any of the output feeds have recorded failures */
private $hasfailedfeeds = false;
function init() {
$this->title = get_string('pluginname', 'block_rss_client');
}
function applicable_formats() {
return array('all' => true, 'tag' => false); // Needs work to make it work on tags MDL-11960
}
function specialization() {
// After the block has been loaded we customize the block's title display
if (!empty($this->config) && !empty($this->config->title)) {
// There is a customized block title, display it
$this->title = $this->config->title;
} else {
// No customized block title, use localized remote news feed string
$this->title = get_string('remotenewsfeed', 'block_rss_client');
}
}
/**
* 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);
}
}
if ($this->hasfailedfeeds) {
if (has_any_capability(['block/rss_client:manageownfeeds', 'block/rss_client:manageanyfeeds'], $this->context)) {
if ($footer === null) {
$footer = new block_rss_client\output\footer();
}
$manageurl = new moodle_url('/blocks/rss_client/managefeeds.php',
['courseid' => $this->page->course->id]);
$footer->set_failed($manageurl);
}
}
return $footer;
}
function get_content() {
global $CFG, $DB;
if ($this->content !== NULL) {
return $this->content;
}
// initalise block content object
$this->content = new stdClass;
$this->content->text = '';
$this->content->footer = '';
if (empty($this->instance)) {
return $this->content;
}
if (!isset($this->config)) {
// The block has yet to be configured - just display configure message in
// the block if user has permission to configure it
if (has_capability('block/rss_client:manageanyfeeds', $this->context)) {
$this->content->text = get_string('feedsconfigurenewinstance2', 'block_rss_client');
}
return $this->content;
}
// How many feed items should we display?
$maxentries = 5;
if ( !empty($this->config->shownumentries) ) {
$maxentries = intval($this->config->shownumentries);
}elseif( isset($CFG->block_rss_client_num_entries) ) {
$maxentries = intval($CFG->block_rss_client_num_entries);
}
/* ---------------------------------
* Begin Normal Display of Block Content
* --------------------------------- */
$renderer = $this->page->get_renderer('block_rss_client');
$block = new \block_rss_client\output\block();
if (!empty($this->config->rssid)) {
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;
}
foreach ($rssfeeds as $feed) {
if ($renderablefeed = $this->get_feed($feed, $maxentries, $showtitle)) {
$block->add_feed($renderablefeed);
}
}
$footer = $this->get_footer($rssfeeds);
}
}
$this->content->text = $renderer->render_block($block);
if (isset($footer)) {
$this->content->footer = $renderer->render_footer($footer);
}
return $this->content;
}
function instance_allow_multiple() {
return true;
}
function has_config() {
return true;
}
function instance_allow_config() {
return true;
}
/**
* Returns the html of a feed to be displaed in the block
*
* @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 block_rss_client\output\feed|null The renderable feed or null of there is an error
*/
public function get_feed($feedrecord, $maxentries, $showtitle) {
global $CFG;
require_once($CFG->libdir.'/simplepie/moodle_simplepie.php');
if ($feedrecord->skipuntil) {
// Last attempt to gather this feed via cron failed - do not try to fetch it now.
$this->hasfailedfeeds = true;
return null;
}
$simplepiefeed = new moodle_simplepie($feedrecord->url);
if(isset($CFG->block_rss_client_timeout)){
$simplepiefeed->set_cache_duration($CFG->block_rss_client_timeout * 60);
}
if ($simplepiefeed->error()) {
debugging($feedrecord->url .' Failed with code: '.$simplepiefeed->error());
return null;
}
if(empty($feedrecord->preferredtitle)){
// Simplepie does escape HTML entities.
$feedtitle = $this->format_title($simplepiefeed->get_title());
}else{
// Moodle custom title does not does escape HTML entities.
$feedtitle = $this->format_title(s($feedrecord->preferredtitle));
}
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);
}
$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());
}
}
}
// Feed image.
if ($imageurl = $simplepiefeed->get_image_url()) {
try {
$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) {
// 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());
}
}
return $feed;
}
/**
* Strips a large title to size and adds ... if title too long
* This function does not escape HTML entities, so they have to be escaped
* before being passed here.
*
* @param string title to shorten
* @param int max character length of title
* @return string title shortened if necessary
*/
function format_title($title,$max=64) {
if (core_text::strlen($title) <= $max) {
return $title;
} else {
return core_text::substr($title, 0, $max - 3) . '...';
}
}
/**
* Return the plugin config settings for external functions.
*
* @return stdClass the configs for both the block instance and plugin
* @since Moodle 3.8
*/
public function get_config_for_external() {
global $CFG;
// Return all settings for all users since it is safe (no private keys, etc..).
$instanceconfigs = !empty($this->config) ? $this->config : new stdClass();
$pluginconfigs = (object) [
'num_entries' => $CFG->block_rss_client_num_entries,
'timeout' => $CFG->block_rss_client_timeout
];
return (object) [
'instance' => $instanceconfigs,
'plugin' => $pluginconfigs,
];
}
}
+104
View File
@@ -0,0 +1,104 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\block
*
* @package block_rss_client
* @copyright 2015 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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;
}
}
@@ -0,0 +1,151 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\channel_image
*
* @package block_rss_client
* @copyright 2016 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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;
}
}
+224
View File
@@ -0,0 +1,224 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\feed
*
* @package block_rss_client
* @copyright 2015 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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 array
*/
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;
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\footer
*
* @package block_rss_client
* @copyright 2015 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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|null
*/
protected $channelurl;
/**
* Link to manage feeds, only provided if a feed has failed.
*
* @var \moodle_url|null
*/
protected $manageurl = null;
/**
* Constructor
*
* @param \moodle_url $channelurl (optional) The link provided in the RSS channel
*/
public function __construct($channelurl = null) {
$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;
}
/**
* Record the fact that there is at least one failed feed (and the URL for viewing
* these failed feeds).
*
* @param \moodle_url $manageurl the URL to link to for more information
*/
public function set_failed(\moodle_url $manageurl) {
$this->manageurl = $manageurl;
}
/**
* 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);
if ($this->manageurl) {
$data->hasfailedfeeds = true;
$data->manageurl = clean_param($this->manageurl, PARAM_URL);
}
return $data;
}
}
+286
View File
@@ -0,0 +1,286 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\feed
*
* @package block_rss_client
* @copyright 2015 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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'] = strip_tags($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;
}
}
@@ -0,0 +1,124 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Contains class block_rss_client\output\block_renderer_html
*
* @package block_rss_client
* @copyright 2015 Howard County Public School System
* @author Brendan Anderson <brendan_anderson@hcpss.org>
* @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 <brendan_anderson@hcpss.org>
* @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
*/
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
*/
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
*/
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
*/
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) {
if (empty($timestamp)) {
return '';
} else {
return \core_date::strftime(get_string('strftimerecentfull', 'langconfig'), $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;
}
}
@@ -0,0 +1,189 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Privacy class for requesting user data.
*
* @package block_rss_client
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_rss_client\privacy;
defined('MOODLE_INTERNAL') || die();
use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\contextlist;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\userlist;
use \core_privacy\local\request\approved_userlist;
/**
* Privacy class for requesting user data.
*
* @package block_rss_client
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider {
/**
* Returns meta data about this system.
*
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection): collection {
$collection->add_database_table('block_rss_client', [
'userid' => 'privacy:metadata:block_rss_client:userid',
'title' => 'privacy:metadata:block_rss_client:title',
'preferredtitle' => 'privacy:metadata:block_rss_client:preferredtitle',
'description' => 'privacy:metadata:block_rss_client:description',
'shared' => 'privacy:metadata:block_rss_client:shared',
'url' => 'privacy:metadata:block_rss_client:url',
'skiptime' => 'privacy:metadata:block_rss_client:skiptime',
'skipuntil' => 'privacy:metadata:block_rss_client:skipuntil',
], 'privacy:metadata:block_rss_client:tableexplanation');
return $collection;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
public static function get_contexts_for_userid(int $userid): contextlist {
$sql = "SELECT ctx.id
FROM {block_rss_client} brc
JOIN {user} u
ON brc.userid = u.id
JOIN {context} ctx
ON ctx.instanceid = u.id
AND ctx.contextlevel = :contextlevel
WHERE brc.userid = :userid";
$params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER];
$contextlist = new contextlist();
$contextlist->add_from_sql($sql, $params);
return $contextlist;
}
/**
* Get the list of users within a specific context.
*
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
*/
public static function get_users_in_context(userlist $userlist) {
$context = $userlist->get_context();
if (!$context instanceof \context_user) {
return;
}
$sql = "SELECT userid
FROM {block_rss_client}
WHERE userid = ?";
$params = [$context->instanceid];
$userlist->add_from_sql('userid', $sql, $params);
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist) {
$rssdata = [];
$results = static::get_records($contextlist->get_user()->id);
foreach ($results as $result) {
$rssdata[] = (object) [
'title' => $result->title,
'preferredtitle' => $result->preferredtitle,
'description' => $result->description,
'shared' => \core_privacy\local\request\transform::yesno($result->shared),
'url' => $result->url
];
}
if (!empty($rssdata)) {
$data = (object) [
'feeds' => $rssdata,
];
\core_privacy\local\request\writer::with_context($contextlist->current())->export_data([
get_string('pluginname', 'block_rss_client')], $data);
}
}
/**
* Delete all use data which matches the specified deletion_criteria.
*
* @param \context $context A user context.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
if ($context instanceof \context_user) {
static::delete_data($context->instanceid);
}
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
$context = $userlist->get_context();
if ($context instanceof \context_user) {
static::delete_data($context->instanceid);
}
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
static::delete_data($contextlist->get_user()->id);
}
/**
* Delete data related to a userid.
*
* @param int $userid The user ID
*/
protected static function delete_data($userid) {
global $DB;
$DB->delete_records('block_rss_client', ['userid' => $userid]);
}
/**
* Get records related to this plugin and user.
*
* @param int $userid The user ID
* @return array An array of records.
*/
protected static function get_records($userid) {
global $DB;
return $DB->get_records('block_rss_client', ['userid' => $userid]);
}
}
@@ -0,0 +1,151 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Task for updating RSS feeds for rss client block
*
* @package block_rss_client
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_rss_client\task;
defined('MOODLE_INTERNAL') || die();
/**
* Task for updating RSS feeds for rss client block
*
* @package block_rss_client
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class refreshfeeds extends \core\task\scheduled_task {
/** The maximum time in seconds that cron will wait between attempts to retry failing RSS feeds. */
const CLIENT_MAX_SKIPTIME = HOURSECS * 12;
/**
* Name for this task.
*
* @return string
*/
public function get_name() {
return get_string('refreshfeedstask', 'block_rss_client');
}
/**
* This task goes through all the feeds. If the feed has a skipuntil value
* that is less than the current time cron will attempt to retrieve it
* with the cache duration set to 0 in order to force the retrieval of
* the item and refresh the cache.
*
* If a feed fails then the skipuntil time of that feed is set to be
* later than the next expected task time. The amount of time will
* increase each time the fetch fails until the maximum is reached.
*
* If a feed that has been failing is successfully retrieved it will
* go back to being handled as though it had never failed.
*
* Task should therefore process requests for permanently broken RSS
* feeds infrequently, and temporarily unavailable feeds will be tried
* less often until they become available again.
*/
public function execute() {
global $CFG, $DB;
require_once("{$CFG->libdir}/simplepie/moodle_simplepie.php");
// We are going to measure execution times.
$starttime = microtime();
$starttimesec = time();
// Fetch all site feeds.
$rs = $DB->get_recordset('block_rss_client');
$counter = 0;
mtrace('');
foreach ($rs as $rec) {
mtrace(' ' . $rec->url . ' ', '');
// Skip feed if it failed recently.
if ($starttimesec < $rec->skipuntil) {
mtrace('skipping until ' . userdate($rec->skipuntil));
continue;
}
$feed = $this->fetch_feed($rec->url);
if ($feed->error()) {
// Skip this feed (for an ever-increasing time if it keeps failing).
$rec->skiptime = $this->calculate_skiptime($rec->skiptime);
$rec->skipuntil = time() + $rec->skiptime;
$DB->update_record('block_rss_client', $rec);
mtrace("Error: could not load/find the RSS feed - skipping for {$rec->skiptime} seconds.");
} else {
mtrace ('ok');
// It worked this time, so reset the skiptime.
if ($rec->skiptime > 0) {
$rec->skiptime = 0;
$rec->skipuntil = 0;
$DB->update_record('block_rss_client', $rec);
}
// Only increase the counter when a feed is sucesfully refreshed.
$counter ++;
}
}
$rs->close();
// Show times.
mtrace($counter . ' feeds refreshed (took ' . microtime_diff($starttime, microtime()) . ' seconds)');
}
/**
* Fetch a feed for the specified URL.
*
* @param string $url The URL to fetch
* @return \moodle_simplepie
*/
protected function fetch_feed(string $url): \moodle_simplepie {
// Fetch the rss feed, using standard simplepie caching so feeds will be renewed only if cache has expired.
\core_php_time_limit::raise(60);
$feed = new \moodle_simplepie();
// Set timeout for longer than normal to be agressive at fetching feeds if possible..
$feed->set_timeout(40);
$feed->set_cache_duration(0);
$feed->set_feed_url($url);
$feed->init();
return $feed;
}
/**
* Calculates a new skip time for a record based on the current skip time.
*
* @param int $currentskip The current skip time of a record.
* @return int The newly calculated skip time.
*/
protected function calculate_skiptime(int $currentskip): int {
// If the feed has never failed, then the initial skiptime will be 0. We use a default of 5 minutes in this case.
// If the feed has previously failed then we double that time.
$newskiptime = max(MINSECS * 5, ($currentskip * 2));
// Max out at the CLIENT_MAX_SKIPTIME.
return min($newskiptime, self::CLIENT_MAX_SKIPTIME);
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* RSS client block caps.
*
* @package block_rss_client
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/rss_client:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/rss_client:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/rss_client:manageownfeeds' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'block/rss_client:manageanyfeeds' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'manager' => CAP_ALLOW
)
)
);
+33
View File
@@ -0,0 +1,33 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* RSS client block installation.
*
* @package block_rss_client
* @copyright 2021 Amaia Anabitarte <amaia@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Perform the post-install procedures.
*/
function xmldb_block_rss_client_install() {
global $DB;
// Disable rss_client on new installs by default.
$DB->set_field('block', 'visible', 0, ['name' => 'rss_client']);
}
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="blocks/rss_client/db" VERSION="20150717" COMMENT="XMLDB file for Moodle rss_client block"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="block_rss_client" COMMENT="Remote news feed information. Contains the news feed id, the userid of the user who added the feed, the title of the feed itself and a description of the feed contents along with the url used to access the remote feed. Preferredtitle is a field for future use - intended to allow for custom titles rather than those found in the feed">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="title" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="preferredtitle" TYPE="char" LENGTH="64" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="shared" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="url" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="skiptime" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="How many seconds skip this feed for (increases every time it fails, resets to 0 when it succeeds)"/>
<FIELD NAME="skipuntil" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Do not query this RSS feed again until this time"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
+39
View File
@@ -0,0 +1,39 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Task definition for block_rss_client.
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @package block_rss_client
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$tasks = array(
array(
'classname' => '\block_rss_client\task\refreshfeeds',
'blocking' => 0,
'minute' => '*/5',
'hour' => '*',
'day' => '*',
'month' => '*',
'dayofweek' => '*',
'disabled' => 0
)
);
+45
View File
@@ -0,0 +1,45 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Database upgrades for the RSS block.
*
* @package block_rss_client
* @copyright 2014 Davo Smith
* @author Neill Magill <neill.magill@nottingham.ac.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
*/
/**
* Upgrade the block_rss_client database.
*
* @param int $oldversion The version number of the plugin that was installed.
* @return boolean
*/
function xmldb_block_rss_client_upgrade($oldversion) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+101
View File
@@ -0,0 +1,101 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Form for editing RSS client block instances.
*
* @package block_rss_client
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Form for editing RSS client block instances.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_rss_client_edit_form extends block_edit_form {
protected function specific_definition($mform) {
global $CFG, $DB, $USER;
// Fields for editing block contents.
$mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
$mform->addElement('selectyesno', 'config_display_description', get_string('displaydescriptionlabel', 'block_rss_client'));
$mform->setDefault('config_display_description', 0);
$mform->addElement('text', 'config_shownumentries', get_string('shownumentrieslabel', 'block_rss_client'), array('size' => 5));
$mform->setType('config_shownumentries', PARAM_INT);
$mform->addRule('config_shownumentries', null, 'numeric', null, 'client');
if (!empty($CFG->block_rss_client_num_entries)) {
$mform->setDefault('config_shownumentries', $CFG->block_rss_client_num_entries);
} else {
$mform->setDefault('config_shownumentries', 5);
}
$insql = '';
$params = array('userid' => $USER->id);
if (!empty($this->block->config) && !empty($this->block->config->rssid)) {
list($insql, $inparams) = $DB->get_in_or_equal($this->block->config->rssid, SQL_PARAMS_NAMED);
$insql = "OR id $insql ";
$params += $inparams;
}
$titlesql = "CASE WHEN {$DB->sql_isempty('block_rss_client','preferredtitle', false, false)}
THEN {$DB->sql_compare_text('title', 64)} ELSE preferredtitle END";
$rssfeeds = $DB->get_records_sql_menu("
SELECT id, $titlesql
FROM {block_rss_client}
WHERE userid = :userid OR shared = 1 $insql
ORDER BY $titlesql",
$params);
if ($rssfeeds) {
$select = $mform->addElement('select', 'config_rssid', get_string('choosefeedlabel', 'block_rss_client'), $rssfeeds);
$select->setMultiple(true);
} else {
$mform->addElement('static', 'config_rssid_no_feeds', get_string('choosefeedlabel', 'block_rss_client'),
get_string('nofeeds', 'block_rss_client'));
}
if (has_any_capability(array('block/rss_client:manageanyfeeds', 'block/rss_client:manageownfeeds'), $this->block->context)) {
$mform->addElement('static', 'nofeedmessage', '',
'<a href="' . $CFG->wwwroot . '/blocks/rss_client/managefeeds.php?courseid=' . $this->page->course->id . '">' .
get_string('feedsaddedit', 'block_rss_client') . '</a>');
}
$mform->addElement('text', 'config_title', get_string('uploadlabel'));
$mform->setType('config_title', PARAM_NOTAGS);
$mform->addElement('selectyesno', 'config_block_rss_client_show_channel_link', get_string('clientshowchannellinklabel', 'block_rss_client'));
$mform->setDefault('config_block_rss_client_show_channel_link', 0);
$mform->addElement('selectyesno', 'config_block_rss_client_show_channel_image', get_string('clientshowimagelabel', 'block_rss_client'));
$mform->setDefault('config_block_rss_client_show_channel_image', 0);
}
/**
* Display the configuration form when block is being added to the page
*
* @return bool
*/
public static function display_form_when_adding(): bool {
return true;
}
}
+232
View File
@@ -0,0 +1,232 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Script to let a user edit the properties of a particular RSS feed.
*
* @package block_rss_client
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->libdir .'/simplepie/moodle_simplepie.php');
class feed_edit_form extends moodleform {
protected $isadding;
protected $caneditshared;
protected $title = '';
protected $description = '';
function __construct($actionurl, $isadding, $caneditshared) {
$this->isadding = $isadding;
$this->caneditshared = $caneditshared;
parent::__construct($actionurl);
}
function definition() {
$mform =& $this->_form;
// Then show the fields about where this block appears.
$mform->addElement('header', 'rsseditfeedheader', get_string('feed', 'block_rss_client'));
$mform->addElement('text', 'url', get_string('feedurl', 'block_rss_client'), array('size' => 60));
$mform->setType('url', PARAM_URL);
$mform->addRule('url', null, 'required');
$mform->addElement('checkbox', 'autodiscovery', get_string('enableautodiscovery', 'block_rss_client'));
$mform->setDefault('autodiscovery', 1);
$mform->setAdvanced('autodiscovery');
$mform->addHelpButton('autodiscovery', 'enableautodiscovery', 'block_rss_client');
$mform->addElement('text', 'preferredtitle', get_string('customtitlelabel', 'block_rss_client'), array('size' => 60));
$mform->setType('preferredtitle', PARAM_NOTAGS);
if ($this->caneditshared) {
$mform->addElement('selectyesno', 'shared', get_string('sharedfeed', 'block_rss_client'));
$mform->setDefault('shared', 0);
}
$submitlabal = null; // Default
if ($this->isadding) {
$submitlabal = get_string('addnewfeed', 'block_rss_client');
}
$this->add_action_buttons(true, $submitlabal);
}
function definition_after_data(){
$mform =& $this->_form;
if($mform->getElementValue('autodiscovery')){
$mform->applyFilter('url', 'feed_edit_form::autodiscover_feed_url');
}
}
function validation($data, $files) {
$errors = parent::validation($data, $files);
$rss = new moodle_simplepie();
// set timeout for longer than normal to try and grab the feed
$rss->set_timeout(10);
$rss->set_feed_url($data['url']);
$rss->set_autodiscovery_cache_duration(0);
$rss->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE);
$rss->init();
if ($rss->error()) {
$errors['url'] = get_string('couldnotfindloadrssfeed', 'block_rss_client');
} else {
$this->title = $rss->get_title();
$this->description = $rss->get_description();
}
return $errors;
}
function get_data() {
$data = parent::get_data();
if ($data) {
$data->title = '';
$data->description = '';
if($this->title){
$data->title = $this->title;
}
if($this->description){
$data->description = $this->description;
}
}
return $data;
}
/**
* Autodiscovers a feed url from a given url, to be used by the formslibs
* filter function
*
* Uses simplepie with autodiscovery set to maximum level to try and find
* a feed to subscribe to.
* See: http://simplepie.org/wiki/reference/simplepie/set_autodiscovery_level
*
* @param string URL to autodiscover a url
* @return string URL of feed or original url if none found
*/
public static function autodiscover_feed_url($url){
$rss = new moodle_simplepie();
$rss->set_feed_url($url);
$rss->set_autodiscovery_level(SIMPLEPIE_LOCATOR_ALL);
// When autodiscovering an RSS feed, simplepie will try lots of
// rss links on a page, so set the timeout high
$rss->set_timeout(20);
$rss->init();
if($rss->error()){
return $url;
}
// return URL without quoting..
$discoveredurl = new moodle_url($rss->subscribe_url());
return $discoveredurl->out(false);
}
}
$returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
$courseid = optional_param('courseid', 0, PARAM_INT);
$rssid = optional_param('rssid', 0, PARAM_INT); // 0 mean create new.
if ($courseid == SITEID) {
$courseid = 0;
}
if ($courseid) {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$PAGE->set_course($course);
$context = $PAGE->context;
} else {
$context = context_system::instance();
$PAGE->set_context($context);
}
$managesharedfeeds = has_capability('block/rss_client:manageanyfeeds', $context);
if (!$managesharedfeeds) {
require_capability('block/rss_client:manageownfeeds', $context);
}
$urlparams = array('rssid' => $rssid);
if ($courseid) {
$urlparams['courseid'] = $courseid;
}
if ($returnurl) {
$urlparams['returnurl'] = $returnurl;
}
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->set_url('/blocks/rss_client/editfeed.php', $urlparams);
$PAGE->set_pagelayout('admin');
if ($rssid) {
$isadding = false;
$rssrecord = $DB->get_record('block_rss_client', array('id' => $rssid), '*', MUST_EXIST);
} else {
$isadding = true;
$rssrecord = new stdClass;
}
$mform = new feed_edit_form($PAGE->url, $isadding, $managesharedfeeds);
$mform->set_data($rssrecord);
if ($mform->is_cancelled()) {
redirect($managefeeds);
} else if ($data = $mform->get_data()) {
$data->userid = $USER->id;
if (!$managesharedfeeds) {
$data->shared = 0;
}
if ($isadding) {
$DB->insert_record('block_rss_client', $data);
} else {
$data->id = $rssid;
$DB->update_record('block_rss_client', $data);
}
redirect($managefeeds);
} else {
if ($isadding) {
$strtitle = get_string('addnewfeed', 'block_rss_client');
} else {
$strtitle = get_string('editafeed', 'block_rss_client');
}
$PAGE->set_title($strtitle);
$PAGE->set_heading($strtitle);
$PAGE->navbar->add(get_string('blocks'));
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds );
$PAGE->navbar->add($strtitle);
echo $OUTPUT->header();
echo $OUTPUT->heading($strtitle, 2);
$mform->display();
echo $OUTPUT->footer();
}
@@ -0,0 +1,91 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Strings for component 'block_rss_client', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_rss_client
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['addfeed'] = 'Add RSS feed URL';
$string['addheadlineblock'] = 'Add RSS headline block';
$string['addnew'] = 'Add new';
$string['addnewfeed'] = 'Add a new feed';
$string['cannotmakemodification'] = 'You are not allowed to make modifications to this RSS feed at this time.';
$string['clientchannellink'] = 'Source site...';
$string['clientnumentries'] = 'The default number of entries to show per feed.';
$string['clientshowchannellinklabel'] = 'Should a link to the original site (channel link) be displayed? (Note that if no feed link is supplied in the news feed then no link will be shown) :';
$string['clientshowimagelabel'] = 'Show channel image if available';
$string['configblock'] = 'Configure this block';
$string['couldnotfindfeed'] = 'Could not find feed with ID.';
$string['couldnotfindloadrssfeed'] = 'Could not find or load the RSS feed.';
$string['customtitlelabel'] = 'Custom title (leave blank to use title supplied by feed)';
$string['deletefeedconfirm'] = 'Are you sure you want to delete this feed?';
$string['disabledrssfeeds'] = 'RSS feeds are disabled';
$string['displaydescriptionlabel'] = 'Display each link\'s description?';
$string['editafeed'] = 'Edit a feed';
$string['editfeeds'] = 'Edit, subscribe or unsubscribe from RSS feeds';
$string['editnewsfeeds'] = 'Edit news feeds';
$string['editrssblock'] = 'Edit RSS headline block';
$string['enableautodiscovery'] = 'Enable auto-discovery of feeds?';
$string['enableautodiscovery_help'] = 'If enabled, feeds on web pages are found automatically. For example, if https://docs.moodle.org is entered, then https://docs.moodle.org/en/index.php?title=Special:RecentChanges&feed=rss would be found.';
$string['failedfeed'] = 'Feed failed to download - will retry after {$a}';
$string['failedfeeds'] = 'One or more RSS feeds have failed';
$string['feed'] = 'Feed';
$string['feedadded'] = 'RSS feed added';
$string['feeddeleted'] = 'RSS feed deleted';
$string['feeds'] = 'RSS feeds';
$string['feedsaddedit'] = 'Add/edit feeds';
$string['feedsconfigurenewinstance'] = 'Click here to configure this block to display RSS feeds.';
$string['feedsconfigurenewinstance2'] = 'Click the edit icon above to configure this block to display RSS feeds.';
$string['feedupdated'] = 'RSS feed updated';
$string['feedurl'] = 'Feed URL';
$string['findmorefeeds'] = 'Find more RSS feeds';
$string['choosefeedlabel'] = 'Choose the feeds which you would like to make available in this block:';
$string['managefeeds'] = 'Manage RSS feeds';
$string['nofeeds'] = 'There are no RSS feeds defined for this site.';
$string['numentries'] = 'Entries per feed';
$string['pickfeed'] = 'Pick a RSS feed';
$string['pluginname'] = 'RSS feeds';
$string['privacy:metadata:block_rss_client:description'] = 'The description of the RSS feed.';
$string['privacy:metadata:block_rss_client:preferredtitle'] = 'The preferred (custom) title of the RSS feed.';
$string['privacy:metadata:block_rss_client:shared'] = 'If the RSS feed is available to all courses.';
$string['privacy:metadata:block_rss_client:skiptime'] = 'The defined time in seconds that the cron will wait between attempts to retry failing RSS feeds.';
$string['privacy:metadata:block_rss_client:skipuntil'] = 'The maximum defined time that the cron will attempt to open failing RSS feeds.';
$string['privacy:metadata:block_rss_client:tableexplanation'] = 'RSS block information is stored here.';
$string['privacy:metadata:block_rss_client:title'] = 'The title of the RSS feed.';
$string['privacy:metadata:block_rss_client:url'] = 'The URL of the RSS feed.';
$string['privacy:metadata:block_rss_client:userid'] = 'The ID of the user that added the RSS feed.';
$string['remotenewsfeed'] = 'RSS feed';
$string['refreshfeedstask'] = 'Refresh RSS feeds task';
$string['rss_client:addinstance'] = 'Add new RSS feeds block';
$string['rss_client:createprivatefeeds'] = 'Create private RSS feeds';
$string['rss_client:createsharedfeeds'] = 'Create shared RSS feeds';
$string['rss_client:manageanyfeeds'] = 'Manage any RSS feeds';
$string['rss_client:manageownfeeds'] = 'Manage own RSS feeds';
$string['rss_client:myaddinstance'] = 'Add new RSS feeds block to Dashboard';
$string['seeallfeeds'] = 'See all feeds';
$string['sharedfeed'] = 'Shared feed';
$string['shownumentrieslabel'] = 'Max number entries to show per block.';
$string['submitters'] = 'Who will be allowed to define new RSS feeds? Defined feeds are available for any page on your site.';
$string['submitters2'] = 'Submitters';
$string['timeout'] = 'Time in minutes before an RSS feed expires in cache. Note that this time defines the minimum time before expiry; the feed will be refreshed in cache on the next cron execution after expiry. Recommended values are 30 mins or greater.';
$string['timeoutdesc'] = 'Time in minutes for an RSS feed to live in cache.';
$string['timeout2'] = 'Timeout';
$string['updatefeed'] = 'Update RSS feed URL';
$string['viewfeed'] = 'View feed';
+147
View File
@@ -0,0 +1,147 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Script to let a user manage their RSS feeds.
*
* @package block_rss_client
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/tablelib.php');
require_login();
$returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
$courseid = optional_param('courseid', 0, PARAM_INT);
$deleterssid = optional_param('deleterssid', 0, PARAM_INT);
if ($courseid == SITEID) {
$courseid = 0;
}
if ($courseid) {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$PAGE->set_course($course);
$context = $PAGE->context;
} else {
$context = context_system::instance();
$PAGE->set_context($context);
}
$managesharedfeeds = has_capability('block/rss_client:manageanyfeeds', $context);
if (!$managesharedfeeds) {
require_capability('block/rss_client:manageownfeeds', $context);
}
$urlparams = array();
$extraparams = '';
if ($courseid) {
$urlparams['courseid'] = $courseid;
$extraparams = '&courseid=' . $courseid;
}
if ($returnurl) {
$urlparams['returnurl'] = $returnurl;
$extraparams = '&returnurl=' . $returnurl;
}
$baseurl = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->set_url($baseurl);
// Process any actions
if ($deleterssid && confirm_sesskey()) {
$DB->delete_records('block_rss_client', array('id'=>$deleterssid));
redirect($PAGE->url, get_string('feeddeleted', 'block_rss_client'));
}
// Display the list of feeds.
if ($managesharedfeeds) {
$select = '(userid = ' . $USER->id . ' OR shared = 1)';
} else {
$select = 'userid = ' . $USER->id;
}
$feeds = $DB->get_records_select('block_rss_client', $select, null, $DB->sql_order_by_text('title'));
$strmanage = get_string('managefeeds', 'block_rss_client');
$PAGE->set_pagelayout('standard');
$PAGE->set_title($strmanage);
$PAGE->set_heading($strmanage);
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->navbar->add(get_string('blocks'));
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
echo $OUTPUT->header();
$table = new flexible_table('rss-display-feeds');
$table->define_columns(array('feed', 'actions'));
$table->define_headers(array(get_string('feed', 'block_rss_client'), get_string('actions', 'moodle')));
$table->define_baseurl($baseurl);
$table->set_attribute('cellspacing', '0');
$table->set_attribute('id', 'rssfeeds');
$table->set_attribute('class', 'generaltable generalbox');
$table->column_class('feed', 'feed');
$table->column_class('actions', 'actions');
$table->setup();
foreach($feeds as $feed) {
if (!empty($feed->preferredtitle)) {
$feedtitle = s($feed->preferredtitle);
} else {
$feedtitle = $feed->title;
}
$viewlink = html_writer::link($CFG->wwwroot .'/blocks/rss_client/viewfeed.php?rssid=' . $feed->id . $extraparams, $feedtitle);
$feedinfo = '<div class="title">' . $viewlink . '</div>' .
'<div class="url">' . html_writer::link($feed->url, $feed->url) .'</div>' .
'<div class="description">' . $feed->description . '</div>';
if ($feed->skipuntil) {
$skipuntil = userdate($feed->skipuntil, get_string('strftimedatetime', 'langconfig'));
$skipmsg = get_string('failedfeed', 'block_rss_client', $skipuntil);
$notification = new \core\output\notification($skipmsg, 'error');
$notification->set_show_closebutton(false);
$feedinfo .= $OUTPUT->render($notification);
}
$editurl = new moodle_url('/blocks/rss_client/editfeed.php?rssid=' . $feed->id . $extraparams);
$editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')));
$deleteurl = new moodle_url('/blocks/rss_client/managefeeds.php?deleterssid=' . $feed->id . '&sesskey=' . sesskey() . $extraparams);
$deleteicon = new pix_icon('t/delete', get_string('delete'));
$deleteaction = $OUTPUT->action_icon($deleteurl, $deleteicon, new confirm_action(get_string('deletefeedconfirm', 'block_rss_client')));
$feedicons = $editaction . ' ' . $deleteaction;
$table->add_data(array($feedinfo, $feedicons));
}
$table->print_html();
$url = $CFG->wwwroot . '/blocks/rss_client/editfeed.php?' . substr($extraparams, 1);
echo '<div class="actionbuttons">' . $OUTPUT->single_button($url, get_string('addnewfeed', 'block_rss_client'), 'get') . '</div>';
if ($returnurl) {
echo '<div class="backlink">' . html_writer::link($returnurl, get_string('back')) . '</div>';
}
echo $OUTPUT->footer();
+36
View File
@@ -0,0 +1,36 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Settings for the RSS client block.
*
* @package block_rss_client
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configtext('block_rss_client_num_entries', get_string('numentries', 'block_rss_client'),
get_string('clientnumentries', 'block_rss_client'), 5, PARAM_INT));
$settings->add(new admin_setting_configtext('block_rss_client_timeout', get_string('timeout2', 'block_rss_client'),
get_string('timeout', 'block_rss_client'), 30, PARAM_INT));
$link ='<a href="'.$CFG->wwwroot.'/blocks/rss_client/managefeeds.php">'.get_string('feedsaddedit', 'block_rss_client').'</a>';
$settings->add(new admin_setting_heading('block_rss_addheading', '', $link));
}
+10
View File
@@ -0,0 +1,10 @@
/* RSS Feeds
-------------------------*/
.block_rss_client .list li:first-child {
border-top-width: 0;
}
.block_rss_client .list li {
border-top: 1px solid;
padding: 5px;
}
@@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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}}
@@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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/"
}
}}
<div class="image" title="{{title}}">
{{#link}}
<a href="{{{link}}}">
{{/link}}
<img src="{{{url}}}" alt="{{title}}" />
{{#link}}
</a>
{{/link}}
</div>
+79
View File
@@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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}}
<div class="title">{{title}}</div>
{{/title}}
{{/title}}
{{$items}}
<ul class="list no-overflow">
{{#items}}
{{> block_rss_client/item}}
{{/items}}
</ul>
{{/items}}
@@ -0,0 +1,42 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
}}
{{#channellink}}
<a href="{{{channellink}}}">{{#str}} clientchannellink, block_rss_client {{/str}}</a>
{{#hasfailedfeeds}}<br>{{/hasfailedfeeds}}
{{/channellink}}
{{#hasfailedfeeds}}
<a href="{{{manageurl}}}">{{#str}} failedfeeds, block_rss_client {{/str}}</a>
{{/hasfailedfeeds}}
+63
View File
@@ -0,0 +1,63 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
}}
<li class="py-3">
{{$title}}
<div class="link">
<a href="{{{link}}}" onclick='this.target="_blank"'>{{title}}</a>
</div>
{{/title}}
{{$content}}
{{#description}}
<div class="date text-muted muted mb-1">
<small>{{{datepublished}}}</small>
</div>
<div class="description">
{{{description}}}
</div>
{{/description}}
{{/content}}
</li>
+135
View File
@@ -0,0 +1,135 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
namespace block_rss_client;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../../moodleblock.class.php');
require_once(__DIR__ . '/../block_rss_client.php');
/**
* PHPunit tests for rss client cron.
*
* @package block_rss_client
* @copyright 2015 Universit of Nottingham
* @author Neill Magill <neill.magill@nottingham.ac.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cron_test extends \advanced_testcase {
/**
* Test that when a record has a skipuntil time that is greater
* than the current time the attempt is skipped.
*/
public function test_skip(): void {
global $DB, $CFG;
$this->resetAfterTest();
// Create a RSS feed record with a skip until time set to the future.
$record = (object) array(
'userid' => 1,
'title' => 'Skip test feed',
'preferredtitle' => '',
'description' => 'A feed to test the skip time.',
'shared' => 0,
'url' => 'http://example.com/rss',
'skiptime' => 330,
'skipuntil' => time() + 300,
);
$DB->insert_record('block_rss_client', $record);
$task = new \block_rss_client\task\refreshfeeds();
ob_start();
// Silence SimplePie php notices.
$errorlevel = error_reporting($CFG->debug & ~E_USER_NOTICE);
$task->execute();
error_reporting($errorlevel);
$cronoutput = ob_get_clean();
$this->assertStringContainsString('skipping until ' . userdate($record->skipuntil), $cronoutput);
$this->assertStringContainsString('0 feeds refreshed (took ', $cronoutput);
}
/**
* Data provider for skip time tests.
*
* @return array
*/
public function skip_time_increase_provider(): array {
return [
'Never failed' => [
'skiptime' => 0,
'skipuntil' => 0,
'newvalue' => MINSECS * 5,
],
'Failed before' => [
// This should just double the time.
'skiptime' => 330,
'skipuntil' => time(),
'newvalue' => 660,
],
'Near max' => [
'skiptime' => \block_rss_client\task\refreshfeeds::CLIENT_MAX_SKIPTIME - 5,
'skipuntil' => time(),
'newvalue' => \block_rss_client\task\refreshfeeds::CLIENT_MAX_SKIPTIME,
],
];
}
/**
* Test that when a feed has an error the skip time is increased correctly.
*
* @dataProvider skip_time_increase_provider
*/
public function test_error($skiptime, $skipuntil, $newvalue): void {
global $DB, $CFG;
$this->resetAfterTest();
require_once("{$CFG->libdir}/simplepie/moodle_simplepie.php");
$time = time();
// A record that has failed before.
$record = (object) [
'userid' => 1,
'title' => 'Skip test feed',
'preferredtitle' => '',
'description' => 'A feed to test the skip time.',
'shared' => 0,
'url' => 'http://example.com/rss',
'skiptime' => $skiptime,
'skipuntil' => $skipuntil,
];
$record->id = $DB->insert_record('block_rss_client', $record);
// Run the scheduled task and have it fail.
$task = $this->getMockBuilder(\block_rss_client\task\refreshfeeds::class)
->onlyMethods(['fetch_feed'])
->getMock();
$piemock = $this->getMockBuilder(\moodle_simplepie::class)
->onlyMethods(['error'])
->getMock();
$piemock->method('error')
->willReturn(true);
$task->method('fetch_feed')
->willReturn($piemock);
// Run the cron and capture its output.
$this->expectOutputRegex("/.*Error: could not load\/find the RSS feed - skipping for {$newvalue} seconds.*/");
$task->execute();
}
}
@@ -0,0 +1,238 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Base class for unit tests for block_rss_client.
*
* @package block_rss_client
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_rss_client\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\tests\provider_testcase;
use block_rss_client\privacy\provider;
use core_privacy\local\request\approved_userlist;
/**
* Unit tests for blocks\rss_client\classes\privacy\provider.php
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider_test extends provider_testcase {
/**
* Basic setup for these tests.
*/
public function setUp(): void {
$this->resetAfterTest(true);
}
/**
* Test getting the context for the user ID related to this plugin.
*/
public function test_get_contexts_for_userid(): void {
$user = $this->getDataGenerator()->create_user();
$context = \context_user::instance($user->id);
$this->add_rss_feed($user);
$contextlist = provider::get_contexts_for_userid($user->id);
$this->assertEquals($context, $contextlist->current());
}
/**
* Test that data is exported correctly for this plugin.
*/
public function test_export_user_data(): void {
$user = $this->getDataGenerator()->create_user();
$context = \context_user::instance($user->id);
$this->add_rss_feed($user);
$this->add_rss_feed($user);
$writer = \core_privacy\local\request\writer::with_context($context);
$this->assertFalse($writer->has_any_data());
$this->export_context_data_for_user($user->id, $context, 'block_rss_client');
$data = $writer->get_data([get_string('pluginname', 'block_rss_client')]);
$this->assertCount(2, $data->feeds);
$feed1 = reset($data->feeds);
$this->assertEquals('BBC News - World', $feed1->title);
$this->assertEquals('World News', $feed1->preferredtitle);
$this->assertEquals('Description: BBC News - World', $feed1->description);
$this->assertEquals(get_string('no'), $feed1->shared);
$this->assertEquals('http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk', $feed1->url);
}
/**
* Test that only users within a course context are fetched.
*/
public function test_get_users_in_context(): void {
$component = 'block_rss_client';
// Create a user.
$user = $this->getDataGenerator()->create_user();
$usercontext = \context_user::instance($user->id);
$userlist = new \core_privacy\local\request\userlist($usercontext, $component);
provider::get_users_in_context($userlist);
$this->assertCount(0, $userlist);
$this->add_rss_feed($user);
// The list of users within the user context should contain user.
provider::get_users_in_context($userlist);
$this->assertCount(1, $userlist);
$expected = [$user->id];
$actual = $userlist->get_userids();
$this->assertEquals($expected, $actual);
// The list of users within the system context should be empty.
$systemcontext = \context_system::instance();
$userlist2 = new \core_privacy\local\request\userlist($systemcontext, $component);
provider::get_users_in_context($userlist2);
$this->assertCount(0, $userlist2);
}
/**
* Test that data for users in approved userlist is deleted.
*/
public function test_delete_data_for_users(): void {
$component = 'block_rss_client';
$user1 = $this->getDataGenerator()->create_user();
$usercontext1 = \context_user::instance($user1->id);
$user2 = $this->getDataGenerator()->create_user();
$usercontext2 = \context_user::instance($user2->id);
$this->add_rss_feed($user1);
$this->add_rss_feed($user2);
$userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
provider::get_users_in_context($userlist1);
$this->assertCount(1, $userlist1);
$expected = [$user1->id];
$actual = $userlist1->get_userids();
$this->assertEquals($expected, $actual);
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
$this->assertCount(1, $userlist2);
$expected = [$user2->id];
$actual = $userlist2->get_userids();
$this->assertEquals($expected, $actual);
// Convert $userlist1 into an approved_contextlist.
$approvedlist1 = new approved_userlist($usercontext1, $component, $userlist1->get_userids());
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist1);
// Re-fetch users in usercontext1.
$userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
provider::get_users_in_context($userlist1);
// The user data in usercontext1 should be deleted.
$this->assertCount(0, $userlist1);
// Re-fetch users in usercontext2.
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
// The user data in usercontext2 should be still present.
$this->assertCount(1, $userlist2);
// Convert $userlist2 into an approved_contextlist in the system context.
$systemcontext = \context_system::instance();
$approvedlist2 = new approved_userlist($systemcontext, $component, $userlist2->get_userids());
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist2);
// Re-fetch users in usercontext2.
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
// The user data in systemcontext should not be deleted.
$this->assertCount(1, $userlist2);
}
/**
* Test that user data is deleted using the context.
*/
public function test_delete_data_for_all_users_in_context(): void {
global $DB;
$user = $this->getDataGenerator()->create_user();
$context = \context_user::instance($user->id);
$this->add_rss_feed($user);
// Check that we have an entry.
$rssfeeds = $DB->get_records('block_rss_client', ['userid' => $user->id]);
$this->assertCount(1, $rssfeeds);
provider::delete_data_for_all_users_in_context($context);
// Check that it has now been deleted.
$rssfeeds = $DB->get_records('block_rss_client', ['userid' => $user->id]);
$this->assertCount(0, $rssfeeds);
}
/**
* Test that user data is deleted for this user.
*/
public function test_delete_data_for_user(): void {
global $DB;
$user = $this->getDataGenerator()->create_user();
$context = \context_user::instance($user->id);
$this->add_rss_feed($user);
// Check that we have an entry.
$rssfeeds = $DB->get_records('block_rss_client', ['userid' => $user->id]);
$this->assertCount(1, $rssfeeds);
$approvedlist = new \core_privacy\local\request\approved_contextlist($user, 'block_rss_feed',
[$context->id]);
provider::delete_data_for_user($approvedlist);
// Check that it has now been deleted.
$rssfeeds = $DB->get_records('block_rss_client', ['userid' => $user->id]);
$this->assertCount(0, $rssfeeds);
}
/**
* Add dummy rss feed.
*
* @param object $user User object
*/
private function add_rss_feed($user) {
global $DB;
$rssfeeddata = array(
'userid' => $user->id,
'title' => 'BBC News - World',
'preferredtitle' => 'World News',
'description' => 'Description: BBC News - World',
'shared' => 0,
'url' => 'http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk',
);
$DB->insert_record('block_rss_client', $rssfeeddata);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package block_rss_client
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_rss_client'; // Full name of the plugin (used for diagnostics)
+99
View File
@@ -0,0 +1,99 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Script to let a user edit the properties of a particular RSS feed.
*
* @package block_rss_client
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir .'/simplepie/moodle_simplepie.php');
require_login();
if (isguestuser()) {
throw new \moodle_exception('guestsarenotallowed');
}
$returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
$courseid = optional_param('courseid', 0, PARAM_INT);
$rssid = required_param('rssid', PARAM_INT);
if ($courseid = SITEID) {
$courseid = 0;
}
if ($courseid) {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$PAGE->set_course($course);
$context = $PAGE->context;
} else {
$context = context_system::instance();
$PAGE->set_context($context);
}
$urlparams = array('rssid' => $rssid);
if ($courseid) {
$urlparams['courseid'] = $courseid;
}
if ($returnurl) {
$urlparams['returnurl'] = $returnurl;
}
$PAGE->set_url('/blocks/rss_client/viewfeed.php', $urlparams);
$PAGE->set_pagelayout('popup');
$rssrecord = $DB->get_record('block_rss_client', array('id' => $rssid), '*', MUST_EXIST);
$rss = new moodle_simplepie($rssrecord->url);
if ($rss->error()) {
debugging($rss->error());
throw new \moodle_exception('errorfetchingrssfeed');
}
$strviewfeed = get_string('viewfeed', 'block_rss_client');
$PAGE->set_title($strviewfeed);
$PAGE->set_heading($strviewfeed);
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->navbar->add(get_string('blocks'));
$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
$PAGE->navbar->add($strviewfeed);
echo $OUTPUT->header();
if (!empty($rssrecord->preferredtitle)) {
$feedtitle = $rssrecord->preferredtitle;
} else {
$feedtitle = $rss->get_title();
}
echo '<table align="center" width="50%" cellspacing="1">'."\n";
echo '<tr><td colspan="2"><strong>'. s($feedtitle) .'</strong></td></tr>'."\n";
foreach ($rss->get_items() as $item) {
echo '<tr><td valign="middle">'."\n";
echo '<a href="'.$item->get_link().'" target="_blank"><strong>';
echo s($item->get_title());
echo '</strong></a>'."\n";
echo '</td>'."\n";
echo '</tr>'."\n";
echo '<tr><td colspan="2"><small>';
echo format_text($item->get_description(), FORMAT_HTML) .'</small></td></tr>'."\n";
}
echo '</table>'."\n";
echo $OUTPUT->footer();