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