1: <?php
2:
3: namespace Guzzle\Service\Command\LocationVisitor\Request;
4:
5: use Guzzle\Http\Message\RequestInterface;
6: use Guzzle\Service\Command\CommandInterface;
7: use Guzzle\Service\Description\Operation;
8: use Guzzle\Service\Description\Parameter;
9:
10: 11: 12:
13: class XmlVisitor extends AbstractRequestVisitor
14: {
15: 16: 17:
18: protected $data;
19:
20: 21: 22:
23: protected $contentType = 'application/xml';
24:
25: 26: 27:
28: public function __construct()
29: {
30: $this->data = new \SplObjectStorage();
31: }
32:
33: 34: 35: 36: 37: 38: 39:
40: public function ($header)
41: {
42: $this->contentType = $header;
43:
44: return $this;
45: }
46:
47: 48: 49:
50: public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
51: {
52: $xml = isset($this->data[$command])
53: ? $this->data[$command]
54: : $this->createRootElement($param->getParent());
55: $this->addXml($xml, $param, $value);
56: $this->data[$command] = $xml;
57: }
58:
59: 60: 61:
62: public function after(CommandInterface $command, RequestInterface $request)
63: {
64: $xml = null;
65:
66:
67: if (isset($this->data[$command])) {
68: $xml = $this->data[$command]->asXML();
69: unset($this->data[$command]);
70: } else {
71:
72: $operation = $command->getOperation();
73: if ($operation->getData('xmlAllowEmpty')) {
74: $xml = $this->createRootElement($operation)->asXML();
75: }
76: }
77:
78: if ($xml) {
79: $request->setBody($xml);
80:
81: if ($this->contentType && !$request->hasHeader('Content-Type')) {
82: $request->setHeader('Content-Type', $this->contentType);
83: }
84: }
85: }
86:
87: 88: 89: 90: 91: 92: 93:
94: protected function createRootElement(Operation $operation)
95: {
96: static $defaultRoot = array('name' => 'Request');
97:
98: $root = $operation->getData('xmlRoot') ?: $defaultRoot;
99:
100:
101: $declaration = '<?xml version="1.0"';
102: if ($encoding = $operation->getData('xmlEncoding')) {
103: $declaration .= ' encoding="' . $encoding . '"';
104: }
105: $declaration .= "?>";
106:
107:
108: if (empty($root['namespaces'])) {
109: return new \SimpleXMLElement("{$declaration}\n<{$root['name']}/>");
110: } else {
111:
112: $xml = "{$declaration}\n<{$root['name']} ";
113: foreach ((array) $root['namespaces'] as $prefix => $uri) {
114: $xml .= is_numeric($prefix) ? "xmlns=\"{$uri}\" " : "xmlns:{$prefix}=\"{$uri}\" ";
115: }
116: return new \SimpleXMLElement($xml . "/>");
117: }
118: }
119:
120: 121: 122: 123: 124: 125: 126:
127: protected function addXml(\SimpleXMLElement $xml, Parameter $param, $value)
128: {
129: if ($value === null) {
130: return;
131: }
132:
133: $value = $param->filter($value);
134: $type = $param->getType();
135:
136: if ($type == 'object' || $type == 'array') {
137: $ele = $param->getData('xmlFlattened') ? $xml : $xml->addChild($param->getWireName());
138: if ($param->getType() == 'array') {
139: $this->addXmlArray($ele, $param, $value, $param->getData('xmlNamespace'));
140: } elseif ($param->getType() == 'object') {
141: $this->addXmlObject($ele, $param, $value);
142: }
143: } elseif ($param->getData('xmlAttribute')) {
144: $xml->addAttribute($param->getWireName(), $value, $param->getData('xmlNamespace'));
145: } else {
146: $xml->addChild($param->getWireName(), $value, $param->getData('xmlNamespace'));
147: }
148: }
149:
150: 151: 152:
153: protected function addXmlArray(\SimpleXMLElement $xml, Parameter $param, &$value)
154: {
155: if ($items = $param->getItems()) {
156: foreach ($value as $v) {
157: $this->addXml($xml, $items, $v);
158: }
159: }
160: }
161:
162: 163: 164:
165: protected function addXmlObject(\SimpleXMLElement $xml, Parameter $param, &$value)
166: {
167: foreach ($value as $name => $v) {
168: if ($property = $param->getProperty($name)) {
169: $this->addXml($xml, $property, $v);
170: }
171: }
172: }
173: }
174: