2015-08-17 17:00:26 -07:00
< ? php
namespace Doctrine\Common\Cache ;
2018-11-23 12:29:20 +00:00
use function array_combine ;
use function array_key_exists ;
use function array_map ;
use function sprintf ;
2015-08-17 17:00:26 -07:00
/**
* Base class for cache provider implementations .
*
*/
2018-11-23 12:29:20 +00:00
abstract class CacheProvider implements Cache , FlushableCache , ClearableCache , MultiOperationCache
2015-08-17 17:00:26 -07:00
{
2018-11-23 12:29:20 +00:00
public const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]' ;
2015-08-17 17:00:26 -07:00
/**
* The namespace to prefix all cache ids with .
*
* @ var string
*/
private $namespace = '' ;
/**
* The namespace version .
*
2018-11-23 12:29:20 +00:00
* @ var int | null
2015-08-17 17:00:26 -07:00
*/
private $namespaceVersion ;
/**
* Sets the namespace to prefix all cache ids with .
*
* @ param string $namespace
*
* @ return void
*/
public function setNamespace ( $namespace )
{
$this -> namespace = ( string ) $namespace ;
$this -> namespaceVersion = null ;
}
/**
* Retrieves the namespace that prefixes all cache ids .
*
* @ return string
*/
public function getNamespace ()
{
return $this -> namespace ;
}
/**
* { @ inheritdoc }
*/
public function fetch ( $id )
{
return $this -> doFetch ( $this -> getNamespacedId ( $id ));
}
2015-10-08 11:40:12 -07:00
/**
* { @ inheritdoc }
*/
public function fetchMultiple ( array $keys )
{
2017-04-13 15:53:35 +01:00
if ( empty ( $keys )) {
2018-11-23 12:29:20 +00:00
return [];
2017-04-13 15:53:35 +01:00
}
2018-11-23 12:29:20 +00:00
2015-10-08 11:40:12 -07:00
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
2018-11-23 12:29:20 +00:00
$namespacedKeys = array_combine ( $keys , array_map ([ $this , 'getNamespacedId' ], $keys ));
2015-10-08 11:40:12 -07:00
$items = $this -> doFetchMultiple ( $namespacedKeys );
2018-11-23 12:29:20 +00:00
$foundItems = [];
2015-10-08 11:40:12 -07:00
// no internal array function supports this sort of mapping: needs to be iterative
// this filters and combines keys in one pass
foreach ( $namespacedKeys as $requestedKey => $namespacedKey ) {
2018-11-23 12:29:20 +00:00
if ( ! isset ( $items [ $namespacedKey ]) && ! array_key_exists ( $namespacedKey , $items )) {
continue ;
2015-10-08 11:40:12 -07:00
}
2018-11-23 12:29:20 +00:00
$foundItems [ $requestedKey ] = $items [ $namespacedKey ];
2015-10-08 11:40:12 -07:00
}
return $foundItems ;
}
2017-04-13 15:53:35 +01:00
/**
* { @ inheritdoc }
*/
public function saveMultiple ( array $keysAndValues , $lifetime = 0 )
{
2018-11-23 12:29:20 +00:00
$namespacedKeysAndValues = [];
2017-04-13 15:53:35 +01:00
foreach ( $keysAndValues as $key => $value ) {
$namespacedKeysAndValues [ $this -> getNamespacedId ( $key )] = $value ;
}
return $this -> doSaveMultiple ( $namespacedKeysAndValues , $lifetime );
}
2015-08-17 17:00:26 -07:00
/**
* { @ inheritdoc }
*/
public function contains ( $id )
{
return $this -> doContains ( $this -> getNamespacedId ( $id ));
}
/**
* { @ inheritdoc }
*/
public function save ( $id , $data , $lifeTime = 0 )
{
return $this -> doSave ( $this -> getNamespacedId ( $id ), $data , $lifeTime );
}
2018-11-23 12:29:20 +00:00
/**
* { @ inheritdoc }
*/
public function deleteMultiple ( array $keys )
{
return $this -> doDeleteMultiple ( array_map ([ $this , 'getNamespacedId' ], $keys ));
}
2015-08-17 17:00:26 -07:00
/**
* { @ inheritdoc }
*/
public function delete ( $id )
{
return $this -> doDelete ( $this -> getNamespacedId ( $id ));
}
/**
* { @ inheritdoc }
*/
public function getStats ()
{
return $this -> doGetStats ();
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritDoc }
2015-08-17 17:00:26 -07:00
*/
public function flushAll ()
{
return $this -> doFlush ();
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritDoc }
2015-08-17 17:00:26 -07:00
*/
public function deleteAll ()
{
$namespaceCacheKey = $this -> getNamespaceCacheKey ();
$namespaceVersion = $this -> getNamespaceVersion () + 1 ;
2017-04-13 15:53:35 +01:00
if ( $this -> doSave ( $namespaceCacheKey , $namespaceVersion )) {
$this -> namespaceVersion = $namespaceVersion ;
return true ;
}
2015-08-17 17:00:26 -07:00
2017-04-13 15:53:35 +01:00
return false ;
2015-08-17 17:00:26 -07:00
}
/**
* Prefixes the passed id with the configured namespace value .
*
* @ param string $id The id to namespace .
*
* @ return string The namespaced id .
*/
2018-11-23 12:29:20 +00:00
private function getNamespacedId ( string $id ) : string
2015-08-17 17:00:26 -07:00
{
2018-11-23 12:29:20 +00:00
$namespaceVersion = $this -> getNamespaceVersion ();
2015-08-17 17:00:26 -07:00
return sprintf ( '%s[%s][%s]' , $this -> namespace , $id , $namespaceVersion );
}
/**
* Returns the namespace cache key .
*/
2018-11-23 12:29:20 +00:00
private function getNamespaceCacheKey () : string
2015-08-17 17:00:26 -07:00
{
return sprintf ( self :: DOCTRINE_NAMESPACE_CACHEKEY , $this -> namespace );
}
/**
* Returns the namespace version .
*/
2018-11-23 12:29:20 +00:00
private function getNamespaceVersion () : int
2015-08-17 17:00:26 -07:00
{
2018-11-23 12:29:20 +00:00
if ( $this -> namespaceVersion !== null ) {
2015-08-17 17:00:26 -07:00
return $this -> namespaceVersion ;
}
2018-11-23 12:29:20 +00:00
$namespaceCacheKey = $this -> getNamespaceCacheKey ();
$this -> namespaceVersion = ( int ) $this -> doFetch ( $namespaceCacheKey ) ? : 1 ;
2015-08-17 17:00:26 -07:00
return $this -> namespaceVersion ;
}
2015-10-08 11:40:12 -07:00
/**
* Default implementation of doFetchMultiple . Each driver that supports multi - get should owerwrite it .
*
* @ param array $keys Array of keys to retrieve from cache
* @ return array Array of values retrieved for the given keys .
*/
protected function doFetchMultiple ( array $keys )
{
2018-11-23 12:29:20 +00:00
$returnValues = [];
2015-10-08 11:40:12 -07:00
2017-04-13 15:53:35 +01:00
foreach ( $keys as $key ) {
2018-11-23 12:29:20 +00:00
$item = $this -> doFetch ( $key );
if ( $item === false && ! $this -> doContains ( $key )) {
continue ;
2015-10-08 11:40:12 -07:00
}
2018-11-23 12:29:20 +00:00
$returnValues [ $key ] = $item ;
2015-10-08 11:40:12 -07:00
}
return $returnValues ;
}
2015-08-17 17:00:26 -07:00
/**
* Fetches an entry from the cache .
*
* @ param string $id The id of the cache entry to fetch .
*
2017-04-13 15:53:35 +01:00
* @ return mixed | false The cached data or FALSE , if no cache entry exists for the given id .
2015-08-17 17:00:26 -07:00
*/
abstract protected function doFetch ( $id );
/**
* Tests if an entry exists in the cache .
*
* @ param string $id The cache id of the entry to check for .
*
2017-04-13 15:53:35 +01:00
* @ return bool TRUE if a cache entry exists for the given cache id , FALSE otherwise .
2015-08-17 17:00:26 -07:00
*/
abstract protected function doContains ( $id );
2017-04-13 15:53:35 +01:00
/**
* Default implementation of doSaveMultiple . Each driver that supports multi - put should override it .
*
2018-11-23 12:29:20 +00:00
* @ param array $keysAndValues Array of keys and values to save in cache
* @ param int $lifetime The lifetime . If != 0 , sets a specific lifetime for these
* cache entries ( 0 => infinite lifeTime ) .
2017-04-13 15:53:35 +01:00
*
* @ return bool TRUE if the operation was successful , FALSE if it wasn ' t .
*/
protected function doSaveMultiple ( array $keysAndValues , $lifetime = 0 )
{
$success = true ;
foreach ( $keysAndValues as $key => $value ) {
2018-11-23 12:29:20 +00:00
if ( $this -> doSave ( $key , $value , $lifetime )) {
continue ;
2017-04-13 15:53:35 +01:00
}
2018-11-23 12:29:20 +00:00
$success = false ;
2017-04-13 15:53:35 +01:00
}
return $success ;
}
2015-08-17 17:00:26 -07:00
/**
* Puts data into the cache .
*
* @ param string $id The cache id .
* @ param string $data The cache entry / data .
* @ param int $lifeTime The lifetime . If != 0 , sets a specific lifetime for this
* cache entry ( 0 => infinite lifeTime ) .
*
2017-04-13 15:53:35 +01:00
* @ return bool TRUE if the entry was successfully stored in the cache , FALSE otherwise .
2015-08-17 17:00:26 -07:00
*/
abstract protected function doSave ( $id , $data , $lifeTime = 0 );
2018-11-23 12:29:20 +00:00
/**
* Default implementation of doDeleteMultiple . Each driver that supports multi - delete should override it .
*
* @ param array $keys Array of keys to delete from cache
*
* @ return bool TRUE if the operation was successful , FALSE if it wasn ' t
*/
protected function doDeleteMultiple ( array $keys )
{
$success = true ;
foreach ( $keys as $key ) {
if ( $this -> doDelete ( $key )) {
continue ;
}
$success = false ;
}
return $success ;
}
2015-08-17 17:00:26 -07:00
/**
* Deletes a cache entry .
*
* @ param string $id The cache id .
*
2017-04-13 15:53:35 +01:00
* @ return bool TRUE if the cache entry was successfully deleted , FALSE otherwise .
2015-08-17 17:00:26 -07:00
*/
abstract protected function doDelete ( $id );
/**
* Flushes all cache entries .
*
2017-04-13 15:53:35 +01:00
* @ return bool TRUE if the cache entries were successfully flushed , FALSE otherwise .
2015-08-17 17:00:26 -07:00
*/
abstract protected function doFlush ();
/**
* Retrieves cached information from the data store .
*
* @ return array | null An associative array with server ' s statistics if available , NULL otherwise .
*/
abstract protected function doGetStats ();
}