See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 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 66 $info = trim($name ?? ''); 67 if (empty($info) or strpos($info, 'http') === 0) { 68 $info = get_string('pluginname', 'media_youtube'); 69 } 70 $info = s($info); 71 72 self::pick_video_size($width, $height); 73 74 if ($this->isplaylist) { 75 76 $site = $this->matches[1]; 77 $playlist = $this->matches[3]; 78 79 return <<<OET 80 <span class="mediaplugin mediaplugin_youtube"> 81 <iframe width="$width" height="$height" src="https://$site/embed/videoseries?list=$playlist" frameborder="0" allowfullscreen="1"></iframe> 82 </span> 83 OET; 84 } else { 85 86 $videoid = end($this->matches); 87 $params = ''; 88 $start = self::get_start_time($url); 89 if ($start > 0) { 90 $params .= "start=$start&"; 91 } 92 93 $listid = $url->param('list'); 94 // Check for non-empty but valid playlist ID. 95 if (!empty($listid) && !preg_match('/[^a-zA-Z0-9\-_]/', $listid)) { 96 // This video is part of a playlist, and we want to embed it as such. 97 $params .= "list=$listid&"; 98 } 99 100 return <<<OET 101 <span class="mediaplugin mediaplugin_youtube"> 102 <iframe title="$info" width="$width" height="$height" 103 src="https://www.youtube.com/embed/$videoid?{$params}rel=0&wmode=transparent" frameborder="0" allowfullscreen="1"></iframe> 104 </span> 105 OET; 106 } 107 108 } 109 110 /** 111 * Check for start time parameter. Note that it's in hours/mins/secs in the URL, 112 * but the embedded player takes only a number of seconds as the "start" parameter. 113 * @param moodle_url $url URL of video to be embedded. 114 * @return int Number of seconds video should start at. 115 */ 116 protected static function get_start_time($url) { 117 $matches = array(); 118 $seconds = 0; 119 120 $rawtime = $url->param('t'); 121 if (empty($rawtime)) { 122 $rawtime = $url->param('start'); 123 } 124 125 if (is_numeric($rawtime)) { 126 // Start time already specified as a number of seconds; ensure it's an integer. 127 $seconds = $rawtime; 128 } else if (preg_match('/(\d+?h)?(\d+?m)?(\d+?s)?/i', $rawtime ?? '', $matches)) { 129 // Convert into a raw number of seconds, as that's all embedded players accept. 130 for ($i = 1; $i < count($matches); $i++) { 131 if (empty($matches[$i])) { 132 continue; 133 } 134 $part = str_split($matches[$i], strlen($matches[$i]) - 1); 135 switch ($part[1]) { 136 case 'h': 137 $seconds += 3600 * $part[0]; 138 break; 139 case 'm': 140 $seconds += 60 * $part[0]; 141 break; 142 default: 143 $seconds += $part[0]; 144 } 145 } 146 } 147 148 return intval($seconds); 149 } 150 151 /** 152 * Returns regular expression used to match URLs for single youtube video 153 * @return string PHP regular expression e.g. '~^https?://example.org/~' 154 */ 155 protected function get_regex() { 156 // Regex for standard youtube link. 157 $link = '(youtube(-nocookie)?\.com/(?:watch\?v=|v/))'; 158 // Regex for shortened youtube link. 159 $shortlink = '((youtu|y2u)\.be/)'; 160 161 // Initial part of link. 162 $start = '~^https?://((www|m)\.)?(' . $link . '|' . $shortlink . ')'; 163 // Middle bit: Video key value. 164 $middle = '([a-z0-9\-_]+)'; 165 return $start . $middle . core_media_player_external::END_LINK_REGEX_PART; 166 } 167 168 /** 169 * Returns regular expression used to match URLs for youtube playlist 170 * @return string PHP regular expression e.g. '~^https?://example.org/~' 171 */ 172 protected function get_regex_playlist() { 173 // Initial part of link. 174 $start = '~^https?://(www\.youtube(-nocookie)?\.com)/'; 175 // Middle bit: either view_play_list?p= or p/ (doesn't work on youtube) or playlist?list=. 176 $middle = '(?:view_play_list\?p=|p/|playlist\?list=)([a-z0-9\-_]+)'; 177 return $start . $middle . core_media_player_external::END_LINK_REGEX_PART; 178 } 179 180 public function get_embeddable_markers() { 181 return array('youtube.com', 'youtube-nocookie.com', 'youtu.be', 'y2u.be'); 182 } 183 184 /** 185 * Default rank 186 * @return int 187 */ 188 public function get_rank() { 189 return 1001; 190 } 191 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body