From d9d8d4a497d49de90845438fb4e38db15171573e Mon Sep 17 00:00:00 2001 From: MaZderMind Date: Mon, 5 Oct 2015 17:28:23 +0200 Subject: use php-based lesscss compiler --- lib/less.php/Cache.php | 316 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 lib/less.php/Cache.php (limited to 'lib/less.php/Cache.php') diff --git a/lib/less.php/Cache.php b/lib/less.php/Cache.php new file mode 100644 index 0000000..8c8be39 --- /dev/null +++ b/lib/less.php/Cache.php @@ -0,0 +1,316 @@ + '/'); + } + + + // 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); + + // 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 ); + $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 ){ + + //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)).'.css'; + } + + + public static function SetCacheDir( $dir ){ + Less_Cache::$cache_dir = $dir; + } + + 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 ){ + return; + } + + $files = scandir(Less_Cache::$cache_dir); + if( $files ){ + $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; + } + + $full_path = Less_Cache::$cache_dir . $file; + + // make sure the file still exists + // css files may have already been deleted + if( !file_exists($full_path) ){ + continue; + } + $mtime = filemtime($full_path); + + // don't delete if it's a relatively new file + if( $mtime > $check_time ){ + continue; + } + + $parts = explode('.',$file); + $type = array_pop($parts); + + + // delete css files based on the list files + if( $type === 'css' ){ + 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); + } + } + + $clean = true; + } + + + /** + * 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; + } + + } + +} -- cgit v1.2.3