1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196:
<?php
namespace Guzzle\Service\Command;
use Guzzle\Http\Message\Response;
use Guzzle\Service\Command\LocationVisitor\VisitorFlyweight;
use Guzzle\Service\Command\LocationVisitor\Response\ResponseVisitorInterface;
use Guzzle\Service\Description\Parameter;
use Guzzle\Service\Description\OperationInterface;
use Guzzle\Service\Description\Operation;
use Guzzle\Service\Exception\ResponseClassException;
use Guzzle\Service\Resource\Model;
class OperationResponseParser extends DefaultResponseParser
{
protected $factory;
protected static $instance;
private $schemaInModels;
public static function getInstance()
{
if (!static::$instance) {
static::$instance = new static(VisitorFlyweight::getInstance());
}
return static::$instance;
}
public function __construct(VisitorFlyweight $factory, $schemaInModels = false)
{
$this->factory = $factory;
$this->schemaInModels = $schemaInModels;
}
public function addVisitor($location, ResponseVisitorInterface $visitor)
{
$this->factory->addResponseVisitor($location, $visitor);
return $this;
}
protected function handleParsing(CommandInterface $command, Response $response, $contentType)
{
$operation = $command->getOperation();
$type = $operation->getResponseType();
$model = null;
if ($type == OperationInterface::TYPE_MODEL) {
$model = $operation->getServiceDescription()->getModel($operation->getResponseClass());
} elseif ($type == OperationInterface::TYPE_CLASS) {
return $this->parseClass($command);
}
if (!$model) {
return parent::handleParsing($command, $response, $contentType);
} elseif ($command[AbstractCommand::RESPONSE_PROCESSING] != AbstractCommand::TYPE_MODEL) {
return new Model(parent::handleParsing($command, $response, $contentType));
} else {
return new Model($this->visitResult($model, $command, $response), $this->schemaInModels ? $model : null);
}
}
protected function parseClass(CommandInterface $command)
{
$event = new CreateResponseClassEvent(array('command' => $command));
$command->getClient()->getEventDispatcher()->dispatch('command.parse_response', $event);
if ($result = $event->getResult()) {
return $result;
}
$className = $command->getOperation()->getResponseClass();
if (!method_exists($className, 'fromCommand')) {
throw new ResponseClassException("{$className} must exist and implement a static fromCommand() method");
}
return $className::fromCommand($command);
}
protected function visitResult(Parameter $model, CommandInterface $command, Response $response)
{
$foundVisitors = $result = $knownProps = array();
$props = $model->getProperties();
foreach ($props as $schema) {
if ($location = $schema->getLocation()) {
if (!isset($foundVisitors[$location])) {
$foundVisitors[$location] = $this->factory->getResponseVisitor($location);
$foundVisitors[$location]->before($command, $result);
}
}
}
if (($additional = $model->getAdditionalProperties()) instanceof Parameter) {
$this->visitAdditionalProperties($model, $command, $response, $additional, $result, $foundVisitors);
}
foreach ($props as $schema) {
$knownProps[$schema->getName()] = 1;
if ($location = $schema->getLocation()) {
$foundVisitors[$location]->visit($command, $response, $schema, $result);
}
}
if ($additional === false) {
$result = array_intersect_key($result, $knownProps);
}
foreach ($foundVisitors as $visitor) {
$visitor->after($command);
}
return $result;
}
protected function visitAdditionalProperties(
Parameter $model,
CommandInterface $command,
Response $response,
Parameter $additional,
&$result,
array &$foundVisitors
) {
if ($location = $additional->getLocation()) {
if (!isset($foundVisitors[$location])) {
$foundVisitors[$location] = $this->factory->getResponseVisitor($location);
$foundVisitors[$location]->before($command, $result);
}
if (is_array($result)) {
foreach (array_keys($result) as $key) {
if (!$model->getProperty($key)) {
$additional->setName($key);
$foundVisitors[$location]->visit($command, $response, $additional, $result);
}
}
$additional->setName(null);
}
}
}
}