[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * Private url module utility functions 20 * 21 * @package mod_url 22 * @copyright 2009 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die; 27 28 require_once("$CFG->libdir/filelib.php"); 29 require_once("$CFG->libdir/resourcelib.php"); 30 require_once("$CFG->dirroot/mod/url/lib.php"); 31 32 /** 33 * This methods does weak url validation, we are looking for major problems only, 34 * no strict RFE validation. 35 * 36 * @param $url 37 * @return bool true is seems valid, false if definitely not valid URL 38 */ 39 function url_appears_valid_url($url) { 40 if (preg_match('/^(\/|https?:|ftp:)/i', $url)) { 41 // note: this is not exact validation, we look for severely malformed URLs only 42 return (bool)preg_match('/^[a-z]+:\/\/([^:@\s]+:[^@\s]+@)?[a-z0-9_\.\-]+(:[0-9]+)?(\/[^#]*)?(#.*)?$/i', $url); 43 } else { 44 return (bool)preg_match('/^[a-z]+:\/\/...*$/i', $url); 45 } 46 } 47 48 /** 49 * Fix common URL problems that we want teachers to see fixed 50 * the next time they edit the resource. 51 * 52 * This function does not include any XSS protection. 53 * 54 * @param string $url 55 * @return string 56 */ 57 function url_fix_submitted_url($url) { 58 // note: empty urls are prevented in form validation 59 $url = trim($url); 60 61 // remove encoded entities - we want the raw URI here 62 $url = html_entity_decode($url, ENT_QUOTES, 'UTF-8'); 63 64 if (!preg_match('|^[a-z]+:|i', $url) and !preg_match('|^/|', $url)) { 65 // invalid URI, try to fix it by making it normal URL, 66 // please note relative urls are not allowed, /xx/yy links are ok 67 $url = 'http://'.$url; 68 } 69 70 return $url; 71 } 72 73 /** 74 * Return full url with all extra parameters 75 * 76 * This function does not include any XSS protection. 77 * 78 * @param string $url 79 * @param object $cm 80 * @param object $course 81 * @param object $config 82 * @return string url with & encoded as & 83 */ 84 function url_get_full_url($url, $cm, $course, $config=null) { 85 86 $parameters = empty($url->parameters) ? array() : unserialize($url->parameters); 87 88 // make sure there are no encoded entities, it is ok to do this twice 89 $fullurl = html_entity_decode($url->externalurl, ENT_QUOTES, 'UTF-8'); 90 91 if (preg_match('/^(\/|https?:|ftp:)/i', $fullurl) or preg_match('|^/|', $fullurl)) { 92 // encode extra chars in URLs - this does not make it always valid, but it helps with some UTF-8 problems 93 $allowed = "a-zA-Z0-9".preg_quote(';/?:@=&$_.+!*(),-#%', '/'); 94 $fullurl = preg_replace_callback("/[^$allowed]/", 'url_filter_callback', $fullurl); 95 } else { 96 // encode special chars only 97 $fullurl = str_replace('"', '%22', $fullurl); 98 $fullurl = str_replace('\'', '%27', $fullurl); 99 $fullurl = str_replace(' ', '%20', $fullurl); 100 $fullurl = str_replace('<', '%3C', $fullurl); 101 $fullurl = str_replace('>', '%3E', $fullurl); 102 } 103 104 // add variable url parameters 105 if (!empty($parameters)) { 106 if (!$config) { 107 $config = get_config('url'); 108 } 109 $paramvalues = url_get_variable_values($url, $cm, $course, $config); 110 111 foreach ($parameters as $parse=>$parameter) { 112 if (isset($paramvalues[$parameter])) { 113 $parameters[$parse] = rawurlencode($parse).'='.rawurlencode($paramvalues[$parameter]); 114 } else { 115 unset($parameters[$parse]); 116 } 117 } 118 119 if (!empty($parameters)) { 120 if (stripos($fullurl, 'teamspeak://') === 0) { 121 $fullurl = $fullurl.'?'.implode('?', $parameters); 122 } else { 123 $join = (strpos($fullurl, '?') === false) ? '?' : '&'; 124 $fullurl = $fullurl.$join.implode('&', $parameters); 125 } 126 } 127 } 128 129 // encode all & to & entity 130 $fullurl = str_replace('&', '&', $fullurl); 131 132 return $fullurl; 133 } 134 135 /** 136 * Unicode encoding helper callback 137 * @internal 138 * @param array $matches 139 * @return string 140 */ 141 function url_filter_callback($matches) { 142 return rawurlencode($matches[0]); 143 } 144 145 /** 146 * Print url header. 147 * @param object $url 148 * @param object $cm 149 * @param object $course 150 * @return void 151 */ 152 function url_print_header($url, $cm, $course) { 153 global $PAGE, $OUTPUT; 154 155 $PAGE->set_title($course->shortname.': '.$url->name); 156 $PAGE->set_heading($course->fullname); 157 $PAGE->set_activity_record($url); 158 echo $OUTPUT->header(); 159 } 160 161 /** 162 * Print url heading. 163 * @param object $url 164 * @param object $cm 165 * @param object $course 166 * @param bool $notused This variable is no longer used. 167 * @return void 168 */ 169 function url_print_heading($url, $cm, $course, $notused = false) { 170 global $OUTPUT; 171 echo $OUTPUT->heading(format_string($url->name), 2); 172 } 173 174 /** 175 * Print url introduction. 176 * @param object $url 177 * @param object $cm 178 * @param object $course 179 * @param bool $ignoresettings print even if not specified in modedit 180 * @return void 181 */ 182 function url_print_intro($url, $cm, $course, $ignoresettings=false) { 183 global $OUTPUT; 184 185 $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions); 186 if ($ignoresettings or !empty($options['printintro'])) { 187 if (trim(strip_tags($url->intro))) { 188 echo $OUTPUT->box_start('mod_introbox', 'urlintro'); 189 echo format_module_intro('url', $url, $cm->id); 190 echo $OUTPUT->box_end(); 191 } 192 } 193 } 194 195 /** 196 * Display url frames. 197 * @param object $url 198 * @param object $cm 199 * @param object $course 200 * @return does not return 201 */ 202 function url_display_frame($url, $cm, $course) { 203 global $PAGE, $OUTPUT, $CFG; 204 205 $frame = optional_param('frameset', 'main', PARAM_ALPHA); 206 207 if ($frame === 'top') { 208 $PAGE->set_pagelayout('frametop'); 209 url_print_header($url, $cm, $course); 210 url_print_heading($url, $cm, $course); 211 url_print_intro($url, $cm, $course); 212 echo $OUTPUT->footer(); 213 die; 214 215 } else { 216 $config = get_config('url'); 217 $context = context_module::instance($cm->id); 218 $exteurl = url_get_full_url($url, $cm, $course, $config); 219 $navurl = "$CFG->wwwroot/mod/url/view.php?id=$cm->id&frameset=top"; 220 $coursecontext = context_course::instance($course->id); 221 $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext)); 222 $title = strip_tags($courseshortname.': '.format_string($url->name)); 223 $framesize = $config->framesize; 224 $modulename = s(get_string('modulename','url')); 225 $contentframetitle = s(format_string($url->name)); 226 $dir = get_string('thisdirection', 'langconfig'); 227 228 $extframe = <<<EOF 229 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 230 <html dir="$dir"> 231 <head> 232 <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 233 <title>$title</title> 234 </head> 235 <frameset rows="$framesize,*"> 236 <frame src="$navurl" title="$modulename"/> 237 <frame src="$exteurl" title="$contentframetitle"/> 238 </frameset> 239 </html> 240 EOF; 241 242 @header('Content-Type: text/html; charset=utf-8'); 243 echo $extframe; 244 die; 245 } 246 } 247 248 /** 249 * Print url info and link. 250 * @param object $url 251 * @param object $cm 252 * @param object $course 253 * @return does not return 254 */ 255 function url_print_workaround($url, $cm, $course) { 256 global $OUTPUT; 257 258 url_print_header($url, $cm, $course); 259 url_print_heading($url, $cm, $course, true); 260 url_print_intro($url, $cm, $course, true); 261 262 $fullurl = url_get_full_url($url, $cm, $course); 263 264 $display = url_get_final_display_type($url); 265 if ($display == RESOURCELIB_DISPLAY_POPUP) { 266 $jsfullurl = addslashes_js($fullurl); 267 $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions); 268 $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; 269 $height = empty($options['popupheight']) ? 450 : $options['popupheight']; 270 $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes"; 271 $extra = "onclick=\"window.open('$jsfullurl', '', '$wh'); return false;\""; 272 273 } else if ($display == RESOURCELIB_DISPLAY_NEW) { 274 $extra = "onclick=\"this.target='_blank';\""; 275 276 } else { 277 $extra = ''; 278 } 279 280 echo '<div class="urlworkaround">'; 281 print_string('clicktoopen', 'url', "<a href=\"$fullurl\" $extra>$fullurl</a>"); 282 echo '</div>'; 283 284 echo $OUTPUT->footer(); 285 die; 286 } 287 288 /** 289 * Display embedded url file. 290 * @param object $url 291 * @param object $cm 292 * @param object $course 293 * @return does not return 294 */ 295 function url_display_embed($url, $cm, $course) { 296 global $CFG, $PAGE, $OUTPUT; 297 298 $mimetype = resourcelib_guess_url_mimetype($url->externalurl); 299 $fullurl = url_get_full_url($url, $cm, $course); 300 $title = $url->name; 301 302 $link = html_writer::tag('a', $fullurl, array('href'=>str_replace('&', '&', $fullurl))); 303 $clicktoopen = get_string('clicktoopen', 'url', $link); 304 $moodleurl = new moodle_url($fullurl); 305 306 $extension = resourcelib_get_extension($url->externalurl); 307 308 $mediarenderer = $PAGE->get_renderer('core', 'media'); 309 $embedoptions = array( 310 core_media::OPTION_TRUSTED => true, 311 core_media::OPTION_BLOCK => true 312 ); 313 314 if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) { // It's an image 315 $code = resourcelib_embed_image($fullurl, $title); 316 317 } else if ($mediarenderer->can_embed_url($moodleurl, $embedoptions)) { 318 // Media (audio/video) file. 319 $code = $mediarenderer->embed_url($moodleurl, $title, 0, 0, $embedoptions); 320 321 } else { 322 // anything else - just try object tag enlarged as much as possible 323 $code = resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype); 324 } 325 326 url_print_header($url, $cm, $course); 327 url_print_heading($url, $cm, $course); 328 329 echo $code; 330 331 url_print_intro($url, $cm, $course); 332 333 echo $OUTPUT->footer(); 334 die; 335 } 336 337 /** 338 * Decide the best display format. 339 * @param object $url 340 * @return int display type constant 341 */ 342 function url_get_final_display_type($url) { 343 global $CFG; 344 345 if ($url->display != RESOURCELIB_DISPLAY_AUTO) { 346 return $url->display; 347 } 348 349 // detect links to local moodle pages 350 if (strpos($url->externalurl, $CFG->wwwroot) === 0) { 351 if (strpos($url->externalurl, 'file.php') === false and strpos($url->externalurl, '.php') !== false ) { 352 // most probably our moodle page with navigation 353 return RESOURCELIB_DISPLAY_OPEN; 354 } 355 } 356 357 static $download = array('application/zip', 'application/x-tar', 'application/g-zip', // binary formats 358 'application/pdf', 'text/html'); // these are known to cause trouble for external links, sorry 359 static $embed = array('image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', // images 360 'application/x-shockwave-flash', 'video/x-flv', 'video/x-ms-wm', // video formats 361 'video/quicktime', 'video/mpeg', 'video/mp4', 362 'audio/mp3', 'audio/x-realaudio-plugin', 'x-realaudio-plugin', // audio formats, 363 ); 364 365 $mimetype = resourcelib_guess_url_mimetype($url->externalurl); 366 367 if (in_array($mimetype, $download)) { 368 return RESOURCELIB_DISPLAY_DOWNLOAD; 369 } 370 if (in_array($mimetype, $embed)) { 371 return RESOURCELIB_DISPLAY_EMBED; 372 } 373 374 // let the browser deal with it somehow 375 return RESOURCELIB_DISPLAY_OPEN; 376 } 377 378 /** 379 * Get the parameters that may be appended to URL 380 * @param object $config url module config options 381 * @return array array describing opt groups 382 */ 383 function url_get_variable_options($config) { 384 global $CFG; 385 386 $options = array(); 387 $options[''] = array('' => get_string('chooseavariable', 'url')); 388 389 $options[get_string('course')] = array( 390 'courseid' => 'id', 391 'coursefullname' => get_string('fullnamecourse'), 392 'courseshortname' => get_string('shortnamecourse'), 393 'courseidnumber' => get_string('idnumbercourse'), 394 'coursesummary' => get_string('summary'), 395 'courseformat' => get_string('format'), 396 ); 397 398 $options[get_string('modulename', 'url')] = array( 399 'urlinstance' => 'id', 400 'urlcmid' => 'cmid', 401 'urlname' => get_string('name'), 402 'urlidnumber' => get_string('idnumbermod'), 403 ); 404 405 $options[get_string('miscellaneous')] = array( 406 'sitename' => get_string('fullsitename'), 407 'serverurl' => get_string('serverurl', 'url'), 408 'currenttime' => get_string('time'), 409 'lang' => get_string('language'), 410 ); 411 if (!empty($config->secretphrase)) { 412 $options[get_string('miscellaneous')]['encryptedcode'] = get_string('encryptedcode'); 413 } 414 415 $options[get_string('user')] = array( 416 'userid' => 'id', 417 'userusername' => get_string('username'), 418 'useridnumber' => get_string('idnumber'), 419 'userfirstname' => get_string('firstname'), 420 'userlastname' => get_string('lastname'), 421 'userfullname' => get_string('fullnameuser'), 422 'useremail' => get_string('email'), 423 'usericq' => get_string('icqnumber'), 424 'userphone1' => get_string('phone1'), 425 'userphone2' => get_string('phone2'), 426 'userinstitution' => get_string('institution'), 427 'userdepartment' => get_string('department'), 428 'useraddress' => get_string('address'), 429 'usercity' => get_string('city'), 430 'usertimezone' => get_string('timezone'), 431 'userurl' => get_string('webpage'), 432 ); 433 434 if ($config->rolesinparams) { 435 $roles = role_fix_names(get_all_roles()); 436 $roleoptions = array(); 437 foreach ($roles as $role) { 438 $roleoptions['course'.$role->shortname] = get_string('yourwordforx', '', $role->localname); 439 } 440 $options[get_string('roles')] = $roleoptions; 441 } 442 443 return $options; 444 } 445 446 /** 447 * Get the parameter values that may be appended to URL 448 * @param object $url module instance 449 * @param object $cm 450 * @param object $course 451 * @param object $config module config options 452 * @return array of parameter values 453 */ 454 function url_get_variable_values($url, $cm, $course, $config) { 455 global $USER, $CFG; 456 457 $site = get_site(); 458 459 $coursecontext = context_course::instance($course->id); 460 461 $values = array ( 462 'courseid' => $course->id, 463 'coursefullname' => format_string($course->fullname), 464 'courseshortname' => format_string($course->shortname, true, array('context' => $coursecontext)), 465 'courseidnumber' => $course->idnumber, 466 'coursesummary' => $course->summary, 467 'courseformat' => $course->format, 468 'lang' => current_language(), 469 'sitename' => format_string($site->fullname), 470 'serverurl' => $CFG->wwwroot, 471 'currenttime' => time(), 472 'urlinstance' => $url->id, 473 'urlcmid' => $cm->id, 474 'urlname' => format_string($url->name), 475 'urlidnumber' => $cm->idnumber, 476 ); 477 478 if (isloggedin()) { 479 $values['userid'] = $USER->id; 480 $values['userusername'] = $USER->username; 481 $values['useridnumber'] = $USER->idnumber; 482 $values['userfirstname'] = $USER->firstname; 483 $values['userlastname'] = $USER->lastname; 484 $values['userfullname'] = fullname($USER); 485 $values['useremail'] = $USER->email; 486 $values['usericq'] = $USER->icq; 487 $values['userphone1'] = $USER->phone1; 488 $values['userphone2'] = $USER->phone2; 489 $values['userinstitution'] = $USER->institution; 490 $values['userdepartment'] = $USER->department; 491 $values['useraddress'] = $USER->address; 492 $values['usercity'] = $USER->city; 493 $now = new DateTime('now', core_date::get_user_timezone_object()); 494 $values['usertimezone'] = $now->getOffset() / 3600.0; // Value in hours for BC. 495 $values['userurl'] = $USER->url; 496 } 497 498 // weak imitation of Single-Sign-On, for backwards compatibility only 499 // NOTE: login hack is not included in 2.0 any more, new contrib auth plugin 500 // needs to be createed if somebody needs the old functionality! 501 if (!empty($config->secretphrase)) { 502 $values['encryptedcode'] = url_get_encrypted_parameter($url, $config); 503 } 504 505 //hmm, this is pretty fragile and slow, why do we need it here?? 506 if ($config->rolesinparams) { 507 $coursecontext = context_course::instance($course->id); 508 $roles = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS); 509 foreach ($roles as $role) { 510 $values['course'.$role->shortname] = $role->localname; 511 } 512 } 513 514 return $values; 515 } 516 517 /** 518 * BC internal function 519 * @param object $url 520 * @param object $config 521 * @return string 522 */ 523 function url_get_encrypted_parameter($url, $config) { 524 global $CFG; 525 526 if (file_exists("$CFG->dirroot/local/externserverfile.php")) { 527 require_once("$CFG->dirroot/local/externserverfile.php"); 528 if (function_exists('extern_server_file')) { 529 return extern_server_file($url, $config); 530 } 531 } 532 return md5(getremoteaddr().$config->secretphrase); 533 } 534 535 /** 536 * Optimised mimetype detection from general URL 537 * @param $fullurl 538 * @param int $size of the icon. 539 * @return string|null mimetype or null when the filetype is not relevant. 540 */ 541 function url_guess_icon($fullurl, $size = null) { 542 global $CFG; 543 require_once("$CFG->libdir/filelib.php"); 544 545 if (substr_count($fullurl, '/') < 3 or substr($fullurl, -1) === '/') { 546 // Most probably default directory - index.php, index.html, etc. Return null because 547 // we want to use the default module icon instead of the HTML file icon. 548 return null; 549 } 550 551 $icon = file_extension_icon($fullurl, $size); 552 $htmlicon = file_extension_icon('.htm', $size); 553 $unknownicon = file_extension_icon('', $size); 554 555 // We do not want to return those icon types, the module icon is more appropriate. 556 if ($icon === $unknownicon || $icon === $htmlicon) { 557 return null; 558 } 559 560 return $icon; 561 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |