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.
   1  <?php
   2  
   3  /*
   4   * This file is part of Mustache.php.
   5   *
   6   * (c) 2010-2017 Justin Hileman
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  /**
  13   * Mustache Cache filesystem implementation.
  14   *
  15   * A FilesystemCache instance caches Mustache Template classes from the filesystem by name:
  16   *
  17   *     $cache = new Mustache_Cache_FilesystemCache(dirname(__FILE__).'/cache');
  18   *     $cache->cache($className, $compiledSource);
  19   *
  20   * The FilesystemCache benefits from any opcode caching that may be setup in your environment. So do that, k?
  21   */
  22  class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
  23  {
  24      private $baseDir;
  25      private $fileMode;
  26  
  27      /**
  28       * Filesystem cache constructor.
  29       *
  30       * @param string $baseDir  Directory for compiled templates
  31       * @param int    $fileMode Override default permissions for cache files. Defaults to using the system-defined umask
  32       */
  33      public function __construct($baseDir, $fileMode = null)
  34      {
  35          $this->baseDir = $baseDir;
  36          $this->fileMode = $fileMode;
  37      }
  38  
  39      /**
  40       * Load the class from cache using `require_once`.
  41       *
  42       * @param string $key
  43       *
  44       * @return bool
  45       */
  46      public function load($key)
  47      {
  48          $fileName = $this->getCacheFilename($key);
  49          if (!is_file($fileName)) {
  50              return false;
  51          }
  52  
  53          require_once $fileName;
  54  
  55          return true;
  56      }
  57  
  58      /**
  59       * Cache and load the compiled class.
  60       *
  61       * @param string $key
  62       * @param string $value
  63       */
  64      public function cache($key, $value)
  65      {
  66          $fileName = $this->getCacheFilename($key);
  67  
  68          $this->log(
  69              Mustache_Logger::DEBUG,
  70              'Writing to template cache: "{fileName}"',
  71              array('fileName' => $fileName)
  72          );
  73  
  74          $this->writeFile($fileName, $value);
  75          $this->load($key);
  76      }
  77  
  78      /**
  79       * Build the cache filename.
  80       * Subclasses should override for custom cache directory structures.
  81       *
  82       * @param string $name
  83       *
  84       * @return string
  85       */
  86      protected function getCacheFilename($name)
  87      {
  88          return sprintf('%s/%s.php', $this->baseDir, $name);
  89      }
  90  
  91      /**
  92       * Create cache directory.
  93       *
  94       * @throws Mustache_Exception_RuntimeException If unable to create directory
  95       *
  96       * @param string $fileName
  97       *
  98       * @return string
  99       */
 100      private function buildDirectoryForFilename($fileName)
 101      {
 102          $dirName = dirname($fileName);
 103          if (!is_dir($dirName)) {
 104              $this->log(
 105                  Mustache_Logger::INFO,
 106                  'Creating Mustache template cache directory: "{dirName}"',
 107                  array('dirName' => $dirName)
 108              );
 109  
 110              @mkdir($dirName, 0777, true);
 111              // @codeCoverageIgnoreStart
 112              if (!is_dir($dirName)) {
 113                  throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName));
 114              }
 115              // @codeCoverageIgnoreEnd
 116          }
 117  
 118          return $dirName;
 119      }
 120  
 121      /**
 122       * Write cache file.
 123       *
 124       * @throws Mustache_Exception_RuntimeException If unable to write file
 125       *
 126       * @param string $fileName
 127       * @param string $value
 128       */
 129      private function writeFile($fileName, $value)
 130      {
 131          $dirName = $this->buildDirectoryForFilename($fileName);
 132  
 133          $this->log(
 134              Mustache_Logger::DEBUG,
 135              'Caching compiled template to "{fileName}"',
 136              array('fileName' => $fileName)
 137          );
 138  
 139          $tempFile = tempnam($dirName, basename($fileName));
 140          if (false !== @file_put_contents($tempFile, $value)) {
 141              if (@rename($tempFile, $fileName)) {
 142                  $mode = isset($this->fileMode) ? $this->fileMode : (0666 & ~umask());
 143                  @chmod($fileName, $mode);
 144  
 145                  return;
 146              }
 147  
 148              // @codeCoverageIgnoreStart
 149              $this->log(
 150                  Mustache_Logger::ERROR,
 151                  'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"',
 152                  array('tempName' => $tempFile, 'fileName' => $fileName)
 153              );
 154              // @codeCoverageIgnoreEnd
 155          }
 156  
 157          // @codeCoverageIgnoreStart
 158          throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName));
 159          // @codeCoverageIgnoreEnd
 160      }
 161  }