1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14: 15: 16: 17: 18:
19:
20: defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
21: require_once XOOPS_ROOT_PATH . '/class/xml/saxparser.php';
22: require_once XOOPS_ROOT_PATH . '/class/xml/xmltaghandler.php';
23:
24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
35: class XoopsXmlRpcParser extends SaxParser
36: {
37: 38: 39: 40:
41: public $_param;
42:
43: 44: 45: 46:
47: public $_methodName;
48:
49: 50: 51: 52:
53: public $_tempName;
54:
55: 56: 57: 58:
59: public $_tempValue;
60:
61: 62: 63: 64:
65: public $_tempMember;
66:
67: 68: 69: 70:
71: public $_tempStruct;
72:
73: 74: 75: 76:
77: public $_tempArray;
78:
79: 80: 81: 82:
83: public $_workingLevel = array();
84:
85: 86: 87: 88: 89: 90: 91:
92: public function __construct(&$input)
93: {
94: parent::__construct($input);
95: $this->addTagHandler(new RpcMethodNameHandler());
96: $this->addTagHandler(new RpcIntHandler());
97: $this->addTagHandler(new RpcDoubleHandler());
98: $this->addTagHandler(new RpcBooleanHandler());
99: $this->addTagHandler(new RpcStringHandler());
100: $this->addTagHandler(new RpcDateTimeHandler());
101: $this->addTagHandler(new RpcBase64Handler());
102: $this->addTagHandler(new RpcNameHandler());
103: $this->addTagHandler(new RpcValueHandler());
104: $this->addTagHandler(new RpcMemberHandler());
105: $this->addTagHandler(new RpcStructHandler());
106: $this->addTagHandler(new RpcArrayHandler());
107: }
108:
109: 110: 111: 112: 113: 114: 115:
116: public function setTempName($name)
117: {
118: $this->_tempName[$this->getWorkingLevel()] = $name;
119: }
120:
121: 122: 123:
124: public function getTempName()
125: {
126: return $this->_tempName[$this->getWorkingLevel()];
127: }
128:
129: 130: 131:
132: public function setTempValue($value)
133: {
134: if (is_array($value)) {
135: settype($this->_tempValue, 'array');
136: foreach ($value as $k => $v) {
137: $this->_tempValue[$k] = $v;
138: }
139: } elseif (is_string($value)) {
140: if (isset($this->_tempValue)) {
141: if (is_string($this->_tempValue)) {
142: $this->_tempValue .= $value;
143: }
144: } else {
145: $this->_tempValue = $value;
146: }
147: } else {
148: $this->_tempValue = $value;
149: }
150: }
151:
152: 153: 154:
155: public function getTempValue()
156: {
157: return $this->_tempValue;
158: }
159:
160: public function resetTempValue()
161: {
162: unset($this->_tempValue);
163: }
164:
165: 166: 167: 168:
169: public function setTempMember($name, $value)
170: {
171: $this->_tempMember[$this->getWorkingLevel()][$name] = $value;
172: }
173:
174: 175: 176:
177: public function getTempMember()
178: {
179: return $this->_tempMember[$this->getWorkingLevel()];
180: }
181:
182: public function resetTempMember()
183: {
184: $this->_tempMember[$this->getCurrentLevel()] = array();
185: }
186:
187: public function setWorkingLevel()
188: {
189: $this->_workingLevel[] = $this->getCurrentLevel();
190: }
191:
192: 193: 194:
195: public function getWorkingLevel()
196: {
197: return $this->_workingLevel[count($this->_workingLevel) - 1];
198: }
199:
200: public function releaseWorkingLevel()
201: {
202: array_pop($this->_workingLevel);
203: }
204:
205: 206: 207:
208: public function setTempStruct($member)
209: {
210: $key = key($member);
211: $this->_tempStruct[$this->getWorkingLevel()][$key] = $member[$key];
212: }
213:
214: 215: 216:
217: public function getTempStruct()
218: {
219: return $this->_tempStruct[$this->getWorkingLevel()];
220: }
221:
222: public function resetTempStruct()
223: {
224: $this->_tempStruct[$this->getCurrentLevel()] = array();
225: }
226:
227: 228: 229:
230: public function setTempArray($value)
231: {
232: $this->_tempArray[$this->getWorkingLevel()][] = $value;
233: }
234:
235: 236: 237:
238: public function getTempArray()
239: {
240: return $this->_tempArray[$this->getWorkingLevel()];
241: }
242:
243: public function resetTempArray()
244: {
245: $this->_tempArray[$this->getCurrentLevel()] = array();
246: }
247:
248: 249: 250:
251: public function setMethodName($methodName)
252: {
253: $this->_methodName = $methodName;
254: }
255:
256: 257: 258:
259: public function getMethodName()
260: {
261: return $this->_methodName;
262: }
263:
264: 265: 266:
267: public function setParam($value)
268: {
269: $this->_param[] = $value;
270: }
271:
272: 273: 274:
275: public function &getParam()
276: {
277: return $this->_param;
278: }
279: }
280:
281: 282: 283:
284: class RpcMethodNameHandler extends XmlTagHandler
285: {
286: 287: 288:
289: public function getName()
290: {
291: return 'methodName';
292: }
293:
294: 295: 296: 297:
298: public function handleCharacterData($parser, &$data)
299: {
300: $parser->setMethodName($data);
301: }
302: }
303:
304: 305: 306:
307: class RpcIntHandler extends XmlTagHandler
308: {
309: 310: 311:
312: public function getName()
313: {
314: return array('int', 'i4');
315: }
316:
317: 318: 319: 320:
321: public function handleCharacterData($parser, &$data)
322: {
323: $parser->setTempValue((int)$data);
324: }
325: }
326:
327: 328: 329:
330: class RpcDoubleHandler extends XmlTagHandler
331: {
332: 333: 334:
335: public function getName()
336: {
337: return 'double';
338: }
339:
340: 341: 342: 343:
344: public function handleCharacterData($parser, &$data)
345: {
346: $data = (float)$data;
347: $parser->setTempValue($data);
348: }
349: }
350:
351: 352: 353:
354: class RpcBooleanHandler extends XmlTagHandler
355: {
356: 357: 358:
359: public function getName()
360: {
361: return 'boolean';
362: }
363:
364: 365: 366: 367:
368: public function handleCharacterData($parser, &$data)
369: {
370: $data = (boolean)$data;
371: $parser->setTempValue($data);
372: }
373: }
374:
375: 376: 377:
378: class RpcStringHandler extends XmlTagHandler
379: {
380: 381: 382:
383: public function getName()
384: {
385: return 'string';
386: }
387:
388: 389: 390: 391:
392: public function handleCharacterData($parser, &$data)
393: {
394: $parser->setTempValue((string)$data);
395: }
396: }
397:
398: 399: 400:
401: class RpcDateTimeHandler extends XmlTagHandler
402: {
403: 404: 405:
406: public function getName()
407: {
408: return 'dateTime.iso8601';
409: }
410:
411: 412: 413: 414:
415: public function handleCharacterData($parser, &$data)
416: {
417: $matches = array();
418: if (!preg_match("/^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})$/", $data, $matches)) {
419: $parser->setTempValue(time());
420: } else {
421: $parser->setTempValue(gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]));
422: }
423: }
424: }
425:
426: 427: 428:
429: class RpcBase64Handler extends XmlTagHandler
430: {
431: 432: 433:
434: public function getName()
435: {
436: return 'base64';
437: }
438:
439: 440: 441: 442:
443: public function handleCharacterData($parser, &$data)
444: {
445: $parser->setTempValue(base64_decode($data));
446: }
447: }
448:
449: 450: 451:
452: class RpcNameHandler extends XmlTagHandler
453: {
454: 455: 456:
457: public function getName()
458: {
459: return 'name';
460: }
461:
462: 463: 464: 465:
466: public function handleCharacterData($parser, &$data)
467: {
468: switch ($parser->getParentTag()) {
469: case 'member':
470: $parser->setTempName($data);
471: break;
472: default:
473: break;
474: }
475: }
476: }
477:
478: 479: 480:
481: class RpcValueHandler extends XmlTagHandler
482: {
483: 484: 485:
486: public function getName()
487: {
488: return 'value';
489: }
490:
491: 492: 493: 494:
495: public function handleCharacterData($parser, &$data)
496: {
497: switch ($parser->getParentTag()) {
498: case 'member':
499: $parser->setTempValue($data);
500: break;
501: case 'data':
502: case 'array':
503: $parser->setTempValue($data);
504: break;
505: default:
506: break;
507: }
508: }
509:
510: 511: 512: 513:
514: public function handleBeginElement($parser, &$attributes)
515: {
516:
517: }
518:
519: 520: 521:
522: public function handleEndElement($parser)
523: {
524: switch ($parser->getCurrentTag()) {
525: case 'member':
526: $parser->setTempMember($parser->getTempName(), $parser->getTempValue());
527: break;
528: case 'array':
529: case 'data':
530: $parser->setTempArray($parser->getTempValue());
531: break;
532: default:
533: $parser->setParam($parser->getTempValue());
534: break;
535: }
536: $parser->resetTempValue();
537: }
538: }
539:
540: 541: 542:
543: class RpcMemberHandler extends XmlTagHandler
544: {
545: 546: 547:
548: public function getName()
549: {
550: return 'member';
551: }
552:
553: 554: 555: 556:
557: public function handleBeginElement($parser, &$attributes)
558: {
559: $parser->setWorkingLevel();
560: $parser->resetTempMember();
561: }
562:
563: 564: 565:
566: public function handleEndElement($parser)
567: {
568: $member =& $parser->getTempMember();
569: $parser->releaseWorkingLevel();
570: $parser->setTempStruct($member);
571: }
572: }
573:
574: 575: 576:
577: class RpcArrayHandler extends XmlTagHandler
578: {
579: 580: 581:
582: public function getName()
583: {
584: return 'array';
585: }
586:
587: 588: 589: 590:
591: public function handleBeginElement($parser, &$attributes)
592: {
593: $parser->setWorkingLevel();
594: $parser->resetTempArray();
595: }
596:
597: 598: 599:
600: public function handleEndElement($parser)
601: {
602: $parser->setTempValue($parser->getTempArray());
603: $parser->releaseWorkingLevel();
604: }
605: }
606:
607: 608: 609:
610: class RpcStructHandler extends XmlTagHandler
611: {
612: 613: 614:
615: public function getName()
616: {
617: return 'struct';
618: }
619:
620: 621: 622: 623:
624: public function handleBeginElement($parser, &$attributes)
625: {
626: $parser->setWorkingLevel();
627: $parser->resetTempStruct();
628: }
629:
630: 631: 632:
633: public function handleEndElement($parser)
634: {
635: $parser->setTempValue($parser->getTempStruct());
636: $parser->releaseWorkingLevel();
637: }
638: }
639: