Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
209 additions
and
35 deletions.
There are no files selected for viewing
68 changes: 68 additions & 0 deletions
68
src/Symfony/Component/Serializer/Mapping/Factory/CacheClassMetadataFactory.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?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\Serializer\Mapping\Factory; | ||
|
||
use Psr\Cache\CacheItemPoolInterface; | ||
|
||
/** | ||
* Caches metadata using a PSR-6 implementation. | ||
* | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class CacheClassMetadataFactory implements ClassMetadataFactoryInterface | ||
{ | ||
use ClassResolverTrait; | ||
|
||
/** | ||
* @var ClassMetadataFactoryInterface | ||
*/ | ||
private $decorated; | ||
|
||
/** | ||
* @var CacheItemPoolInterface | ||
*/ | ||
private $cacheItemPool; | ||
|
||
public function __construct(ClassMetadataFactoryInterface $decorated, CacheItemPoolInterface $cacheItemPool) | ||
{ | ||
$this->decorated = $decorated; | ||
$this->cacheItemPool = $cacheItemPool; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getMetadataFor($value) | ||
{ | ||
$class = $this->getClass($value); | ||
// Key cannot contain backslashes according to PSR-6 | ||
$key = strtr($class, '\\', '_'); | ||
|
||
$item = $this->cacheItemPool->getItem($key); | ||
if ($item->isHit()) { | ||
return $item->get(); | ||
} | ||
|
||
$metadata = $this->decorated->getMetadataFor($value); | ||
$this->cacheItemPool->save($item->set($metadata)); | ||
|
||
return $metadata; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function hasMetadataFor($value) | ||
{ | ||
return $this->decorated->hasMetadataFor($value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
src/Symfony/Component/Serializer/Mapping/Factory/ClassResolverTrait.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?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\Serializer\Mapping\Factory; | ||
|
||
use Symfony\Component\Serializer\Exception\InvalidArgumentException; | ||
|
||
/** | ||
* Resolves a class name. | ||
* | ||
* @internal | ||
* | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
trait ClassResolverTrait | ||
{ | ||
/** | ||
* Gets a class name for a given class or instance. | ||
* | ||
* @param mixed $value | ||
* | ||
* @return string | ||
* | ||
* @throws InvalidArgumentException If the class does not exists | ||
*/ | ||
private function getClass($value) | ||
{ | ||
if (is_string($value)) { | ||
if (!class_exists($value) && !interface_exists($value)) { | ||
throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $value)); | ||
} | ||
|
||
return ltrim($value, '\\'); | ||
} | ||
|
||
if (!is_object($value)) { | ||
throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value))); | ||
} | ||
|
||
return get_class($value); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/Symfony/Component/Serializer/Tests/Mapping/Factory/CacheMetadataFactoryTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?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\Serializer\Tests\Mapping\Factory; | ||
|
||
use Symfony\Component\Cache\Adapter\ArrayAdapter; | ||
use Symfony\Component\Serializer\Mapping\ClassMetadata; | ||
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory; | ||
|
||
/** | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class CacheMetadataFactoryTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
public function testGetMetadataFor() | ||
{ | ||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Dummy'); | ||
|
||
$decorated = $this->getMock('Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface'); | ||
$decorated | ||
->expects($this->once()) | ||
->method('getMetadataFor') | ||
->will($this->returnValue($metadata)) | ||
; | ||
|
||
$factory = new CacheClassMetadataFactory($decorated, new ArrayAdapter()); | ||
|
||
$this->assertEquals($metadata, $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Dummy')); | ||
// The second call should retrieve the value from the cache | ||
$this->assertEquals($metadata, $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Dummy')); | ||
} | ||
|
||
public function testHasMetadataFor() | ||
{ | ||
$decorated = $this->getMock('Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface'); | ||
$decorated | ||
->expects($this->once()) | ||
->method('hasMetadataFor') | ||
->will($this->returnValue(true)) | ||
; | ||
|
||
$factory = new CacheClassMetadataFactory($decorated, new ArrayAdapter()); | ||
|
||
$this->assertTrue($factory->hasMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Dummy')); | ||
} | ||
|
||
/** | ||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException | ||
*/ | ||
public function testInvalidClassThrowsException() | ||
{ | ||
$decorated = $this->getMock('Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface'); | ||
$factory = new CacheClassMetadataFactory($decorated, new ArrayAdapter()); | ||
|
||
$factory->getMetadataFor('Not\Exist'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters