FileCache.php

Same filename in other branches
  1. 9 core/lib/Drupal/Component/FileCache/FileCache.php
  2. 8.9.x core/lib/Drupal/Component/FileCache/FileCache.php
  3. 10 core/lib/Drupal/Component/FileCache/FileCache.php

Namespace

Drupal\Component\FileCache

File

core/lib/Drupal/Component/FileCache/FileCache.php

View source
<?php

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 $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 = [];
    }

}

Classes

Title Deprecated Summary
FileCache Allows to cache data based on file modification dates.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.