Skip to content

Instantly share code, notes, and snippets.

@bendavies
Last active March 19, 2018 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bendavies/87cea8fffa85c75db7118322d27cf86a to your computer and use it in GitHub Desktop.
Save bendavies/87cea8fffa85c75db7118322d27cf86a to your computer and use it in GitHub Desktop.
<?php
/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Abacus\Core\Api;
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
use ApiPlatform\Core\Exception\InvalidArgumentException;
use ApiPlatform\Core\Util\ClassInfoTrait;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Exception\CacheException;
final class CachedResourceClassResolver implements ResourceClassResolverInterface
{
use ClassInfoTrait;
const CACHE_KEY_GET_PREFIX = 'resource_class_get_';
const CACHE_KEY_IS_PREFIX = 'resource_class_is_';
private $cacheItemPool;
private $decorated;
private $localCacheGet = [];
private $localCacheIs = [];
public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceClassResolverInterface $decorated)
{
$this->cacheItemPool = $cacheItemPool;
$this->decorated = $decorated;
}
public function getResourceClass($value, string $resourceClass = null, bool $strict = false): string
{
$typeToFind = $this->getObjectClass($value);
$localCacheKey = serialize([$typeToFind, $resourceClass, $strict]);
if (isset($this->localCacheGet[$localCacheKey])) {
$class = $this->localCacheGet[$localCacheKey];
if ($class instanceof InvalidArgumentException) {
throw $class;
}
return $class;
}
$cacheKey = self::CACHE_KEY_GET_PREFIX.md5($localCacheKey);
try {
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
if ($cacheItem->isHit()) {
$class = $this->localCacheGet[$localCacheKey] = $cacheItem->get();
if ($class instanceof InvalidArgumentException) {
throw $class;
}
return $class;
}
} catch (CacheException $e) {
// do nothing
}
try {
$class = $this->decorated->getResourceClass($value, $resourceClass, $strict);
} catch (InvalidArgumentException $e) {
$class = $e;
}
if (isset($cacheItem)) {
$cacheItem->set($class);
$this->cacheItemPool->save($cacheItem);
}
$this->localCacheGet[$localCacheKey] = $class;
if ($class instanceof InvalidArgumentException) {
throw $class;
}
return $class;
}
public function isResourceClass(string $type): bool
{
$cacheKey = self::CACHE_KEY_IS_PREFIX.md5($type);
if (isset($this->localCacheIs[$cacheKey])) {
return $this->localCacheIs[$cacheKey];
}
try {
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
if ($cacheItem->isHit()) {
return $this->localCacheIs[$cacheKey] = $cacheItem->get();
}
} catch (CacheException $e) {
}
$isResourceClass = $this->decorated->isResourceClass($type);
if (isset($cacheItem)) {
$cacheItem->set($isResourceClass);
$this->cacheItemPool->save($cacheItem);
}
return $this->localCacheIs[$cacheKey] = $isResourceClass;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment