1
0
mirror of https://github.com/guzzle/guzzle.git synced 2025-02-24 18:13:00 +01:00

[Service] Adding a setOnComplete method to commands that is used to specify a callable that is called when a command completes. This callable can also be specified in the command.on_complete option of a command in the constructor.

This commit is contained in:
Michael Dowling 2012-05-10 22:26:50 -07:00
parent 424e3d555e
commit 776818c90e
4 changed files with 94 additions and 7 deletions

View File

@ -209,12 +209,11 @@ class Client extends HttpClient implements ClientInterface
{
if ($command instanceof CommandInterface) {
$command->setClient($this)->prepare();
$request = $command->setClient($this)->prepare();
$this->dispatch('command.before_send', array(
'command' => $command
));
$request = $command->getRequest();
// Set the state to new if the command was previously executed
if ($request->getState() !== RequestInterface::STATE_NEW) {
$request->setState(RequestInterface::STATE_NEW);

View File

@ -5,6 +5,7 @@ namespace Guzzle\Service\Command;
use Guzzle\Common\Collection;
use Guzzle\Common\NullObject;
use Guzzle\Common\Exception\BadMethodCallException;
use Guzzle\Common\Exception\InvalidArgumentException;
use Guzzle\Http\Message\Response;
use Guzzle\Http\Message\RequestInterface;
use Guzzle\Service\Description\ApiCommand;
@ -40,6 +41,11 @@ abstract class AbstractCommand extends Collection implements CommandInterface
*/
protected $apiCommand;
/**
* @var mixed callable
*/
protected $onComplete;
/**
* Constructor
*
@ -59,8 +65,17 @@ abstract class AbstractCommand extends Collection implements CommandInterface
Inspector::getInstance()->validateClass(get_class($this), $this, false, false);
}
if (!$this->get('headers') instanceof Collection) {
$this->set('headers', new Collection((array) $this->get('headers')));
$headers = $this->get('headers');
if (!$headers instanceof Collection) {
$this->set('headers', new Collection((array) $headers));
}
// You can set a command.on_complete option in your parameters as a
// convenience method for setting an onComplete function
$onComplete = $this->get('command.on_complete');
if ($onComplete) {
$this->remove('command.on_complete');
$this->setOnComplete($onComplete);
}
$this->init();
@ -137,6 +152,27 @@ abstract class AbstractCommand extends Collection implements CommandInterface
return $this->apiCommand ?: new NullObject();
}
/**
* Specify a callable to execute when the command completes
*
* @param mixed $callable Callable to execute when the command completes.
* The callable must accept a {@see CommandInterface} object as the
* only argument.
*
* @return Command
* @throws InvalidArgumentException
*/
public function setOnComplete($callable)
{
if (!is_callable($callable)) {
throw new InvalidArgumentException('The onComplete function must be callable');
}
$this->onComplete = $callable;
return $this;
}
/**
* Execute the command and return the result
*
@ -149,9 +185,7 @@ abstract class AbstractCommand extends Collection implements CommandInterface
throw new CommandException('A Client object must be associated with the command before it can be executed from the context of the command.');
}
$this->client->execute($this);
return $this->getResult();
return $this->client->execute($this);
}
/**
@ -223,6 +257,10 @@ abstract class AbstractCommand extends Collection implements CommandInterface
if (null === $this->result) {
$this->process();
// Call the onComplete method if one is set
if ($this->onComplete) {
call_user_func($this->onComplete, $this);
}
}
return $this->result;

View File

@ -3,6 +3,7 @@
namespace Guzzle\Service\Command;
use Guzzle\Common\Collection;
use Guzzle\Common\Exception\InvalidArgumentException;
use Guzzle\Http\Message\Response;
use Guzzle\Http\Message\RequestInterface;
use Guzzle\Service\ClientInterface;
@ -24,6 +25,18 @@ interface CommandInterface
*/
function __construct($parameters = null, ApiCommand $apiCommand = null);
/**
* Specify a callable to execute when the command completes
*
* @param mixed $callable Callable to execute when the command completes.
* The callable must accept a {@see CommandInterface} object as the
* only argument.
*
* @return CommandInterface
* @throws InvalidArgumentException
*/
function setOnComplete($callable);
/**
* Get the short form name of the command
*

View File

@ -327,4 +327,41 @@ class CommandTest extends AbstractCommandTest
$command2 = clone $command;
$this->assertFalse($command2->isPrepared());
}
/**
* @covers Guzzle\Service\Command\AbstractCommand::setOnComplete
* @covers Guzzle\Service\Command\AbstractCommand::__construct
* @covers Guzzle\Service\Command\AbstractCommand::getResult
*/
public function testHasOnCompleteMethod()
{
$that = $this;
$called = 0;
$testFunction = function($command) use (&$called, $that) {
$called++;
$that->assertInstanceOf('Guzzle\Service\Command\CommandInterface', $command);
};
$client = $this->getClient();
$command = new MockCommand(array(
'command.on_complete' => $testFunction
), $this->getApiCommand());
$command->setClient($client);
$command->prepare()->setResponse(new Response(200));
$command->execute();
$this->assertEquals(1, $called);
}
/**
* @covers Guzzle\Service\Command\AbstractCommand::setOnComplete
* @expectedException Guzzle\Common\Exception\InvalidArgumentException
*/
public function testOnCompleteMustBeCallable()
{
$client = $this->getClient();
$command = new MockCommand();
$command->setOnComplete('foo');
}
}