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 https://xoops.org/
14: * @license GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
15: * @package
16: * @since
17: * @author XOOPS Development Team, Kazumi Ono (AKA onokazu)
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: * Class RSS Parser
26: *
27: * This class offers methods to parse RSS Files
28: *
29: * @link https://xoops.org/ Latest release of this class
30: * @package class
31: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
32: * @author Kazumi Ono <onokazu@xoops.org>
33: * @access public
34: */
35: class XoopsXmlRpcParser extends SaxParser
36: {
37: /**
38: * @access private
39: * @var array
40: */
41: public $_param;
42:
43: /**
44: * @access private
45: * @var string
46: */
47: public $_methodName;
48:
49: /**
50: * @access private
51: * @var array
52: */
53: public $_tempName;
54:
55: /**
56: * @access private
57: * @var array
58: */
59: public $_tempValue;
60:
61: /**
62: * @access private
63: * @var array
64: */
65: public $_tempMember;
66:
67: /**
68: * @access private
69: * @var array
70: */
71: public $_tempStruct;
72:
73: /**
74: * @access private
75: * @var array
76: */
77: public $_tempArray;
78:
79: /**
80: * @access private
81: * @var array
82: */
83: public $_workingLevel = array();
84:
85: /**
86: * Constructor of the class
87: * @access
88: * @author
89: * @see
90: * @param $input
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: * This Method starts the parsing of the specified RDF File. The File can be a local or a remote File.
111: *
112: * @param $name
113: *
114: * @return void
115: */
116: public function setTempName($name)
117: {
118: $this->_tempName[$this->getWorkingLevel()] = $name;
119: }
120:
121: /**
122: * @return mixed
123: */
124: public function getTempName()
125: {
126: return $this->_tempName[$this->getWorkingLevel()];
127: }
128:
129: /**
130: * @param $value
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: * @return array
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: * @param $name
167: * @param $value
168: */
169: public function setTempMember($name, $value)
170: {
171: $this->_tempMember[$this->getWorkingLevel()][$name] = $value;
172: }
173:
174: /**
175: * @return mixed
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: * @return mixed
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: * @param $member
207: */
208: public function setTempStruct($member)
209: {
210: $key = key($member);
211: $this->_tempStruct[$this->getWorkingLevel()][$key] = $member[$key];
212: }
213:
214: /**
215: * @return mixed
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: * @param $value
229: */
230: public function setTempArray($value)
231: {
232: $this->_tempArray[$this->getWorkingLevel()][] = $value;
233: }
234:
235: /**
236: * @return mixed
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: * @param $methodName
250: */
251: public function setMethodName($methodName)
252: {
253: $this->_methodName = $methodName;
254: }
255:
256: /**
257: * @return string
258: */
259: public function getMethodName()
260: {
261: return $this->_methodName;
262: }
263:
264: /**
265: * @param $value
266: */
267: public function setParam($value)
268: {
269: $this->_param[] = $value;
270: }
271:
272: /**
273: * @return array
274: */
275: public function &getParam()
276: {
277: return $this->_param;
278: }
279: }
280:
281: /**
282: * Class RpcMethodNameHandler
283: */
284: class RpcMethodNameHandler extends XmlTagHandler
285: {
286: /**
287: * @return string
288: */
289: public function getName()
290: {
291: return 'methodName';
292: }
293:
294: /**
295: * @param $parser
296: * @param $data
297: */
298: public function handleCharacterData($parser, &$data)
299: {
300: $parser->setMethodName($data);
301: }
302: }
303:
304: /**
305: * Class RpcIntHandler
306: */
307: class RpcIntHandler extends XmlTagHandler
308: {
309: /**
310: * @return array
311: */
312: public function getName()
313: {
314: return array('int', 'i4');
315: }
316:
317: /**
318: * @param $parser
319: * @param $data
320: */
321: public function handleCharacterData($parser, &$data)
322: {
323: $parser->setTempValue((int)$data);
324: }
325: }
326:
327: /**
328: * Class RpcDoubleHandler
329: */
330: class RpcDoubleHandler extends XmlTagHandler
331: {
332: /**
333: * @return string
334: */
335: public function getName()
336: {
337: return 'double';
338: }
339:
340: /**
341: * @param $parser
342: * @param $data
343: */
344: public function handleCharacterData($parser, &$data)
345: {
346: $data = (float)$data;
347: $parser->setTempValue($data);
348: }
349: }
350:
351: /**
352: * Class RpcBooleanHandler
353: */
354: class RpcBooleanHandler extends XmlTagHandler
355: {
356: /**
357: * @return string
358: */
359: public function getName()
360: {
361: return 'boolean';
362: }
363:
364: /**
365: * @param $parser
366: * @param $data
367: */
368: public function handleCharacterData($parser, &$data)
369: {
370: $data = (boolean)$data;
371: $parser->setTempValue($data);
372: }
373: }
374:
375: /**
376: * Class RpcStringHandler
377: */
378: class RpcStringHandler extends XmlTagHandler
379: {
380: /**
381: * @return string
382: */
383: public function getName()
384: {
385: return 'string';
386: }
387:
388: /**
389: * @param $parser
390: * @param $data
391: */
392: public function handleCharacterData($parser, &$data)
393: {
394: $parser->setTempValue((string)$data);
395: }
396: }
397:
398: /**
399: * Class RpcDateTimeHandler
400: */
401: class RpcDateTimeHandler extends XmlTagHandler
402: {
403: /**
404: * @return string
405: */
406: public function getName()
407: {
408: return 'dateTime.iso8601';
409: }
410:
411: /**
412: * @param $parser
413: * @param $data
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: * Class RpcBase64Handler
428: */
429: class RpcBase64Handler extends XmlTagHandler
430: {
431: /**
432: * @return string
433: */
434: public function getName()
435: {
436: return 'base64';
437: }
438:
439: /**
440: * @param $parser
441: * @param $data
442: */
443: public function handleCharacterData($parser, &$data)
444: {
445: $parser->setTempValue(base64_decode($data));
446: }
447: }
448:
449: /**
450: * Class RpcNameHandler
451: */
452: class RpcNameHandler extends XmlTagHandler
453: {
454: /**
455: * @return string
456: */
457: public function getName()
458: {
459: return 'name';
460: }
461:
462: /**
463: * @param $parser
464: * @param $data
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: * Class RpcValueHandler
480: */
481: class RpcValueHandler extends XmlTagHandler
482: {
483: /**
484: * @return string
485: */
486: public function getName()
487: {
488: return 'value';
489: }
490:
491: /**
492: * @param $parser
493: * @param $data
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: * @param $parser
512: * @param $attributes
513: */
514: public function handleBeginElement($parser, &$attributes)
515: {
516: //$parser->resetTempValue();
517: }
518:
519: /**
520: * @param $parser
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: * Class RpcMemberHandler
542: */
543: class RpcMemberHandler extends XmlTagHandler
544: {
545: /**
546: * @return string
547: */
548: public function getName()
549: {
550: return 'member';
551: }
552:
553: /**
554: * @param $parser
555: * @param $attributes
556: */
557: public function handleBeginElement($parser, &$attributes)
558: {
559: $parser->setWorkingLevel();
560: $parser->resetTempMember();
561: }
562:
563: /**
564: * @param $parser
565: */
566: public function handleEndElement($parser)
567: {
568: $member =& $parser->getTempMember();
569: $parser->releaseWorkingLevel();
570: $parser->setTempStruct($member);
571: }
572: }
573:
574: /**
575: * Class RpcArrayHandler
576: */
577: class RpcArrayHandler extends XmlTagHandler
578: {
579: /**
580: * @return string
581: */
582: public function getName()
583: {
584: return 'array';
585: }
586:
587: /**
588: * @param $parser
589: * @param $attributes
590: */
591: public function handleBeginElement($parser, &$attributes)
592: {
593: $parser->setWorkingLevel();
594: $parser->resetTempArray();
595: }
596:
597: /**
598: * @param $parser
599: */
600: public function handleEndElement($parser)
601: {
602: $parser->setTempValue($parser->getTempArray());
603: $parser->releaseWorkingLevel();
604: }
605: }
606:
607: /**
608: * Class RpcStructHandler
609: */
610: class RpcStructHandler extends XmlTagHandler
611: {
612: /**
613: * @return string
614: */
615: public function getName()
616: {
617: return 'struct';
618: }
619:
620: /**
621: * @param $parser
622: * @param $attributes
623: */
624: public function handleBeginElement($parser, &$attributes)
625: {
626: $parser->setWorkingLevel();
627: $parser->resetTempStruct();
628: }
629:
630: /**
631: * @param $parser
632: */
633: public function handleEndElement($parser)
634: {
635: $parser->setTempValue($parser->getTempStruct());
636: $parser->releaseWorkingLevel();
637: }
638: }
639: