PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file Cache.php

Documentation is available at Cache.php

  1. <?php
  2. /**
  3.  * Function for caching between runs.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  6.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8.  */
  9.  
  10. namespace PHP_CodeSniffer\Util;
  11.  
  12. use PHP_CodeSniffer\Autoload;
  13. use PHP_CodeSniffer\Config;
  14. use PHP_CodeSniffer\Ruleset;
  15. use PHP_CodeSniffer\Util\Common;
  16.  
  17. class Cache
  18. {
  19.  
  20.     /**
  21.      * The filesystem location of the cache file.
  22.      *
  23.      * @var void 
  24.      */
  25.     private static $path '';
  26.  
  27.     /**
  28.      * The cached data.
  29.      *
  30.      * @var array<string, mixed>
  31.      */
  32.     private static $cache = array();
  33.  
  34.  
  35.     /**
  36.      * Loads existing cache data for the run, if any.
  37.      *
  38.      * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
  39.      * @param \PHP_CodeSniffer\Config  $config  The config data for the run.
  40.      *
  41.      * @return void 
  42.      */
  43.     public static function load(Ruleset $rulesetConfig $config)
  44.     {
  45.         // Look at every loaded sniff class so far and use their file contents
  46.         // to generate a hash for the code used during the run.
  47.         // At this point, the loaded class list contains the core PHPCS code
  48.         // and all sniffs that have been loaded as part of the run.
  49.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  50.             echo PHP_EOL."\tGenerating loaded file list for code hash".PHP_EOL;
  51.         }
  52.  
  53.         $codeHash '';
  54.         $classes  array_keys(Autoload::getLoadedClasses());
  55.         sort($classes);
  56.  
  57.         $installDir     dirname(__DIR__);
  58.         $installDirLen  strlen($installDir);
  59.         $standardDir    $installDir.DIRECTORY_SEPARATOR.'Standards';
  60.         $standardDirLen strlen($standardDir);
  61.         foreach ($classes as $file{
  62.             if (substr($file0$standardDirLen!== $standardDir{
  63.                 if (substr($file0$installDirLen=== $installDir{
  64.                     // We are only interested in sniffs here.
  65.                     continue;
  66.                 }
  67.  
  68.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  69.                     echo "\t\t=> external file: $file".PHP_EOL;
  70.                 }
  71.             else if (PHP_CODESNIFFER_VERBOSITY > 1{
  72.                 echo "\t\t=> internal sniff: $file".PHP_EOL;
  73.             }
  74.  
  75.             $codeHash .= md5_file($file);
  76.         }
  77.  
  78.         // Add the content of the used rulesets to the hash so that sniff setting
  79.         // changes in the ruleset invalidate the cache.
  80.         $rulesets $ruleset->paths;
  81.         sort($rulesets);
  82.         foreach ($rulesets as $file{
  83.             if (substr($file0$standardDirLen!== $standardDir{
  84.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  85.                     echo "\t\t=> external ruleset: $file".PHP_EOL;
  86.                 }
  87.             else if (PHP_CODESNIFFER_VERBOSITY > 1{
  88.                 echo "\t\t=> internal ruleset: $file".PHP_EOL;
  89.             }
  90.  
  91.             $codeHash .= md5_file($file);
  92.         }
  93.  
  94.         // Go through the core PHPCS code and add those files to the file
  95.         // hash. This ensures that core PHPCS changes will also invalidate the cache.
  96.         // Note that we ignore sniffs here, and any files that don't affect
  97.         // the outcome of the run.
  98.         $di = new \RecursiveIteratorIterator(
  99.             new \RecursiveDirectoryIterator($installDir),
  100.             0,
  101.             \RecursiveIteratorIterator::CATCH_GET_CHILD
  102.         );
  103.  
  104.         $di     = new \RecursiveDirectoryIterator($installDir);
  105.         $filter = new \RecursiveCallbackFilterIterator(
  106.             $di,
  107.             function ($file$key$iterator{
  108.                 // Skip hidden files.
  109.                 $filename $file->getFilename();
  110.                 if (substr($filename01=== '.'{
  111.                     return false;
  112.                 }
  113.  
  114.                 $filePath = Common::realpath($file->getPathname());
  115.                 if ($filePath === false{
  116.                     return false;
  117.                 }
  118.  
  119.                 if (is_dir($filePath=== true
  120.                     && ($filename === 'Standards'
  121.                     || $filename === 'Exceptions'
  122.                     || $filename === 'Reports'
  123.                     || $filename === 'Generators')
  124.                 {
  125.                     return false;
  126.                 }
  127.  
  128.                 return true;
  129.             }
  130.         );
  131.  
  132.         $iterator = new \RecursiveIteratorIterator($filter);
  133.         foreach ($iterator as $file{
  134.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  135.                 echo "\t\t=> core file: $file".PHP_EOL;
  136.             }
  137.  
  138.             $codeHash .= md5_file($file);
  139.         }
  140.  
  141.         $codeHash md5($codeHash);
  142.  
  143.         // Along with the code hash, use various settings that can affect
  144.         // the results of a run to create a new hash. This hash will be used
  145.         // in the cache file name.
  146.         $rulesetHash md5(var_export($ruleset->ignorePatternstrue).var_export($ruleset->includePatternstrue));
  147.         $configData  = array(
  148.                         'tabWidth'     => $config->tabWidth,
  149.                         'encoding'     => $config->encoding,
  150.                         'recordErrors' => $config->recordErrors,
  151.                         'annotations'  => $config->annotations,
  152.                         'codeHash'     => $codeHash,
  153.                         'rulesetHash'  => $rulesetHash,
  154.                        );
  155.  
  156.         $configString implode(','$configData);
  157.         $cacheHash    substr(sha1($configString)012);
  158.  
  159.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  160.             echo "\tGenerating cache key data".PHP_EOL;
  161.             echo "\t\t=> tabWidth: ".$configData['tabWidth'].PHP_EOL;
  162.             echo "\t\t=> encoding: ".$configData['encoding'].PHP_EOL;
  163.             echo "\t\t=> recordErrors: ".(int) $configData['recordErrors'].PHP_EOL;
  164.             echo "\t\t=> annotations: ".(int) $configData['annotations'].PHP_EOL;
  165.             echo "\t\t=> codeHash: ".$configData['codeHash'].PHP_EOL;
  166.             echo "\t\t=> rulesetHash: ".$configData['rulesetHash'].PHP_EOL;
  167.             echo "\t\t=> cacheHash: $cacheHash".PHP_EOL;
  168.         }
  169.  
  170.         if ($config->cacheFile !== null{
  171.             $cacheFile $config->cacheFile;
  172.         else {
  173.             // Determine the common paths for all files being checked.
  174.             // We can use this to locate an existing cache file, or to
  175.             // determine where to create a new one.
  176.             if (PHP_CODESNIFFER_VERBOSITY > 1{
  177.                 echo "\tChecking possible cache file paths".PHP_EOL;
  178.             }
  179.  
  180.             $paths = array();
  181.             foreach ($config->files as $file{
  182.                 $file = Common::realpath($file);
  183.                 while ($file !== DIRECTORY_SEPARATOR{
  184.                     if (isset($paths[$file]=== false{
  185.                         $paths[$file= 1;
  186.                     else {
  187.                         $paths[$file]++;
  188.                     }
  189.  
  190.                     $lastFile $file;
  191.                     $file     dirname($file);
  192.                     if ($file === $lastFile{
  193.                         // Just in case something went wrong,
  194.                         // we don't want to end up in an infinite loop.
  195.                         break;
  196.                     }
  197.                 }
  198.             }
  199.  
  200.             ksort($paths);
  201.             $paths array_reverse($paths);
  202.  
  203.             $numFiles  count($config->files);
  204.             $tmpDir    sys_get_temp_dir();
  205.             $cacheFile = null;
  206.             foreach ($paths as $file => $count{
  207.                 if ($count !== $numFiles{
  208.                     unset($paths[$file]);
  209.                     continue;
  210.                 }
  211.  
  212.                 $fileHash substr(sha1($file)012);
  213.                 $testFile $tmpDir.DIRECTORY_SEPARATOR."phpcs.$fileHash.$cacheHash.cache";
  214.                 if ($cacheFile === null{
  215.                     // This will be our default location if we can't find
  216.                     // an existing file.
  217.                     $cacheFile $testFile;
  218.                 }
  219.  
  220.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  221.                     echo "\t\t=> $testFile".PHP_EOL;
  222.                     echo "\t\t\t * based on shared location: $file *".PHP_EOL;
  223.                 }
  224.  
  225.                 if (file_exists($testFile=== true{
  226.                     $cacheFile $testFile;
  227.                     break;
  228.                 }
  229.             }//end foreach
  230.  
  231.             if ($cacheFile === null{
  232.                 // Unlikely, but just in case $paths is empty for some reason.
  233.                 $cacheFile $tmpDir.DIRECTORY_SEPARATOR."phpcs.$cacheHash.cache";
  234.             }
  235.         }//end if
  236.  
  237.         self::$path $cacheFile;
  238.         if (PHP_CODESNIFFER_VERBOSITY > 1{
  239.             echo "\t=> Using cache file: ".self::$path.PHP_EOL;
  240.         }
  241.  
  242.         if (file_exists(self::$path=== true{
  243.             self::$cache = json_decode(file_get_contents(self::$path)true);
  244.  
  245.             // Verify the contents of the cache file.
  246.             if (self::$cache['config'!== $configData{
  247.                 self::$cache = array();
  248.                 if (PHP_CODESNIFFER_VERBOSITY > 1{
  249.                     echo "\t* cache was invalid and has been cleared *".PHP_EOL;
  250.                 }
  251.             }
  252.         else if (PHP_CODESNIFFER_VERBOSITY > 1{
  253.             echo "\t* cache file does not exist *".PHP_EOL;
  254.         }
  255.  
  256.         self::$cache['config'$configData;
  257.  
  258.     }//end load()
  259.  
  260.  
  261.     /**
  262.      * Saves the current cache to the filesystem.
  263.      *
  264.      * @return void 
  265.      */
  266.     public static function save()
  267.     {
  268.         file_put_contents(self::$pathjson_encode(self::$cache));
  269.  
  270.     }//end save()
  271.  
  272.  
  273.     /**
  274.      * Retrieves a single entry from the cache.
  275.      *
  276.      * @param string $key The key of the data to get. If NULL,
  277.      *                     everything in the cache is returned.
  278.      *
  279.      * @return mixed 
  280.      */
  281.     public static function get($key=null)
  282.     {
  283.         if ($key === null{
  284.             return self::$cache;
  285.         }
  286.  
  287.         if (isset(self::$cache[$key]=== true{
  288.             return self::$cache[$key];
  289.         }
  290.  
  291.         return false;
  292.  
  293.     }//end get()
  294.  
  295.  
  296.     /**
  297.      * Retrieves a single entry from the cache.
  298.      *
  299.      * @param string $key   The key of the data to set. If NULL,
  300.      *                       sets the entire cache.
  301.      * @param mixed  $value The value to set.
  302.      *
  303.      * @return void 
  304.      */
  305.     public static function set($key$value)
  306.     {
  307.         if ($key === null{
  308.             self::$cache $value;
  309.         else {
  310.             self::$cache[$key$value;
  311.         }
  312.  
  313.     }//end set()
  314.  
  315.  
  316.     /**
  317.      * Retrieves the number of cache entries.
  318.      *
  319.      * @return int 
  320.      */
  321.     public static function getSize()
  322.     {
  323.         return (count(self::$cache- 1);
  324.  
  325.     }//end getSize()
  326.  
  327.  
  328. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:15 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.