Skip to content

Commit

Permalink
Merge branch 'MDL-72607-MOODLE-311-STABLE_fix_media_vimeo_url_parser'…
Browse files Browse the repository at this point in the history
… of https://github.com/praxisdigital/moodle into MOODLE_311_STABLE
  • Loading branch information
vmdef committed Oct 21, 2021
2 parents d524f2e + 81c0b42 commit 9b67243
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 3 deletions.
33 changes: 30 additions & 3 deletions media/player/vimeo/classes/plugin.php
Expand Up @@ -34,7 +34,7 @@
*/
class media_vimeo_plugin extends core_media_player_external {
protected function embed_external(moodle_url $url, $name, $width, $height, $options) {
$videoid = $this->matches[1];
$videoid = $this->get_video_id();
$info = s($name);

// Note: resizing via url is not supported, user can click the fullscreen
Expand All @@ -53,15 +53,42 @@ protected function embed_external(moodle_url $url, $name, $width, $height, $opti
return $output;
}

/**
* Get Vimeo video ID.
* @return string
*/
protected function get_video_id(): string {
return $this->get_video_id_with_code() ?? $this->matches[1] ?? '';
}

/**
* Get video id with code.
* @return string|null If NULL then the URL does not contain the code.
*/
protected function get_video_id_with_code(): ?string {
$id = $this->matches[2] ?? null;

if (!empty($id)) {
$code = $this->matches[3] ?? null;
if (!empty($code)) {
return "{$id}?h={$code}";
}

return $id;
}

return null;
}

/**
* Returns regular expression to match vimeo URLs.
* @return string
*/
protected function get_regex() {
// Initial part of link.
$start = '~^https?://vimeo\.com/';
// Middle bit: either watch?v= or v/.
$middle = '([0-9]+)';
// Middle bit: either 123456789 or 123456789/abdef12345.
$middle = '(([0-9]+)/([0-9a-f]+)|[0-9]+)';
return $start . $middle . core_media_player_external::END_LINK_REGEX_PART;
}

Expand Down
100 changes: 100 additions & 0 deletions media/player/vimeo/tests/player_test.php
Expand Up @@ -131,4 +131,104 @@ public function test_embed_media() {
$this->assertMatchesRegularExpression('~</iframe>~', $content);
$this->assertMatchesRegularExpression('~width="123" height="35"~', $content);
}

/**
* Test embedding without media filter (for example for displaying URL resorce)
* and test that player plugin is parsing the URL with the code.
*/
public function test_embed_url_with_code() {
global $CFG;

$url = new moodle_url('https://vimeo.com/1176321/abcdef12345');

$manager = core_media_manager::instance();
$embedoptions = array(
core_media_manager::OPTION_TRUSTED => true,
core_media_manager::OPTION_BLOCK => true,
);

$this->assertTrue($manager->can_embed_url($url, $embedoptions));
$content = $manager->embed_url($url, 'Test & file', 0, 0, $embedoptions);

// Video source URL is contains the new vimeo embedded URL format.
$this->assertStringContainsString('player.vimeo.com/video/1176321?h=abcdef12345', $content);

$this->assertMatchesRegularExpression('~mediaplugin_vimeo~', $content);
$this->assertMatchesRegularExpression('~</iframe>~', $content);
$this->assertMatchesRegularExpression('~width="' . $CFG->media_default_width . '" height="' .
$CFG->media_default_height . '"~', $content);

// Repeat sending the specific size to the manager.
$content = $manager->embed_url($url, 'New file', 123, 50, $embedoptions);
$this->assertMatchesRegularExpression('~width="123" height="50"~', $content);
}

/**
* Test that mediaplugin filter replaces a link to the supported file with media tag
* and test that player plugin is parsing the URL with the code.
*
* filter_mediaplugin is enabled by default.
*/
public function test_embed_link_with_code() {
global $CFG;
$url = new moodle_url('https://vimeo.com/1176321/abcdef12345');
$text = html_writer::link($url, 'Watch this one');
$content = format_text($text, FORMAT_HTML);

// Video source URL is contains the new vimeo embedded URL format.
$this->assertStringContainsString('player.vimeo.com/video/1176321?h=abcdef12345', $content);

$this->assertMatchesRegularExpression('~mediaplugin_vimeo~', $content);
$this->assertMatchesRegularExpression('~</iframe>~', $content);
$this->assertMatchesRegularExpression('~width="' . $CFG->media_default_width . '" height="' .
$CFG->media_default_height . '"~', $content);
}

/**
* Test that mediaplugin filter adds player code on top of <video> tags
* and test that player plugin is parse the URL with the code.
*
* filter_mediaplugin is enabled by default.
*/
public function test_embed_media_with_code() {
global $CFG;
$url = new moodle_url('https://vimeo.com/1176321/abcdef12345');
$trackurl = new moodle_url('http://example.org/some_filename.vtt');
$text = '<video controls="true"><source src="'.$url.'"/>' .
'<track src="'.$trackurl.'">Unsupported text</video>';
$content = format_text($text, FORMAT_HTML);

// Video source URL is contains the new vimeo embedded URL format.
$this->assertStringContainsString('player.vimeo.com/video/1176321?h=abcdef12345', $content);

$this->assertMatchesRegularExpression('~mediaplugin_vimeo~', $content);
$this->assertMatchesRegularExpression('~</iframe>~', $content);
$this->assertMatchesRegularExpression('~width="' . $CFG->media_default_width . '" height="' .
$CFG->media_default_height . '"~', $content);
// Video tag, unsupported text and tracks are removed.
$this->assertDoesNotMatchRegularExpression('~</video>~', $content);
$this->assertDoesNotMatchRegularExpression('~<source\b~', $content);
$this->assertDoesNotMatchRegularExpression('~Unsupported text~', $content);
$this->assertDoesNotMatchRegularExpression('~<track\b~i', $content);

// Video with dimensions and source specified as src attribute without <source> tag.
$text = '<video controls="true" width="123" height="35" src="'.$url.'">Unsupported text</video>';
$content = format_text($text, FORMAT_HTML);
$this->assertMatchesRegularExpression('~mediaplugin_vimeo~', $content);
$this->assertMatchesRegularExpression('~</iframe>~', $content);
$this->assertMatchesRegularExpression('~width="123" height="35"~', $content);
}

/**
* Test that mediaplugin filter skip the process when the URL is invalid.
*/
public function test_skip_invalid_url_format_with_code() {
$url = new moodle_url('https://vimeo.com/_________/abcdef12345s');
$text = html_writer::link($url, 'Invalid Vimeo URL');
$content = format_text($text, FORMAT_HTML);

$this->assertStringNotContainsString('player.vimeo.com/video/_________?h=abcdef12345s', $content);
$this->assertDoesNotMatchRegularExpression('~mediaplugin_vimeo~', $content);
$this->assertDoesNotMatchRegularExpression('~</iframe>~', $content);
}
}

0 comments on commit 9b67243

Please sign in to comment.