diff --git a/media/player/vimeo/classes/plugin.php b/media/player/vimeo/classes/plugin.php
index 80a8601b23c..8908ad68c5a 100644
--- a/media/player/vimeo/classes/plugin.php
+++ b/media/player/vimeo/classes/plugin.php
@@ -34,7 +34,7 @@ defined('MOODLE_INTERNAL') || die();
*/
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
@@ -53,6 +53,33 @@ OET;
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
@@ -60,8 +87,8 @@ OET;
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;
}
diff --git a/media/player/vimeo/tests/player_test.php b/media/player/vimeo/tests/player_test.php
index 3e669891f11..889285c35db 100644
--- a/media/player/vimeo/tests/player_test.php
+++ b/media/player/vimeo/tests/player_test.php
@@ -131,4 +131,104 @@ class media_vimeo_testcase extends advanced_testcase {
$this->assertMatchesRegularExpression('~~', $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('~~', $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('~~', $content);
+ $this->assertMatchesRegularExpression('~width="' . $CFG->media_default_width . '" height="' .
+ $CFG->media_default_height . '"~', $content);
+ }
+
+ /**
+ * Test that mediaplugin filter adds player code on top of ~', $content);
+ $this->assertDoesNotMatchRegularExpression('~assertDoesNotMatchRegularExpression('~Unsupported text~', $content);
+ $this->assertDoesNotMatchRegularExpression('~