Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   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   * Recourse module like helper functions
  20   *
  21   * @package    core
  22   * @subpackage lib
  23   * @copyright  2009 Petr Skoda (http://skodak.org)
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /** Try the best way */
  30  define('RESOURCELIB_DISPLAY_AUTO', 0);
  31  /** Display using object tag */
  32  define('RESOURCELIB_DISPLAY_EMBED', 1);
  33  /** Display inside frame */
  34  define('RESOURCELIB_DISPLAY_FRAME', 2);
  35  /** Display normal link in new window */
  36  define('RESOURCELIB_DISPLAY_NEW', 3);
  37  /** Force download of file instead of display */
  38  define('RESOURCELIB_DISPLAY_DOWNLOAD', 4);
  39  /** Open directly */
  40  define('RESOURCELIB_DISPLAY_OPEN', 5);
  41  /** Open in "emulated" pop-up without navigation */
  42  define('RESOURCELIB_DISPLAY_POPUP', 6);
  43  
  44  /** Legacy files not needed or new resource */
  45  define('RESOURCELIB_LEGACYFILES_NO', 0);
  46  /** Legacy files conversion marked as completed */
  47  define('RESOURCELIB_LEGACYFILES_DONE', 1);
  48  /** Legacy files conversion in progress*/
  49  define('RESOURCELIB_LEGACYFILES_ACTIVE', 2);
  50  
  51  
  52  /**
  53   * Try on demand migration of file from old course files
  54   * @param string $filepath old file path
  55   * @param int $cmid migrated course module if
  56   * @param int $courseid
  57   * @param string $component
  58   * @param string $filearea new file area
  59   * @param int $itemid migrated file item id
  60   * @return mixed, false if not found, stored_file instance if migrated to new area
  61   */
  62  function resourcelib_try_file_migration($filepath, $cmid, $courseid, $component, $filearea, $itemid) {
  63      $fs = get_file_storage();
  64  
  65      if (stripos($filepath, '/backupdata/') === 0 or stripos($filepath, '/moddata/') === 0) {
  66          // do not steal protected files!
  67          return false;
  68      }
  69  
  70      if (!$context = context_module::instance($cmid)) {
  71          return false;
  72      }
  73      if (!$coursecontext = context_course::instance($courseid)) {
  74          return false;
  75      }
  76  
  77      $fullpath = rtrim("/$coursecontext->id/course/legacy/0".$filepath, '/');
  78      do {
  79          if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
  80              if ($file = $fs->get_file_by_hash(sha1("$fullpath/.")) and $file->is_directory()) {
  81                  if ($file = $fs->get_file_by_hash(sha1("$fullpath/index.htm"))) {
  82                      break;
  83                  }
  84                  if ($file = $fs->get_file_by_hash(sha1("$fullpath/index.html"))) {
  85                      break;
  86                  }
  87                  if ($file = $fs->get_file_by_hash(sha1("$fullpath/Default.htm"))) {
  88                      break;
  89                  }
  90              }
  91              return false;
  92          }
  93      } while (false);
  94  
  95      // copy and keep the same path, name, etc.
  96      $file_record = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid);
  97      try {
  98          return $fs->create_file_from_storedfile($file_record, $file);
  99      } catch (Exception $e) {
 100          // file may exist - highly unlikely, we do not want upgrades to stop here
 101          return false;
 102      }
 103  }
 104  
 105  /**
 106   * Returns list of available display options
 107   * @param array $enabled list of options enabled in module configuration
 108   * @param int $current current display options for existing instances
 109   * @return array of key=>name pairs
 110   */
 111  function resourcelib_get_displayoptions(array $enabled, $current=null) {
 112      if (is_number($current)) {
 113          $enabled[] = $current;
 114      }
 115  
 116      $options = array(RESOURCELIB_DISPLAY_AUTO     => get_string('resourcedisplayauto'),
 117                       RESOURCELIB_DISPLAY_EMBED    => get_string('resourcedisplayembed'),
 118                       RESOURCELIB_DISPLAY_FRAME    => get_string('resourcedisplayframe'),
 119                       RESOURCELIB_DISPLAY_NEW      => get_string('resourcedisplaynew'),
 120                       RESOURCELIB_DISPLAY_DOWNLOAD => get_string('resourcedisplaydownload'),
 121                       RESOURCELIB_DISPLAY_OPEN     => get_string('resourcedisplayopen'),
 122                       RESOURCELIB_DISPLAY_POPUP    => get_string('resourcedisplaypopup'));
 123  
 124      $result = array();
 125  
 126      foreach ($options as $key=>$value) {
 127          if (in_array($key, $enabled)) {
 128              $result[$key] = $value;
 129          }
 130      }
 131  
 132      if (empty($result)) {
 133          // there should be always something in case admin misconfigures module
 134          $result[RESOURCELIB_DISPLAY_OPEN] = $options[RESOURCELIB_DISPLAY_OPEN];
 135      }
 136  
 137      return $result;
 138  }
 139  
 140  /**
 141   * Tries to guess correct mimetype for arbitrary URL
 142   * @param string $fullurl
 143   * @return string mimetype
 144   */
 145  function resourcelib_guess_url_mimetype($fullurl) {
 146      global $CFG;
 147      require_once("$CFG->libdir/filelib.php");
 148  
 149      if ($fullurl instanceof moodle_url) {
 150          $fullurl = $fullurl->out(false);
 151      }
 152  
 153      $matches = null;
 154      if (preg_match("|^(.*)/[a-z]*file.php(\?file=)?(/[^&\?#]*)|", $fullurl, $matches)) {
 155          // remove the special moodle file serving hacks so that the *file.php is ignored
 156          $fullurl = $matches[1].$matches[3];
 157      }
 158  
 159      if (preg_match("|^(.*)#.*|", $fullurl, $matches)) {
 160          // ignore all anchors
 161          $fullurl = $matches[1];
 162      }
 163  
 164      if (strpos($fullurl, '.php')){
 165          // we do not really know what is in general php script
 166          return 'text/html';
 167  
 168      } else if (substr($fullurl, -1) === '/') {
 169          // directory index (http://example.com/smaples/)
 170          return 'text/html';
 171  
 172      } else if (strpos($fullurl, '//') !== false and substr_count($fullurl, '/') == 2) {
 173          // just a host name (http://example.com), solves Australian servers "audio" problem too
 174          return 'text/html';
 175  
 176      } else {
 177          // ok, this finally looks like a real file
 178          $parts = explode('?', $fullurl);
 179          $url = reset($parts);
 180          return mimeinfo('type', $url);
 181      }
 182  }
 183  
 184  /**
 185   * Looks for the extension.
 186   *
 187   * @param string $fullurl
 188   * @return string file extension
 189   */
 190  function resourcelib_get_extension($fullurl) {
 191  
 192      if ($fullurl instanceof moodle_url) {
 193          $fullurl = $fullurl->out(false);
 194      }
 195  
 196      $matches = null;
 197      if (preg_match("|^(.*)/[a-z]*file.php(\?file=)?(/.*)|", $fullurl, $matches)) {
 198          // remove the special moodle file serving hacks so that the *file.php is ignored
 199          $fullurl = $matches[1].$matches[3];
 200      }
 201  
 202      $matches = null;
 203      if (preg_match('/^[^#\?]+\.([a-z0-9]+)([#\?].*)?$/i', $fullurl, $matches)) {
 204          return strtolower($matches[1]);
 205      }
 206  
 207      return '';
 208  }
 209  
 210  /**
 211   * Returns image embedding html.
 212   * @param string $fullurl
 213   * @param string $title
 214   * @return string html
 215   */
 216  function resourcelib_embed_image($fullurl, $title) {
 217      $code = '';
 218      $code .= '<div class="resourcecontent resourceimg">';
 219      $code .= "<img title=\"".s(strip_tags(format_string($title)))."\" class=\"resourceimage\" src=\"$fullurl\" alt=\"\" />";
 220      $code .= '</div>';
 221  
 222      return $code;
 223  }
 224  
 225  /**
 226   * Returns general link or pdf embedding html.
 227   * @param string $fullurl
 228   * @param string $title
 229   * @param string $clicktoopen
 230   * @return string html
 231   */
 232  function resourcelib_embed_pdf($fullurl, $title, $clicktoopen) {
 233      global $CFG, $PAGE;
 234  
 235      $code = <<<EOT
 236  <div class="resourcecontent resourcepdf">
 237    <object id="resourceobject" data="$fullurl" type="application/pdf" width="800" height="600">
 238      <param name="src" value="$fullurl" />
 239      $clicktoopen
 240    </object>
 241  </div>
 242  EOT;
 243  
 244      // the size is hardcoded in the boject obove intentionally because it is adjusted by the following function on-the-fly
 245      $PAGE->requires->js_init_call('M.util.init_maximised_embed', array('resourceobject'), true);
 246  
 247      return $code;
 248  }
 249  
 250  /**
 251   * Returns general link or file embedding html.
 252   * @param string $fullurl
 253   * @param string $title
 254   * @param string $clicktoopen
 255   * @param string $mimetype
 256   * @return string html
 257   */
 258  function resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype) {
 259      global $CFG, $PAGE;
 260  
 261      if ($fullurl instanceof moodle_url) {
 262          $fullurl = $fullurl->out();
 263      }
 264  
 265      $title = s($title);
 266  
 267      // Always use iframe embedding because object tag does not work much,
 268      // this is ok in HTML5.
 269      $code = <<<EOT
 270  <div class="resourcecontent resourcegeneral">
 271    <iframe id="resourceobject" src="$fullurl" title="$title">
 272      $clicktoopen
 273    </iframe>
 274  </div>
 275  EOT;
 276  
 277      // the size is hardcoded in the boject obove intentionally because it is adjusted by the following function on-the-fly
 278      $PAGE->requires->js_init_call('M.util.init_maximised_embed', array('resourceobject'), true);
 279  
 280      return $code;
 281  }