2018-04-17 04:11:51 +02:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Cache\Simple ;
use Psr\Log\LoggerAwareInterface ;
2024-03-20 03:35:09 +01:00
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface ;
use Symfony\Component\Cache\Adapter\AbstractAdapter ;
2018-04-17 04:11:51 +02:00
use Symfony\Component\Cache\CacheItem ;
use Symfony\Component\Cache\Exception\InvalidArgumentException ;
use Symfony\Component\Cache\ResettableInterface ;
2024-01-12 06:08:24 +01:00
use Symfony\Component\Cache\Traits\AbstractTrait ;
2024-03-20 03:35:09 +01:00
use Symfony\Contracts\Cache\CacheInterface ;
@ trigger_error ( sprintf ( 'The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.' , AbstractCache :: class , AbstractAdapter :: class , CacheInterface :: class ), \E_USER_DEPRECATED );
2018-04-17 04:11:51 +02:00
/**
2024-03-20 03:35:09 +01:00
* @ deprecated since Symfony 4.3 , use AbstractAdapter and type - hint for CacheInterface instead .
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
abstract class AbstractCache implements Psr16CacheInterface , LoggerAwareInterface , ResettableInterface
2018-04-17 04:11:51 +02:00
{
use AbstractTrait {
deleteItems as private ;
AbstractTrait :: deleteItem as delete ;
AbstractTrait :: hasItem as has ;
}
/**
2024-03-20 03:35:09 +01:00
* @ internal
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
protected const NS_SEPARATOR = ':' ;
private $defaultLifetime ;
protected function __construct ( string $namespace = '' , int $defaultLifetime = 0 )
2018-04-17 04:11:51 +02:00
{
2024-03-20 03:35:09 +01:00
$this -> defaultLifetime = max ( 0 , $defaultLifetime );
2018-04-17 04:11:51 +02:00
$this -> namespace = '' === $namespace ? '' : CacheItem :: validateKey ( $namespace ) . ':' ;
2024-01-12 06:08:24 +01:00
if ( null !== $this -> maxIdLength && \strlen ( $namespace ) > $this -> maxIdLength - 24 ) {
throw new InvalidArgumentException ( sprintf ( 'Namespace must be %d chars max, %d given ("%s").' , $this -> maxIdLength - 24 , \strlen ( $namespace ), $namespace ));
2018-04-17 04:11:51 +02:00
}
}
/**
* { @ inheritdoc }
*/
public function get ( $key , $default = null )
{
$id = $this -> getId ( $key );
try {
2024-01-12 06:08:24 +01:00
foreach ( $this -> doFetch ([ $id ]) as $value ) {
2018-04-17 04:11:51 +02:00
return $value ;
}
} catch ( \Exception $e ) {
2024-03-20 03:35:09 +01:00
CacheItem :: log ( $this -> logger , 'Failed to fetch key "{key}": ' . $e -> getMessage (), [ 'key' => $key , 'exception' => $e ]);
2018-04-17 04:11:51 +02:00
}
return $default ;
}
/**
* { @ inheritdoc }
2024-03-20 03:35:09 +01:00
*
* @ return bool
2018-04-17 04:11:51 +02:00
*/
public function set ( $key , $value , $ttl = null )
{
CacheItem :: validateKey ( $key );
2024-01-12 06:08:24 +01:00
return $this -> setMultiple ([ $key => $value ], $ttl );
2018-04-17 04:11:51 +02:00
}
/**
* { @ inheritdoc }
2024-03-20 03:35:09 +01:00
*
* @ return iterable
2018-04-17 04:11:51 +02:00
*/
public function getMultiple ( $keys , $default = null )
{
if ( $keys instanceof \Traversable ) {
$keys = iterator_to_array ( $keys , false );
2024-01-12 06:08:24 +01:00
} elseif ( ! \is_array ( $keys )) {
throw new InvalidArgumentException ( sprintf ( 'Cache keys must be array or Traversable, "%s" given.' , \is_object ( $keys ) ? \get_class ( $keys ) : \gettype ( $keys )));
2018-04-17 04:11:51 +02:00
}
2024-01-12 06:08:24 +01:00
$ids = [];
2018-04-17 04:11:51 +02:00
foreach ( $keys as $key ) {
$ids [] = $this -> getId ( $key );
}
try {
$values = $this -> doFetch ( $ids );
} catch ( \Exception $e ) {
2024-03-20 03:35:09 +01:00
CacheItem :: log ( $this -> logger , 'Failed to fetch values: ' . $e -> getMessage (), [ 'keys' => $keys , 'exception' => $e ]);
2024-01-12 06:08:24 +01:00
$values = [];
2018-04-17 04:11:51 +02:00
}
$ids = array_combine ( $ids , $keys );
return $this -> generateValues ( $values , $ids , $default );
}
/**
* { @ inheritdoc }
2024-03-20 03:35:09 +01:00
*
* @ return bool
2018-04-17 04:11:51 +02:00
*/
public function setMultiple ( $values , $ttl = null )
{
2024-01-12 06:08:24 +01:00
if ( ! \is_array ( $values ) && ! $values instanceof \Traversable ) {
throw new InvalidArgumentException ( sprintf ( 'Cache values must be array or Traversable, "%s" given.' , \is_object ( $values ) ? \get_class ( $values ) : \gettype ( $values )));
2018-04-17 04:11:51 +02:00
}
2024-01-12 06:08:24 +01:00
$valuesById = [];
2018-04-17 04:11:51 +02:00
foreach ( $values as $key => $value ) {
2024-01-12 06:08:24 +01:00
if ( \is_int ( $key )) {
2018-04-17 04:11:51 +02:00
$key = ( string ) $key ;
}
$valuesById [ $this -> getId ( $key )] = $value ;
}
if ( false === $ttl = $this -> normalizeTtl ( $ttl )) {
return $this -> doDelete ( array_keys ( $valuesById ));
}
try {
$e = $this -> doSave ( $valuesById , $ttl );
} catch ( \Exception $e ) {
}
2024-01-12 06:08:24 +01:00
if ( true === $e || [] === $e ) {
2018-04-17 04:11:51 +02:00
return true ;
}
2024-01-12 06:08:24 +01:00
$keys = [];
foreach ( \is_array ( $e ) ? $e : array_keys ( $valuesById ) as $id ) {
$keys [] = substr ( $id , \strlen ( $this -> namespace ));
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
$message = 'Failed to save values' . ( $e instanceof \Exception ? ': ' . $e -> getMessage () : '.' );
CacheItem :: log ( $this -> logger , $message , [ 'keys' => $keys , 'exception' => $e instanceof \Exception ? $e : null ]);
2018-04-17 04:11:51 +02:00
return false ;
}
/**
* { @ inheritdoc }
2024-03-20 03:35:09 +01:00
*
* @ return bool
2018-04-17 04:11:51 +02:00
*/
public function deleteMultiple ( $keys )
{
if ( $keys instanceof \Traversable ) {
$keys = iterator_to_array ( $keys , false );
2024-01-12 06:08:24 +01:00
} elseif ( ! \is_array ( $keys )) {
throw new InvalidArgumentException ( sprintf ( 'Cache keys must be array or Traversable, "%s" given.' , \is_object ( $keys ) ? \get_class ( $keys ) : \gettype ( $keys )));
2018-04-17 04:11:51 +02:00
}
return $this -> deleteItems ( $keys );
}
private function normalizeTtl ( $ttl )
{
if ( null === $ttl ) {
return $this -> defaultLifetime ;
}
if ( $ttl instanceof \DateInterval ) {
$ttl = ( int ) \DateTime :: createFromFormat ( 'U' , 0 ) -> add ( $ttl ) -> format ( 'U' );
}
2024-01-12 06:08:24 +01:00
if ( \is_int ( $ttl )) {
2018-04-17 04:11:51 +02:00
return 0 < $ttl ? $ttl : false ;
}
2024-01-12 06:08:24 +01:00
throw new InvalidArgumentException ( sprintf ( 'Expiration date must be an integer, a DateInterval or null, "%s" given.' , \is_object ( $ttl ) ? \get_class ( $ttl ) : \gettype ( $ttl )));
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
private function generateValues ( iterable $values , array & $keys , $default ) : iterable
2018-04-17 04:11:51 +02:00
{
try {
foreach ( $values as $id => $value ) {
if ( ! isset ( $keys [ $id ])) {
2024-03-20 03:35:09 +01:00
throw new InvalidArgumentException ( sprintf ( 'Could not match value id "%s" to keys "%s".' , $id , implode ( '", "' , $keys )));
2018-04-17 04:11:51 +02:00
}
$key = $keys [ $id ];
unset ( $keys [ $id ]);
yield $key => $value ;
}
} catch ( \Exception $e ) {
2024-03-20 03:35:09 +01:00
CacheItem :: log ( $this -> logger , 'Failed to fetch values: ' . $e -> getMessage (), [ 'keys' => array_values ( $keys ), 'exception' => $e ]);
2018-04-17 04:11:51 +02:00
}
foreach ( $keys as $key ) {
yield $key => $default ;
}
}
}