From 6d38972cbc7755828bcc553ba09503852fa8cfb3 Mon Sep 17 00:00:00 2001 From: Matt Porritt Date: Sat, 24 Jun 2023 15:23:36 +1000 Subject: [PATCH 1/2] MDL-62401 Media: Embed Youtube Videos with nocookie extension Refactor YouTube media player to use templates. Use mustache templates for rendering YouTube embed iframe code. --- media/player/youtube/classes/plugin.php | 58 +++++++++++++------ media/player/youtube/templates/embed.mustache | 41 +++++++++++++ 2 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 media/player/youtube/templates/embed.mustache diff --git a/media/player/youtube/classes/plugin.php b/media/player/youtube/classes/plugin.php index 10216231903..acc71f488d5 100644 --- a/media/player/youtube/classes/plugin.php +++ b/media/player/youtube/classes/plugin.php @@ -62,6 +62,8 @@ class media_youtube_plugin extends core_media_player_external { } protected function embed_external(moodle_url $url, $name, $width, $height, $options) { + global $OUTPUT; + $nocookie = get_config('media_youtube', 'nocookie'); $info = trim($name ?? ''); if (empty($info) or strpos($info, 'http') === 0) { @@ -71,40 +73,60 @@ class media_youtube_plugin extends core_media_player_external { self::pick_video_size($width, $height); - if ($this->isplaylist) { + // Template context. + $context = [ + 'width' => $width, + 'height' => $height, + 'title' => $info + ]; + if ($this->isplaylist) { $site = $this->matches[1]; $playlist = $this->matches[3]; - return << - - -OET; - } else { + $params = ['list' => $playlist]; + // Handle no cookie option. + if (!$nocookie) { + $embedurl = new moodle_url("https://$site/embed/videoseries", $params); + } else { + $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/videoseries', $params ); + } + $context['embedurl'] = $embedurl->out(false); + + // Return the rendered template. + return $OUTPUT->render_from_template('media_youtube/embed', $context); + + } else { $videoid = end($this->matches); - $params = ''; + $params = []; $start = self::get_start_time($url); if ($start > 0) { - $params .= "start=$start&"; + $params['start'] = $start; } $listid = $url->param('list'); // Check for non-empty but valid playlist ID. if (!empty($listid) && !preg_match('/[^a-zA-Z0-9\-_]/', $listid)) { // This video is part of a playlist, and we want to embed it as such. - $params .= "list=$listid&"; + $params['list'] = $listid; } - return << - - -OET; + // Add parameters to object to be passed to the mustache template. + $params['rel'] = 0; + $params['wmode'] = 'transparent'; + + // Handle no cookie option. + if (!$nocookie) { + $embedurl = new moodle_url('https://www.youtube.com/embed/' . $videoid, $params ); + } else { + $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/' . $videoid, $params ); + } + + $context['embedurl'] = $embedurl->out(false); + + // Return the rendered template. + return $OUTPUT->render_from_template('media_youtube/embed', $context); } } diff --git a/media/player/youtube/templates/embed.mustache b/media/player/youtube/templates/embed.mustache new file mode 100644 index 00000000000..f4f64fe56fe --- /dev/null +++ b/media/player/youtube/templates/embed.mustache @@ -0,0 +1,41 @@ +{{! + 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 . +}} +{{! + @template media/embed + + This template will render the YouTube embeded player. + + Variables required for this template: + * info: The title of the video. + * width: The width of the video. + * height: The height of the video. + * embedurl: The URL to the video. + + Example context (json): + { + "info": "YouTube video", + "width": 640, + "height": 360, + "embedurl": "https://www.youtube.com/embed/9bZkp7q19f0?rel=0&wmode=transparent" + } + +}} + + + + From d0a5e3fb392caa4c2fe9e9d8cf3a47ad8f4f45e0 Mon Sep 17 00:00:00 2001 From: Matt Porritt Date: Sat, 24 Jun 2023 16:10:32 +1000 Subject: [PATCH 2/2] MDL-62401 Media: Embed Youtube Videos with nocookie extension Add config option to embed YouTube links using the youtube-nocookie.com YouTube domain. This will stop extra YouTube cookies from being added to the users computer it also stops calls to certain add tracking sites. --- filter/mediaplugin/tests/filter_test.php | 5 ++- .../player/youtube/lang/en/media_youtube.php | 2 ++ media/player/youtube/settings.php | 36 +++++++++++++++++++ media/player/youtube/templates/embed.mustache | 10 +++--- media/player/youtube/tests/player_test.php | 23 ++++++++++++ media/player/youtube/version.php | 2 +- 6 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 media/player/youtube/settings.php diff --git a/filter/mediaplugin/tests/filter_test.php b/filter/mediaplugin/tests/filter_test.php index 8a57f3cf254..8b198da733b 100644 --- a/filter/mediaplugin/tests/filter_test.php +++ b/filter/mediaplugin/tests/filter_test.php @@ -95,9 +95,8 @@ class filter_test extends \advanced_testcase { 'Valid link
';
         $paddedurl = str_pad($originalurl, 6000, 'z');
         $validpaddedurl = '

Some text.


-
+
 
';
         $validpaddedurl = str_pad($validpaddedurl, 6000 + (strlen($validpaddedurl) - strlen($originalurl)), 'z');
 
diff --git a/media/player/youtube/lang/en/media_youtube.php b/media/player/youtube/lang/en/media_youtube.php
index 486292ce4bf..f8834fcdedd 100644
--- a/media/player/youtube/lang/en/media_youtube.php
+++ b/media/player/youtube/lang/en/media_youtube.php
@@ -27,3 +27,5 @@ $string['pluginname_help'] = 'The video-sharing website youtube.com. Video and p
 $string['privacy:metadata'] = 'The Youtube media plugin does not store any personal data.';
 $string['supportsvideo'] = 'YouTube videos';
 $string['supportsplaylist'] = 'YouTube playlists';
+$string['nocookie'] = 'Use no cookie domain';
+$string['nocookie_desc'] = 'Use youtube-nocookie.com domain for embedding videos. This reduces the number of third party cookies used in embedding. This domain is also not blocked by some adblockers.';
diff --git a/media/player/youtube/settings.php b/media/player/youtube/settings.php
new file mode 100644
index 00000000000..a92da22053f
--- /dev/null
+++ b/media/player/youtube/settings.php
@@ -0,0 +1,36 @@
+.
+
+/**
+ * Settings file for plugin 'media_youtube'
+ *
+ * @package   media_youtube
+ * @copyright 2023 Matt Porritt fulltree) {
+    // Add the settings page.
+    $settings->add(new admin_setting_heading('media_youtube_settings',
+                    get_string('pluginname', 'media_youtube'),
+                    get_string('pluginname_help', 'media_youtube')));
+    // Add a settings checkbox to enable or disable no cookie YouTube links.
+    $settings->add(new admin_setting_configcheckbox('media_youtube/nocookie',
+        new lang_string('nocookie', 'media_youtube'),
+        new lang_string('nocookie_desc', 'media_youtube'), 0));
+}
diff --git a/media/player/youtube/templates/embed.mustache b/media/player/youtube/templates/embed.mustache
index f4f64fe56fe..ca49c401996 100644
--- a/media/player/youtube/templates/embed.mustache
+++ b/media/player/youtube/templates/embed.mustache
@@ -15,19 +15,19 @@
     along with Moodle.  If not, see .
 }}
 {{!
-    @template media/embed
+    @template media_youtube/embed
 
     This template will render the YouTube embeded player.
 
     Variables required for this template:
-    * info: The title of the video.
+    * title: The title of the video.
     * width: The width of the video.
     * height: The height of the video.
     * embedurl: The URL to the video.
 
     Example context (json):
     {
-        "info": "YouTube video",
+        "title": "YouTube video",
         "width": 640,
         "height": 360,
         "embedurl": "https://www.youtube.com/embed/9bZkp7q19f0?rel=0&wmode=transparent"
@@ -36,6 +36,6 @@
 }}
 
 
-
+
 
diff --git a/media/player/youtube/tests/player_test.php b/media/player/youtube/tests/player_test.php
index d50ec85f28d..9dd77b1d41a 100644
--- a/media/player/youtube/tests/player_test.php
+++ b/media/player/youtube/tests/player_test.php
@@ -184,4 +184,27 @@ class player_test extends \advanced_testcase {
         $this->assertMatchesRegularExpression('~~', $content);
         $this->assertMatchesRegularExpression('~width="123" height="35"~', $content);
     }
+
+    /**
+     * Test that YouTube media plugin renders embed code correctly
+     * when the "nocookie" config options is set to true.
+     *
+     * @covers \media_youtube_plugin::embed_external
+     */
+    public function test_youtube_nocookie() {
+        // Turn on the no cookie option.
+        set_config('nocookie', true, 'media_youtube');
+
+        // Test that the embed code contains the no cookie domain.
+        $url = new \moodle_url('http://www.youtube.com/v/vyrwMmsufJc');
+        $text = \html_writer::link($url, 'Watch this one');
+        $content = format_text($text, FORMAT_HTML);
+        $this->assertMatchesRegularExpression('~youtube-nocookie~', $content);
+
+        // Next test for a playlist.
+        $url = new \moodle_url('https://www.youtube.com/playlist?list=PL59FEE129ADFF2B12');
+        $text = \html_writer::link($url, 'Great Playlist');
+        $content = format_text($text, FORMAT_HTML);
+        $this->assertMatchesRegularExpression('~youtube-nocookie~', $content);
+    }
 }
diff --git a/media/player/youtube/version.php b/media/player/youtube/version.php
index d1ef347adc5..52aa77e8c4e 100644
--- a/media/player/youtube/version.php
+++ b/media/player/youtube/version.php
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2023042400;      // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version   = 2023062400;      // The current plugin version (Date: YYYYMMDDXX).
 $plugin->requires  = 2023041800;      // Requires this Moodle version.
 $plugin->component = 'media_youtube'; // Full name of the plugin (used for diagnostics).