From 1514e0c2cd538b5264ce4bdc3469f7cd3a2eab64 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Fri, 8 Apr 2016 06:56:52 -0700 Subject: [PATCH] Add stat() options to ProductionFilesystemLoader * By default, continue to use `size` and `mtime` to invalidate template cache * Allow overriding to use any properties of `stat()` * Allow disabling stat entirely * Add a Big Kid Pants disclaimer if you choose to go down this path --- .../Loader/ProductionFilesystemLoader.php | 48 ++++++++++++++++++- src/Mustache/Source/FilesystemSource.php | 31 ++++++++---- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/Mustache/Loader/ProductionFilesystemLoader.php b/src/Mustache/Loader/ProductionFilesystemLoader.php index a79b6f4..85428f0 100644 --- a/src/Mustache/Loader/ProductionFilesystemLoader.php +++ b/src/Mustache/Loader/ProductionFilesystemLoader.php @@ -18,6 +18,52 @@ */ class Mustache_Loader_ProductionFilesystemLoader extends Mustache_Loader_FilesystemLoader { + private $statProps; + + /** + * Mustache production filesystem Loader constructor. + * + * Passing an $options array allows overriding certain Loader options during instantiation: + * + * $options = array( + * // The filename extension used for Mustache templates. Defaults to '.mustache' + * 'extension' => '.ms', + * 'stat_props' => array('size', 'mtime'), + * ); + * + * Specifying 'stat_props' overrides the stat properties used to invalidate the template cache. By default, this + * uses 'mtime' and 'size', but this can be set to any of the properties supported by stat(): + * + * http://php.net/manual/en/function.stat.php + * + * You can also disable filesystem stat entirely: + * + * $options = array('stat_props' => null); + * + * But with great power comes great responsibility. Namely, if you disable stat-based cache invalidation, + * YOU MUST CLEAR THE TEMPLATE CACHE YOURSELF when your templates change. Make it part of your build or deploy + * process so you don't forget! + * + * @throws Mustache_Exception_RuntimeException if $baseDir does not exist. + * + * @param string $baseDir Base directory containing Mustache template files. + * @param array $options Array of Loader options (default: array()) + */ + public function __construct($baseDir, array $options = array()) + { + parent::__construct($baseDir, $options); + + if (array_key_exists('stat_props', $options)) { + if (empty($options['stat_props'])) { + $this->statProps = array(); + } else { + $this->statProps = $options['stat_props']; + } + } else { + $this->statProps = array('size', 'mtime'); + } + } + /** * Helper function for loading a Mustache file by name. * @@ -35,6 +81,6 @@ class Mustache_Loader_ProductionFilesystemLoader extends Mustache_Loader_Filesys throw new Mustache_Exception_UnknownTemplateException($name); } - return new Mustache_Source_FilesystemSource($fileName); + return new Mustache_Source_FilesystemSource($fileName, $this->statProps); } } diff --git a/src/Mustache/Source/FilesystemSource.php b/src/Mustache/Source/FilesystemSource.php index c54a406..7928ab2 100644 --- a/src/Mustache/Source/FilesystemSource.php +++ b/src/Mustache/Source/FilesystemSource.php @@ -19,17 +19,20 @@ */ class Mustache_Source_FilesystemSource implements Mustache_Source { - private $stat; private $filename; + private $statProps; + private $stat; /** * Filesystem Source constructor. * * @param string $filename + * @param array $statProps */ - public function __construct($filename) + public function __construct($filename, array $statProps) { $this->filename = $filename; + $this->statProps = $statProps; } /** @@ -41,15 +44,25 @@ class Mustache_Source_FilesystemSource implements Mustache_Source */ public function getKey() { - if (!isset($this->stat)) { - $this->stat = stat($this->filename); + $chunks = array( + sprintf('filename:%s', $this->filename), + ); + + if (!empty($this->statProps)) { + if (!isset($this->stat)) { + $this->stat = stat($this->filename); + } + + if ($this->stat === false) { + throw new RuntimeException(sprintf('Failed to read source file "%s".', $this->filename)); + } + + foreach ($this->statProps as $prop) { + $chunks[] = sprintf('%s:%s', $prop, $this->stat[$prop]); + } } - if ($this->stat === false) { - throw new RuntimeException(sprintf('Failed to read source file "%s".', $this->filename)); - } - - return sprintf('filename:%s,size:%s,mtime:%s', $this->filename, $this->stat['size'], $this->stat['mtime']); + return implode(',', $chunks); } /**