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
16 * @since
17 * @author       XOOPS Development Team, Kazumi Ono (AKA onokazu)
18 */
19
20/**
21 * Class XoopsXmlRpcDocument
22 */
23class XoopsXmlRpcDocument
24{
25    public $_tags = array();
26
27    /**
28     * XoopsXmlRpcDocument constructor.
29     */
30    public function __construct()
31    {
32    }
33
34    /**
35     * @param $tagobj
36     */
37    public function add(&$tagobj)
38    {
39        $this->_tags[] =& $tagobj;
40    }
41
42    public function render()
43    {
44    }
45}
46
47/**
48 * Class XoopsXmlRpcResponse
49 */
50class XoopsXmlRpcResponse extends XoopsXmlRpcDocument
51{
52    /**
53     * @return string
54     */
55    public function render()
56    {
57        $count   = count($this->_tags);
58        $payload = '';
59        for ($i = 0; $i < $count; ++$i) {
60            if (!$this->_tags[$i]->isFault()) {
61                $payload .= $this->_tags[$i]->render();
62            } else {
63                return '<?xml version="1.0"?><methodResponse>' . $this->_tags[$i]->render() . '</methodResponse>';
64            }
65        }
66
67        return '<?xml version="1.0"?><methodResponse><params><param>' . $payload . '</param></params></methodResponse>';
68    }
69}
70
71/**
72 * Class XoopsXmlRpcRequest
73 */
74class XoopsXmlRpcRequest extends XoopsXmlRpcDocument
75{
76    public $methodName;
77
78    /**
79     * @param $methodName
80     */
81    public function __construct($methodName)
82    {
83        $this->methodName = trim($methodName);
84    }
85
86    /**
87     * @return string
88     */
89    public function render()
90    {
91        $count   = count($this->_tags);
92        $payload = '';
93        for ($i = 0; $i < $count; ++$i) {
94            $payload .= '<param>' . $this->_tags[$i]->render() . '</param>';
95        }
96
97        return '<?xml version="1.0"?><methodCall><methodName>' . $this->methodName . '</methodName><params>' . $payload . '</params></methodCall>';
98    }
99}
100
101/**
102 * Class XoopsXmlRpcTag
103 */
104class XoopsXmlRpcTag
105{
106    public $_fault = false;
107
108    /**
109     * XoopsXmlRpcTag constructor.
110     */
111    public function __construct()
112    {
113    }
114
115    /**
116     * @param $text
117     *
118     * @return mixed
119     */
120    public function &encode(&$text)
121    {
122        $text = preg_replace(array("/\&([a-z\d\#]+)\;/i", "/\&/", "/\#\|\|([a-z\d\#]+)\|\|\#/i"), array(
123            "#||\\1||#",
124            '&amp;',
125            "&\\1;"), str_replace(array(
126                                      '<',
127                                      '>'), array(
128                                      '&lt;',
129                                      '&gt;'), $text));
130
131        return $text;
132    }
133
134    /**
135     * @param bool $fault
136     */
137    public function setFault($fault = true)
138    {
139        $this->_fault = ((int)$fault > 0);// ? true : false;
140    }
141
142    /**
143     * @return bool
144     */
145    public function isFault()
146    {
147        return $this->_fault;
148    }
149
150    public function render()
151    {
152    }
153}
154
155/**
156 * Class XoopsXmlRpcFault
157 */
158class XoopsXmlRpcFault extends XoopsXmlRpcTag
159{
160    public $_code;
161    public $_extra;
162
163    /**
164     * @param      $code
165     * @param null $extra
166     */
167    public function __construct($code, $extra = null)
168    {
169        $this->setFault(true);
170        $this->_code  = (int)$code;
171        $this->_extra = isset($extra) ? trim($extra) : '';
172    }
173
174    /**
175     * @return string
176     */
177    public function render()
178    {
179        switch ($this->_code) {
180            case 101:
181                $string = 'Invalid server URI';
182                break;
183            case 102:
184                $string = 'Parser parse error';
185                break;
186            case 103:
187                $string = 'Module not found';
188                break;
189            case 104:
190                $string = 'User authentication failed';
191                break;
192            case 105:
193                $string = 'Module API not found';
194                break;
195            case 106:
196                $string = 'Method response error';
197                break;
198            case 107:
199                $string = 'Method not supported';
200                break;
201            case 108:
202                $string = 'Invalid parameter';
203                break;
204            case 109:
205                $string = 'Missing parameters';
206                break;
207            case 110:
208                $string = 'Selected blog application does not exist';
209                break;
210            case 111:
211                $string = 'Method permission denied';
212                break;
213            default:
214                $string = 'Method response error';
215                break;
216        }
217        $string .= "\n" . $this->_extra;
218
219        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>';
220    }
221}
222
223/**
224 * Class XoopsXmlRpcInt
225 */
226class XoopsXmlRpcInt extends XoopsXmlRpcTag
227{
228    public $_value;
229
230    /**
231     * @param $value
232     */
233    public function __construct($value)
234    {
235        $this->_value = (int)$value;
236    }
237
238    /**
239     * @return string
240     */
241    public function render()
242    {
243        return '<value><int>' . $this->_value . '</int></value>';
244    }
245}
246
247/**
248 * Class XoopsXmlRpcDouble
249 */
250class XoopsXmlRpcDouble extends XoopsXmlRpcTag
251{
252    public $_value;
253
254    /**
255     * @param $value
256     */
257    public function __construct($value)
258    {
259        $this->_value = (float)$value;
260    }
261
262    /**
263     * @return string
264     */
265    public function render()
266    {
267        return '<value><double>' . $this->_value . '</double></value>';
268    }
269}
270
271/**
272 * Class XoopsXmlRpcBoolean
273 */
274class XoopsXmlRpcBoolean extends XoopsXmlRpcTag
275{
276    public $_value;
277
278    /**
279     * @param $value
280     */
281    public function __construct($value)
282    {
283        $this->_value = (!empty($value) && $value != false) ? 1 : 0;
284    }
285
286    /**
287     * @return string
288     */
289    public function render()
290    {
291        return '<value><boolean>' . $this->_value . '</boolean></value>';
292    }
293}
294
295/**
296 * Class XoopsXmlRpcString
297 */
298class XoopsXmlRpcString extends XoopsXmlRpcTag
299{
300    public $_value;
301
302    /**
303     * @param $value
304     */
305    public function __construct($value)
306    {
307        $this->_value = (string)$value;
308    }
309
310    /**
311     * @return string
312     */
313    public function render()
314    {
315        return '<value><string>' . $this->encode($this->_value) . '</string></value>';
316    }
317}
318
319/**
320 * Class XoopsXmlRpcDatetime
321 */
322class XoopsXmlRpcDatetime extends XoopsXmlRpcTag
323{
324    public $_value;
325
326    /**
327     * @param $value
328     */
329    public function __construct($value)
330    {
331        if (!is_numeric($value)) {
332            $this->_value = strtotime($value);
333        } else {
334            $this->_value = (int)$value;
335        }
336    }
337
338    /**
339     * @return string
340     */
341    public function render()
342    {
343        return '<value><dateTime.iso8601>' . gmstrftime('%Y%m%dT%H:%M:%S', $this->_value) . '</dateTime.iso8601></value>';
344    }
345}
346
347/**
348 * Class XoopsXmlRpcBase64
349 */
350class XoopsXmlRpcBase64 extends XoopsXmlRpcTag
351{
352    public $_value;
353
354    /**
355     * @param $value
356     */
357    public function __construct($value)
358    {
359        $this->_value = base64_encode($value);
360    }
361
362    /**
363     * @return string
364     */
365    public function render()
366    {
367        return '<value><base64>' . $this->_value . '</base64></value>';
368    }
369}
370
371/**
372 * Class XoopsXmlRpcArray
373 */
374class XoopsXmlRpcArray extends XoopsXmlRpcTag
375{
376    public $_tags = array();
377
378    /**
379     * XoopsXmlRpcArray constructor.
380     */
381    public function __construct()
382    {
383    }
384
385    /**
386     * @param $tagobj
387     */
388    public function add(&$tagobj)
389    {
390        $this->_tags[] =& $tagobj;
391    }
392
393    /**
394     * @return string
395     */
396    public function render()
397    {
398        $count = count($this->_tags);
399        $ret   = '<value><array><data>';
400        for ($i = 0; $i < $count; ++$i) {
401            $ret .= $this->_tags[$i]->render();
402        }
403        $ret .= '</data></array></value>';
404
405        return $ret;
406    }
407}
408
409/**
410 * Class XoopsXmlRpcStruct
411 */
412class XoopsXmlRpcStruct extends XoopsXmlRpcTag
413{
414    public $_tags = array();
415
416    /**
417     * XoopsXmlRpcStruct constructor.
418     */
419    public function __construct()
420    {
421    }
422
423    /**
424     * @param $name
425     * @param $tagobj
426     */
427    public function add($name, &$tagobj)
428    {
429        $this->_tags[] = array('name' => $name, 'value' => $tagobj);
430    }
431
432    /**
433     * @return string
434     */
435    public function render()
436    {
437        $count = count($this->_tags);
438        $ret   = '<value><struct>';
439        for ($i = 0; $i < $count; ++$i) {
440            $ret .= '<member><name>' . $this->encode($this->_tags[$i]['name']) . '</name>' . $this->_tags[$i]['value']->render() . '</member>';
441        }
442        $ret .= '</struct></value>';
443
444        return $ret;
445    }
446}
447