|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @package Zend_XmlRpc |
|
16 * @subpackage Server |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: Fault.php 20208 2010-01-11 22:37:37Z lars $ |
|
20 */ |
|
21 |
|
22 /** |
|
23 * Zend_XmlRpc_Value |
|
24 */ |
|
25 require_once 'Zend/XmlRpc/Value.php'; |
|
26 |
|
27 /** |
|
28 * XMLRPC Faults |
|
29 * |
|
30 * Container for XMLRPC faults, containing both a code and a message; |
|
31 * additionally, has methods for determining if an XML response is an XMLRPC |
|
32 * fault, as well as generating the XML for an XMLRPC fault response. |
|
33 * |
|
34 * To allow method chaining, you may only use the {@link getInstance()} factory |
|
35 * to instantiate a Zend_XmlRpc_Server_Fault. |
|
36 * |
|
37 * @category Zend |
|
38 * @package Zend_XmlRpc |
|
39 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
40 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
41 */ |
|
42 class Zend_XmlRpc_Fault |
|
43 { |
|
44 /** |
|
45 * Fault code |
|
46 * @var int |
|
47 */ |
|
48 protected $_code; |
|
49 |
|
50 /** |
|
51 * Fault character encoding |
|
52 * @var string |
|
53 */ |
|
54 protected $_encoding = 'UTF-8'; |
|
55 |
|
56 /** |
|
57 * Fault message |
|
58 * @var string |
|
59 */ |
|
60 protected $_message; |
|
61 |
|
62 /** |
|
63 * Internal fault codes => messages |
|
64 * @var array |
|
65 */ |
|
66 protected $_internal = array( |
|
67 404 => 'Unknown Error', |
|
68 |
|
69 // 610 - 619 reflection errors |
|
70 610 => 'Invalid method class', |
|
71 611 => 'Unable to attach function or callback; not callable', |
|
72 612 => 'Unable to load array; not an array', |
|
73 613 => 'One or more method records are corrupt or otherwise unusable', |
|
74 |
|
75 // 620 - 629 dispatch errors |
|
76 620 => 'Method does not exist', |
|
77 621 => 'Error instantiating class to invoke method', |
|
78 622 => 'Method missing implementation', |
|
79 623 => 'Calling parameters do not match signature', |
|
80 |
|
81 // 630 - 639 request errors |
|
82 630 => 'Unable to read request', |
|
83 631 => 'Failed to parse request', |
|
84 632 => 'Invalid request, no method passed; request must contain a \'methodName\' tag', |
|
85 633 => 'Param must contain a value', |
|
86 634 => 'Invalid method name', |
|
87 635 => 'Invalid XML provided to request', |
|
88 636 => 'Error creating xmlrpc value', |
|
89 |
|
90 // 640 - 649 system.* errors |
|
91 640 => 'Method does not exist', |
|
92 |
|
93 // 650 - 659 response errors |
|
94 650 => 'Invalid XML provided for response', |
|
95 651 => 'Failed to parse response', |
|
96 652 => 'Invalid response', |
|
97 653 => 'Invalid XMLRPC value in response', |
|
98 ); |
|
99 |
|
100 /** |
|
101 * Constructor |
|
102 * |
|
103 * @return Zend_XmlRpc_Fault |
|
104 */ |
|
105 public function __construct($code = 404, $message = '') |
|
106 { |
|
107 $this->setCode($code); |
|
108 $code = $this->getCode(); |
|
109 |
|
110 if (empty($message) && isset($this->_internal[$code])) { |
|
111 $message = $this->_internal[$code]; |
|
112 } elseif (empty($message)) { |
|
113 $message = 'Unknown error'; |
|
114 } |
|
115 $this->setMessage($message); |
|
116 } |
|
117 |
|
118 /** |
|
119 * Set the fault code |
|
120 * |
|
121 * @param int $code |
|
122 * @return Zend_XmlRpc_Fault |
|
123 */ |
|
124 public function setCode($code) |
|
125 { |
|
126 $this->_code = (int) $code; |
|
127 return $this; |
|
128 } |
|
129 |
|
130 /** |
|
131 * Return fault code |
|
132 * |
|
133 * @return int |
|
134 */ |
|
135 public function getCode() |
|
136 { |
|
137 return $this->_code; |
|
138 } |
|
139 |
|
140 /** |
|
141 * Retrieve fault message |
|
142 * |
|
143 * @param string |
|
144 * @return Zend_XmlRpc_Fault |
|
145 */ |
|
146 public function setMessage($message) |
|
147 { |
|
148 $this->_message = (string) $message; |
|
149 return $this; |
|
150 } |
|
151 |
|
152 /** |
|
153 * Retrieve fault message |
|
154 * |
|
155 * @return string |
|
156 */ |
|
157 public function getMessage() |
|
158 { |
|
159 return $this->_message; |
|
160 } |
|
161 |
|
162 /** |
|
163 * Set encoding to use in fault response |
|
164 * |
|
165 * @param string $encoding |
|
166 * @return Zend_XmlRpc_Fault |
|
167 */ |
|
168 public function setEncoding($encoding) |
|
169 { |
|
170 $this->_encoding = $encoding; |
|
171 Zend_XmlRpc_Value::setEncoding($encoding); |
|
172 return $this; |
|
173 } |
|
174 |
|
175 /** |
|
176 * Retrieve current fault encoding |
|
177 * |
|
178 * @return string |
|
179 */ |
|
180 public function getEncoding() |
|
181 { |
|
182 return $this->_encoding; |
|
183 } |
|
184 |
|
185 /** |
|
186 * Load an XMLRPC fault from XML |
|
187 * |
|
188 * @param string $fault |
|
189 * @return boolean Returns true if successfully loaded fault response, false |
|
190 * if response was not a fault response |
|
191 * @throws Zend_XmlRpc_Exception if no or faulty XML provided, or if fault |
|
192 * response does not contain either code or message |
|
193 */ |
|
194 public function loadXml($fault) |
|
195 { |
|
196 if (!is_string($fault)) { |
|
197 require_once 'Zend/XmlRpc/Exception.php'; |
|
198 throw new Zend_XmlRpc_Exception('Invalid XML provided to fault'); |
|
199 } |
|
200 |
|
201 try { |
|
202 $xml = @new SimpleXMLElement($fault); |
|
203 } catch (Exception $e) { |
|
204 // Not valid XML |
|
205 require_once 'Zend/XmlRpc/Exception.php'; |
|
206 throw new Zend_XmlRpc_Exception('Failed to parse XML fault: ' . $e->getMessage(), 500, $e); |
|
207 } |
|
208 |
|
209 // Check for fault |
|
210 if (!$xml->fault) { |
|
211 // Not a fault |
|
212 return false; |
|
213 } |
|
214 |
|
215 if (!$xml->fault->value->struct) { |
|
216 // not a proper fault |
|
217 require_once 'Zend/XmlRpc/Exception.php'; |
|
218 throw new Zend_XmlRpc_Exception('Invalid fault structure', 500); |
|
219 } |
|
220 |
|
221 $structXml = $xml->fault->value->asXML(); |
|
222 $struct = Zend_XmlRpc_Value::getXmlRpcValue($structXml, Zend_XmlRpc_Value::XML_STRING); |
|
223 $struct = $struct->getValue(); |
|
224 |
|
225 if (isset($struct['faultCode'])) { |
|
226 $code = $struct['faultCode']; |
|
227 } |
|
228 if (isset($struct['faultString'])) { |
|
229 $message = $struct['faultString']; |
|
230 } |
|
231 |
|
232 if (empty($code) && empty($message)) { |
|
233 require_once 'Zend/XmlRpc/Exception.php'; |
|
234 throw new Zend_XmlRpc_Exception('Fault code and string required'); |
|
235 } |
|
236 |
|
237 if (empty($code)) { |
|
238 $code = '404'; |
|
239 } |
|
240 |
|
241 if (empty($message)) { |
|
242 if (isset($this->_internal[$code])) { |
|
243 $message = $this->_internal[$code]; |
|
244 } else { |
|
245 $message = 'Unknown Error'; |
|
246 } |
|
247 } |
|
248 |
|
249 $this->setCode($code); |
|
250 $this->setMessage($message); |
|
251 |
|
252 return true; |
|
253 } |
|
254 |
|
255 /** |
|
256 * Determine if an XML response is an XMLRPC fault |
|
257 * |
|
258 * @param string $xml |
|
259 * @return boolean |
|
260 */ |
|
261 public static function isFault($xml) |
|
262 { |
|
263 $fault = new self(); |
|
264 require_once 'Zend/XmlRpc/Exception.php'; |
|
265 try { |
|
266 $isFault = $fault->loadXml($xml); |
|
267 } catch (Zend_XmlRpc_Exception $e) { |
|
268 $isFault = false; |
|
269 } |
|
270 |
|
271 return $isFault; |
|
272 } |
|
273 |
|
274 /** |
|
275 * Serialize fault to XML |
|
276 * |
|
277 * @return string |
|
278 */ |
|
279 public function saveXml() |
|
280 { |
|
281 // Create fault value |
|
282 $faultStruct = array( |
|
283 'faultCode' => $this->getCode(), |
|
284 'faultString' => $this->getMessage() |
|
285 ); |
|
286 $value = Zend_XmlRpc_Value::getXmlRpcValue($faultStruct); |
|
287 |
|
288 $generator = Zend_XmlRpc_Value::getGenerator(); |
|
289 $generator->openElement('methodResponse') |
|
290 ->openElement('fault'); |
|
291 $value->generateXml(); |
|
292 $generator->closeElement('fault') |
|
293 ->closeElement('methodResponse'); |
|
294 |
|
295 return $generator->flush(); |
|
296 } |
|
297 |
|
298 /** |
|
299 * Return XML fault response |
|
300 * |
|
301 * @return string |
|
302 */ |
|
303 public function __toString() |
|
304 { |
|
305 return $this->saveXML(); |
|
306 } |
|
307 } |