diff options
| author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
| commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
| tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/symfony/cache/Adapter/PhpArrayAdapter.php | |
| parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
| download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.gz AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.tar.bz2 AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip | |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/symfony/cache/Adapter/PhpArrayAdapter.php')
| -rw-r--r-- | vendor/symfony/cache/Adapter/PhpArrayAdapter.php | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/vendor/symfony/cache/Adapter/PhpArrayAdapter.php b/vendor/symfony/cache/Adapter/PhpArrayAdapter.php new file mode 100644 index 0000000..f92a238 --- /dev/null +++ b/vendor/symfony/cache/Adapter/PhpArrayAdapter.php | |||
| @@ -0,0 +1,389 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | /* | ||
| 4 | * This file is part of the Symfony package. | ||
| 5 | * | ||
| 6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
| 7 | * | ||
| 8 | * For the full copyright and license information, please view the LICENSE | ||
| 9 | * file that was distributed with this source code. | ||
| 10 | */ | ||
| 11 | |||
| 12 | namespace Symfony\Component\Cache\Adapter; | ||
| 13 | |||
| 14 | use Psr\Cache\CacheItemInterface; | ||
| 15 | use Psr\Cache\CacheItemPoolInterface; | ||
| 16 | use Symfony\Component\Cache\CacheItem; | ||
| 17 | use Symfony\Component\Cache\Exception\InvalidArgumentException; | ||
| 18 | use Symfony\Component\Cache\PruneableInterface; | ||
| 19 | use Symfony\Component\Cache\ResettableInterface; | ||
| 20 | use Symfony\Component\Cache\Traits\ContractsTrait; | ||
| 21 | use Symfony\Component\Cache\Traits\ProxyTrait; | ||
| 22 | use Symfony\Component\VarExporter\VarExporter; | ||
| 23 | use Symfony\Contracts\Cache\CacheInterface; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. | ||
| 27 | * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter. | ||
| 28 | * | ||
| 29 | * @author Titouan Galopin <galopintitouan@gmail.com> | ||
| 30 | * @author Nicolas Grekas <p@tchwork.com> | ||
| 31 | */ | ||
| 32 | class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface | ||
| 33 | { | ||
| 34 | use ContractsTrait; | ||
| 35 | use ProxyTrait; | ||
| 36 | |||
| 37 | private array $keys; | ||
| 38 | private array $values; | ||
| 39 | |||
| 40 | private static \Closure $createCacheItem; | ||
| 41 | private static array $valuesCache = []; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * @param string $file The PHP file were values are cached | ||
| 45 | * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit | ||
| 46 | */ | ||
| 47 | public function __construct( | ||
| 48 | private string $file, | ||
| 49 | AdapterInterface $fallbackPool, | ||
| 50 | ) { | ||
| 51 | $this->pool = $fallbackPool; | ||
| 52 | self::$createCacheItem ??= \Closure::bind( | ||
| 53 | static function ($key, $value, $isHit) { | ||
| 54 | $item = new CacheItem(); | ||
| 55 | $item->key = $key; | ||
| 56 | $item->value = $value; | ||
| 57 | $item->isHit = $isHit; | ||
| 58 | |||
| 59 | return $item; | ||
| 60 | }, | ||
| 61 | null, | ||
| 62 | CacheItem::class | ||
| 63 | ); | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * This adapter takes advantage of how PHP stores arrays in its latest versions. | ||
| 68 | * | ||
| 69 | * @param string $file The PHP file were values are cached | ||
| 70 | * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit | ||
| 71 | */ | ||
| 72 | public static function create(string $file, CacheItemPoolInterface $fallbackPool): CacheItemPoolInterface | ||
| 73 | { | ||
| 74 | if (!$fallbackPool instanceof AdapterInterface) { | ||
| 75 | $fallbackPool = new ProxyAdapter($fallbackPool); | ||
| 76 | } | ||
| 77 | |||
| 78 | return new static($file, $fallbackPool); | ||
| 79 | } | ||
| 80 | |||
| 81 | public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed | ||
| 82 | { | ||
| 83 | if (!isset($this->values)) { | ||
| 84 | $this->initialize(); | ||
| 85 | } | ||
| 86 | if (!isset($this->keys[$key])) { | ||
| 87 | get_from_pool: | ||
| 88 | if ($this->pool instanceof CacheInterface) { | ||
| 89 | return $this->pool->get($key, $callback, $beta, $metadata); | ||
| 90 | } | ||
| 91 | |||
| 92 | return $this->doGet($this->pool, $key, $callback, $beta, $metadata); | ||
| 93 | } | ||
| 94 | $value = $this->values[$this->keys[$key]]; | ||
| 95 | |||
| 96 | if ('N;' === $value) { | ||
| 97 | return null; | ||
| 98 | } | ||
| 99 | try { | ||
| 100 | if ($value instanceof \Closure) { | ||
| 101 | return $value(); | ||
| 102 | } | ||
| 103 | } catch (\Throwable) { | ||
| 104 | unset($this->keys[$key]); | ||
| 105 | goto get_from_pool; | ||
| 106 | } | ||
| 107 | |||
| 108 | return $value; | ||
| 109 | } | ||
| 110 | |||
| 111 | public function getItem(mixed $key): CacheItem | ||
| 112 | { | ||
| 113 | if (!\is_string($key)) { | ||
| 114 | throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); | ||
| 115 | } | ||
| 116 | if (!isset($this->values)) { | ||
| 117 | $this->initialize(); | ||
| 118 | } | ||
| 119 | if (!isset($this->keys[$key])) { | ||
| 120 | return $this->pool->getItem($key); | ||
| 121 | } | ||
| 122 | |||
| 123 | $value = $this->values[$this->keys[$key]]; | ||
| 124 | $isHit = true; | ||
| 125 | |||
| 126 | if ('N;' === $value) { | ||
| 127 | $value = null; | ||
| 128 | } elseif ($value instanceof \Closure) { | ||
| 129 | try { | ||
| 130 | $value = $value(); | ||
| 131 | } catch (\Throwable) { | ||
| 132 | $value = null; | ||
| 133 | $isHit = false; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | return (self::$createCacheItem)($key, $value, $isHit); | ||
| 138 | } | ||
| 139 | |||
| 140 | public function getItems(array $keys = []): iterable | ||
| 141 | { | ||
| 142 | foreach ($keys as $key) { | ||
| 143 | if (!\is_string($key)) { | ||
| 144 | throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | if (!isset($this->values)) { | ||
| 148 | $this->initialize(); | ||
| 149 | } | ||
| 150 | |||
| 151 | return $this->generateItems($keys); | ||
| 152 | } | ||
| 153 | |||
| 154 | public function hasItem(mixed $key): bool | ||
| 155 | { | ||
| 156 | if (!\is_string($key)) { | ||
| 157 | throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); | ||
| 158 | } | ||
| 159 | if (!isset($this->values)) { | ||
| 160 | $this->initialize(); | ||
| 161 | } | ||
| 162 | |||
| 163 | return isset($this->keys[$key]) || $this->pool->hasItem($key); | ||
| 164 | } | ||
| 165 | |||
| 166 | public function deleteItem(mixed $key): bool | ||
| 167 | { | ||
| 168 | if (!\is_string($key)) { | ||
| 169 | throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); | ||
| 170 | } | ||
| 171 | if (!isset($this->values)) { | ||
| 172 | $this->initialize(); | ||
| 173 | } | ||
| 174 | |||
| 175 | return !isset($this->keys[$key]) && $this->pool->deleteItem($key); | ||
| 176 | } | ||
| 177 | |||
| 178 | public function deleteItems(array $keys): bool | ||
| 179 | { | ||
| 180 | $deleted = true; | ||
| 181 | $fallbackKeys = []; | ||
| 182 | |||
| 183 | foreach ($keys as $key) { | ||
| 184 | if (!\is_string($key)) { | ||
| 185 | throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); | ||
| 186 | } | ||
| 187 | |||
| 188 | if (isset($this->keys[$key])) { | ||
| 189 | $deleted = false; | ||
| 190 | } else { | ||
| 191 | $fallbackKeys[] = $key; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | if (!isset($this->values)) { | ||
| 195 | $this->initialize(); | ||
| 196 | } | ||
| 197 | |||
| 198 | if ($fallbackKeys) { | ||
| 199 | $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted; | ||
| 200 | } | ||
| 201 | |||
| 202 | return $deleted; | ||
| 203 | } | ||
| 204 | |||
| 205 | public function save(CacheItemInterface $item): bool | ||
| 206 | { | ||
| 207 | if (!isset($this->values)) { | ||
| 208 | $this->initialize(); | ||
| 209 | } | ||
| 210 | |||
| 211 | return !isset($this->keys[$item->getKey()]) && $this->pool->save($item); | ||
| 212 | } | ||
| 213 | |||
| 214 | public function saveDeferred(CacheItemInterface $item): bool | ||
| 215 | { | ||
| 216 | if (!isset($this->values)) { | ||
| 217 | $this->initialize(); | ||
| 218 | } | ||
| 219 | |||
| 220 | return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item); | ||
| 221 | } | ||
| 222 | |||
| 223 | public function commit(): bool | ||
| 224 | { | ||
| 225 | return $this->pool->commit(); | ||
| 226 | } | ||
| 227 | |||
| 228 | public function clear(string $prefix = ''): bool | ||
| 229 | { | ||
| 230 | $this->keys = $this->values = []; | ||
| 231 | |||
| 232 | $cleared = @unlink($this->file) || !file_exists($this->file); | ||
| 233 | unset(self::$valuesCache[$this->file]); | ||
| 234 | |||
| 235 | if ($this->pool instanceof AdapterInterface) { | ||
| 236 | return $this->pool->clear($prefix) && $cleared; | ||
| 237 | } | ||
| 238 | |||
| 239 | return $this->pool->clear() && $cleared; | ||
| 240 | } | ||
| 241 | |||
| 242 | /** | ||
| 243 | * Store an array of cached values. | ||
| 244 | * | ||
| 245 | * @param array $values The cached values | ||
| 246 | * | ||
| 247 | * @return string[] A list of classes to preload on PHP 7.4+ | ||
| 248 | */ | ||
| 249 | public function warmUp(array $values): array | ||
| 250 | { | ||
| 251 | if (file_exists($this->file)) { | ||
| 252 | if (!is_file($this->file)) { | ||
| 253 | throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file)); | ||
| 254 | } | ||
| 255 | |||
| 256 | if (!is_writable($this->file)) { | ||
| 257 | throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file)); | ||
| 258 | } | ||
| 259 | } else { | ||
| 260 | $directory = \dirname($this->file); | ||
| 261 | |||
| 262 | if (!is_dir($directory) && !@mkdir($directory, 0777, true)) { | ||
| 263 | throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); | ||
| 264 | } | ||
| 265 | |||
| 266 | if (!is_writable($directory)) { | ||
| 267 | throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory)); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | $preload = []; | ||
| 272 | $dumpedValues = ''; | ||
| 273 | $dumpedMap = []; | ||
| 274 | $dump = <<<'EOF' | ||
| 275 | <?php | ||
| 276 | |||
| 277 | // This file has been auto-generated by the Symfony Cache Component. | ||
| 278 | |||
| 279 | return [[ | ||
| 280 | |||
| 281 | |||
| 282 | EOF; | ||
| 283 | |||
| 284 | foreach ($values as $key => $value) { | ||
| 285 | CacheItem::validateKey(\is_int($key) ? (string) $key : $key); | ||
| 286 | $isStaticValue = true; | ||
| 287 | |||
| 288 | if (null === $value) { | ||
| 289 | $value = "'N;'"; | ||
| 290 | } elseif (\is_object($value) || \is_array($value)) { | ||
| 291 | try { | ||
| 292 | $value = VarExporter::export($value, $isStaticValue, $preload); | ||
| 293 | } catch (\Exception $e) { | ||
| 294 | throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); | ||
| 295 | } | ||
| 296 | } elseif (\is_string($value)) { | ||
| 297 | // Wrap "N;" in a closure to not confuse it with an encoded `null` | ||
| 298 | if ('N;' === $value) { | ||
| 299 | $isStaticValue = false; | ||
| 300 | } | ||
| 301 | $value = var_export($value, true); | ||
| 302 | } elseif (!\is_scalar($value)) { | ||
| 303 | throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); | ||
| 304 | } else { | ||
| 305 | $value = var_export($value, true); | ||
| 306 | } | ||
| 307 | |||
| 308 | if (!$isStaticValue) { | ||
| 309 | $value = str_replace("\n", "\n ", $value); | ||
| 310 | $value = "static function () {\n return {$value};\n}"; | ||
| 311 | } | ||
| 312 | $hash = hash('xxh128', $value); | ||
| 313 | |||
| 314 | if (null === $id = $dumpedMap[$hash] ?? null) { | ||
| 315 | $id = $dumpedMap[$hash] = \count($dumpedMap); | ||
| 316 | $dumpedValues .= "{$id} => {$value},\n"; | ||
| 317 | } | ||
| 318 | |||
| 319 | $dump .= var_export($key, true)." => {$id},\n"; | ||
| 320 | } | ||
| 321 | |||
| 322 | $dump .= "\n], [\n\n{$dumpedValues}\n]];\n"; | ||
| 323 | |||
| 324 | $tmpFile = uniqid($this->file, true); | ||
| 325 | |||
| 326 | file_put_contents($tmpFile, $dump); | ||
| 327 | @chmod($tmpFile, 0666 & ~umask()); | ||
| 328 | unset($serialized, $value, $dump); | ||
| 329 | |||
| 330 | @rename($tmpFile, $this->file); | ||
| 331 | unset(self::$valuesCache[$this->file]); | ||
| 332 | |||
| 333 | $this->initialize(); | ||
| 334 | |||
| 335 | return $preload; | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Load the cache file. | ||
| 340 | */ | ||
| 341 | private function initialize(): void | ||
| 342 | { | ||
| 343 | if (isset(self::$valuesCache[$this->file])) { | ||
| 344 | $values = self::$valuesCache[$this->file]; | ||
| 345 | } elseif (!is_file($this->file)) { | ||
| 346 | $this->keys = $this->values = []; | ||
| 347 | |||
| 348 | return; | ||
| 349 | } else { | ||
| 350 | $values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []]; | ||
| 351 | } | ||
| 352 | |||
| 353 | if (2 !== \count($values) || !isset($values[0], $values[1])) { | ||
| 354 | $this->keys = $this->values = []; | ||
| 355 | } else { | ||
| 356 | [$this->keys, $this->values] = $values; | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | private function generateItems(array $keys): \Generator | ||
| 361 | { | ||
| 362 | $f = self::$createCacheItem; | ||
| 363 | $fallbackKeys = []; | ||
| 364 | |||
| 365 | foreach ($keys as $key) { | ||
| 366 | if (isset($this->keys[$key])) { | ||
| 367 | $value = $this->values[$this->keys[$key]]; | ||
| 368 | |||
| 369 | if ('N;' === $value) { | ||
| 370 | yield $key => $f($key, null, true); | ||
| 371 | } elseif ($value instanceof \Closure) { | ||
| 372 | try { | ||
| 373 | yield $key => $f($key, $value(), true); | ||
| 374 | } catch (\Throwable) { | ||
| 375 | yield $key => $f($key, null, false); | ||
| 376 | } | ||
| 377 | } else { | ||
| 378 | yield $key => $f($key, $value, true); | ||
| 379 | } | ||
| 380 | } else { | ||
| 381 | $fallbackKeys[] = $key; | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 385 | if ($fallbackKeys) { | ||
| 386 | yield from $this->pool->getItems($fallbackKeys); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | } | ||
