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