XRL  latest
Simple XML-RPC Library (both client and server)
Node.php
1 <?php
2 /*
3  * This file is part of XRL, a simple XML-RPC Library for PHP.
4  *
5  * Copyright (c) 2012, XRL Team. All rights reserved.
6  * XRL is licensed under the 3-clause BSD License.
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace fpoirotte\XRL;
13 
25 class Node
26 {
28  protected $properties;
29 
32  const XML_ERR_NO_MEMORY = 2;
33  const XML_ERR_DOCUMENT_EMPTY = 4;
34  const XML_ERR_DOCUMENT_END = 5;
35  const XML_ERR_INVALID_CHAR = 9;
36  const XML_ERR_UNKNOWN_ENCODING = 31;
37  const XML_ERR_UNSUPPORTED_ENCODING = 32;
38 
53  public function __construct(\XMLReader $reader, $validate, $subtrees)
54  {
55  do {
56  // We must silence read()/next() as old PHPs (5.3.x) emit warnings
57  // which get caught by PHPUnit and other custom error handlers
58  // when the methods fail and this is known to cause some issues.
59  if (($subtrees && !@$reader->read()) ||
60  (!$subtrees && !@$reader->next())) {
61  $error = libxml_get_last_error();
62 
63  // We reached the end of the document.
64  // This is not an error per-se,
65  // but it causes read() to fail anyway.
66  // We throw a special error which gets caught
67  // and dealt with appropriately by the caller.
68  if ($error === false) {
69  throw new \InvalidArgumentException('End of document');
70  }
71 
72  switch ($error->code) {
73  case self::XML_ERR_UNKNOWN_ENCODING:
74  case self::XML_ERR_UNSUPPORTED_ENCODING:
75  throw new \fpoirotte\XRL\Faults\UnsupportedEncodingException();
76 
77  // Internal & memory errors are too hard to recreate
78  // and are thus excluded from code coverage analysis.
79  // @codeCoverageIgnoreStart
80  case self::XML_ERR_INTERNAL_ERROR:
81  case self::XML_ERR_NO_MEMORY:
82  throw new \fpoirotte\XRL\Faults\InternalErrorException();
83  // @codeCoverageIgnoreEnd
84 
85  case self::XML_ERR_INVALID_CHAR:
86  throw new \fpoirotte\XRL\Faults\InvalidCharacterException();
87 
88  // Generic error handling.
89  default:
90  throw new \fpoirotte\XRL\Faults\NotWellFormedException();
91  }
92  }
93 
94  if ($validate && !$reader->isValid()) {
95  $errors = '';
96  foreach (libxml_get_errors() as $error) {
97  $message = trim($error->message);
98  $file = $error->file;
99  $line = $error->line;
100  $column = $error->column;
101  $errors .= "$message in '$file' on line $line, column $column\n";
102  }
103  if ($errors) {
104  throw new \fpoirotte\XRL\Faults\InvalidXmlRpcException(trim($errors));
105  } else {
106  // Use a generic error message in case the specific reason
107  // for the error cannot be pin-pointed.
108  throw new \fpoirotte\XRL\Faults\InvalidXmlRpcException();
109  }
110  }
111 
112  $subtrees = true;
113  } while ($reader->nodeType === \XMLReader::SIGNIFICANT_WHITESPACE);
114 
115  $fields = array(
116  'isEmptyElement',
117  'localName',
118  'namespaceURI',
119  'nodeType',
120  'value',
121  );
122 
123  $this->properties = array();
124  foreach ($fields as $field) {
125  $this->properties[$field] = $reader->$field;
126  }
127  $name = $reader->localName;
128  if ($reader->namespaceURI !== '') {
129  $name = '{' . $reader->namespaceURI . '}' . $name;
130  }
131  $this->properties['name'] = $name;
132  }
133 
153  public function __get($field)
154  {
155  if (!isset($this->properties[$field])) {
156  throw new \UnexpectedValueException("Unknown property '$field'");
157  }
158 
159  return $this->properties[$field];
160  }
161 
170  public function emptyNodeExpansionWorked()
171  {
172  if ($this->properties['nodeType'] == \XMLReader::ELEMENT &&
173  $this->properties['isEmptyElement'] == true) {
174  $this->properties['nodeType'] = \XMLReader::END_ELEMENT;
175  $this->properties['isEmptyElement'] = false;
176  return true;
177  }
178  return false;
179  }
180 }
An XML node as read from an XML reader.
Definition: Node.php:25
__get($field)
Definition: Node.php:153
__construct(\XMLReader $reader, $validate, $subtrees)
Definition: Node.php:53
emptyNodeExpansionWorked()
Definition: Node.php:170
const XML_ERR_INTERNAL_ERROR
Error codes from http://www.xmlsoft.org/html/libxml-xmlerror.html.
Definition: Node.php:31
$properties
Fields that make up this node.
Definition: Node.php:28