Source of file ProxyCacheAdapter.php
Size: 5,080 Bytes - Last Modified: 2021-12-23T10:35:47+00:00
/var/www/docs.ssmods.com/process/src/src/Caching/ProxyCacheAdapter.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 | <?php namespace SilverStripe\Versioned\Caching; use Psr\Log\InvalidArgumentException; use Psr\SimpleCache\CacheInterface; use SilverStripe\Versioned\Versioned; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Traversable; /** * psr-6 cache proxy for an internal cache, which provides segmentation of * cache keys based on current versioned mode. This ensures that cross-stage * content cannot cross-pollenate each other. * * Note: segmentation can be disabled via 'versionedstate = false' being supplied as a * constructor arg. * * Based on Symfony\Component\Cache\Simple\TraceableCache */ abstract class ProxyCacheAdapter implements CacheInterface, ResettableInterface, PruneableInterface { /** * @var CacheInterface Backend pool */ protected $pool; /** * Create container cache controlling an inner pool cache * * @param CacheInterface $pool */ public function __construct(CacheInterface $pool) { $this->pool = $pool; } /** * Do not serialize() `$this->pool` because it may contain a non-serializable cache. * For instance, Symfony\Component\Cache\Simple\FilesystemCache cannot be serialized because in will throw an * exception in Symfony\Component\Cache\Traits\FilesystemCommonTrait::__sleep() * * @return array */ public function __sleep() { return []; } /** * {@inheritdoc} */ public function get($key, $default = null) { $keyID = $this->getKeyID($key); return $this->pool->get($keyID, $default); } /** * {@inheritdoc} */ public function has($key) { $keyID = $this->getKeyID($key); return $this->pool->has($keyID); } /** * {@inheritdoc} */ public function delete($key) { $keyID = $this->getKeyID($key); return $this->pool->delete($keyID); } /** * {@inheritdoc} */ public function set($key, $value, $ttl = null) { $keyID = $this->getKeyID($key); return $this->pool->set($keyID, $value, $ttl); } /** * {@inheritdoc} */ public function setMultiple($items, $ttl = null) { // Map associative item keys to ids (safely casting as array as byproduct) $itemsByID = []; foreach ($items as $key => $value) { $keyID = $this->getKeyID($key); $itemsByID[$keyID] = $value; } // Pass back return $this->pool->setMultiple($itemsByID, $ttl); } /** * {@inheritdoc} */ public function getMultiple($keys, $default = null) { $keys = $this->iteratorToArray($keys); $keyIDs = $this->getKeyIDs($keys); // Delegate to pool $itemsByID = $this->pool->getMultiple($keyIDs, $default); // Enforce $poolResult is same length / order as $keyIDs prior to combining back $items = array_map(function ($keyID) use ($default, $itemsByID) { return isset($itemsByID[$keyID]) ? $itemsByID[$keyID] : $default; }, $keyIDs); // Combine back with original keys return array_combine($keys, $items); } /** * {@inheritdoc} */ public function clear() { return $this->pool->clear(); } /** * {@inheritdoc} */ public function deleteMultiple($keys) { $keyIDs = $this->getKeyIDs($keys); return $this->pool->deleteMultiple($keyIDs); } /** * {@inheritdoc} */ public function prune() { if ($this->pool instanceof PruneableInterface) { return $this->pool->prune(); } return false; } /** * {@inheritdoc} */ public function reset() { if ($this->pool instanceof ResettableInterface) { $this->pool->reset(); } } /** * Map user cache to internal cache * * @param string $key * @return string */ abstract protected function getKeyID($key); /** * Get key ids * * @param iterable $keys * @return array Array where keys are passed in $keys, and values are key IDs */ protected function getKeyIDs($keys) { // Force iterator to array with simple temp array $map = []; foreach ($keys as $key) { $map[] = $this->getKeyID($key); } return $map; } /** * Ensure that a list is cast to an array * * @param iterable $keys * @return array */ protected function iteratorToArray($keys) { // Already array if (is_array($keys)) { return $keys; } // Handle iterable if ($keys instanceof Traversable) { return iterator_to_array($keys, false); } // Error $keysType = is_object($keys) ? get_class($keys) : gettype($keys); throw new InvalidArgumentException("Cache keys must be array or Traversable, \"{$keysType}\" given"); } } |