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: