Skip to content

Commit 0570325

Browse files
committed
Initial commit
0 parents  commit 0570325

31 files changed

+13006
-0
lines changed

.travis.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
language: php
2+
3+
addons:
4+
postgresql: "9.6"
5+
6+
services:
7+
- mysql
8+
- postgresql
9+
- docker
10+
11+
cache:
12+
directories:
13+
- $HOME/.composer/cache
14+
- $HOME/.npm
15+
16+
php:
17+
- 7.2
18+
- 7.4
19+
20+
env:
21+
matrix:
22+
- DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE
23+
- DB=mysqli MOODLE_BRANCH=MOODLE_39_STABLE
24+
- DB=pgsql MOODLE_BRANCH=MOODLE_39_STABLE
25+
26+
before_install:
27+
- phpenv config-rm xdebug.ini
28+
- cd ../..
29+
- composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3
30+
- export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH"
31+
32+
install:
33+
- moodle-plugin-ci add-plugin call-learning/moodle-customfield_multiselect
34+
- moodle-plugin-ci install
35+
36+
script:
37+
- moodle-plugin-ci phplint
38+
- moodle-plugin-ci phpcpd
39+
- moodle-plugin-ci phpmd
40+
- moodle-plugin-ci codechecker
41+
- moodle-plugin-ci validate
42+
- moodle-plugin-ci savepoints
43+
- moodle-plugin-ci mustache
44+
- moodle-plugin-ci grunt
45+
- moodle-plugin-ci phpdoc
46+
- moodle-plugin-ci phpunit
47+
- moodle-plugin-ci behat

README.txt

Whitespace-only changes.

amd/build/config.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amd/build/config.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amd/build/glide.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amd/build/glide.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amd/src/config.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* RSS Thumbnails block
3+
*
4+
* @package block_rss_thumbnails
5+
* @copyright 2020 - CALL Learning - Laurent David <laurent@call-learning>
6+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
7+
*/
8+
define(['core/config'], function (cfg) {
9+
window.requirejs.config({
10+
paths: {
11+
"glide":
12+
cfg.wwwroot
13+
+ '/lib/javascript.php/'
14+
+ cfg.jsrev
15+
+ '/blocks/rss_thumbnails/js/glide/dist/glide'
16+
+ (cfg.developerdebug ? '.min' : ''),
17+
},
18+
shim: {
19+
'glide': {exports: 'glide'},
20+
}
21+
});
22+
});

amd/src/glide.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* RSS Thumbnails block
3+
*
4+
* @package block_rss_thumbnails
5+
* @copyright 2020 - CALL Learning - Laurent David <laurent@call-learning>
6+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
7+
*/
8+
define([ 'jquery', 'block_rss_thumbnails/config'], function ($) {
9+
return function (locator, config) {
10+
require(['glide'], function (Glide) {
11+
// Show the slider now we are initialised.
12+
$(locator).removeClass('d-none');
13+
new Glide(locator, config).mount();
14+
});
15+
};
16+
});

block_rss_thumbnails.php

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* RSS Thumbnail Block
19+
*
20+
* @package block_rss_thumbnails
21+
* @copyright 2020 - CALL Learning - Laurent David <laurent@call-learning>
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
use block_rss_thumbnails\output\block;
26+
27+
defined('MOODLE_INTERNAL') || die();
28+
global $CFG;
29+
require_once($CFG->dirroot . '/blocks/rss_client/block_rss_client.php');
30+
31+
/**
32+
* Class block_rss_thumbnails
33+
*
34+
* @package block_rss_thumbnails
35+
* @copyright 2020 - CALL Learning - Laurent David <laurent@call-learning>
36+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37+
*/
38+
class block_rss_thumbnails extends block_rss_client {
39+
40+
const DEFAULT_CAROUSSEL_SPEED = 4000;
41+
42+
/** @var bool track whether any of the output feeds have recorded failures */
43+
private $hasfailedfeeds = false;
44+
45+
/**
46+
* Init function
47+
*
48+
* @throws coding_exception
49+
*/
50+
public function init() {
51+
$this->title = get_string('pluginname', 'block_rss_thumbnails');
52+
}
53+
54+
/**
55+
* Content for the block
56+
*
57+
* @return \stdClass|string|null
58+
* @throws coding_exception
59+
*/
60+
public function get_content() {
61+
$this->page->requires->css(
62+
new moodle_url('/blocks/rss_thumbnails/js/glide/dist/css/glide.core' .
63+
(debugging() ? '.min' : '') . '.css'));
64+
global $CFG, $DB;
65+
66+
if ($this->content !== null) {
67+
return $this->content;
68+
}
69+
70+
// initalise block content object
71+
$this->content = new stdClass;
72+
$this->content->text = '';
73+
$this->content->footer = '';
74+
75+
if (empty($this->instance)) {
76+
return $this->content;
77+
}
78+
79+
if (!isset($this->config)) {
80+
// The block has yet to be configured - just display configure message in
81+
// the block if user has permission to configure it
82+
83+
if (has_capability('block/rss_client:manageanyfeeds', $this->context)) {
84+
$this->content->text = get_string('feedsconfigurenewinstance2', 'block_rss_client');
85+
}
86+
87+
return $this->content;
88+
}
89+
90+
// How many feed items should we display?
91+
$maxentries = 5;
92+
if (!empty($this->config->shownumentries)) {
93+
$maxentries = intval($this->config->shownumentries);
94+
} else if (isset($CFG->block_rss_client_num_entries)) {
95+
$maxentries = intval($CFG->block_rss_client_num_entries);
96+
}
97+
98+
/* ---------------------------------
99+
* Begin Normal Display of Block Content
100+
* --------------------------------- */
101+
102+
$renderer = $this->page->get_renderer('block_rss_thumbnails');
103+
$carousselspeed = empty($this->config->carousselspeed) ? self::DEFAULT_CAROUSSEL_SPEED : $this->config->carousselspeed;
104+
$block = new block($carousselspeed);
105+
106+
if (!empty($this->config->rssid)) {
107+
list($rssidssql, $params) = $DB->get_in_or_equal($this->config->rssid);
108+
$rssfeeds = $DB->get_records_select('block_rss_client', "id $rssidssql", $params);
109+
110+
if (!empty($rssfeeds)) {
111+
$showtitle = false;
112+
if (count($rssfeeds) > 1) {
113+
// When many feeds show the title for each feed.
114+
$showtitle = true;
115+
}
116+
117+
foreach ($rssfeeds as $feed) {
118+
if ($renderablefeed = $this->get_feed($feed, $maxentries, $showtitle)) {
119+
$block->add_feed($renderablefeed);
120+
}
121+
}
122+
123+
$footer = $this->get_footer($rssfeeds);
124+
}
125+
}
126+
127+
$this->content->text = $renderer->render_block($block);
128+
if (isset($footer)) {
129+
$this->content->footer = $renderer->render_footer($footer);
130+
}
131+
132+
return $this->content;
133+
}
134+
135+
/**
136+
* Gets the footer, which is the channel link of the last feed in our list of feeds
137+
*
138+
* @param array $feedrecords The feed records from the database.
139+
* @return block_rss_client\output\footer|null The renderable footer or null if none should be displayed.
140+
*/
141+
protected function get_footer($feedrecords) {
142+
$footer = null;
143+
144+
if (!empty($this->config->show_channel_link)) {
145+
global $CFG;
146+
require_once($CFG->libdir . '/simplepie/moodle_simplepie.php');
147+
148+
$feedrecord = array_pop($feedrecords);
149+
$feed = new moodle_simplepie($feedrecord->url);
150+
$channellink = new moodle_url($feed->get_link());
151+
152+
if (!empty($channellink)) {
153+
$footer = new block_rss_client\output\footer($channellink);
154+
}
155+
}
156+
157+
if ($this->hasfailedfeeds) {
158+
if (has_any_capability(['block/rss_client:manageownfeeds', 'block/rss_client:manageanyfeeds'], $this->context)) {
159+
if ($footer === null) {
160+
$footer = new block_rss_client\output\footer();
161+
}
162+
$manageurl = new moodle_url('/blocks/rss_client/managefeeds.php',
163+
['courseid' => $this->page->course->id]);
164+
$footer->set_failed($manageurl);
165+
}
166+
}
167+
168+
return $footer;
169+
}
170+
171+
/**
172+
* Returns the html of a feed to be displaed in the block
173+
*
174+
* @param mixed feedrecord The feed record from the database
175+
* @param int maxentries The maximum number of entries to be displayed
176+
* @param boolean showtitle Should the feed title be displayed in html
177+
* @return block_rss_client\output\feed|null The renderable feed or null of there is an error
178+
*/
179+
public function get_feed($feedrecord, $maxentries, $showtitle) {
180+
global $CFG;
181+
require_once($CFG->libdir . '/simplepie/moodle_simplepie.php');
182+
183+
if ($feedrecord->skipuntil) {
184+
// Last attempt to gather this feed via cron failed - do not try to fetch it now.
185+
$this->hasfailedfeeds = true;
186+
return null;
187+
}
188+
189+
$simplepiefeed = new moodle_simplepie($feedrecord->url);
190+
191+
if (isset($CFG->block_rss_client_timeout)) {
192+
$simplepiefeed->set_cache_duration($CFG->block_rss_client_timeout * 60);
193+
}
194+
195+
if ($simplepiefeed->error()) {
196+
debugging($feedrecord->url . ' Failed with code: ' . $simplepiefeed->error());
197+
return null;
198+
}
199+
200+
if (empty($feedrecord->preferredtitle)) {
201+
// Simplepie does escape HTML entities.
202+
$feedtitle = $this->format_title($simplepiefeed->get_title());
203+
} else {
204+
// Moodle custom title does not does escape HTML entities.
205+
$feedtitle = $this->format_title(s($feedrecord->preferredtitle));
206+
}
207+
208+
if (empty($this->config->title)) {
209+
//NOTE: this means the 'last feed' displayed wins the block title - but
210+
//this is exiting behaviour..
211+
$this->title = strip_tags($feedtitle);
212+
}
213+
214+
$feed = new \block_rss_client\output\feed($feedtitle, $showtitle, false);
215+
216+
if ($simplepieitems = $simplepiefeed->get_items(0, $maxentries)) {
217+
foreach ($simplepieitems as $simplepieitem) {
218+
try {
219+
$imageurl = null;
220+
$content = $simplepieitem->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'content');
221+
if ($content && !empty($content[0])) {
222+
$imageurl = $content[0]['attribs']['']['url'];
223+
if (!empty($this->config->remove_image_size_suffix)) {
224+
$imageurl = preg_replace('/-[0-9]+x[0-9]+/', '', $imageurl);
225+
}
226+
}
227+
$categories = array_map(function($cat) {
228+
return $cat->term;
229+
}, $simplepieitem->get_categories());
230+
231+
$item = new \block_rss_thumbnails\output\item(
232+
$simplepieitem->get_id(),
233+
new moodle_url($simplepieitem->get_link()),
234+
$simplepieitem->get_title(),
235+
$simplepieitem->get_description(),
236+
new moodle_url($simplepieitem->get_permalink()),
237+
$simplepieitem->get_date('U'),
238+
$this->config->display_description,
239+
$imageurl,
240+
$categories
241+
);
242+
243+
$feed->add_item($item);
244+
} catch (moodle_exception $e) {
245+
// If there is an error with the RSS item, we don't
246+
// want to crash the page. Specifically, moodle_url can
247+
// throw an exception of the param is an extremely
248+
// malformed url.
249+
debugging($e->getMessage());
250+
}
251+
}
252+
}
253+
254+
// Feed image.
255+
if ($imageurl = $simplepiefeed->get_image_url()) {
256+
try {
257+
$image = new \block_rss_client\output\channel_image(
258+
new moodle_url($imageurl),
259+
$simplepiefeed->get_image_title(),
260+
new moodle_url($simplepiefeed->get_image_link())
261+
);
262+
263+
$feed->set_image($image);
264+
} catch (moodle_exception $e) {
265+
// If there is an error with the RSS image, we don'twant to
266+
// crash the page. Specifically, moodle_url can throw an
267+
// exception if the param is an extremely malformed url.
268+
debugging($e->getMessage());
269+
}
270+
}
271+
272+
return $feed;
273+
}
274+
275+
}

0 commit comments

Comments
 (0)