diff options
Diffstat (limited to 'library/vendor/lessphp/lib/Less/Cache.php')
-rw-r--r-- | library/vendor/lessphp/lib/Less/Cache.php | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/library/vendor/lessphp/lib/Less/Cache.php b/library/vendor/lessphp/lib/Less/Cache.php new file mode 100644 index 0000000..ce09eea --- /dev/null +++ b/library/vendor/lessphp/lib/Less/Cache.php @@ -0,0 +1,290 @@ +<?php + +require_once dirname( __FILE__ ).'/Version.php'; + +/** + * Utility for handling the generation and caching of css files + * + * @package Less + * @subpackage cache + */ +class Less_Cache { + + // directory less.php can use for storing data + public static $cache_dir = false; + + // prefix for the storing data + public static $prefix = 'lessphp_'; + + // prefix for the storing vars + public static $prefix_vars = 'lessphpvars_'; + + // specifies the number of seconds after which data created by less.php will be seen as 'garbage' and potentially cleaned up + public static $gc_lifetime = 604800; + + /** + * Save and reuse the results of compiled less files. + * The first call to Get() will generate css and save it. + * Subsequent calls to Get() with the same arguments will return the same css filename + * + * @param array $less_files Array of .less files to compile + * @param array $parser_options Array of compiler options + * @param array $modify_vars Array of variables + * @return string Name of the css file + */ + public static function Get( $less_files, $parser_options = array(), $modify_vars = array() ) { + // check $cache_dir + if ( isset( $parser_options['cache_dir'] ) ) { + Less_Cache::$cache_dir = $parser_options['cache_dir']; + } + + if ( empty( Less_Cache::$cache_dir ) ) { + throw new Exception( 'cache_dir not set' ); + } + + if ( isset( $parser_options['prefix'] ) ) { + Less_Cache::$prefix = $parser_options['prefix']; + } + + if ( empty( Less_Cache::$prefix ) ) { + throw new Exception( 'prefix not set' ); + } + + if ( isset( $parser_options['prefix_vars'] ) ) { + Less_Cache::$prefix_vars = $parser_options['prefix_vars']; + } + + if ( empty( Less_Cache::$prefix_vars ) ) { + throw new Exception( 'prefix_vars not set' ); + } + + self::CheckCacheDir(); + $less_files = (array)$less_files; + + // create a file for variables + if ( !empty( $modify_vars ) ) { + $lessvars = Less_Parser::serializeVars( $modify_vars ); + $vars_file = Less_Cache::$cache_dir . Less_Cache::$prefix_vars . sha1( $lessvars ) . '.less'; + + if ( !file_exists( $vars_file ) ) { + file_put_contents( $vars_file, $lessvars ); + } + + $less_files += array( $vars_file => '/' ); + } + + // generate name for compiled css file + $hash = md5( json_encode( $less_files ) ); + $list_file = Less_Cache::$cache_dir . Less_Cache::$prefix . $hash . '.list'; + + // check cached content + if ( !isset( $parser_options['use_cache'] ) || $parser_options['use_cache'] === true ) { + if ( file_exists( $list_file ) ) { + + self::ListFiles( $list_file, $list, $cached_name ); + $compiled_name = self::CompiledName( $list, $hash ); + + // if $cached_name is the same as the $compiled name, don't regenerate + if ( !$cached_name || $cached_name === $compiled_name ) { + + $output_file = self::OutputFile( $compiled_name, $parser_options ); + + if ( $output_file && file_exists( $output_file ) ) { + @touch( $list_file ); + return basename( $output_file ); // for backwards compatibility, we just return the name of the file + } + } + } + } + + $compiled = self::Cache( $less_files, $parser_options ); + if ( !$compiled ) { + return false; + } + + $compiled_name = self::CompiledName( $less_files, $hash ); + $output_file = self::OutputFile( $compiled_name, $parser_options ); + + // save the file list + $list = $less_files; + $list[] = $compiled_name; + $cache = implode( "\n", $list ); + file_put_contents( $list_file, $cache ); + + // save the css + file_put_contents( $output_file, $compiled ); + + // clean up + self::CleanCache(); + + return basename( $output_file ); + } + + /** + * Force the compiler to regenerate the cached css file + * + * @param array $less_files Array of .less files to compile + * @param array $parser_options Array of compiler options + * @param array $modify_vars Array of variables + * @return string Name of the css file + */ + public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ) { + $parser_options['use_cache'] = false; + return self::Get( $less_files, $parser_options, $modify_vars ); + } + + public static function Cache( &$less_files, $parser_options = array() ) { + // get less.php if it exists + $file = dirname( __FILE__ ) . '/Less.php'; + if ( file_exists( $file ) && !class_exists( 'Less_Parser' ) ) { + require_once $file; + } + + $parser_options['cache_dir'] = Less_Cache::$cache_dir; + $parser = new Less_Parser( $parser_options ); + + // combine files + foreach ( $less_files as $file_path => $uri_or_less ) { + + // treat as less markup if there are newline characters + if ( strpos( $uri_or_less, "\n" ) !== false ) { + $parser->Parse( $uri_or_less ); + continue; + } + + $parser->ParseFile( $file_path, $uri_or_less ); + } + + $compiled = $parser->getCss(); + + $less_files = $parser->allParsedFiles(); + + return $compiled; + } + + private static function OutputFile( $compiled_name, $parser_options ) { + // custom output file + if ( !empty( $parser_options['output'] ) ) { + + // relative to cache directory? + if ( preg_match( '#[\\\\/]#', $parser_options['output'] ) ) { + return $parser_options['output']; + } + + return Less_Cache::$cache_dir.$parser_options['output']; + } + + return Less_Cache::$cache_dir.$compiled_name; + } + + private static function CompiledName( $files, $extrahash ) { + // save the file list + $temp = array( Less_Version::cache_version ); + foreach ( $files as $file ) { + $temp[] = filemtime( $file )."\t".filesize( $file )."\t".$file; + } + + return Less_Cache::$prefix.sha1( json_encode( $temp ).$extrahash ).'.css'; + } + + public static function SetCacheDir( $dir ) { + Less_Cache::$cache_dir = $dir; + self::CheckCacheDir(); + } + + public static function CheckCacheDir() { + Less_Cache::$cache_dir = str_replace( '\\', '/', Less_Cache::$cache_dir ); + Less_Cache::$cache_dir = rtrim( Less_Cache::$cache_dir, '/' ).'/'; + + if ( !file_exists( Less_Cache::$cache_dir ) ) { + if ( !mkdir( Less_Cache::$cache_dir ) ) { + throw new Less_Exception_Parser( 'Less.php cache directory couldn\'t be created: '.Less_Cache::$cache_dir ); + } + + } elseif ( !is_dir( Less_Cache::$cache_dir ) ) { + throw new Less_Exception_Parser( 'Less.php cache directory doesn\'t exist: '.Less_Cache::$cache_dir ); + + } elseif ( !is_writable( Less_Cache::$cache_dir ) ) { + throw new Less_Exception_Parser( 'Less.php cache directory isn\'t writable: '.Less_Cache::$cache_dir ); + + } + + } + + /** + * Delete unused less.php files + */ + public static function CleanCache() { + static $clean = false; + + if ( $clean || empty( Less_Cache::$cache_dir ) ) { + return; + } + + $clean = true; + + // only remove files with extensions created by less.php + // css files removed based on the list files + $remove_types = array( 'lesscache' => 1,'list' => 1,'less' => 1,'map' => 1 ); + + $files = scandir( Less_Cache::$cache_dir ); + if ( !$files ) { + return; + } + + $check_time = time() - self::$gc_lifetime; + foreach ( $files as $file ) { + + // don't delete if the file wasn't created with less.php + if ( strpos( $file, Less_Cache::$prefix ) !== 0 ) { + continue; + } + + $parts = explode( '.', $file ); + $type = array_pop( $parts ); + + if ( !isset( $remove_types[$type] ) ) { + continue; + } + + $full_path = Less_Cache::$cache_dir . $file; + $mtime = filemtime( $full_path ); + + // don't delete if it's a relatively new file + if ( $mtime > $check_time ) { + continue; + } + + // delete the list file and associated css file + if ( $type === 'list' ) { + self::ListFiles( $full_path, $list, $css_file_name ); + if ( $css_file_name ) { + $css_file = Less_Cache::$cache_dir . $css_file_name; + if ( file_exists( $css_file ) ) { + unlink( $css_file ); + } + } + } + + unlink( $full_path ); + } + + } + + /** + * Get the list of less files and generated css file from a list file + */ + static function ListFiles( $list_file, &$list, &$css_file_name ) { + $list = explode( "\n", file_get_contents( $list_file ) ); + + // pop the cached name that should match $compiled_name + $css_file_name = array_pop( $list ); + + if ( !preg_match( '/^' . Less_Cache::$prefix . '[a-f0-9]+\.css$/', $css_file_name ) ) { + $list[] = $css_file_name; + $css_file_name = false; + } + + } + +} |