Skip to content
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

2.9.0
-----

### Added

* New Feature: Command `fos:httpcache:clear` to clear the whole http cache.

2.8.0
-----

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"require": {
"php": "^7.2",
"friendsofsymfony/http-cache": "^2.5.2",
"friendsofsymfony/http-cache": "^2.6",
"symfony/framework-bundle": "^3.4.26 || ^4.2.7 || ^5.0",
"symfony/http-foundation": "^3.4.26 || ^4.2.7 || ^5.0",
"symfony/http-kernel": "^3.4.26 || ^4.2.7 || ^5.0"
Expand Down
85 changes: 85 additions & 0 deletions src/Command/ClearCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/*
* This file is part of the FOSHttpCacheBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCacheBundle\Command;

use FOS\HttpCache\CacheInvalidator;
use FOS\HttpCacheBundle\CacheManager;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* A command to clear the whole cache from the command line.
*
* @author Alexander Schranz <alexander@sulu.io>
*/
class ClearCommand extends BaseInvalidateCommand
{
use PathSanityCheck;

protected static $defaultName = 'fos:httpcache:clear';

/**
* If no cache manager is specified explicitly, fos_http_cache.cache_manager
* is automatically loaded.
*
* @param CacheManager|null $cacheManager The cache manager to talk to
*/
public function __construct(CacheManager $cacheManager = null)
{
parent::__construct($cacheManager);
}

/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setDescription('Clear the HTTP cache.')
->setHelp(
<<<'EOF'
The <info>%command.name%</info> command clears the whole cache or, if that is not supported, invalidates all cache entries in the configured caching proxies.

Example:

<info>php %command.full_name%</info>
EOF
)
;
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$cacheManager = $this->getCacheManager();

if ($cacheManager->supports(CacheInvalidator::CLEAR)) {
$this->getCacheManager()->clearCache();

return 0;
}

if ($cacheManager->supports(CacheInvalidator::INVALIDATE)) {
$this->getCacheManager()->invalidateRegex('.*');

return 0;
}

$output->writeln(
'<error>The configured HTTP cache does not support "clear" or "invalidate".</error>'
);

return 1;
}
}
1 change: 0 additions & 1 deletion src/Command/InvalidatePathCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public function __construct(CacheManager $cacheManager = null)
protected function configure()
{
$this
->setName(static::$defaultName) // BC with 2.8
->setDescription('Invalidate cached paths on all configured caching proxies')
->addArgument(
'paths',
Expand Down
1 change: 0 additions & 1 deletion src/Command/InvalidateRegexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public function __construct(CacheManager $cacheManager = null, $commandName = 'f
protected function configure()
{
$this
->setName(static::$defaultName) // BC with 2.8
->setDescription('Invalidate everything matching a regular expression on all configured caching proxies')
->addArgument(
'regex',
Expand Down
1 change: 0 additions & 1 deletion src/Command/InvalidateTagCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public function __construct(CacheManager $cacheManager = null, $commandName = 'f
protected function configure()
{
$this
->setName(static::$defaultName) // BC with 2.8
->setDescription('Invalidate cached content matching the specified tags on all configured caching proxies')
->addArgument(
'tags',
Expand Down
1 change: 0 additions & 1 deletion src/Command/RefreshPathCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public function __construct(CacheManager $cacheManager = null)
protected function configure()
{
$this
->setName(static::$defaultName) // BC with 2.8
->setDescription('Refresh paths on all configured caching proxies')
->addArgument(
'paths',
Expand Down
5 changes: 5 additions & 0 deletions src/Resources/config/cache_manager_commands.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
<argument type="service" id="fos_http_cache.cache_manager" />
<tag name="console.command"/>
</service>

<service id="fos_http_cache.command.clear" class="FOS\HttpCacheBundle\Command\ClearCommand">
<argument type="service" id="fos_http_cache.cache_manager" />
<tag name="console.command"/>
</service>
</services>

</container>
91 changes: 91 additions & 0 deletions tests/Functional/Command/ClearCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

/*
* This file is part of the FOSHttpCacheBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCacheBundle\Tests\Functional\Command;

use FOS\HttpCache\CacheInvalidator;
use FOS\HttpCacheBundle\CacheManager;

class ClearCommandTest extends CommandTestCase
{
public function testExecuteClearVerbose()
{
$client = self::createClient();

$mock = \Mockery::mock(CacheManager::class);
$mock->shouldReceive('supports')
->with(CacheInvalidator::CLEAR)
->andReturnTrue();

$mock->shouldReceive('clearCache')
->once()
;
$mock->shouldReceive('flush')
->once()
->andReturn(1)
;
$client->getContainer()->set('fos_http_cache.cache_manager', $mock);

$output = $this->runCommand($client, 'fos:httpcache:clear');

$this->assertEquals("Sent 1 invalidation request(s)\n", $output);
}

public function testExecuteBanVerbose()
{
$client = self::createClient();

$mock = \Mockery::mock(CacheManager::class);
$mock->shouldReceive('supports')
->with(CacheInvalidator::CLEAR)
->andReturnFalse();
$mock->shouldReceive('supports')
->with(CacheInvalidator::INVALIDATE)
->andReturnTrue();

$mock->shouldReceive('invalidateRegex')
->with('.*')
->once()
;
$mock->shouldReceive('flush')
->once()
->andReturn(1)
;
$client->getContainer()->set('fos_http_cache.cache_manager', $mock);

$output = $this->runCommand($client, 'fos:httpcache:clear');

$this->assertEquals("Sent 1 invalidation request(s)\n", $output);
}

public function testExecuteErrorVerbose()
{
$client = self::createClient();

$mock = \Mockery::mock(CacheManager::class);
$mock->shouldReceive('supports')
->with(CacheInvalidator::CLEAR)
->andReturnFalse();
$mock->shouldReceive('supports')
->with(CacheInvalidator::INVALIDATE)
->andReturnFalse();

$mock->shouldReceive('flush')
->once()
->andReturn(0)
;
$client->getContainer()->set('fos_http_cache.cache_manager', $mock);

$output = $this->runCommand($client, 'fos:httpcache:clear', 1);

$this->assertStringContainsString('The configured HTTP cache does not support "clear" or "invalidate".', $output);
}
}
91 changes: 91 additions & 0 deletions tests/Unit/Command/ClearCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

/*
* This file is part of the FOSHttpCacheBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCacheBundle\Tests\Unit\Command;

use FOS\HttpCache\CacheInvalidator;
use FOS\HttpCacheBundle\CacheManager;
use FOS\HttpCacheBundle\Command\ClearCommand;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class ClearCommandTest extends TestCase
{
use MockeryPHPUnitIntegration;

public function testExecuteClear()
{
$invalidator = \Mockery::mock(CacheManager::class)
->shouldReceive('supports')->once()->with(CacheInvalidator::CLEAR)->andReturnTrue()
->shouldReceive('clearCache')->once()
->getMock()
;

$application = new Application();
$application->add(new ClearCommand($invalidator));

$command = $application->find('fos:httpcache:clear');
$commandTester = new CommandTester($command);
$commandTester->execute([
'command' => $command->getName(),
]);

// the only output should be generated by the listener in verbose mode
$this->assertEquals('', $commandTester->getDisplay());
}

public function testExecuteInvalidate()
{
$invalidator = \Mockery::mock(CacheManager::class)
->shouldReceive('supports')->once()->with(CacheInvalidator::CLEAR)->andReturnFalse()
->shouldReceive('supports')->once()->with(CacheInvalidator::INVALIDATE)->andReturnTrue()
->shouldReceive('invalidateRegex')->once()->with('.*')
->getMock()
;

$application = new Application();
$application->add(new ClearCommand($invalidator));

$command = $application->find('fos:httpcache:clear');
$commandTester = new CommandTester($command);
$commandTester->execute([
'command' => $command->getName(),
]);

// the only output should be generated by the listener in verbose mode
$this->assertEquals('', $commandTester->getDisplay());
}

public function testExecuteNotSupported()
{
$invalidator = \Mockery::mock(CacheManager::class)
->shouldReceive('supports')->once()->with(CacheInvalidator::CLEAR)->andReturnFalse()
->shouldReceive('supports')->once()->with(CacheInvalidator::INVALIDATE)->andReturnfalse()
->getMock()
;

$application = new Application();
$application->add(new ClearCommand($invalidator));

$command = $application->find('fos:httpcache:clear');
$commandTester = new CommandTester($command);
$commandTester->execute([
'command' => $command->getName(),
]);

$this->assertStringContainsString(
'The configured HTTP cache does not support "clear" or "invalidate".',
$commandTester->getDisplay()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public function testConfigNoContext()
$this->userContextListenerPass->process($container);
if ($container->hasDefinition('service_container')) {
// symfony 3.3+
$this->assertCount(22, $container->getDefinitions());
$this->assertCount(23, $container->getDefinitions());
} else {
$this->assertCount(21, $container->getDefinitions());
$this->assertCount(24, $container->getDefinitions());
}
}

Expand Down