Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176

This commit is contained in:
Pantheon Automation 2015-08-17 17:00:26 -07:00 committed by Greg Anderson
commit 9921556621
13277 changed files with 1459781 additions and 0 deletions

View file

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\Component\FileCache\ApcuFileCacheBackend.
*/
namespace Drupal\Component\FileCache;
/**
* APCu backend for the file cache.
*/
class ApcuFileCacheBackend implements FileCacheBackendInterface {
/**
* {@inheritdoc}
*/
public function fetch(array $cids) {
return apc_fetch($cids);
}
/**
* {@inheritdoc}
*/
public function store($cid, $data) {
apc_store($cid, $data);
}
/**
* {@inheritdoc}
*/
public function delete($cid) {
apc_delete($cid);
}
}

View file

@ -0,0 +1,156 @@
<?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);
}
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\Component\FileCache\FileCacheBackendInterface.
*/
namespace Drupal\Component\FileCache;
/**
* Defines an interface inspired by APCu for FileCache backends.
*/
interface FileCacheBackendInterface {
/**
* Fetches data from the cache backend.
*
* @param array $cids
* The cache IDs to fetch.
*
* @return array
* An array containing cache entries keyed by cache ID.
*/
public function fetch(array $cids);
/**
* Stores data into a cache backend.
*
* @param string $cid
* The cache ID to store data to.
* @param mixed $data
* The data to store.
*/
public function store($cid, $data);
/**
* Deletes data from a cache backend.
*
* @param string $cid
* The cache ID to delete.
*/
public function delete($cid);
}

View file

@ -0,0 +1,107 @@
<?php
/**
* @file
* Contains \Drupal\Component\FileCache\FileCacheFactory.
*/
namespace Drupal\Component\FileCache;
/**
* Creates a FileCache object.
*/
class FileCacheFactory {
/**
* The configuration used to create FileCache objects.
*
* @var array $configuration
*/
protected static $configuration;
/**
* The cache prefix.
*
* @var string
*/
protected static $prefix;
/**
* Instantiates a FileCache object for a given collection identifier.
*
* @param string $collection
* The collection identifier for this FileCache.
* @param array $default_configuration
* (optional) The default configuration for this FileCache collection. This
* can be used to e.g. specify default usage of a FileCache class.
*
* @return \Drupal\Component\FileCache\FileCacheInterface
* The initialized FileCache object.
*/
public static function get($collection, $default_configuration = []) {
$default_configuration += [
'class' => '\Drupal\Component\FileCache\FileCache',
'collection' => $collection,
'cache_backend_class' => NULL,
'cache_backend_configuration' => [],
];
$configuration = [];
if (isset(static::$configuration[$collection])) {
$configuration = static::$configuration[$collection];
}
elseif (isset(static::$configuration['default'])) {
$configuration = static::$configuration['default'];
}
// Add defaults to the configuration.
$configuration = $configuration + $default_configuration;
$class = $configuration['class'];
return new $class(static::getPrefix(), $configuration['collection'], $configuration['cache_backend_class'], $configuration['cache_backend_configuration']);
}
/**
* Gets the configuration used for constructing future file cache objects.
*
* @return array
* The configuration that is used.
*/
public static function getConfiguration() {
return static::$configuration;
}
/**
* Sets the configuration to use for constructing future file cache objects.
*
* @param array $configuration
* The configuration to use.
*/
public static function setConfiguration($configuration) {
static::$configuration = $configuration;
}
/**
* Returns the cache prefix.
*
* @return string
* The cache prefix.
*/
public static function getPrefix() {
return static::$prefix;
}
/**
* Sets the cache prefix that should be used.
*
* Should be set to a secure, unique key to prevent cache pollution by a
* third party.
*
* @param string $prefix
* The cache prefix.
*/
public static function setPrefix($prefix) {
static::$prefix = $prefix;
}
}

View file

@ -0,0 +1,64 @@
<?php
/**
* @file
* Contains \Drupal\Component\FileCache\FileCacheInterface.
*/
namespace Drupal\Component\FileCache;
/**
* Interface for objects that allow caching file data.
*
* Parsing YAML, annotations or similar data out of files can be a
* time-consuming process, especially since those files usually don't change
* and identical data is parsed over and over again.
*
* File cache is a self-contained caching layer for such processing, that relies
* on the file modification to ensure that cached data is still up to date and
* does not need to be invalidated externally.
*/
interface FileCacheInterface {
/**
* Gets data based on a filename.
*
* @param string $filepath
* Path of the file that the cached data is based on.
*
* @return mixed|null
* The data that was persisted with set() or NULL if there is no data
* or the file has been modified.
*/
public function get($filepath);
/**
* Gets data based on filenames.
*
* @param string[] $filepaths
* List of file paths used as cache identifiers.
*
* @return array
* List of cached data keyed by the passed in file paths.
*/
public function getMultiple(array $filepaths);
/**
* Stores data based on a filename.
*
* @param string $filepath
* Path of the file that the cached data is based on.
* @param mixed $data
* The data that should be cached.
*/
public function set($filepath, $data);
/**
* Deletes data from the cache.
*
* @param string $filepath
* Path of the file that the cached data is based on.
*/
public function delete($filepath);
}

View file

@ -0,0 +1,58 @@
<?php
/**
* @file
* Contains \Drupal\Component\FileCache\NullFileCache.
*/
namespace Drupal\Component\FileCache;
/**
* Null implementation for the file cache.
*/
class NullFileCache implements FileCacheInterface {
/**
* Constructs a FileCache object.
*
* @param string $prefix
* A prefix that is used as a prefix, should be set to a secure, unique key
* to prevent cache pollution by a third party.
* @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 = []) {
}
/**
* {@inheritdoc}
*/
public function get($filepath) {
return NULL;
}
/**
* {@inheritdoc}
*/
public function getMultiple(array $filepaths) {
return [];
}
/**
* {@inheritdoc}
*/
public function set($filepath, $data) {
}
/**
* {@inheritdoc}
*/
public function delete($filepath) {
}
}