Added events for CLI commands
This adds an init and terminate event for commands. They are dispatched from ContainerAwareCommand. The cache:clear command can't implement this (cf. #3889 on Github).
This commit is contained in:
parent
ddd30d0b8e
commit
f224102c72
@ -4,6 +4,7 @@ CHANGELOG
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* added an init and terminate event dispatched by CLI commands
|
||||
* added `--clean` option the the `translation:update` command
|
||||
* added `http_method_override` option
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@ -23,8 +24,10 @@ use Symfony\Component\Finder\Finder;
|
||||
* @author Francis Besset <francis.besset@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CacheClearCommand extends ContainerAwareCommand
|
||||
class CacheClearCommand extends Command
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -197,4 +200,16 @@ EOF;
|
||||
|
||||
return new $class($parent->getEnvironment(), $parent->isDebug());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContainerInterface
|
||||
*/
|
||||
protected function getContainer()
|
||||
{
|
||||
if (null === $this->container) {
|
||||
$this->container = $this->getApplication()->getKernel()->getContainer();
|
||||
}
|
||||
|
||||
return $this->container;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,12 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Console\ConsoleEvents;
|
||||
use Symfony\Bundle\FrameworkBundle\Event\ConsoleEvent;
|
||||
use Symfony\Bundle\FrameworkBundle\Event\ConsoleTerminateEvent;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
|
||||
@ -27,6 +32,24 @@ abstract class ContainerAwareCommand extends Command implements ContainerAwareIn
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$dispatcher = $this->getContainer()->get('event_dispatcher');
|
||||
|
||||
$initEvent = new ConsoleEvent($input, $output);
|
||||
$dispatcher->dispatch(ConsoleEvents::INIT, $initEvent);
|
||||
|
||||
$exitCode = parent::run($input, $output);
|
||||
|
||||
$terminateEvent = new ConsoleTerminateEvent($input, $output, $exitCode);
|
||||
$dispatcher->dispatch(ConsoleEvents::TERMINATE, $terminateEvent);
|
||||
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContainerInterface
|
||||
*/
|
||||
|
43
src/Symfony/Bundle/FrameworkBundle/Console/ConsoleEvents.php
Normal file
43
src/Symfony/Bundle/FrameworkBundle/Console/ConsoleEvents.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?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\Bundle\FrameworkBundle\Console;
|
||||
|
||||
/**
|
||||
* Contains all events thrown during Console commands execution
|
||||
*
|
||||
* @author Francesco Levorato <git@flevour.net>
|
||||
*/
|
||||
final class ConsoleEvents
|
||||
{
|
||||
/**
|
||||
* The INIT event allows you to attach listeners before any command is
|
||||
* executed by the console. It also allows you to modify the input and output
|
||||
* before they are handled to the command.
|
||||
*
|
||||
* The event listener method receives a \Symfony\Bundle\FrameworkBundle\Event\ConsoleEvent
|
||||
* instance.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const INIT = 'console.init';
|
||||
|
||||
/**
|
||||
* The TERMINATE event allows you to attach listeners after a command is
|
||||
* executed by the console.
|
||||
*
|
||||
* The event listener method receives a \Symfony\Bundle\FrameworkBundle\Event\ConsoleTerminateEvent
|
||||
* instance.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TERMINATE = 'console.terminate';
|
||||
}
|
54
src/Symfony/Bundle/FrameworkBundle/Event/ConsoleEvent.php
Normal file
54
src/Symfony/Bundle/FrameworkBundle/Event/ConsoleEvent.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?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\Bundle\FrameworkBundle\Event;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Allows to inspect input and output of a command.
|
||||
*
|
||||
* @author Francesco Levorato <git@flevour.net>
|
||||
*/
|
||||
class ConsoleEvent extends Event
|
||||
{
|
||||
private $input;
|
||||
|
||||
private $output;
|
||||
|
||||
public function __construct(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input object
|
||||
*
|
||||
* @return InputInterface
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output object
|
||||
*
|
||||
* @return OutputInterface
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?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\Bundle\FrameworkBundle\Event;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Allows to receive the exit code of a command after its execution.
|
||||
*
|
||||
* @author Francesco Levorato <git@flevour.net>
|
||||
*/
|
||||
class ConsoleTerminateEvent extends ConsoleEvent
|
||||
{
|
||||
/**
|
||||
* The exit code of the command.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $exitCode;
|
||||
|
||||
public function __construct(InputInterface $input, OutputInterface $output, $exitCode)
|
||||
{
|
||||
parent::__construct($input, $output);
|
||||
$this->exitCode = $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exit code.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
return $this->exitCode;
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Console;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Console\Fixtures\FooCommand;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Console\Fixtures\SilentCommand;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
@ -22,7 +24,7 @@ class ApplicationTest extends TestCase
|
||||
{
|
||||
$bundle = $this->getMock("Symfony\Component\HttpKernel\Bundle\BundleInterface");
|
||||
|
||||
$kernel = $this->getKernel(array($bundle));
|
||||
$kernel = $this->getKernel(array($bundle), $this->never());
|
||||
|
||||
$application = new Application($kernel);
|
||||
$application->doRun(new ArrayInput(array('list')), new NullOutput());
|
||||
@ -33,13 +35,33 @@ class ApplicationTest extends TestCase
|
||||
$bundle = $this->getMock("Symfony\Component\HttpKernel\Bundle\Bundle");
|
||||
$bundle->expects($this->once())->method('registerCommands');
|
||||
|
||||
$kernel = $this->getKernel(array($bundle));
|
||||
$kernel = $this->getKernel(array($bundle), $this->never());
|
||||
|
||||
$application = new Application($kernel);
|
||||
$application->doRun(new ArrayInput(array('list')), new NullOutput());
|
||||
}
|
||||
|
||||
private function getKernel(array $bundles)
|
||||
public function testCommandDispatchEvents()
|
||||
{
|
||||
$kernel = $this->getKernel(array(), $this->once());
|
||||
|
||||
$application = new Application($kernel);
|
||||
$application->add(new FooCommand('foo'));
|
||||
|
||||
$application->doRun(new ArrayInput(array('foo')), new NullOutput());
|
||||
}
|
||||
|
||||
public function testSilentCommand()
|
||||
{
|
||||
$kernel = $this->getKernel(array(), $this->never());
|
||||
|
||||
$application = new Application($kernel);
|
||||
$application->add(new SilentCommand('chut'));
|
||||
|
||||
$application->doRun(new ArrayInput(array('chut')), new NullOutput());
|
||||
}
|
||||
|
||||
private function getKernel(array $bundles, $dispatcherExpected = null)
|
||||
{
|
||||
$kernel = $this->getMock("Symfony\Component\HttpKernel\KernelInterface");
|
||||
$kernel
|
||||
@ -47,6 +69,31 @@ class ApplicationTest extends TestCase
|
||||
->method('getBundles')
|
||||
->will($this->returnValue($bundles))
|
||||
;
|
||||
|
||||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
|
||||
|
||||
$dispatcherExpected = $dispatcherExpected ?: $this->any();
|
||||
if ($this->never() == $dispatcherExpected) {
|
||||
$container
|
||||
->expects($dispatcherExpected)
|
||||
->method('get');
|
||||
} else {
|
||||
$eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$eventDispatcher
|
||||
->expects($this->atLeastOnce())
|
||||
->method('dispatch');
|
||||
$container
|
||||
->expects($dispatcherExpected)
|
||||
->method('get')
|
||||
->with($this->equalTo('event_dispatcher'))
|
||||
->will($this->returnValue($eventDispatcher));
|
||||
}
|
||||
|
||||
$kernel
|
||||
->expects($this->any())
|
||||
->method('getContainer')
|
||||
->will($this->returnValue($container))
|
||||
;
|
||||
|
||||
return $kernel;
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?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\Bundle\FrameworkBundle\Tests\Console\Fixtures;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class FooCommand extends ContainerAwareCommand
|
||||
{
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?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\Bundle\FrameworkBundle\Tests\Console\Fixtures;
|
||||
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SilentCommand extends Command
|
||||
{
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user