mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-25 02:22:57 +01:00
[Service] Adding Model classes that can be used to make it easier to consume the models generated by service description powered OperationCommands.
This commit is contained in:
parent
32080ea36d
commit
0f57d6ac22
@ -29,6 +29,8 @@ abstract class AbstractCommand extends Collection implements CommandInterface
|
||||
const DISABLE_VALIDATION = 'command.disable_validation';
|
||||
// Option used to override how a command result will be formatted
|
||||
const RESPONSE_PROCESSING = 'command.response_processing';
|
||||
// Options to specify that response models should be a raw array rather than a model object
|
||||
const RESPONSE_MODEL_ARRAY = 'command.response_model_array';
|
||||
// Different response types that commands can use
|
||||
const TYPE_RAW = 'raw';
|
||||
const TYPE_NATIVE = 'native';
|
||||
|
@ -10,6 +10,7 @@ use Guzzle\Service\Command\LocationVisitor\Response\BodyVisitor;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\JsonVisitor;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\XmlVisitor;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\ResponseVisitorInterface;
|
||||
use Guzzle\Service\Resource\Model;
|
||||
|
||||
/**
|
||||
* Response parser that attempts to marshal responses into an associative array based on models in a service description
|
||||
@ -112,6 +113,11 @@ class OperationResponseParser extends DefaultResponseParser
|
||||
$visitor->after($command);
|
||||
}
|
||||
|
||||
// Use a model object if it is not disabled on the command
|
||||
if (!$command->get(AbstractCommand::RESPONSE_MODEL_ARRAY)) {
|
||||
$result = new Model($result, $model);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
72
src/Guzzle/Service/Resource/Model.php
Normal file
72
src/Guzzle/Service/Resource/Model.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Guzzle\Service\Resource;
|
||||
|
||||
use Guzzle\Common\Collection;
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
|
||||
/**
|
||||
* Default model created when commands create service description model responses
|
||||
*/
|
||||
class Model extends Collection
|
||||
{
|
||||
/**
|
||||
* @var Parameter Structure of the model
|
||||
*/
|
||||
protected $structure;
|
||||
|
||||
/**
|
||||
* @param array $data Data contained by the model
|
||||
* @param Parameter $structure The structure of the model
|
||||
*/
|
||||
public function __construct(array $data, Parameter $structure)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->structure = $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the structure of the model
|
||||
*
|
||||
* @return Parameter
|
||||
*/
|
||||
public function getStructure()
|
||||
{
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from the model using an array path (e.g. foo/baz/bar would retrieve bar from two nested arrays)
|
||||
*
|
||||
* @param string $path Path to traverse and retrieve a value from
|
||||
* @param string $separator Character used to add depth to the search
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getPath($path, $separator = '/')
|
||||
{
|
||||
$parts = explode($separator, $path);
|
||||
$data = &$this->data;
|
||||
|
||||
// Using an iterative approach rather than recursion for speed
|
||||
while ($part = array_shift($parts)) {
|
||||
// Return null if this path doesn't exist or if there's more depth and the value is not an array
|
||||
if (!isset($data[$part]) || ($parts && !is_array($data[$part]))) {
|
||||
return null;
|
||||
}
|
||||
$data = &$data[$part];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the model to an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ use Guzzle\Service\Command\OperationCommand;
|
||||
use Guzzle\Service\Description\Operation;
|
||||
use Guzzle\Service\Description\ServiceDescription;
|
||||
use Guzzle\Service\Command\DefaultRequestSerializer;
|
||||
use Guzzle\Service\Resource\Model;
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\Command\OperationCommand
|
||||
@ -66,9 +67,9 @@ class OperationCommandTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
$request->setResponse(new Response(200, array(
|
||||
'Content-Type' => 'application/xml'
|
||||
), '<Foo><Baz>Bar</Baz></Foo>'), true);
|
||||
$this->assertEquals(array(
|
||||
$this->assertEquals(new Model(array(
|
||||
'Baz' => 'Bar'
|
||||
), $op->execute());
|
||||
), $description->getModel('bar')), $op->execute());
|
||||
}
|
||||
|
||||
public function testAllowsRawResponses()
|
||||
|
@ -4,13 +4,16 @@ namespace Guzzle\Tests\Service\Command;
|
||||
|
||||
use Guzzle\Http\Message\Response;
|
||||
use Guzzle\Service\Client;
|
||||
use Guzzle\Service\Command\AbstractCommand;
|
||||
use Guzzle\Service\Command\OperationResponseParser;
|
||||
use Guzzle\Service\Command\OperationCommand;
|
||||
use Guzzle\Service\Description\Operation;
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
use Guzzle\Service\Description\ServiceDescription;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\StatusCodeVisitor;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\ReasonPhraseVisitor;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\BodyVisitor;
|
||||
use Guzzle\Service\Resource\Model;
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\Command\OperationResponseParser
|
||||
@ -42,7 +45,20 @@ class OperationResponseParserTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
$op = new OperationCommand(array(), $this->getDescription()->getOperation('test'));
|
||||
$op->setResponseParser($parser)->setClient(new Client());
|
||||
$op->prepare()->setResponse(new Response(200, array('Content-Type' => 'application/xml'), '<F><B>C</B></F>'), true);
|
||||
$this->assertInstanceOf('Guzzle\Service\Resource\Model', $op->execute());
|
||||
$this->assertEquals('C', $op->getResult()->get('B'));
|
||||
}
|
||||
|
||||
public function testUsesRawArraysWhenInstructed()
|
||||
{
|
||||
$parser = new OperationResponseParser();
|
||||
$op = new OperationCommand(array(), $this->getDescription()->getOperation('test'));
|
||||
$op->setResponseParser($parser)->setClient(new Client());
|
||||
$op->prepare()->setResponse(new Response(200, array('Content-Type' => 'application/xml'), '<F><B>C</B></F>'), true);
|
||||
$op->set(AbstractCommand::RESPONSE_MODEL_ARRAY, true);
|
||||
$this->assertInternalType('array', $op->execute());
|
||||
$result = $op->getResult();
|
||||
$this->assertEquals('C', $result['B']);
|
||||
}
|
||||
|
||||
public function testVisitsLocations()
|
||||
|
41
tests/Guzzle/Tests/Service/Resource/ModelTest.php
Normal file
41
tests/Guzzle/Tests/Service/Resource/ModelTest.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Guzzle\Tests\Service\Resource;
|
||||
|
||||
use Guzzle\Service\Resource\Model;
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
|
||||
/**
|
||||
* @covers Guzzle\Service\Resource\Model
|
||||
*/
|
||||
class ModelTest extends \Guzzle\Tests\GuzzleTestCase
|
||||
{
|
||||
public function testOwnsStructure()
|
||||
{
|
||||
$param = new Parameter(array('type' => 'object'));
|
||||
$model = new Model(array('foo' => 'bar'), $param);
|
||||
$this->assertSame($param, $model->getStructure());
|
||||
$this->assertEquals('bar', $model->get('foo'));
|
||||
$this->assertEquals('bar', $model['foo']);
|
||||
}
|
||||
|
||||
public function testRetrievesNestedKeysUsingPath()
|
||||
{
|
||||
$data = array(
|
||||
'foo' => 'bar',
|
||||
'baz' => array(
|
||||
'mesa' => array(
|
||||
'jar' => 'jar'
|
||||
)
|
||||
)
|
||||
);
|
||||
$param = new Parameter(array('type' => 'object'));
|
||||
$model = new Model($data, $param);
|
||||
$this->assertSame($param, $model->getStructure());
|
||||
$this->assertEquals('bar', $model->getPath('foo'));
|
||||
$this->assertEquals('jar', $model->getPath('baz/mesa/jar'));
|
||||
$this->assertNull($model->getPath('wewewf'));
|
||||
$this->assertNull($model->getPath('baz/mesa/jar/jar'));
|
||||
$this->assertSame($data, $model->toArray());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user