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.
/lib/ -> jslib.php (source)
   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   * This file contains various javascript related functions,
  19   * all functions here are self contained and can be used in ABORT_AFTER_CONFIG scripts.
  20   *
  21   * @package   core_lib
  22   * @copyright 2012 Petr Skoda (skodak)  {@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  /**
  29   * Send javascript file content with as much caching as possible
  30   * @param string $jspath
  31   * @param string $etag
  32   * @param string $filename
  33   */
  34  function js_send_cached($jspath, $etag, $filename = 'javascript.php') {
  35      require (__DIR__ . '/xsendfilelib.php');
  36  
  37      // 90 days only - based on Moodle point release cadence being every 3 months.
  38      $lifetime = 60 * 60 * 24 * 90;
  39  
  40      header('Etag: "'.$etag.'"');
  41      header('Content-Disposition: inline; filename="'.$filename.'"');
  42      header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($jspath)) .' GMT');
  43      header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
  44      header('Pragma: ');
  45      header('Cache-Control: public, max-age='.$lifetime.', immutable');
  46      header('Accept-Ranges: none');
  47      header('Content-Type: application/javascript; charset=utf-8');
  48  
  49      if (xsendfile($jspath)) {
  50          die;
  51      }
  52  
  53      if (!min_enable_zlib_compression()) {
  54          header('Content-Length: '.filesize($jspath));
  55      }
  56  
  57      readfile($jspath);
  58      die;
  59  }
  60  
  61  /**
  62   * Send javascript without any caching
  63   * @param string $js
  64   * @param string $filename
  65   */
  66  function js_send_uncached($js, $filename = 'javascript.php') {
  67      header('Content-Disposition: inline; filename="'.$filename.'"');
  68      header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT');
  69      header('Expires: '. gmdate('D, d M Y H:i:s', time() + 2) .' GMT');
  70      header('Pragma: ');
  71      header('Accept-Ranges: none');
  72      header('Content-Type: application/javascript; charset=utf-8');
  73      header('Content-Length: '.strlen($js));
  74  
  75      echo $js;
  76      die;
  77  }
  78  
  79  /**
  80   * Send file not modified headers
  81   * @param int $lastmodified
  82   * @param string $etag
  83   */
  84  function js_send_unmodified($lastmodified, $etag) {
  85      // 90 days only - based on Moodle point release cadence being every 3 months.
  86      $lifetime = 60 * 60 * 24 * 90;
  87      header('HTTP/1.1 304 Not Modified');
  88      header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
  89      header('Cache-Control: public, max-age='.$lifetime);
  90      header('Content-Type: application/javascript; charset=utf-8');
  91      header('Etag: "'.$etag.'"');
  92      if ($lastmodified) {
  93          header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastmodified) .' GMT');
  94      }
  95      die;
  96  }
  97  
  98  /**
  99   * Create cache file for JS content
 100   * @param string $file full file path to cache file
 101   * @param string $content JS code
 102   */
 103  function js_write_cache_file_content($file, $content) {
 104      global $CFG;
 105  
 106      clearstatcache();
 107      if (!file_exists(dirname($file))) {
 108          @mkdir(dirname($file), $CFG->directorypermissions, true);
 109      }
 110  
 111      // Prevent serving of incomplete file from concurrent request,
 112      // the rename() should be more atomic than fwrite().
 113      ignore_user_abort(true);
 114      if ($fp = fopen($file.'.tmp', 'xb')) {
 115          fwrite($fp, $content);
 116          fclose($fp);
 117          rename($file.'.tmp', $file);
 118          @chmod($file, $CFG->filepermissions);
 119          @unlink($file.'.tmp'); // just in case anything fails
 120      }
 121      ignore_user_abort(false);
 122      if (connection_aborted()) {
 123          die;
 124      }
 125  }
 126  
 127  /**
 128   * Sends a 404 message about CSS not being found.
 129   */
 130  function js_send_css_not_found() {
 131      header('HTTP/1.0 404 not found');
 132      die('JS was not found, sorry.');
 133  }