Skip to content

Commit dccd939

Browse files
committed
Add command to delete an item from a cache pool
1 parent 6651087 commit dccd939

File tree

4 files changed

+217
-0
lines changed

4 files changed

+217
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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\Bundle\FrameworkBundle\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Console\Style\SymfonyStyle;
19+
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
20+
21+
/**
22+
* Delete an item from a cachhe pool.
23+
*
24+
* @author Pierre du Plessis <pdples@gmail.com>
25+
*/
26+
final class CachePooltemDeleteCommand extends Command
27+
{
28+
protected static $defaultName = 'cache:pool:delete';
29+
30+
private $poolClearer;
31+
32+
public function __construct(Psr6CacheClearer $poolClearer)
33+
{
34+
parent::__construct();
35+
36+
$this->poolClearer = $poolClearer;
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function configure()
43+
{
44+
$this
45+
->setDefinition(array(
46+
new InputArgument('pool', InputArgument::REQUIRED, 'The cache pool to delete an item from'),
47+
new InputArgument('key', InputArgument::REQUIRED, 'The cache key to delete from the pool'),
48+
))
49+
->setDescription('Deletes an item from a cache pool')
50+
->setHelp(<<<'EOF'
51+
The <info>%command.name%</info> deletes an item from a given cache pool.
52+
53+
%command.full_name% <pool> <key>
54+
EOF
55+
)
56+
;
57+
}
58+
59+
/**
60+
* {@inheritdoc}
61+
*/
62+
protected function execute(InputInterface $input, OutputInterface $output)
63+
{
64+
$io = new SymfonyStyle($input, $output);
65+
$pool = $input->getArgument('pool');
66+
$key = $input->getArgument('key');
67+
$cachePool = $this->poolClearer->getPool($pool);
68+
69+
if (!$cachePool->hasItem($key)) {
70+
$io->warning(sprintf('Cache item "%s" does not exist in cache pool "%s".', $key, $pool));
71+
72+
return;
73+
}
74+
75+
if (!$cachePool->deleteItem($key)) {
76+
throw new \Exception(sprintf('Cache item "%s" could not be deleted.', $key));
77+
}
78+
79+
$io->success(sprintf('Cache item "%s" was successfully deleted.', $key));
80+
}
81+
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
<tag name="console.command" command="cache:pool:prune" />
3939
</service>
4040

41+
<service id="console.command.cache_pool_delete" class="Symfony\Bundle\FrameworkBundle\Command\CachePooltemDeleteCommand">
42+
<argument type="service" id="cache.global_clearer" />
43+
<tag name="console.command" command="cache:pool:delete" />
44+
</service>
45+
4146
<service id="console.command.cache_warmup" class="Symfony\Bundle\FrameworkBundle\Command\CacheWarmupCommand">
4247
<argument type="service" id="cache_warmer" />
4348
<tag name="console.command" command="cache:warmup" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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\Bundle\FrameworkBundle\Tests\Command;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\Bundle\FrameworkBundle\Command\CachePooltemDeleteCommand;
16+
use Symfony\Bundle\FrameworkBundle\Console\Application;
17+
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
18+
use Symfony\Component\Console\Tester\CommandTester;
19+
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
20+
use Symfony\Component\HttpKernel\KernelInterface;
21+
22+
class CachePooltemDeleteCommandTest extends TestCase
23+
{
24+
private $cachePool;
25+
26+
protected function setUp()
27+
{
28+
$this->cachePool = $this->getMockBuilder(CacheItemPoolInterface::class)
29+
->getMock();
30+
}
31+
32+
public function testCommandWithValidKey()
33+
{
34+
$this->cachePool->expects($this->once())
35+
->method('hasItem')
36+
->with('bar')
37+
->willReturn(true);
38+
39+
$this->cachePool->expects($this->once())
40+
->method('deleteItem')
41+
->with('bar')
42+
->willReturn(true);
43+
44+
$tester = $this->getCommandTester($this->getKernel());
45+
$tester->execute(array('pool' => 'foo', 'key' => 'bar'));
46+
47+
$this->assertContains('[OK] Cache item "bar" was successfully deleted.', $tester->getDisplay());
48+
}
49+
50+
public function testCommandWithInValidKey()
51+
{
52+
$this->cachePool->expects($this->once())
53+
->method('hasItem')
54+
->with('bar')
55+
->willReturn(false);
56+
57+
$this->cachePool->expects($this->never())
58+
->method('deleteItem')
59+
->with('bar');
60+
61+
$tester = $this->getCommandTester($this->getKernel());
62+
$tester->execute(array('pool' => 'foo', 'key' => 'bar'));
63+
64+
$this->assertContains('[WARNING] Cache item "bar" does not exist in cache pool "foo".', $tester->getDisplay());
65+
}
66+
67+
public function testCommandDeleteFailed()
68+
{
69+
$this->cachePool->expects($this->once())
70+
->method('hasItem')
71+
->with('bar')
72+
->willReturn(true);
73+
74+
$this->cachePool->expects($this->once())
75+
->method('deleteItem')
76+
->with('bar')
77+
->willReturn(false);
78+
79+
if (method_exists($this, 'expectExceptionMessage')) {
80+
$this->expectExceptionMessage('Cache item "bar" could not be deleted.');
81+
} else {
82+
$this->setExpectedException('Exception', 'Cache item "bar" could not be deleted.');
83+
}
84+
85+
$tester = $this->getCommandTester($this->getKernel());
86+
$tester->execute(array('pool' => 'foo', 'key' => 'bar'));
87+
}
88+
89+
/**
90+
* @return \PHPUnit_Framework_MockObject_MockObject|KernelInterface
91+
*/
92+
private function getKernel()
93+
{
94+
$container = $this
95+
->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')
96+
->getMock();
97+
98+
$kernel = $this
99+
->getMockBuilder(KernelInterface::class)
100+
->getMock();
101+
102+
$kernel
103+
->expects($this->any())
104+
->method('getContainer')
105+
->willReturn($container);
106+
107+
$kernel
108+
->expects($this->once())
109+
->method('getBundles')
110+
->willReturn(array());
111+
112+
return $kernel;
113+
}
114+
115+
private function getCommandTester(KernelInterface $kernel): CommandTester
116+
{
117+
$application = new Application($kernel);
118+
$application->add(new CachePooltemDeleteCommand(new Psr6CacheClearer(array('foo' => $this->cachePool))));
119+
120+
return new CommandTester($application->find('cache:pool:delete'));
121+
}
122+
}

src/Symfony/Component/HttpKernel/CacheClearer/Psr6CacheClearer.php

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ public function hasPool($name)
2828
return isset($this->pools[$name]);
2929
}
3030

31+
public function getPool($name)
32+
{
33+
if (!$this->hasPool($name)) {
34+
throw new \InvalidArgumentException(sprintf('Cache pool not found: %s.', $name));
35+
}
36+
37+
return $this->pools[$name];
38+
}
39+
3140
public function clearPool($name)
3241
{
3342
if (!isset($this->pools[$name])) {

0 commit comments

Comments
 (0)