[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/lessphp/ -> Cache.php (source)

   1  <?php
   2  
   3  require_once( dirname(__FILE__).'/Version.php');
   4  
   5  /**
   6   * Utility for handling the generation and caching of css files
   7   *
   8   * @package Less
   9   * @subpackage cache
  10   *
  11   */
  12  class Less_Cache{
  13  
  14      // directory less.php can use for storing data
  15      public static $cache_dir    = false;
  16  
  17      // prefix for the storing data
  18      public static $prefix        = 'lessphp_';
  19  
  20      // prefix for the storing vars
  21      public static $prefix_vars    = 'lessphpvars_';
  22  
  23      // specifies the number of seconds after which data created by less.php will be seen as 'garbage' and potentially cleaned up
  24      public static $gc_lifetime    = 604800;
  25  
  26  
  27      /**
  28       * Save and reuse the results of compiled less files.
  29       * The first call to Get() will generate css and save it.
  30       * Subsequent calls to Get() with the same arguments will return the same css filename
  31       *
  32       * @param array $less_files Array of .less files to compile
  33       * @param array $parser_options Array of compiler options
  34       * @param array $modify_vars Array of variables
  35       * @return string Name of the css file
  36       */
  37  	public static function Get( $less_files, $parser_options = array(), $modify_vars = array() ){
  38  
  39  
  40          //check $cache_dir
  41          if( isset($parser_options['cache_dir']) ){
  42              Less_Cache::$cache_dir = $parser_options['cache_dir'];
  43          }
  44  
  45          if( empty(Less_Cache::$cache_dir) ){
  46              throw new Exception('cache_dir not set');
  47          }
  48  
  49          if( isset($parser_options['prefix']) ){
  50              Less_Cache::$prefix = $parser_options['prefix'];
  51          }
  52  
  53          if( empty(Less_Cache::$prefix) ){
  54              throw new Exception('prefix not set');
  55          }
  56  
  57          if( isset($parser_options['prefix_vars']) ){
  58              Less_Cache::$prefix_vars = $parser_options['prefix_vars'];
  59          }
  60  
  61          if( empty(Less_Cache::$prefix_vars) ){
  62              throw new Exception('prefix_vars not set');
  63          }
  64  
  65          self::CheckCacheDir();
  66          $less_files = (array)$less_files;
  67  
  68  
  69          //create a file for variables
  70          if( !empty($modify_vars) ){
  71              $lessvars = Less_Parser::serializeVars($modify_vars);
  72              $vars_file = Less_Cache::$cache_dir . Less_Cache::$prefix_vars . sha1($lessvars) . '.less';
  73  
  74              if( !file_exists($vars_file) ){
  75                  file_put_contents($vars_file, $lessvars);
  76              }
  77  
  78              $less_files += array($vars_file => '/');
  79          }
  80  
  81  
  82          // generate name for compiled css file
  83          $hash = md5(json_encode($less_files));
  84           $list_file = Less_Cache::$cache_dir . Less_Cache::$prefix . $hash . '.list';
  85  
  86           // check cached content
  87           if( !isset($parser_options['use_cache']) || $parser_options['use_cache'] === true ){
  88              if( file_exists($list_file) ){
  89  
  90                  self::ListFiles($list_file, $list, $cached_name);
  91                  $compiled_name = self::CompiledName($list, $hash);
  92  
  93                  // if $cached_name is the same as the $compiled name, don't regenerate
  94                  if( !$cached_name || $cached_name === $compiled_name ){
  95  
  96                      $output_file = self::OutputFile($compiled_name, $parser_options );
  97  
  98                      if( $output_file && file_exists($output_file) ){
  99                          @touch($list_file);
 100                          return basename($output_file); // for backwards compatibility, we just return the name of the file
 101                      }
 102                  }
 103              }
 104          }
 105  
 106          $compiled = self::Cache( $less_files, $parser_options );
 107          if( !$compiled ){
 108              return false;
 109          }
 110  
 111          $compiled_name = self::CompiledName( $less_files, $hash );
 112          $output_file = self::OutputFile($compiled_name, $parser_options );
 113  
 114  
 115          //save the file list
 116          $list = $less_files;
 117          $list[] = $compiled_name;
 118          $cache = implode("\n",$list);
 119          file_put_contents( $list_file, $cache );
 120  
 121  
 122          //save the css
 123          file_put_contents( $output_file, $compiled );
 124  
 125  
 126          //clean up
 127          self::CleanCache();
 128  
 129          return basename($output_file);
 130      }
 131  
 132      /**
 133       * Force the compiler to regenerate the cached css file
 134       *
 135       * @param array $less_files Array of .less files to compile
 136       * @param array $parser_options Array of compiler options
 137       * @param array $modify_vars Array of variables
 138       * @return string Name of the css file
 139       */
 140  	public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ){
 141          $parser_options['use_cache'] = false;
 142          return self::Get( $less_files, $parser_options, $modify_vars );
 143      }
 144  
 145  	public static function Cache( &$less_files, $parser_options = array() ){
 146  
 147  
 148          // get less.php if it exists
 149          $file = dirname(__FILE__) . '/Less.php';
 150          if( file_exists($file) && !class_exists('Less_Parser') ){
 151              require_once($file);
 152          }
 153  
 154          $parser_options['cache_dir'] = Less_Cache::$cache_dir;
 155          $parser = new Less_Parser($parser_options);
 156  
 157  
 158          // combine files
 159          foreach($less_files as $file_path => $uri_or_less ){
 160  
 161              //treat as less markup if there are newline characters
 162              if( strpos($uri_or_less,"\n") !== false ){
 163                  $parser->Parse( $uri_or_less );
 164                  continue;
 165              }
 166  
 167              $parser->ParseFile( $file_path, $uri_or_less );
 168          }
 169  
 170          $compiled = $parser->getCss();
 171  
 172  
 173          $less_files = $parser->allParsedFiles();
 174  
 175          return $compiled;
 176      }
 177  
 178  
 179  	private static function OutputFile( $compiled_name, $parser_options ){
 180  
 181          //custom output file
 182          if( !empty($parser_options['output']) ){
 183  
 184              //relative to cache directory?
 185              if( preg_match('#[\\\\/]#',$parser_options['output']) ){
 186                  return $parser_options['output'];
 187              }
 188  
 189              return Less_Cache::$cache_dir.$parser_options['output'];
 190          }
 191  
 192          return Less_Cache::$cache_dir.$compiled_name;
 193      }
 194  
 195  
 196  	private static function CompiledName( $files, $extrahash ){
 197  
 198          //save the file list
 199          $temp = array(Less_Version::cache_version);
 200          foreach($files as $file){
 201              $temp[] = filemtime($file)."\t".filesize($file)."\t".$file;
 202          }
 203  
 204          return Less_Cache::$prefix.sha1(json_encode($temp).$extrahash).'.css';
 205      }
 206  
 207  
 208  	public static function SetCacheDir( $dir ){
 209          Less_Cache::$cache_dir = $dir;
 210      }
 211  
 212  	public static function CheckCacheDir(){
 213  
 214          Less_Cache::$cache_dir = str_replace('\\','/',Less_Cache::$cache_dir);
 215          Less_Cache::$cache_dir = rtrim(Less_Cache::$cache_dir,'/').'/';
 216  
 217          if( !file_exists(Less_Cache::$cache_dir) ){
 218              if( !mkdir(Less_Cache::$cache_dir) ){
 219                  throw new Less_Exception_Parser('Less.php cache directory couldn\'t be created: '.Less_Cache::$cache_dir);
 220              }
 221  
 222          }elseif( !is_dir(Less_Cache::$cache_dir) ){
 223              throw new Less_Exception_Parser('Less.php cache directory doesn\'t exist: '.Less_Cache::$cache_dir);
 224  
 225          }elseif( !is_writable(Less_Cache::$cache_dir) ){
 226              throw new Less_Exception_Parser('Less.php cache directory isn\'t writable: '.Less_Cache::$cache_dir);
 227  
 228          }
 229  
 230      }
 231  
 232  
 233      /**
 234       * Delete unused less.php files
 235       *
 236       */
 237  	public static function CleanCache(){
 238          static $clean = false;
 239  
 240          if( $clean ){
 241              return;
 242          }
 243  
 244          $files = scandir(Less_Cache::$cache_dir);
 245          if( $files ){
 246              $check_time = time() - self::$gc_lifetime;
 247              foreach($files as $file){
 248  
 249                  // don't delete if the file wasn't created with less.php
 250                  if( strpos($file,Less_Cache::$prefix) !== 0 ){
 251                      continue;
 252                  }
 253  
 254                  $full_path = Less_Cache::$cache_dir . $file;
 255  
 256                  // make sure the file still exists
 257                  // css files may have already been deleted
 258                  if( !file_exists($full_path) ){
 259                      continue;
 260                  }
 261                  $mtime = filemtime($full_path);
 262  
 263                  // don't delete if it's a relatively new file
 264                  if( $mtime > $check_time ){
 265                      continue;
 266                  }
 267  
 268                  $parts = explode('.',$file);
 269                  $type = array_pop($parts);
 270  
 271  
 272                  // delete css files based on the list files
 273                  if( $type === 'css' ){
 274                      continue;
 275                  }
 276  
 277  
 278                  // delete the list file and associated css file
 279                  if( $type === 'list' ){
 280                      self::ListFiles($full_path, $list, $css_file_name);
 281                      if( $css_file_name ){
 282                          $css_file = Less_Cache::$cache_dir . $css_file_name;
 283                          if( file_exists($css_file) ){
 284                              unlink($css_file);
 285                          }
 286                      }
 287                  }
 288  
 289                  unlink($full_path);
 290              }
 291          }
 292  
 293          $clean = true;
 294      }
 295  
 296  
 297      /**
 298       * Get the list of less files and generated css file from a list file
 299       *
 300       */
 301  	static function ListFiles($list_file, &$list, &$css_file_name ){
 302  
 303          $list = explode("\n",file_get_contents($list_file));
 304  
 305          //pop the cached name that should match $compiled_name
 306          $css_file_name = array_pop($list);
 307  
 308          if( !preg_match('/^' . Less_Cache::$prefix . '[a-f0-9]+\.css$/',$css_file_name) ){
 309              $list[] = $css_file_name;
 310              $css_file_name = false;
 311          }
 312  
 313      }
 314  
 315  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1