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 ;
use Psr\Log\LoggerInterface ;
use Symfony\Component\Cache\Exception\InvalidArgumentException ;
2024-03-20 03:35:09 +01:00
use Symfony\Component\Cache\Exception\LogicException ;
use Symfony\Contracts\Cache\ItemInterface ;
2018-04-17 04:11:51 +02:00
/**
* @ author Nicolas Grekas < p @ tchwork . com >
*/
2024-03-20 03:35:09 +01:00
final class CacheItem implements ItemInterface
2018-04-17 04:11:51 +02:00
{
2024-03-20 03:35:09 +01:00
private const METADATA_EXPIRY_OFFSET = 1527506807 ;
2018-04-17 04:11:51 +02:00
protected $key ;
protected $value ;
protected $isHit = false ;
protected $expiry ;
2024-03-20 03:35:09 +01:00
protected $metadata = [];
protected $newMetadata = [];
2018-04-17 04:11:51 +02:00
protected $innerItem ;
protected $poolHash ;
2024-03-20 03:35:09 +01:00
protected $isTaggable = false ;
2018-04-17 04:11:51 +02:00
/**
* { @ inheritdoc }
*/
2024-03-20 03:35:09 +01:00
public function getKey () : string
2018-04-17 04:11:51 +02:00
{
return $this -> key ;
}
/**
* { @ inheritdoc }
2024-03-20 03:35:09 +01:00
*
* @ return mixed
2018-04-17 04:11:51 +02:00
*/
public function get ()
{
return $this -> value ;
}
/**
* { @ inheritdoc }
*/
2024-03-20 03:35:09 +01:00
public function isHit () : bool
2018-04-17 04:11:51 +02:00
{
return $this -> isHit ;
}
/**
* { @ inheritdoc }
2024-01-12 06:08:24 +01:00
*
* @ return $this
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
public function set ( $value ) : self
2018-04-17 04:11:51 +02:00
{
$this -> value = $value ;
return $this ;
}
/**
* { @ inheritdoc }
2024-01-12 06:08:24 +01:00
*
* @ return $this
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
public function expiresAt ( $expiration ) : self
2018-04-17 04:11:51 +02:00
{
if ( null === $expiration ) {
2024-01-12 06:08:24 +01:00
$this -> expiry = null ;
2018-04-17 04:11:51 +02:00
} elseif ( $expiration instanceof \DateTimeInterface ) {
2024-03-20 03:35:09 +01:00
$this -> expiry = ( float ) $expiration -> format ( 'U.u' );
2018-04-17 04:11:51 +02:00
} else {
2024-01-12 06:08:24 +01:00
throw new InvalidArgumentException ( sprintf ( 'Expiration date must implement DateTimeInterface or be null, "%s" given.' , \is_object ( $expiration ) ? \get_class ( $expiration ) : \gettype ( $expiration )));
2018-04-17 04:11:51 +02:00
}
return $this ;
}
/**
* { @ inheritdoc }
2024-01-12 06:08:24 +01:00
*
* @ return $this
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
public function expiresAfter ( $time ) : self
2018-04-17 04:11:51 +02:00
{
if ( null === $time ) {
2024-01-12 06:08:24 +01:00
$this -> expiry = null ;
2018-04-17 04:11:51 +02:00
} elseif ( $time instanceof \DateInterval ) {
2024-03-20 03:35:09 +01:00
$this -> expiry = microtime ( true ) + \DateTime :: createFromFormat ( 'U' , 0 ) -> add ( $time ) -> format ( 'U.u' );
2024-01-12 06:08:24 +01:00
} elseif ( \is_int ( $time )) {
2024-03-20 03:35:09 +01:00
$this -> expiry = $time + microtime ( true );
2018-04-17 04:11:51 +02:00
} else {
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 ( $time ) ? \get_class ( $time ) : \gettype ( $time )));
2018-04-17 04:11:51 +02:00
}
return $this ;
}
/**
2024-03-20 03:35:09 +01:00
* { @ inheritdoc }
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
public function tag ( $tags ) : ItemInterface
2018-04-17 04:11:51 +02:00
{
2024-03-20 03:35:09 +01:00
if ( ! $this -> isTaggable ) {
throw new LogicException ( sprintf ( 'Cache item "%s" comes from a non tag-aware pool: you cannot tag it.' , $this -> key ));
}
if ( ! is_iterable ( $tags )) {
2024-01-12 06:08:24 +01:00
$tags = [ $tags ];
2018-04-17 04:11:51 +02:00
}
foreach ( $tags as $tag ) {
2024-03-20 03:35:09 +01:00
if ( ! \is_string ( $tag ) && ! ( \is_object ( $tag ) && method_exists ( $tag , '__toString' ))) {
throw new InvalidArgumentException ( sprintf ( 'Cache tag must be string or object that implements __toString(), "%s" given.' , \is_object ( $tag ) ? \get_class ( $tag ) : \gettype ( $tag )));
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
$tag = ( string ) $tag ;
if ( isset ( $this -> newMetadata [ self :: METADATA_TAGS ][ $tag ])) {
2018-04-17 04:11:51 +02:00
continue ;
}
2024-01-12 06:08:24 +01:00
if ( '' === $tag ) {
throw new InvalidArgumentException ( 'Cache tag length must be greater than zero.' );
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
if ( false !== strpbrk ( $tag , self :: RESERVED_CHARACTERS )) {
throw new InvalidArgumentException ( sprintf ( 'Cache tag "%s" contains reserved characters "%s".' , $tag , self :: RESERVED_CHARACTERS ));
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
$this -> newMetadata [ self :: METADATA_TAGS ][ $tag ] = $tag ;
2018-04-17 04:11:51 +02:00
}
return $this ;
}
2024-03-20 03:35:09 +01:00
/**
* { @ inheritdoc }
*/
public function getMetadata () : array
{
return $this -> metadata ;
}
2018-04-17 04:11:51 +02:00
/**
* Returns the list of tags bound to the value coming from the pool storage if any .
*
2024-03-20 03:35:09 +01:00
* @ deprecated since Symfony 4.2 , use the " getMetadata() " method instead .
2018-04-17 04:11:51 +02:00
*/
2024-03-20 03:35:09 +01:00
public function getPreviousTags () : array
2018-04-17 04:11:51 +02:00
{
2024-03-20 03:35:09 +01:00
@ trigger_error ( sprintf ( 'The "%s()" method is deprecated since Symfony 4.2, use the "getMetadata()" method instead.' , __METHOD__ ), \E_USER_DEPRECATED );
return $this -> metadata [ self :: METADATA_TAGS ] ? ? [];
2018-04-17 04:11:51 +02:00
}
/**
* Validates a cache key according to PSR - 6.
*
2024-03-20 03:35:09 +01:00
* @ param mixed $key The key to validate
2018-04-17 04:11:51 +02:00
*
* @ throws InvalidArgumentException When $key is not valid
*/
2024-03-20 03:35:09 +01:00
public static function validateKey ( $key ) : string
2018-04-17 04:11:51 +02:00
{
2024-01-12 06:08:24 +01:00
if ( ! \is_string ( $key )) {
throw new InvalidArgumentException ( sprintf ( 'Cache key must be string, "%s" given.' , \is_object ( $key ) ? \get_class ( $key ) : \gettype ( $key )));
2018-04-17 04:11:51 +02:00
}
2024-01-12 06:08:24 +01:00
if ( '' === $key ) {
throw new InvalidArgumentException ( 'Cache key length must be greater than zero.' );
2018-04-17 04:11:51 +02:00
}
2024-03-20 03:35:09 +01:00
if ( false !== strpbrk ( $key , self :: RESERVED_CHARACTERS )) {
throw new InvalidArgumentException ( sprintf ( 'Cache key "%s" contains reserved characters "%s".' , $key , self :: RESERVED_CHARACTERS ));
2018-04-17 04:11:51 +02:00
}
return $key ;
}
/**
* Internal logging helper .
*
* @ internal
*/
2024-03-20 03:35:09 +01:00
public static function log ( ? LoggerInterface $logger , string $message , array $context = [])
2018-04-17 04:11:51 +02:00
{
if ( $logger ) {
$logger -> warning ( $message , $context );
} else {
2024-01-12 06:08:24 +01:00
$replace = [];
2018-04-17 04:11:51 +02:00
foreach ( $context as $k => $v ) {
2024-03-20 03:35:09 +01:00
if ( \is_scalar ( $v )) {
2018-04-17 04:11:51 +02:00
$replace [ '{' . $k . '}' ] = $v ;
}
}
2024-01-12 06:08:24 +01:00
@ trigger_error ( strtr ( $message , $replace ), \E_USER_WARNING );
2018-04-17 04:11:51 +02:00
}
}
}