157 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			157 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?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\Traits; | ||
|  | 
 | ||
|  | use Psr\Cache\CacheItemInterface; | ||
|  | use Symfony\Component\Cache\CacheItem; | ||
|  | use Symfony\Component\Cache\Exception\InvalidArgumentException; | ||
|  | 
 | ||
|  | /** | ||
|  |  * @author Nicolas Grekas <p@tchwork.com> | ||
|  |  * | ||
|  |  * @internal | ||
|  |  */ | ||
|  | trait AbstractAdapterTrait | ||
|  | { | ||
|  |     use AbstractTrait; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var \Closure needs to be set by class, signature is function(string <key>, mixed <value>, bool <isHit>) | ||
|  |      */ | ||
|  |     private $createCacheItem; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var \Closure needs to be set by class, signature is function(array <deferred>, string <namespace>, array <&expiredIds>) | ||
|  |      */ | ||
|  |     private $mergeByLifetime; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getItem($key) | ||
|  |     { | ||
|  |         if ($this->deferred) { | ||
|  |             $this->commit(); | ||
|  |         } | ||
|  |         $id = $this->getId($key); | ||
|  | 
 | ||
|  |         $f = $this->createCacheItem; | ||
|  |         $isHit = false; | ||
|  |         $value = null; | ||
|  | 
 | ||
|  |         try { | ||
|  |             foreach ($this->doFetch([$id]) as $value) { | ||
|  |                 $isHit = true; | ||
|  |             } | ||
|  | 
 | ||
|  |             return $f($key, $value, $isHit); | ||
|  |         } catch (\Exception $e) { | ||
|  |             CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $f($key, null, false); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getItems(array $keys = []) | ||
|  |     { | ||
|  |         if ($this->deferred) { | ||
|  |             $this->commit(); | ||
|  |         } | ||
|  |         $ids = []; | ||
|  | 
 | ||
|  |         foreach ($keys as $key) { | ||
|  |             $ids[] = $this->getId($key); | ||
|  |         } | ||
|  |         try { | ||
|  |             $items = $this->doFetch($ids); | ||
|  |         } catch (\Exception $e) { | ||
|  |             CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]); | ||
|  |             $items = []; | ||
|  |         } | ||
|  |         $ids = array_combine($ids, $keys); | ||
|  | 
 | ||
|  |         return $this->generateItems($items, $ids); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      * | ||
|  |      * @return bool | ||
|  |      */ | ||
|  |     public function save(CacheItemInterface $item) | ||
|  |     { | ||
|  |         if (!$item instanceof CacheItem) { | ||
|  |             return false; | ||
|  |         } | ||
|  |         $this->deferred[$item->getKey()] = $item; | ||
|  | 
 | ||
|  |         return $this->commit(); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      * | ||
|  |      * @return bool | ||
|  |      */ | ||
|  |     public function saveDeferred(CacheItemInterface $item) | ||
|  |     { | ||
|  |         if (!$item instanceof CacheItem) { | ||
|  |             return false; | ||
|  |         } | ||
|  |         $this->deferred[$item->getKey()] = $item; | ||
|  | 
 | ||
|  |         return true; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function __sleep() | ||
|  |     { | ||
|  |         throw new \BadMethodCallException('Cannot serialize '.__CLASS__); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function __wakeup() | ||
|  |     { | ||
|  |         throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function __destruct() | ||
|  |     { | ||
|  |         if ($this->deferred) { | ||
|  |             $this->commit(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     private function generateItems(iterable $items, array &$keys): iterable | ||
|  |     { | ||
|  |         $f = $this->createCacheItem; | ||
|  | 
 | ||
|  |         try { | ||
|  |             foreach ($items as $id => $value) { | ||
|  |                 if (!isset($keys[$id])) { | ||
|  |                     throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys))); | ||
|  |                 } | ||
|  |                 $key = $keys[$id]; | ||
|  |                 unset($keys[$id]); | ||
|  |                 yield $key => $f($key, $value, true); | ||
|  |             } | ||
|  |         } catch (\Exception $e) { | ||
|  |             CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]); | ||
|  |         } | ||
|  | 
 | ||
|  |         foreach ($keys as $key) { | ||
|  |             yield $key => $f($key, null, false); | ||
|  |         } | ||
|  |     } | ||
|  | } |