|
17 | 17 | use Psr\Cache\CacheItemInterface; |
18 | 18 | use Psr\Log\LoggerAwareInterface; |
19 | 19 | use Psr\Log\LoggerInterface; |
| 20 | +use Psr\SimpleCache\CacheInterface; |
20 | 21 |
|
21 | 22 | /** |
22 | 23 | * @author Aaron Scherer <[email protected]> |
23 | 24 | * @author Tobias Nyholm <[email protected]> |
24 | 25 | */ |
25 | | -abstract class AbstractCachePool implements PhpCachePool, LoggerAwareInterface |
| 26 | +abstract class AbstractCachePool implements PhpCachePool, LoggerAwareInterface, CacheInterface |
26 | 27 | { |
27 | 28 | const SEPARATOR_TAG = '!'; |
28 | 29 |
|
@@ -281,7 +282,10 @@ protected function validateKey($key) |
281 | 282 | )); |
282 | 283 | $this->handleException($e, __FUNCTION__); |
283 | 284 | } |
284 | | - |
| 285 | + if (!isset($key[0])) { |
| 286 | + $e = new InvalidArgumentException('Cache key cannot be an empty string'); |
| 287 | + $this->handleException($e, __FUNCTION__); |
| 288 | + } |
285 | 289 | if (preg_match('|[\{\}\(\)/\\\@\:]|', $key)) { |
286 | 290 | $e = new InvalidArgumentException(sprintf( |
287 | 291 | 'Invalid key: "%s". The key contains one or more characters reserved for future extension: {}()/\@:', |
@@ -415,4 +419,140 @@ protected function getTagKey($tag) |
415 | 419 | { |
416 | 420 | return 'tag'.self::SEPARATOR_TAG.$tag; |
417 | 421 | } |
| 422 | + |
| 423 | + /** |
| 424 | + * {@inheritdoc} |
| 425 | + */ |
| 426 | + public function get($key, $default = null) |
| 427 | + { |
| 428 | + $item = $this->getItem($key); |
| 429 | + if (!$item->isHit()) { |
| 430 | + return $default; |
| 431 | + } |
| 432 | + |
| 433 | + return $item->get(); |
| 434 | + } |
| 435 | + |
| 436 | + /** |
| 437 | + * {@inheritdoc} |
| 438 | + */ |
| 439 | + public function set($key, $value, $ttl = null) |
| 440 | + { |
| 441 | + $item = $this->getItem($key); |
| 442 | + $item->set($value); |
| 443 | + $item->expiresAfter($ttl); |
| 444 | + |
| 445 | + return $this->save($item); |
| 446 | + } |
| 447 | + |
| 448 | + /** |
| 449 | + * {@inheritdoc} |
| 450 | + */ |
| 451 | + public function delete($key) |
| 452 | + { |
| 453 | + return $this->deleteItem($key); |
| 454 | + } |
| 455 | + |
| 456 | + /** |
| 457 | + * {@inheritdoc} |
| 458 | + */ |
| 459 | + public function getMultiple($keys, $default = null) |
| 460 | + { |
| 461 | + if (!is_array($keys)) { |
| 462 | + if (!$keys instanceof \Traversable) { |
| 463 | + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); |
| 464 | + } |
| 465 | + |
| 466 | + // Since we need to throw an exception if *any* key is invalid, it doesn't |
| 467 | + // make sense to wrap iterators or something like that. |
| 468 | + $keys = iterator_to_array($keys, false); |
| 469 | + } |
| 470 | + |
| 471 | + $items = $this->getItems($keys); |
| 472 | + |
| 473 | + return $this->generateValues($default, $items); |
| 474 | + } |
| 475 | + |
| 476 | + /** |
| 477 | + * @param $default |
| 478 | + * @param $items |
| 479 | + * |
| 480 | + * @return \Generator |
| 481 | + */ |
| 482 | + private function generateValues($default, $items) |
| 483 | + { |
| 484 | + foreach ($items as $key => $item) { |
| 485 | + /** @type $item CacheItemInterface */ |
| 486 | + if (!$item->isHit()) { |
| 487 | + yield $key => $default; |
| 488 | + } else { |
| 489 | + yield $key => $item->get(); |
| 490 | + } |
| 491 | + } |
| 492 | + } |
| 493 | + |
| 494 | + /** |
| 495 | + * {@inheritdoc} |
| 496 | + */ |
| 497 | + public function setMultiple($values, $ttl = null) |
| 498 | + { |
| 499 | + if (!is_array($values)) { |
| 500 | + if (!$values instanceof \Traversable) { |
| 501 | + throw new InvalidArgumentException('$values is neither an array nor Traversable'); |
| 502 | + } |
| 503 | + } |
| 504 | + |
| 505 | + $keys = []; |
| 506 | + $arrayValues = []; |
| 507 | + foreach ($values as $key => $value) { |
| 508 | + if (is_int($key)) { |
| 509 | + $key = (string) $key; |
| 510 | + } |
| 511 | + $this->validateKey($key); |
| 512 | + $keys[] = $key; |
| 513 | + $arrayValues[$key] = $value; |
| 514 | + } |
| 515 | + |
| 516 | + $items = $this->getItems($keys); |
| 517 | + $itemSuccess = true; |
| 518 | + foreach ($items as $key => $item) { |
| 519 | + $item->set($arrayValues[$key]); |
| 520 | + |
| 521 | + try { |
| 522 | + $item->expiresAfter($ttl); |
| 523 | + } catch (InvalidArgumentException $e) { |
| 524 | + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); |
| 525 | + } |
| 526 | + |
| 527 | + $itemSuccess = $itemSuccess && $this->saveDeferred($item); |
| 528 | + } |
| 529 | + |
| 530 | + return $itemSuccess && $this->commit(); |
| 531 | + } |
| 532 | + |
| 533 | + /** |
| 534 | + * {@inheritdoc} |
| 535 | + */ |
| 536 | + public function deleteMultiple($keys) |
| 537 | + { |
| 538 | + if (!is_array($keys)) { |
| 539 | + if (!$keys instanceof \Traversable) { |
| 540 | + throw new InvalidArgumentException('$keys is neither an array nor Traversable'); |
| 541 | + } |
| 542 | + |
| 543 | + // Since we need to throw an exception if *any* key is invalid, it doesn't |
| 544 | + // make sense to wrap iterators or something like that. |
| 545 | + $keys = iterator_to_array($keys, false); |
| 546 | + } |
| 547 | + |
| 548 | + return $this->deleteItems($keys); |
| 549 | + } |
| 550 | + |
| 551 | + /** |
| 552 | + * {@inheritdoc} |
| 553 | + */ |
| 554 | + public function has($key) |
| 555 | + { |
| 556 | + return $this->hasItem($key); |
| 557 | + } |
418 | 558 | } |
0 commit comments