diff --git a/.travis.yml b/.travis.yml index 8a255b5..b52b493 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ cache: php: - 7.2 - 7.4 + - 8.0 env: matrix: diff --git a/block_rss_thumbnails.php b/block_rss_thumbnails.php index 65b2e17..03948bb 100644 --- a/block_rss_thumbnails.php +++ b/block_rss_thumbnails.php @@ -91,10 +91,19 @@ public function init(?int $carousseldelay = null): void { public function get_content() { global $DB; + if ($this->content != null && !empty($this->content->text)) { + return $this->content; + } + $this->page->requires->css( new moodle_url('/blocks/rss_thumbnails/js/glide/dist/css/glide.core' . (debugging() ? '.min' : '') . '.css')); + if (!$this->config_is_valid()) { + $this->content->text = get_string("invalidconfig", "block_rss_thumbnails"); + 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. @@ -106,11 +115,6 @@ public function get_content() { return $this->content; } - // We need this if an user deletes a field in the configuration of the block. - $this->title = $this->config->title ?? self::DEFAULT_TITLE; - $this->carousseldelay = $this->config->carousseldelay ?? self::DEFAULT_CAROUSSEL_DELAY; - $this->maxentries = $this->config->numentries ?? self::DEFAULT_MAX_ENTRIES; - $block = new block($this->get_carousseldelay()); if (!empty($this->config->rssid)) { @@ -215,4 +219,25 @@ public function format_title($title, $max = 64): string { public function get_carousseldelay(): int { return $this->carousseldelay; } + + /** + * Checks wether the configuration of the block is valid or not. + * + * @return bool true if the configuration of the block is valid, false if it's not. + */ + public function config_is_valid(): bool { + if (empty($this->config)) { + return false; + } + if (!is_integer($this->config->carousseldelay)) { + return false; + } + if (!is_integer($this->config->numentries)) { + return false; + } + if (!$this->config->title) { + return false; + } + return true; + } } diff --git a/classes/form/feed_edit.php b/classes/form/feed_edit.php new file mode 100644 index 0000000..129cdd0 --- /dev/null +++ b/classes/form/feed_edit.php @@ -0,0 +1,192 @@ +. + + +namespace block_rss_thumbnails\form; + +defined('MOODLE_INTERNAL') || die(); + +require_login(); +require_once($CFG->libdir . '/formslib.php'); +require_once($CFG->libdir .'/simplepie/moodle_simplepie.php'); + +use moodle_simplepie; +use moodle_url; +use moodleform; + +/** + * A class to be able to edit the feeds we import in the plugin. + * + * @package block_rss_thumbnails + * @copyright 2022 - CALL Learning - Martin CORNU-MANSUY + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class feed_edit extends moodleform { + + // TODO review this file. + + /** @var bool $isadding checks whether the user is adding a new feed or not. */ + protected $isadding; + + /** @var bool $caneditshared checks whether the user has the capability to edit a shared feed or not. */ + protected $caneditshared; + + /** @var string $title The title */ + protected $title = ''; + + /** @var string $description The description */ + protected $description = ''; + + /** + * Constructor. + * + * @param string $actionurl the url of the action. + * @param bool $isadding to know if the user is adding a new feed or not. + * @param bool $caneditshared to know if the user has the ability to edit a shared feed or not. + */ + public function __construct($actionurl, $isadding, $caneditshared) { + $this->isadding = $isadding; + $this->caneditshared = $caneditshared; + parent::__construct($actionurl); + } + + /** + * Defines the form allowing to edit a feed. + * + * @return void + */ + public function definition() { + $mform =& $this->_form; + + // Then show the fields about where this block appears. + $mform->addElement('header', 'rsseditfeedheader', get_string('feed', 'block_rss_thumbnails')); + + $mform->addElement('text', 'url', get_string('feedurl', 'block_rss_thumbnails'), array('size' => 60)); + $mform->setType('url', PARAM_URL); + $mform->addRule('url', null, 'required'); + + $mform->addElement('checkbox', 'autodiscovery', get_string('enableautodiscovery', 'block_rss_thumbnails')); + $mform->setDefault('autodiscovery', 1); + $mform->setAdvanced('autodiscovery'); + $mform->addHelpButton('autodiscovery', 'enableautodiscovery', 'block_rss_thumbnails'); + + $mform->addElement('text', 'preferredtitle', get_string('customtitlelabel', 'block_rss_thumbnails'), array('size' => 60)); + $mform->setType('preferredtitle', PARAM_NOTAGS); + + if ($this->caneditshared) { + $mform->addElement('selectyesno', 'shared', get_string('sharedfeed', 'block_rss_thumbnails')); + $mform->setDefault('shared', 0); + } + + $submitlabal = null; // Default. + if ($this->isadding) { + $submitlabal = get_string('addnewfeed', 'block_rss_thumbnails'); + } + $this->add_action_buttons(true, $submitlabal); + } + + /** + * Defines the form after the discovery of data + * + * @return void + */ + public function definition_after_data() { + $mform =& $this->_form; + + if ($mform->getElementValue('autodiscovery')) { + $mform->applyFilter('url', self::class . '::autodiscover_feed_url'); + } + } + + /** + * Validates the edition form. + * + * @param array $data Datas of the form. + * @param array $files Files of the form. + * @return array + */ + public function validation($data, $files): array { + $errors = parent::validation($data, $files); + + $rss = new moodle_simplepie(); + // Set timeout for longer than normal to try and grab the feed. + $rss->set_timeout(); + $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_thumbnails'); + } else { + $this->title = $rss->get_title(); + $this->description = $rss->get_description(); + } + + return $errors; + } + + /** + * Gets data of the form. + * + * @return object|null + */ + public function get_data(): ?object { + $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 URL to autodiscover a url + * @return string URL of feed or original url if none found + */ + public static function autodiscover_feed_url($url): string { + $rss = new moodle_simplepie(); + $rss->set_feed_url($url); + $rss->set_autodiscovery_level(); + // 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); + } +} diff --git a/db/upgrade.php b/db/upgrade.php index 796bb0a..1a45501 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -34,32 +34,39 @@ function xmldb_block_rss_thumbnails_upgrade($oldversion) { // Automatically generated Moodle v3.9.0 release upgrade line. // Put any upgrade step following this. $dbman = $DB->get_manager(); - if ($oldversion < 2022091502) { + if ($oldversion < 2022111004) { - // Define table block_rss_thumbnails to be created. - $table = new xmldb_table('block_rss_thumbnails'); - - // Adding fields to table block_rss_thumbnails. - $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); - $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); - $table->add_field('title', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); - $table->add_field('preferredtitle', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null); - $table->add_field('description', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); - $table->add_field('shared', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0'); - $table->add_field('url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); - $table->add_field('skiptime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); - $table->add_field('skipuntil', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); - - // Adding keys to table block_rss_thumbnails. - $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); + $table = create_block_rss_thumbnails_table(); + $params = ['blockname' => 'rss_thumbnails']; // Conditionally launch create table for block_rss_thumbnails. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } + if ($DB->record_exists('block_instances', $params)) { + if ($dbman->table_exists('block_rss_client')) { + $rssfeeds = $DB->get_records('block_rss_client'); + $DB->insert_records('block_rss_thumbnails', $rssfeeds); + } + $blockinstances = $DB->get_records('block_instances', ['blockname' => 'rss_thumbnails']); + foreach ($blockinstances as $blockinstance) { + // Access to block's configdata. + $blockconfig = unserialize(base64_decode($blockinstance->configdata)); + + // Update caroussel speed variable that changed into carousseldelay for semantical reasons. + $blockconfig->carousseldelay = $blockconfig->carousselspeed; + $blockconfig->numentries = $blockconfig->shownumentries; + + $newblockinstance = clone $blockinstance; + // Re-serialize block's configdata. + $newblockinstance->configdata = base64_encode(serialize($blockconfig)); + + $DB->update_record('block_instances', $newblockinstance); + } + } // Rss_thumbnails savepoint reached. - upgrade_block_savepoint(true, 2022091502, 'rss_thumbnails'); + upgrade_block_savepoint(true, 2022111004, 'rss_thumbnails'); } // Automatically generated Moodle v4.0.0 release upgrade line. @@ -67,3 +74,28 @@ function xmldb_block_rss_thumbnails_upgrade($oldversion) { return true; } + +/** + * Creates an empty block_rss_thumbnails table by adding to it all the fields it needs and setting up the right primary key. + * + * @return xmldb_table + */ +function create_block_rss_thumbnails_table(): xmldb_table { + // Define table block_rss_thumbnails to be created. + $table = new xmldb_table('block_rss_thumbnails'); + + // Adding fields to table block_rss_thumbnails. + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); + $table->add_field('title', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); + $table->add_field('preferredtitle', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null); + $table->add_field('description', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); + $table->add_field('shared', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0'); + $table->add_field('url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); + $table->add_field('skiptime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); + $table->add_field('skipuntil', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); + + // Adding keys to table block_rss_thumbnails. + $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); + return $table; +} diff --git a/edit_form.php b/edit_form.php index 7929fd8..336657b 100644 --- a/edit_form.php +++ b/edit_form.php @@ -45,7 +45,7 @@ class block_rss_thumbnails_edit_form extends block_edit_form { * @return void */ protected function specific_definition($mform) { - global $CFG, $DB, $USER, $SESSION; + global $CFG, $DB, $USER; // Fields for editing block contents. $mform->addElement('header', 'configheader', get_string('blocksettings', 'block')); diff --git a/editfeed.php b/editfeed.php index 0238583..fefa26d 100644 --- a/editfeed.php +++ b/editfeed.php @@ -22,175 +22,15 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +namespace block_rss_thumbnails; require_once(__DIR__ . '/../../config.php'); require_login(); -require_once($CFG->libdir . '/formslib.php'); -require_once($CFG->libdir .'/simplepie/moodle_simplepie.php'); -/** - * A class to be able to edit the feeds we import in the plugin. - * - * @package block_rss_thumbnails - * @copyright 2022 - CALL Learning - Martin CORNU-MANSUY - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class feed_edit_form extends moodleform { - - // TODO review this file because a lot of things are just none sense. - - /** @var bool $isadding checks whether the user is adding a new feed or not. */ - protected $isadding; - - /** @var bool $caneditshared checks whether the user has the capability to edit a shared feed or not. */ - protected $caneditshared; - - /** @var string $title The title */ - protected $title = ''; - - /** @var string $description The description */ - protected $description = ''; - - /** - * Constructor. - * - * @param string $actionurl the url of the action. - * @param bool $isadding to know if the user is adding a new feed or not. - * @param bool $caneditshared to know if the user has the ability to edit a shared feed or not. - */ - public function __construct($actionurl, $isadding, $caneditshared) { - $this->isadding = $isadding; - $this->caneditshared = $caneditshared; - parent::__construct($actionurl); - } - - /** - * Defines the form allowing to edit a feed. - * - * @return void - */ - public function definition() { - $mform =& $this->_form; - - // Then show the fields about where this block appears. - $mform->addElement('header', 'rsseditfeedheader', get_string('feed', 'block_rss_thumbnails')); - - $mform->addElement('text', 'url', get_string('feedurl', 'block_rss_thumbnails'), array('size' => 60)); - $mform->setType('url', PARAM_URL); - $mform->addRule('url', null, 'required'); - - $mform->addElement('checkbox', 'autodiscovery', get_string('enableautodiscovery', 'block_rss_thumbnails')); - $mform->setDefault('autodiscovery', 1); - $mform->setAdvanced('autodiscovery'); - $mform->addHelpButton('autodiscovery', 'enableautodiscovery', 'block_rss_thumbnails'); - - $mform->addElement('text', 'preferredtitle', get_string('customtitlelabel', 'block_rss_thumbnails'), array('size' => 60)); - $mform->setType('preferredtitle', PARAM_NOTAGS); - - if ($this->caneditshared) { - $mform->addElement('selectyesno', 'shared', get_string('sharedfeed', 'block_rss_thumbnails')); - $mform->setDefault('shared', 0); - } - - $submitlabal = null; // Default. - if ($this->isadding) { - $submitlabal = get_string('addnewfeed', 'block_rss_thumbnails'); - } - $this->add_action_buttons(true, $submitlabal); - } - - /** - * Defines the form after the discovery of data - * - * @return void - */ - public function definition_after_data() { - $mform =& $this->_form; - - if ($mform->getElementValue('autodiscovery')) { - $mform->applyFilter('url', 'feed_edit_form::autodiscover_feed_url'); - } - } - - /** - * Validates the edition form. - * - * @param array $data Datas of the form. - * @param array $files Files of the form. - * @return array - */ - public function validation($data, $files): array { - $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_thumbnails'); - } else { - $this->title = $rss->get_title(); - $this->description = $rss->get_description(); - } - - return $errors; - } - - /** - * Gets data of the form. - * - * @return object|null - */ - public function get_data(): ?object { - $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 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); - } -} +use block_rss_thumbnails\form\feed_edit; +use context_system; +use moodle_url; +use stdClass; $returnurl = optional_param('returnurl', '', PARAM_LOCALURL); $courseid = optional_param('courseid', 0, PARAM_INT); @@ -230,10 +70,10 @@ public static function autodiscover_feed_url($url) { $rssrecord = $DB->get_record('block_rss_thumbnails', array('id' => $rssid), '*', MUST_EXIST); } else { $isadding = true; - $rssrecord = new stdClass; + $rssrecord = new stdClass(); } -$mform = new feed_edit_form($PAGE->url, $isadding, $managesharedfeeds); +$mform = new feed_edit($PAGE->url, $isadding, $managesharedfeeds); $mform->set_data($rssrecord); if ($mform->is_cancelled()) { diff --git a/lang/en/block_rss_thumbnails.php b/lang/en/block_rss_thumbnails.php index 988f09a..5ab77d4 100644 --- a/lang/en/block_rss_thumbnails.php +++ b/lang/en/block_rss_thumbnails.php @@ -36,6 +36,7 @@ $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['managefeeds'] = 'Manage feeds'; $string['addnewfeed'] = 'Add a new feed'; +$string['editafeed'] = 'Edit a feed'; $string['feedurl'] = 'URL of the feed'; $string['feed'] = 'Feed'; $string['customtitlelabel'] = 'Enter feed\'s title'; @@ -47,3 +48,4 @@ $string['enableautodiscovery_help'] = 'By checking this, the RSS feed will reload automatically'; // TODO make sure it is correct. $string['feeddeleted'] = 'The feed has been successfully deleted'; $string['configureblock'] = "Click the edit icon above to configure this block to display RSS thumbnails ."; +$string['invalidconfig'] = "It looks like your block configuration is invalid.
Make sure you did not lay some empty fields."; diff --git a/tests/block_rss_thumbnails_test.php b/tests/block_rss_thumbnails_test.php index 001d3df..24a7120 100644 --- a/tests/block_rss_thumbnails_test.php +++ b/tests/block_rss_thumbnails_test.php @@ -39,8 +39,6 @@ */ class block_rss_thumbnails_test extends advanced_testcase { - // TODO IMPORTANT TO CHANGE CAROUSSEL SPEED INTO SMTHING LIKE CAROUSSEL DELAY (in ms). - /** * Expected config data. */ diff --git a/thirdpartylibs.xml b/thirdpartylibs.xml new file mode 100644 index 0000000..b49d63f --- /dev/null +++ b/thirdpartylibs.xml @@ -0,0 +1,10 @@ + + + + js/glide/dist/glide.js + Glide + 3.5.2 + MIT + 1.0 + + \ No newline at end of file diff --git a/version.php b/version.php index f500cd8..81c3c8f 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,9 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2022102500; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2022120700; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2012112900; // Requires this Moodle version. +$plugin->release = 1.0; +$plugin->maturity = MATURITY_STABLE; $plugin->component = 'block_rss_thumbnails'; // Full name of the plugin (used for diagnostics). $plugin->dependencies = [];