1: <?php
2: /*
3: You may not change or alter any portion of this comment or credits
4: of supporting developers from this source code or any supporting source code
5: which is considered copyrighted (c) material of the original comment or credit authors.
6:
7: This program is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY; without even the implied warranty of
9: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10: */
11:
12: /**
13: * @copyright XOOPS Project (http://xoops.org)
14: * @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
15: * @package class
16: * @subpackage xml
17: * @since 1.0.0
18: * @author Kazumi Ono (AKA onokazu)
19: * @version $Id $
20: */
21:
22: abstract class XoopsXmlRpcDocument
23: {
24: /**
25: * @var array of XoopsXmlRpcTag
26: */
27: protected $_tags = array();
28:
29: /**
30: * @param XoopsXmlRpcTag $tagobj
31: * @return void
32: */
33: public function add(XoopsXmlRpcTag $tagobj)
34: {
35: $this->_tags[] = $tagobj;
36: }
37:
38: abstract public function render();
39: }
40:
41: class XoopsXmlRpcResponse extends XoopsXmlRpcDocument
42: {
43: /**
44: * @return string
45: */
46: public function render()
47: {
48: $payload = '';
49: foreach ($this->_tags as $tag) {
50: /* @var $tag XoopsXmlRpcTag */
51: if (!$tag->isFault()) {
52: $payload .= $tag->render();
53: } else {
54: return '<?xml version="1.0"?><methodResponse>' . $tag->render() . '</methodResponse>';
55: }
56: }
57: return '<?xml version="1.0"?><methodResponse><params><param>' . $payload . '</param></params></methodResponse>';
58: }
59: }
60:
61: class XoopsXmlRpcRequest extends XoopsXmlRpcDocument
62: {
63:
64: /**
65: * @var string
66: */
67: public $methodName;
68:
69: /**
70: * @param string $methodName
71: */
72: public function __construct($methodName)
73: {
74: $this->methodName = trim($methodName);
75: }
76:
77: public function render()
78: {
79: $payload = '';
80: foreach ($this->_tags as $tag) {
81: /* @var $tag XoopsXmlRpcTag */
82: $payload .= '<param>' . $tag->render() . '</param>';
83: }
84: return '<?xml version="1.0"?><methodCall><methodName>' . $this->methodName . '</methodName><params>' . $payload . '</params></methodCall>';
85: }
86: }
87:
88: abstract class XoopsXmlRpcTag
89: {
90: /**
91: * @var bool
92: */
93: protected $_fault = false;
94:
95: /**
96: * encode - make string HTML safe
97: *
98: * @param string $text string to encode
99: *
100: * @return string
101: */
102: public function encode($text)
103: {
104: return htmlspecialchars($text, ENT_XML1, 'UTF-8');
105: }
106:
107: /**
108: * @param bool $fault
109: * @return void
110: */
111: public function setFault($fault = true)
112: {
113: $this->_fault = (bool)$fault;
114: }
115:
116: /**
117: * @return bool
118: */
119: public function isFault()
120: {
121: return $this->_fault;
122: }
123:
124: /**
125: * @abstract
126: * @return void
127: */
128: abstract public function render();
129: }
130:
131: class XoopsXmlRpcFault extends XoopsXmlRpcTag
132: {
133: /**
134: * @var int
135: */
136: protected $_code;
137:
138: /**
139: * @var string
140: */
141: protected $_extra;
142:
143: /**
144: * @param int $code
145: * @param string $extra
146: */
147: public function __construct($code, $extra = null)
148: {
149: $this->setFault(true);
150: $this->_code = (int)($code);
151: $this->_extra = isset($extra) ? trim($extra) : '';
152: }
153:
154: /**
155: * @return string
156: */
157: public function render()
158: {
159: switch ($this->_code) {
160: case 101:
161: $string = 'Invalid server URI';
162: break;
163: case 102:
164: $string = 'Parser parse error';
165: break;
166: case 103:
167: $string = 'Module not found';
168: break;
169: case 104:
170: $string = 'User authentication failed';
171: break;
172: case 105:
173: $string = 'Module API not found';
174: break;
175: case 106:
176: $string = 'Method response error';
177: break;
178: case 107:
179: $string = 'Method not supported';
180: break;
181: case 108:
182: $string = 'Invalid parameter';
183: break;
184: case 109:
185: $string = 'Missing parameters';
186: break;
187: case 110:
188: $string = 'Selected blog application does not exist';
189: break;
190: case 111:
191: $string = 'Method permission denied';
192: break;
193: default:
194: $string = 'Method response error';
195: break;
196: }
197: $string .= "\n" . $this->_extra;
198: return '<fault><value><struct><member><name>faultCode</name><value>' . $this->_code . '</value></member><member><name>faultString</name><value>' . $this->encode($string) . '</value></member></struct></value></fault>';
199: }
200: }
201:
202: class XoopsXmlRpcInt extends XoopsXmlRpcTag
203: {
204: /**
205: * @var int
206: */
207: protected $_value;
208:
209: /**
210: * @param $value
211: */
212: public function __construct($value)
213: {
214: $this->_value = (int)($value);
215: }
216:
217: /**
218: * @return string
219: */
220: public function render()
221: {
222: return '<value><int>' . $this->_value . '</int></value>';
223: }
224: }
225:
226: class XoopsXmlRpcDouble extends XoopsXmlRpcTag
227: {
228: /**
229: * @var float
230: */
231: protected $_value;
232:
233: /**
234: * @param float $value
235: */
236: public function __construct($value)
237: {
238: $this->_value = (float)$value;
239: }
240:
241: /**
242: * @return string
243: */
244: public function render()
245: {
246: return '<value><double>' . $this->_value . '</double></value>';
247: }
248: }
249:
250: class XoopsXmlRpcBoolean extends XoopsXmlRpcTag
251: {
252: /**
253: * @var int
254: */
255: protected $_value;
256:
257: /**
258: * @param boolean $value
259: */
260: public function __construct($value)
261: {
262: $this->_value = (!empty($value) && $value != false) ? 1 : 0;
263: }
264:
265: /**
266: * @return string
267: */
268: public function render()
269: {
270: return '<value><boolean>' . $this->_value . '</boolean></value>';
271: }
272: }
273:
274: class XoopsXmlRpcString extends XoopsXmlRpcTag
275: {
276: /**
277: * @var string
278: */
279: protected $_value;
280:
281: /**
282: * @param string $value
283: */
284: public function __construct($value)
285: {
286: $this->_value = (string)($value);
287: }
288:
289: /**
290: * @return string
291: */
292: public function render()
293: {
294: return '<value><string>' . $this->encode($this->_value) . '</string></value>';
295: }
296: }
297:
298: class XoopsXmlRpcDatetime extends XoopsXmlRpcTag
299: {
300: /**
301: * @var int
302: */
303: protected $_value;
304:
305: /**
306: * @param int|string $value
307: */
308: public function __construct($value)
309: {
310: if (!is_numeric($value)) {
311: $this->_value = strtotime($value);
312: } else {
313: $this->_value = (int)($value);
314: }
315: }
316:
317: /**
318: * @return string
319: */
320: public function render()
321: {
322: return '<value><dateTime.iso8601>' . gmstrftime("%Y%m%dT%H:%M:%S", $this->_value) . '</dateTime.iso8601></value>';
323: }
324: }
325:
326: class XoopsXmlRpcBase64 extends XoopsXmlRpcTag
327: {
328: /**
329: * @var string
330: */
331: protected $_value;
332:
333: /**
334: * @param string $value
335: */
336: public function __construct($value)
337: {
338: $this->_value = base64_encode($value);
339: }
340:
341: /**
342: * @return string
343: */
344: public function render()
345: {
346: return '<value><base64>' . $this->_value . '</base64></value>';
347: }
348: }
349:
350: class XoopsXmlRpcArray extends XoopsXmlRpcTag
351: {
352: /**
353: * @var array of XoopsXmlRpcTag
354: */
355: protected $_tags = array();
356:
357: /**
358: * @param XoopsXmlRpcTag $tagobj
359: * @return void
360: */
361: public function add(XoopsXmlRpcTag $tagobj)
362: {
363: $this->_tags[] = $tagobj;
364: }
365:
366: /**
367: * @return string
368: */
369: public function render()
370: {
371: $ret = '<value><array><data>';
372: foreach ($this->_tags as $tag) {
373: /* @var $tag XoopsXmlRpcTag */
374: $ret .= $tag->render();
375: }
376: $ret .= '</data></array></value>';
377: return $ret;
378: }
379: }
380:
381: class XoopsXmlRpcStruct extends XoopsXmlRpcTag
382: {
383: /**
384: * @var array of array containing XoopsXmlRpcTag
385: */
386: protected $_tags = array();
387:
388: /**
389: * @param $name
390: * @param XoopsXmlRpcTag $tagobj
391: * @return void
392: */
393: public function add($name, XoopsXmlRpcTag $tagobj)
394: {
395: $this->_tags[] = array('name' => $name, 'value' => $tagobj);
396: }
397:
398: public function render()
399: {
400: $ret = '<value><struct>';
401: foreach ($this->_tags as $tag) {
402: /* @var $tag['value'] XoopsXmlRplTag */
403: $ret .= '<member><name>' . $this->encode($tag['name']) . '</name>' . $tag['value']->render() . '</member>';
404: }
405: $ret .= '</struct></value>';
406: return $ret;
407: }
408: }
409: