[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/url/ -> locallib.php (source)

   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 &amp;
  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 &amp; entity
 130      $fullurl = str_replace('&', '&amp;', $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&amp;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('&amp;', '&', $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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1