Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
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 * Main class for plugin 'media_youtube' 19 * 20 * @package media_youtube 21 * @copyright 2016 Marina Glancy 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 /** 28 * Player that creates youtube embedding. 29 * 30 * @package media_youtube 31 * @author 2011 The Open University 32 * @copyright 2016 Marina Glancy 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class media_youtube_plugin extends core_media_player_external { 36 /** 37 * Stores whether the playlist regex was matched last time when 38 * {@link list_supported_urls()} was called 39 * @var bool 40 */ 41 protected $isplaylist = false; 42 43 public function list_supported_urls(array $urls, array $options = array()) { 44 // These only work with a SINGLE url (there is no fallback). 45 if (count($urls) == 1) { 46 $url = reset($urls); 47 48 // Check against regex. 49 if (preg_match($this->get_regex(), $url->out(false), $this->matches)) { 50 $this->isplaylist = false; 51 return array($url); 52 } 53 54 // Check against playlist regex. 55 if (preg_match($this->get_regex_playlist(), $url->out(false), $this->matches)) { 56 $this->isplaylist = true; 57 return array($url); 58 } 59 } 60 61 return array(); 62 } 63 64 protected function embed_external(moodle_url $url, $name, $width, $height, $options) { 65 global $OUTPUT; 66 $nocookie = get_config('media_youtube', 'nocookie'); 67 68 $info = trim($name ?? ''); 69 if (empty($info) or strpos($info, 'http') === 0) { 70 $info = get_string('pluginname', 'media_youtube'); 71 } 72 $info = s($info); 73 74 self::pick_video_size($width, $height); 75 76 // Template context. 77 $context = [ 78 'width' => $width, 79 'height' => $height, 80 'title' => $info 81 ]; 82 83 if ($this->isplaylist) { 84 $site = $this->matches[1]; 85 $playlist = $this->matches[3]; 86 87 $params = ['list' => $playlist]; 88 89 // Handle no cookie option. 90 if (!$nocookie) { 91 $embedurl = new moodle_url("https://$site/embed/videoseries", $params); 92 } else { 93 $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/videoseries', $params ); 94 } 95 $context['embedurl'] = $embedurl->out(false); 96 97 // Return the rendered template. 98 return $OUTPUT->render_from_template('media_youtube/embed', $context); 99 100 } else { 101 $videoid = end($this->matches); 102 $params = []; 103 $start = self::get_start_time($url); 104 if ($start > 0) { 105 $params['start'] = $start; 106 } 107 108 $listid = $url->param('list'); 109 // Check for non-empty but valid playlist ID. 110 if (!empty($listid) && !preg_match('/[^a-zA-Z0-9\-_]/', $listid)) { 111 // This video is part of a playlist, and we want to embed it as such. 112 $params['list'] = $listid; 113 } 114 115 // Add parameters to object to be passed to the mustache template. 116 $params['rel'] = 0; 117 $params['wmode'] = 'transparent'; 118 119 // Handle no cookie option. 120 if (!$nocookie) { 121 $embedurl = new moodle_url('https://www.youtube.com/embed/' . $videoid, $params ); 122 } else { 123 $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/' . $videoid, $params ); 124 } 125 126 $context['embedurl'] = $embedurl->out(false); 127 128 // Return the rendered template. 129 return $OUTPUT->render_from_template('media_youtube/embed', $context); 130 } 131 132 } 133 134 /** 135 * Check for start time parameter. Note that it's in hours/mins/secs in the URL, 136 * but the embedded player takes only a number of seconds as the "start" parameter. 137 * @param moodle_url $url URL of video to be embedded. 138 * @return int Number of seconds video should start at. 139 */ 140 protected static function get_start_time($url) { 141 $matches = array(); 142 $seconds = 0; 143 144 $rawtime = $url->param('t'); 145 if (empty($rawtime)) { 146 $rawtime = $url->param('start'); 147 } 148 149 if (is_numeric($rawtime)) { 150 // Start time already specified as a number of seconds; ensure it's an integer. 151 $seconds = $rawtime; 152 } else if (preg_match('/(\d+?h)?(\d+?m)?(\d+?s)?/i', $rawtime ?? '', $matches)) { 153 // Convert into a raw number of seconds, as that's all embedded players accept. 154 for ($i = 1; $i < count($matches); $i++) { 155 if (empty($matches[$i])) { 156 continue; 157 } 158 $part = str_split($matches[$i], strlen($matches[$i]) - 1); 159 switch ($part[1]) { 160 case 'h': 161 $seconds += 3600 * $part[0]; 162 break; 163 case 'm': 164 $seconds += 60 * $part[0]; 165 break; 166 default: 167 $seconds += $part[0]; 168 } 169 } 170 } 171 172 return intval($seconds); 173 } 174 175 /** 176 * Returns regular expression used to match URLs for single youtube video 177 * @return string PHP regular expression e.g. '~^https?://example.org/~' 178 */ 179 protected function get_regex() { 180 // Regex for standard youtube link. 181 $link = '(youtube(-nocookie)?\.com/(?:watch\?v=|v/))'; 182 // Regex for shortened youtube link. 183 $shortlink = '((youtu|y2u)\.be/)'; 184 185 // Initial part of link. 186 $start = '~^https?://((www|m)\.)?(' . $link . '|' . $shortlink . ')'; 187 // Middle bit: Video key value. 188 $middle = '([a-z0-9\-_]+)'; 189 return $start . $middle . core_media_player_external::END_LINK_REGEX_PART; 190 } 191 192 /** 193 * Returns regular expression used to match URLs for youtube playlist 194 * @return string PHP regular expression e.g. '~^https?://example.org/~' 195 */ 196 protected function get_regex_playlist() { 197 // Initial part of link. 198 $start = '~^https?://(www\.youtube(-nocookie)?\.com)/'; 199 // Middle bit: either view_play_list?p= or p/ (doesn't work on youtube) or playlist?list=. 200 $middle = '(?:view_play_list\?p=|p/|playlist\?list=)([a-z0-9\-_]+)'; 201 return $start . $middle . core_media_player_external::END_LINK_REGEX_PART; 202 } 203 204 public function get_embeddable_markers() { 205 return array('youtube.com', 'youtube-nocookie.com', 'youtu.be', 'y2u.be'); 206 } 207 208 /** 209 * Default rank 210 * @return int 211 */ 212 public function get_rank() { 213 return 1001; 214 } 215 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body