mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'MDL-66398-master' of git://github.com/aanabit/moodle
This commit is contained in:
commit
cd0a9144b4
@ -2384,8 +2384,8 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertCount(2, $result['courses']);
|
||||
|
||||
// Check default filters.
|
||||
$this->assertCount(3, $result['courses'][0]['filters']);
|
||||
$this->assertCount(3, $result['courses'][1]['filters']);
|
||||
$this->assertCount(4, $result['courses'][0]['filters']);
|
||||
$this->assertCount(4, $result['courses'][1]['filters']);
|
||||
|
||||
$result = core_course_external::get_courses_by_field('category', $category1->id);
|
||||
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
|
||||
@ -2427,7 +2427,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
|
||||
// Check default filters.
|
||||
$filters = $result['courses'][0]['filters'];
|
||||
$this->assertCount(3, $filters);
|
||||
$this->assertCount(4, $filters);
|
||||
$found = false;
|
||||
foreach ($filters as $filter) {
|
||||
if ($filter['filter'] == 'mediaplugin' and $filter['localstate'] == TEXTFILTER_OFF) {
|
||||
|
38
filter/displayh5p/db/install.php
Normal file
38
filter/displayh5p/db/install.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Display H5P active by default
|
||||
*
|
||||
* @package filter_displayh5p
|
||||
* @copyright 2019 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Enable displayh5p filter by default to render H5P contents.
|
||||
* @throws coding_exception
|
||||
*/
|
||||
function xmldb_filter_displayh5p_install() {
|
||||
global $CFG;
|
||||
|
||||
require_once("$CFG->libdir/filterlib.php");
|
||||
|
||||
// Display H5P filter should be enabled by default because we need this filter for H5P atto button to work.
|
||||
filter_set_global_state('displayh5p', TEXTFILTER_ON, -1);
|
||||
}
|
@ -47,49 +47,89 @@ class filter_displayh5p extends moodle_text_filter {
|
||||
* @return string
|
||||
*/
|
||||
public function filter($text, array $options = array()) {
|
||||
global $CFG;
|
||||
|
||||
if (!is_string($text) or empty($text)) {
|
||||
// Non string data can not be filtered anyway.
|
||||
return $text;
|
||||
}
|
||||
|
||||
if (stripos($text, 'http') === false) {
|
||||
// We are trying to minimize performance impact checking there's some H5P related URL.
|
||||
$h5purl = '(http[^ &<]*h5p)';
|
||||
if (!preg_match($h5purl, $text)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$allowedsources = get_config('filter_displayh5p', 'allowedsources');
|
||||
$allowedsources = array_filter(array_map('trim', explode("\n", $allowedsources)));
|
||||
if (empty($allowedsources)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$localsource = '('.preg_quote($CFG->wwwroot).'/[^ &<]*\.h5p([?][^ <]*)?[^ &<]*)';
|
||||
$allowedsources[] = $localsource;
|
||||
|
||||
$params = array(
|
||||
'tagbegin' => "<iframe src=",
|
||||
'tagend' => "</iframe>"
|
||||
'tagbegin' => '<iframe src="',
|
||||
'tagend' => '</iframe>'
|
||||
);
|
||||
|
||||
$specialchars = ['*', '?', '&', '[^<]'];
|
||||
$escapedspecialchars = ['[^.]+', '\?', '&', '[^<]*'];
|
||||
$h5pcontents = array();
|
||||
|
||||
// Check all allowed sources.
|
||||
foreach ($allowedsources as $source) {
|
||||
// It is needed to add "/embed" at the end of URLs like https:://*.h5p.com/content/12345 (H5P.com).
|
||||
$params['urlmodifier'] = '';
|
||||
if (!(stripos($source, 'embed'))) {
|
||||
$params['urlmodifier'] = '/embed';
|
||||
|
||||
if (($source == $localsource)) {
|
||||
$params['tagbegin'] = '<iframe src="'.$CFG->wwwroot.'/h5p/embed.php?url=';
|
||||
$ultimatepattern = '#'.$source.'#';
|
||||
} else {
|
||||
if (!stripos($source, 'embed')) {
|
||||
$params['urlmodifier'] = '/embed';
|
||||
}
|
||||
// Convert special chars.
|
||||
$sourceid = str_replace('[id]', '[0-9]+', $source);
|
||||
$escapechars = str_replace($specialchars, $escapedspecialchars, $sourceid);
|
||||
$ultimatepattern = '#(' . $escapechars . ')#';
|
||||
}
|
||||
|
||||
// Convert special chars.
|
||||
$specialchars = ['*', '?', '&'];
|
||||
$escapedspecialchars = ['[^.]+', '\?', '&'];
|
||||
$sourceid = str_replace('[id]', '[0-9]+', $source);
|
||||
$escapechars = str_replace($specialchars, $escapedspecialchars, $sourceid);
|
||||
$ultimatepattern = '#(' . $escapechars . ')#';
|
||||
// Improve performance creating filterobjects only when needed.
|
||||
if (!preg_match($ultimatepattern, $text)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$h5pcontenturl = new filterobject($source, null, null, false,
|
||||
false, null, [$this, 'filterobject_prepare_replacement_callback'], $params);
|
||||
false, null, [$this, 'filterobject_prepare_replacement_callback'], $params);
|
||||
|
||||
$h5pcontenturl->workregexp = $ultimatepattern;
|
||||
$h5pcontents[] = $h5pcontenturl;
|
||||
}
|
||||
|
||||
return filter_phrases($text, $h5pcontents, null, null, false, true);
|
||||
if (empty($h5pcontents)) {
|
||||
// No matches to deal with.
|
||||
return $text;
|
||||
}
|
||||
|
||||
$result = filter_phrases($text, $h5pcontents, null, null, false, true);
|
||||
|
||||
// Encoding H5P file URLs.
|
||||
// embed.php page is requesting a PARAM_LOCALURL url parameter, so for files/directories use non-alphanumeric
|
||||
// characters, we need to encode the parameter. Fetch url parameter added to embed.php and encode the whole url.
|
||||
$localurl = '#\?url=([^" <]*[\/]+[^" <]*\.h5p)([?][^"]*)?#';
|
||||
$result = preg_replace_callback($localurl,
|
||||
function ($matches) {
|
||||
$baseurl = rawurlencode($matches[1]);
|
||||
// Deal with possible parameters in the url link.
|
||||
if (!empty($matches[2])) {
|
||||
$match = explode('?', $matches[2]);
|
||||
if (!empty($match[1])) {
|
||||
$baseurl = $baseurl."&".$match[1];
|
||||
}
|
||||
}
|
||||
return "?url=".$baseurl;
|
||||
}, $result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,13 +141,13 @@ class filter_displayh5p extends moodle_text_filter {
|
||||
* @return array [$hreftagbegin, $hreftagend, $replacementphrase] for filterobject.
|
||||
*/
|
||||
public function filterobject_prepare_replacement_callback($tagbegin, $tagend, $urlmodifier) {
|
||||
|
||||
$sourceurl = "$1";
|
||||
if ($urlmodifier !== "") {
|
||||
$sourceurl .= $urlmodifier;
|
||||
}
|
||||
|
||||
$h5piframesrc = "\"".$sourceurl."\" width=\"100%\" height=\"637\" allowfullscreen=\"allowfullscreen\" style=\"border: 0;\">";
|
||||
$h5piframesrc = $sourceurl.
|
||||
'" class="h5p-iframe" style="height:230px; width: 100%; border: 0;" allowfullscreen="allowfullscreen">';
|
||||
|
||||
// We want to request the resizing script only once.
|
||||
if (self::$loadresizerjs) {
|
||||
|
@ -45,8 +45,6 @@ class filter_displayh5p_testcase extends advanced_testcase {
|
||||
"https://h5p.org/h5p/embed/[id]\nhttps://*.h5p.com/content/[id]/embed\nhttps://*.h5p.com/content/[id]
|
||||
\nhttps://generic.wordpress.soton.ac.uk/altc/wp-admin/admin-ajax.php?action=h5p_embed&id=[id]",
|
||||
'filter_displayh5p');
|
||||
// Enable display h5p filter at top level.
|
||||
filter_set_global_state('displayh5p', TEXTFILTER_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,6 +69,8 @@ class filter_displayh5p_testcase extends advanced_testcase {
|
||||
* @return array
|
||||
*/
|
||||
public function texts_provider() {
|
||||
global $CFG;
|
||||
|
||||
return [
|
||||
["http:://example.com", "#http:://example.com#"],
|
||||
["http://google.es/h5p/embed/3425234", "#http://google.es/h5p/embed/3425234#"],
|
||||
@ -83,7 +83,13 @@ class filter_displayh5p_testcase extends advanced_testcase {
|
||||
["https://generic.wordpress.soton.ac.uk/altc/wp-admin/admin-ajax.php?action=h5p_embed&id=13",
|
||||
"#<iframe src=\"https://generic.wordpress.soton.ac.uk/altc/wp-admin/admin-ajax.php\?action=h5p_embed\&\;id=13\"[^>]+?>#"],
|
||||
["https://h5p.org/h5p/embed/547225 another content in the same page https://moodle.h5p.com/content/1290729733828858779/embed",
|
||||
"#<iframe src=\"https://h5p.org/h5p/embed/547225\"[^>]+?>((?!<iframe).)*<iframe src=\"https://moodle.h5p.com/content/1290729733828858779/embed\"[^>]+?>#"]
|
||||
"#<iframe src=\"https://h5p.org/h5p/embed/547225\"[^>]+?>((?!<iframe).)*<iframe src=\"https://moodle.h5p.com/content/1290729733828858779/embed\"[^>]+?>#"],
|
||||
[$CFG->wwwroot."/pluginfile.php/5/user/private/interactive-video.h5p?export=1&embed=1",
|
||||
"#<iframe src=\"{$CFG->wwwroot}/h5p/embed.php\?url=".rawurlencode("{$CFG->wwwroot}/pluginfile.php/5/user/private/interactive-video.h5p").
|
||||
"&export=1&embed=1\"[^>]*?></iframe>#"],
|
||||
[$CFG->wwwroot."/pluginfile.php/5/user/private/accordion-6-7138%20%281%29.h5p.h5p",
|
||||
"#<iframe src=\"{$CFG->wwwroot}/h5p/embed.php\?url=".rawurlencode("{$CFG->wwwroot}/pluginfile.php/5/user/private/accordion-6-7138%20%281%29.h5p.h5p").
|
||||
"\"[^>]*?></iframe>#"]
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user