-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[Validator] Add a PSR-6 adapter #17440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?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\Validator\Mapping\Cache; | ||
|
||
use Psr\Cache\CacheItemPoolInterface; | ||
use Symfony\Component\Validator\Mapping\ClassMetadata; | ||
|
||
/** | ||
* PSR-6 adapter. | ||
* | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class Psr6Cache implements CacheInterface | ||
{ | ||
/** | ||
* @var CacheItemPoolInterface | ||
*/ | ||
private $cacheItemPool; | ||
|
||
public function __construct(CacheItemPoolInterface $cacheItemPool) | ||
{ | ||
$this->cacheItemPool = $cacheItemPool; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function has($class) | ||
{ | ||
$item = $this->cacheItemPool->getItem($this->escapeClassName($class)); | ||
|
||
return $item->isHit(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function read($class) | ||
{ | ||
$item = $this->cacheItemPool->getItem($this->escapeClassName($class)); | ||
|
||
if (!$item->isHit()) { | ||
return false; | ||
} | ||
|
||
return $item->get(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function write(ClassMetadata $metadata) | ||
{ | ||
$item = $this->cacheItemPool->getItem($this->escapeClassName($metadata->getClassName())); | ||
$item->set($metadata); | ||
|
||
$this->cacheItemPool->save($item); | ||
} | ||
|
||
/** | ||
* Replaces backslashes by underscores in a class name. | ||
* | ||
* @param string $class | ||
* | ||
* @return string | ||
*/ | ||
private function escapeClassName($class) | ||
{ | ||
return strtr($class, '\\', '_'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we normalized this sort of operations to str_replace before |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?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\Validator\Tests\Mapping\Cache; | ||
|
||
use Symfony\Component\Validator\Mapping\Cache\CacheInterface; | ||
|
||
abstract class AbstractCacheTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @var CacheInterface | ||
*/ | ||
protected $cache; | ||
|
||
public function testWrite() | ||
{ | ||
$meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for new code we should really use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I'll open another PR. |
||
->disableOriginalConstructor() | ||
->setMethods(array('getClassName')) | ||
->getMock(); | ||
|
||
$meta->expects($this->once()) | ||
->method('getClassName') | ||
->will($this->returnValue('Foo\\Bar')); | ||
|
||
$this->cache->write($meta); | ||
|
||
$this->assertInstanceOf( | ||
'Symfony\\Component\\Validator\\Mapping\\ClassMetadata', | ||
$this->cache->read('Foo\\Bar'), | ||
'write() stores metadata' | ||
); | ||
} | ||
|
||
public function testHas() | ||
{ | ||
$meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') | ||
->disableOriginalConstructor() | ||
->setMethods(array('getClassName')) | ||
->getMock(); | ||
|
||
$meta->expects($this->once()) | ||
->method('getClassName') | ||
->will($this->returnValue('Foo\\Bar')); | ||
|
||
$this->assertFalse($this->cache->has('Foo\\Bar'), 'has() returns false when there is no entry'); | ||
|
||
$this->cache->write($meta); | ||
$this->assertTrue($this->cache->has('Foo\\Bar'), 'has() returns true when the is an entry'); | ||
} | ||
|
||
public function testRead() | ||
{ | ||
$meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') | ||
->disableOriginalConstructor() | ||
->setMethods(array('getClassName')) | ||
->getMock(); | ||
|
||
$meta->expects($this->once()) | ||
->method('getClassName') | ||
->will($this->returnValue('Foo\\Bar')); | ||
|
||
$this->assertFalse($this->cache->read('Foo\\Bar'), 'read() returns false when there is no entry'); | ||
|
||
$this->cache->write($meta); | ||
|
||
$this->assertInstanceOf( | ||
'Symfony\\Component\\Validator\\Mapping\\ClassMetadata', | ||
$this->cache->read('Foo\\Bar'), | ||
'read() returns metadata' | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\Validator\Tests\Mapping\Cache; | ||
|
||
use Symfony\Component\Cache\Adapter\ArrayAdapter; | ||
use Symfony\Component\Validator\Mapping\Cache\Psr6Cache; | ||
|
||
/** | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class Psr6CacheTest extends AbstractCacheTest | ||
{ | ||
protected function setUp() | ||
{ | ||
$this->cache = new Psr6Cache(new ArrayAdapter()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply use
return $this->cacheItemPool->hasItem($this->escapeClassName($class));
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the PSR-6,
hasItem
can in be unreliable:It looks better to me to keep it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Performance doesn't matter here, the metadata caching occurs at "compile" time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dunglas that PSR-6 quote is correct but in this context here it is prone to race conditions anyway if used incorrectly as read() and has() are seperate methods working independently. So your code to retrieve the cache data first for no reason makes no sense and @dmaicher proposal is valid.