mailpoet
/
vendor-prefixed
/
doctrine
/
cache
/
lib
/
Doctrine
/
Common
/
Cache
/
Psr6
/
CacheAdapter.php
mailpoet
/
vendor-prefixed
/
doctrine
/
cache
/
lib
/
Doctrine
/
Common
/
Cache
/
Psr6
Last commit date
CacheAdapter.php
4 years ago
CacheItem.php
4 years ago
DoctrineProvider.php
2 years ago
InvalidArgument.php
4 years ago
TypedCacheItem.php
2 years ago
index.php
3 years ago
CacheAdapter.php
238 lines
| 1 | <?php |
| 2 | namespace MailPoetVendor\Doctrine\Common\Cache\Psr6; |
| 3 | if (!defined('ABSPATH')) exit; |
| 4 | use MailPoetVendor\Doctrine\Common\Cache\Cache; |
| 5 | use MailPoetVendor\Doctrine\Common\Cache\ClearableCache; |
| 6 | use MailPoetVendor\Doctrine\Common\Cache\MultiDeleteCache; |
| 7 | use MailPoetVendor\Doctrine\Common\Cache\MultiGetCache; |
| 8 | use MailPoetVendor\Doctrine\Common\Cache\MultiPutCache; |
| 9 | use MailPoetVendor\Psr\Cache\CacheItemInterface; |
| 10 | use MailPoetVendor\Psr\Cache\CacheItemPoolInterface; |
| 11 | use MailPoetVendor\Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider; |
| 12 | use function array_key_exists; |
| 13 | use function assert; |
| 14 | use function count; |
| 15 | use function current; |
| 16 | use function get_class; |
| 17 | use function gettype; |
| 18 | use function is_object; |
| 19 | use function is_string; |
| 20 | use function microtime; |
| 21 | use function sprintf; |
| 22 | use function strpbrk; |
| 23 | use const PHP_VERSION_ID; |
| 24 | final class CacheAdapter implements CacheItemPoolInterface |
| 25 | { |
| 26 | private const RESERVED_CHARACTERS = '{}()/\\@:'; |
| 27 | private $cache; |
| 28 | private $deferredItems = []; |
| 29 | public static function wrap(Cache $cache) : CacheItemPoolInterface |
| 30 | { |
| 31 | if ($cache instanceof DoctrineProvider && !$cache->getNamespace()) { |
| 32 | return $cache->getPool(); |
| 33 | } |
| 34 | if ($cache instanceof SymfonyDoctrineProvider && !$cache->getNamespace()) { |
| 35 | $getPool = function () { |
| 36 | // phpcs:ignore Squiz.Scope.StaticThisUsage.Found |
| 37 | return $this->pool; |
| 38 | }; |
| 39 | return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)(); |
| 40 | } |
| 41 | return new self($cache); |
| 42 | } |
| 43 | private function __construct(Cache $cache) |
| 44 | { |
| 45 | $this->cache = $cache; |
| 46 | } |
| 47 | public function getCache() : Cache |
| 48 | { |
| 49 | return $this->cache; |
| 50 | } |
| 51 | public function getItem($key) : CacheItemInterface |
| 52 | { |
| 53 | assert(self::validKey($key)); |
| 54 | if (isset($this->deferredItems[$key])) { |
| 55 | $this->commit(); |
| 56 | } |
| 57 | $value = $this->cache->fetch($key); |
| 58 | if (PHP_VERSION_ID >= 80000) { |
| 59 | if ($value !== \false) { |
| 60 | return new TypedCacheItem($key, $value, \true); |
| 61 | } |
| 62 | return new TypedCacheItem($key, null, \false); |
| 63 | } |
| 64 | if ($value !== \false) { |
| 65 | return new CacheItem($key, $value, \true); |
| 66 | } |
| 67 | return new CacheItem($key, null, \false); |
| 68 | } |
| 69 | public function getItems(array $keys = []) : array |
| 70 | { |
| 71 | if ($this->deferredItems) { |
| 72 | $this->commit(); |
| 73 | } |
| 74 | assert(self::validKeys($keys)); |
| 75 | $values = $this->doFetchMultiple($keys); |
| 76 | $items = []; |
| 77 | if (PHP_VERSION_ID >= 80000) { |
| 78 | foreach ($keys as $key) { |
| 79 | if (array_key_exists($key, $values)) { |
| 80 | $items[$key] = new TypedCacheItem($key, $values[$key], \true); |
| 81 | } else { |
| 82 | $items[$key] = new TypedCacheItem($key, null, \false); |
| 83 | } |
| 84 | } |
| 85 | return $items; |
| 86 | } |
| 87 | foreach ($keys as $key) { |
| 88 | if (array_key_exists($key, $values)) { |
| 89 | $items[$key] = new CacheItem($key, $values[$key], \true); |
| 90 | } else { |
| 91 | $items[$key] = new CacheItem($key, null, \false); |
| 92 | } |
| 93 | } |
| 94 | return $items; |
| 95 | } |
| 96 | public function hasItem($key) : bool |
| 97 | { |
| 98 | assert(self::validKey($key)); |
| 99 | if (isset($this->deferredItems[$key])) { |
| 100 | $this->commit(); |
| 101 | } |
| 102 | return $this->cache->contains($key); |
| 103 | } |
| 104 | public function clear() : bool |
| 105 | { |
| 106 | $this->deferredItems = []; |
| 107 | if (!$this->cache instanceof ClearableCache) { |
| 108 | return \false; |
| 109 | } |
| 110 | return $this->cache->deleteAll(); |
| 111 | } |
| 112 | public function deleteItem($key) : bool |
| 113 | { |
| 114 | assert(self::validKey($key)); |
| 115 | unset($this->deferredItems[$key]); |
| 116 | return $this->cache->delete($key); |
| 117 | } |
| 118 | public function deleteItems(array $keys) : bool |
| 119 | { |
| 120 | foreach ($keys as $key) { |
| 121 | assert(self::validKey($key)); |
| 122 | unset($this->deferredItems[$key]); |
| 123 | } |
| 124 | return $this->doDeleteMultiple($keys); |
| 125 | } |
| 126 | public function save(CacheItemInterface $item) : bool |
| 127 | { |
| 128 | return $this->saveDeferred($item) && $this->commit(); |
| 129 | } |
| 130 | public function saveDeferred(CacheItemInterface $item) : bool |
| 131 | { |
| 132 | if (!$item instanceof CacheItem && !$item instanceof TypedCacheItem) { |
| 133 | return \false; |
| 134 | } |
| 135 | $this->deferredItems[$item->getKey()] = $item; |
| 136 | return \true; |
| 137 | } |
| 138 | public function commit() : bool |
| 139 | { |
| 140 | if (!$this->deferredItems) { |
| 141 | return \true; |
| 142 | } |
| 143 | $now = microtime(\true); |
| 144 | $itemsCount = 0; |
| 145 | $byLifetime = []; |
| 146 | $expiredKeys = []; |
| 147 | foreach ($this->deferredItems as $key => $item) { |
| 148 | $lifetime = ($item->getExpiry() ?? $now) - $now; |
| 149 | if ($lifetime < 0) { |
| 150 | $expiredKeys[] = $key; |
| 151 | continue; |
| 152 | } |
| 153 | ++$itemsCount; |
| 154 | $byLifetime[(int) $lifetime][$key] = $item->get(); |
| 155 | } |
| 156 | $this->deferredItems = []; |
| 157 | switch (count($expiredKeys)) { |
| 158 | case 0: |
| 159 | break; |
| 160 | case 1: |
| 161 | $this->cache->delete(current($expiredKeys)); |
| 162 | break; |
| 163 | default: |
| 164 | $this->doDeleteMultiple($expiredKeys); |
| 165 | break; |
| 166 | } |
| 167 | if ($itemsCount === 1) { |
| 168 | return $this->cache->save($key, $item->get(), (int) $lifetime); |
| 169 | } |
| 170 | $success = \true; |
| 171 | foreach ($byLifetime as $lifetime => $values) { |
| 172 | $success = $this->doSaveMultiple($values, $lifetime) && $success; |
| 173 | } |
| 174 | return $success; |
| 175 | } |
| 176 | public function __destruct() |
| 177 | { |
| 178 | $this->commit(); |
| 179 | } |
| 180 | private static function validKey($key) : bool |
| 181 | { |
| 182 | if (!is_string($key)) { |
| 183 | throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); |
| 184 | } |
| 185 | if ($key === '') { |
| 186 | throw new InvalidArgument('Cache key length must be greater than zero.'); |
| 187 | } |
| 188 | if (strpbrk($key, self::RESERVED_CHARACTERS) !== \false) { |
| 189 | throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS)); |
| 190 | } |
| 191 | return \true; |
| 192 | } |
| 193 | private static function validKeys(array $keys) : bool |
| 194 | { |
| 195 | foreach ($keys as $key) { |
| 196 | self::validKey($key); |
| 197 | } |
| 198 | return \true; |
| 199 | } |
| 200 | private function doDeleteMultiple(array $keys) : bool |
| 201 | { |
| 202 | if ($this->cache instanceof MultiDeleteCache) { |
| 203 | return $this->cache->deleteMultiple($keys); |
| 204 | } |
| 205 | $success = \true; |
| 206 | foreach ($keys as $key) { |
| 207 | $success = $this->cache->delete($key) && $success; |
| 208 | } |
| 209 | return $success; |
| 210 | } |
| 211 | private function doFetchMultiple(array $keys) : array |
| 212 | { |
| 213 | if ($this->cache instanceof MultiGetCache) { |
| 214 | return $this->cache->fetchMultiple($keys); |
| 215 | } |
| 216 | $values = []; |
| 217 | foreach ($keys as $key) { |
| 218 | $value = $this->cache->fetch($key); |
| 219 | if (!$value) { |
| 220 | continue; |
| 221 | } |
| 222 | $values[$key] = $value; |
| 223 | } |
| 224 | return $values; |
| 225 | } |
| 226 | private function doSaveMultiple(array $keysAndValues, int $lifetime = 0) : bool |
| 227 | { |
| 228 | if ($this->cache instanceof MultiPutCache) { |
| 229 | return $this->cache->saveMultiple($keysAndValues, $lifetime); |
| 230 | } |
| 231 | $success = \true; |
| 232 | foreach ($keysAndValues as $key => $value) { |
| 233 | $success = $this->cache->save($key, $value, $lifetime) && $success; |
| 234 | } |
| 235 | return $success; |
| 236 | } |
| 237 | } |
| 238 |