Open Journal Systems  3.3.0
Request/XmlVisitor.php
1 <?php
2 
4 
9 
14 {
16  protected $data;
17 
19  protected $contentType = 'application/xml';
20 
21  public function __construct()
22  {
23  $this->data = new \SplObjectStorage();
24  }
25 
33  public function setContentTypeHeader($header)
34  {
35  $this->contentType = $header;
36 
37  return $this;
38  }
39 
40  public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
41  {
42  $xml = isset($this->data[$command])
43  ? $this->data[$command]
44  : $this->createRootElement($param->getParent());
45  $this->addXml($xml, $param, $value);
46 
47  $this->data[$command] = $xml;
48  }
49 
50  public function after(CommandInterface $command, RequestInterface $request)
51  {
52  $xml = null;
53 
54  // If data was found that needs to be serialized, then do so
55  if (isset($this->data[$command])) {
56  $xml = $this->finishDocument($this->data[$command]);
57  unset($this->data[$command]);
58  } else {
59  // Check if XML should always be sent for the command
60  $operation = $command->getOperation();
61  if ($operation->getData('xmlAllowEmpty')) {
62  $xmlWriter = $this->createRootElement($operation);
63  $xml = $this->finishDocument($xmlWriter);
64  }
65  }
66 
67  if ($xml) {
68  // Don't overwrite the Content-Type if one is set
69  if ($this->contentType && !$request->hasHeader('Content-Type')) {
70  $request->setHeader('Content-Type', $this->contentType);
71  }
72  $request->setBody($xml);
73  }
74  }
75 
83  protected function createRootElement(Operation $operation)
84  {
85  static $defaultRoot = array('name' => 'Request');
86  // If no root element was specified, then just wrap the XML in 'Request'
87  $root = $operation->getData('xmlRoot') ?: $defaultRoot;
88  // Allow the XML declaration to be customized with xmlEncoding
89  $encoding = $operation->getData('xmlEncoding');
90 
91  $xmlWriter = $this->startDocument($encoding);
92 
93  $xmlWriter->startElement($root['name']);
94  // Create the wrapping element with no namespaces if no namespaces were present
95  if (!empty($root['namespaces'])) {
96  // Create the wrapping element with an array of one or more namespaces
97  foreach ((array) $root['namespaces'] as $prefix => $uri) {
98  $nsLabel = 'xmlns';
99  if (!is_numeric($prefix)) {
100  $nsLabel .= ':'.$prefix;
101  }
102  $xmlWriter->writeAttribute($nsLabel, $uri);
103  }
104  }
105  return $xmlWriter;
106  }
107 
115  protected function addXml(\XMLWriter $xmlWriter, Parameter $param, $value)
116  {
117  if ($value === null) {
118  return;
119  }
120 
121  $value = $param->filter($value);
122  $type = $param->getType();
123  $name = $param->getWireName();
124  $prefix = null;
125  $namespace = $param->getData('xmlNamespace');
126  if (false !== strpos($name, ':')) {
127  list($prefix, $name) = explode(':', $name, 2);
128  }
129 
130  if ($type == 'object' || $type == 'array') {
131  if (!$param->getData('xmlFlattened')) {
132  $xmlWriter->startElementNS(null, $name, $namespace);
133  }
134  if ($param->getType() == 'array') {
135  $this->addXmlArray($xmlWriter, $param, $value);
136  } elseif ($param->getType() == 'object') {
137  $this->addXmlObject($xmlWriter, $param, $value);
138  }
139  if (!$param->getData('xmlFlattened')) {
140  $xmlWriter->endElement();
141  }
142  return;
143  }
144  if ($param->getData('xmlAttribute')) {
145  $this->writeAttribute($xmlWriter, $prefix, $name, $namespace, $value);
146  } else {
147  $this->writeElement($xmlWriter, $prefix, $name, $namespace, $value);
148  }
149  }
150 
160  protected function writeAttribute($xmlWriter, $prefix, $name, $namespace, $value)
161  {
162  if (empty($namespace)) {
163  $xmlWriter->writeAttribute($name, $value);
164  } else {
165  $xmlWriter->writeAttributeNS($prefix, $name, $namespace, $value);
166  }
167  }
168 
178  protected function writeElement(\XMLWriter $xmlWriter, $prefix, $name, $namespace, $value)
179  {
180  $xmlWriter->startElementNS($prefix, $name, $namespace);
181  if (strpbrk($value, '<>&')) {
182  $xmlWriter->writeCData($value);
183  } else {
184  $xmlWriter->writeRaw($value);
185  }
186  $xmlWriter->endElement();
187  }
188 
196  protected function startDocument($encoding)
197  {
198  $xmlWriter = new \XMLWriter();
199  $xmlWriter->openMemory();
200  $xmlWriter->startDocument('1.0', $encoding);
201 
202  return $xmlWriter;
203  }
204 
212  protected function finishDocument($xmlWriter)
213  {
214  $xmlWriter->endDocument();
215 
216  return $xmlWriter->outputMemory();
217  }
218 
222  protected function addXmlArray(\XMLWriter $xmlWriter, Parameter $param, &$value)
223  {
224  if ($items = $param->getItems()) {
225  foreach ($value as $v) {
226  $this->addXml($xmlWriter, $items, $v);
227  }
228  }
229  }
230 
234  protected function addXmlObject(\XMLWriter $xmlWriter, Parameter $param, &$value)
235  {
236  $noAttributes = array();
237  // add values which have attributes
238  foreach ($value as $name => $v) {
239  if ($property = $param->getProperty($name)) {
240  if ($property->getData('xmlAttribute')) {
241  $this->addXml($xmlWriter, $property, $v);
242  } else {
243  $noAttributes[] = array('value' => $v, 'property' => $property);
244  }
245  }
246  }
247  // now add values with no attributes
248  foreach ($noAttributes as $element) {
249  $this->addXml($xmlWriter, $element['property'], $element['value']);
250  }
251  }
252 }
Guzzle\Service\Description\Parameter\getItems
getItems()
Definition: Parameter.php:820
Guzzle\Service\Command\LocationVisitor\Request
Definition: AbstractRequestVisitor.php:3
Guzzle\Service\Description\Operation\getData
getData($name)
Definition: Operation.php:535
Guzzle\Http\Message\RequestInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestInterface.php:16
Guzzle\Service\Description\Parameter\filter
filter($value)
Definition: Parameter.php:201
Guzzle\Http\Message\MessageInterface\setHeader
setHeader($header, $value)
Guzzle\Service\Description\Operation
Definition: Operation.php:10
Guzzle\Service\Description\Parameter\getProperty
getProperty($name)
Definition: Parameter.php:724
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\writeAttribute
writeAttribute($xmlWriter, $prefix, $name, $namespace, $value)
Definition: Request/XmlVisitor.php:166
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\writeElement
writeElement(\XMLWriter $xmlWriter, $prefix, $name, $namespace, $value)
Definition: Request/XmlVisitor.php:184
Guzzle\Service\Command\LocationVisitor\Request\AbstractRequestVisitor
Definition: AbstractRequestVisitor.php:9
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\__construct
__construct()
Definition: Request/XmlVisitor.php:27
Guzzle\Service\Description\Parameter
Definition: Parameter.php:10
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\addXml
addXml(\XMLWriter $xmlWriter, Parameter $param, $value)
Definition: Request/XmlVisitor.php:121
Guzzle\Service\Command\CommandInterface
Definition: CommandInterface.php:17
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\$contentType
$contentType
Definition: Request/XmlVisitor.php:25
Guzzle\Service\Description\Parameter\getParent
getParent()
Definition: Parameter.php:681
Guzzle\Service\Description\Parameter\getWireName
getWireName()
Definition: Parameter.php:250
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor
Definition: Request/XmlVisitor.php:13
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\createRootElement
createRootElement(Operation $operation)
Definition: Request/XmlVisitor.php:89
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\visit
visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
Definition: Request/XmlVisitor.php:46
Guzzle\Http\Message\MessageInterface\hasHeader
hasHeader($header)
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\startDocument
startDocument($encoding)
Definition: Request/XmlVisitor.php:202
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\addXmlObject
addXmlObject(\XMLWriter $xmlWriter, Parameter $param, &$value)
Definition: Request/XmlVisitor.php:240
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\after
after(CommandInterface $command, RequestInterface $request)
Definition: Request/XmlVisitor.php:56
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\setContentTypeHeader
setContentTypeHeader($header)
Definition: Request/XmlVisitor.php:39
Guzzle\Service\Description\Parameter\getData
getData($name=null)
Definition: Parameter.php:566
Guzzle\Service\Description\Parameter\getType
getType()
Definition: Parameter.php:274
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\$data
$data
Definition: Request/XmlVisitor.php:19
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\addXmlArray
addXmlArray(\XMLWriter $xmlWriter, Parameter $param, &$value)
Definition: Request/XmlVisitor.php:228
Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor\finishDocument
finishDocument($xmlWriter)
Definition: Request/XmlVisitor.php:218