Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
50.00% |
3 / 6 |
CRAP | |
91.49% |
43 / 47 |
FileCache | |
0.00% |
0 / 1 |
|
50.00% |
3 / 6 |
21.27 | |
91.49% |
43 / 47 |
__construct | |
0.00% |
0 / 1 |
3.03 | |
85.71% |
6 / 7 |
|||
get | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
getMultiple | |
0.00% |
0 / 1 |
11 | |
95.00% |
19 / 20 |
|||
set | |
100.00% |
1 / 1 |
2 | |
100.00% |
9 / 9 |
|||
delete | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
reset | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
<?php | |
/** | |
* @file | |
* Contains \Drupal\Component\FileCache\FileCache. | |
*/ | |
namespace Drupal\Component\FileCache; | |
/** | |
* Allows to cache data based on file modification dates. | |
*/ | |
class FileCache implements FileCacheInterface { | |
/** | |
* Prefix that is used for cache entries. | |
* | |
* @var string | |
*/ | |
protected $prefix; | |
/** | |
* Static cache that contains already loaded cache entries. | |
* | |
* @var array | |
*/ | |
protected static $cached = []; | |
/** | |
* The collection identifier of this cache. | |
* | |
* @var string | |
*/ | |
protected $collection; | |
/** | |
* The cache backend backing this FileCache object. | |
* | |
* @var \Drupal\Component\FileCache\FileCacheBackendInterface | |
*/ | |
protected $cache; | |
/** | |
* Constructs a FileCache object. | |
* | |
* @param string $prefix | |
* The cache prefix. | |
* @param string $collection | |
* A collection identifier to ensure that the same files could be cached for | |
* different purposes without clashing. | |
* @param string|null $cache_backend_class | |
* (optional) The class that should be used as cache backend. | |
* @param array $cache_backend_configuration | |
* (optional) The configuration for the backend class. | |
*/ | |
public function __construct($prefix, $collection, $cache_backend_class = NULL, array $cache_backend_configuration = []) { | |
if (empty($prefix)) { | |
throw new \InvalidArgumentException('Required prefix configuration is missing'); | |
} | |
$this->prefix = $prefix; | |
$this->collection = $collection; | |
if (isset($cache_backend_class)) { | |
$this->cache = new $cache_backend_class($cache_backend_configuration); | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function get($filepath) { | |
$filepaths = [$filepath]; | |
$cached = $this->getMultiple($filepaths); | |
return isset($cached[$filepath]) ? $cached[$filepath] : NULL; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getMultiple(array $filepaths) { | |
$file_data = []; | |
$remaining_cids = []; | |
// First load from the static cache what we can. | |
foreach ($filepaths as $filepath) { | |
if (!file_exists($filepath)) { | |
continue; | |
} | |
$realpath = realpath($filepath); | |
// If the file exists but realpath returns nothing, it is using a stream | |
// wrapper, those are not supported. | |
if (empty($realpath)) { | |
continue; | |
} | |
$cid = $this->prefix . ':' . $this->collection . ':' . $realpath; | |
if (isset(static::$cached[$cid]) && static::$cached[$cid]['mtime'] == filemtime($filepath)) { | |
$file_data[$filepath] = static::$cached[$cid]['data']; | |
} | |
else { | |
// Collect a list of cache IDs that we still need to fetch from cache | |
// backend. | |
$remaining_cids[$cid] = $filepath; | |
} | |
} | |
// If there are any cache IDs left to fetch from the cache backend. | |
if ($remaining_cids && $this->cache) { | |
$cache_results = $this->cache->fetch(array_keys($remaining_cids)) ?: []; | |
foreach ($cache_results as $cid => $cached) { | |
$filepath = $remaining_cids[$cid]; | |
if ($cached['mtime'] == filemtime($filepath)) { | |
$file_data[$cached['filepath']] = $cached['data']; | |
static::$cached[$cid] = $cached; | |
} | |
} | |
} | |
return $file_data; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function set($filepath, $data) { | |
$realpath = realpath($filepath); | |
$cached = [ | |
'mtime' => filemtime($filepath), | |
'filepath' => $filepath, | |
'data' => $data, | |
]; | |
$cid = $this->prefix . ':' . $this->collection . ':' . $realpath; | |
static::$cached[$cid] = $cached; | |
if ($this->cache) { | |
$this->cache->store($cid, $cached); | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function delete($filepath) { | |
$realpath = realpath($filepath); | |
$cid = $this->prefix . ':' . $this->collection . ':' . $realpath; | |
unset(static::$cached[$cid]); | |
if ($this->cache) { | |
$this->cache->delete($cid); | |
} | |
} | |
/** | |
* Resets the static cache. | |
* | |
* @todo Replace this once https://www.drupal.org/node/2260187 is in. | |
*/ | |
public static function reset() { | |
static::$cached = []; | |
} | |
} |