/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/system/libraries/Xmlrpc.php

  • Committer: galaxyAbstractor
  • Date: 2013-04-10 15:58:59 UTC
  • mfrom: (20.1.1 lenasys)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: galaxyabstractor@gmail.com-20130410155859-cih60kaz5es8savt
CodeIgniter implementation of basic CMS system

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
2
/**
 
3
 * CodeIgniter
 
4
 *
 
5
 * An open source application development framework for PHP 5.1.6 or newer
 
6
 *
 
7
 * @package             CodeIgniter
 
8
 * @author              ExpressionEngine Dev Team
 
9
 * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
 
10
 * @license             http://codeigniter.com/user_guide/license.html
 
11
 * @link                http://codeigniter.com
 
12
 * @since               Version 1.0
 
13
 * @filesource
 
14
 */
 
15
 
 
16
if ( ! function_exists('xml_parser_create'))
 
17
{
 
18
        show_error('Your PHP installation does not support XML');
 
19
}
 
20
 
 
21
 
 
22
// ------------------------------------------------------------------------
 
23
 
 
24
/**
 
25
 * XML-RPC request handler class
 
26
 *
 
27
 * @package             CodeIgniter
 
28
 * @subpackage  Libraries
 
29
 * @category    XML-RPC
 
30
 * @author              ExpressionEngine Dev Team
 
31
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
 
32
 */
 
33
class CI_Xmlrpc {
 
34
 
 
35
        var $debug                      = FALSE;        // Debugging on or off
 
36
        var $xmlrpcI4           = 'i4';
 
37
        var $xmlrpcInt          = 'int';
 
38
        var $xmlrpcBoolean      = 'boolean';
 
39
        var $xmlrpcDouble       = 'double';
 
40
        var $xmlrpcString       = 'string';
 
41
        var $xmlrpcDateTime     = 'dateTime.iso8601';
 
42
        var $xmlrpcBase64       = 'base64';
 
43
        var $xmlrpcArray        = 'array';
 
44
        var $xmlrpcStruct       = 'struct';
 
45
 
 
46
        var $xmlrpcTypes        = array();
 
47
        var $valid_parents      = array();
 
48
        var $xmlrpcerr          = array();      // Response numbers
 
49
        var $xmlrpcstr          = array();  // Response strings
 
50
 
 
51
        var $xmlrpc_defencoding = 'UTF-8';
 
52
        var $xmlrpcName                 = 'XML-RPC for CodeIgniter';
 
53
        var $xmlrpcVersion              = '1.1';
 
54
        var $xmlrpcerruser              = 800; // Start of user errors
 
55
        var $xmlrpcerrxml               = 100; // Start of XML Parse errors
 
56
        var $xmlrpc_backslash   = ''; // formulate backslashes for escaping regexp
 
57
 
 
58
        var $client;
 
59
        var $method;
 
60
        var $data;
 
61
        var $message                    = '';
 
62
        var $error                              = '';           // Error string for request
 
63
        var $result;
 
64
        var $response                   = array();  // Response from remote server
 
65
 
 
66
        var $xss_clean                  = TRUE;
 
67
 
 
68
        //-------------------------------------
 
69
        //  VALUES THAT MULTIPLE CLASSES NEED
 
70
        //-------------------------------------
 
71
 
 
72
        public function __construct($config = array())
 
73
        {
 
74
                $this->xmlrpcName               = $this->xmlrpcName;
 
75
                $this->xmlrpc_backslash = chr(92).chr(92);
 
76
 
 
77
                // Types for info sent back and forth
 
78
                $this->xmlrpcTypes = array(
 
79
                        $this->xmlrpcI4                 => '1',
 
80
                        $this->xmlrpcInt                => '1',
 
81
                        $this->xmlrpcBoolean    => '1',
 
82
                        $this->xmlrpcString             => '1',
 
83
                        $this->xmlrpcDouble             => '1',
 
84
                        $this->xmlrpcDateTime   => '1',
 
85
                        $this->xmlrpcBase64             => '1',
 
86
                        $this->xmlrpcArray              => '2',
 
87
                        $this->xmlrpcStruct             => '3'
 
88
                        );
 
89
 
 
90
                // Array of Valid Parents for Various XML-RPC elements
 
91
                $this->valid_parents = array('BOOLEAN'                  => array('VALUE'),
 
92
                                                                         'I4'                           => array('VALUE'),
 
93
                                                                         'INT'                          => array('VALUE'),
 
94
                                                                         'STRING'                       => array('VALUE'),
 
95
                                                                         'DOUBLE'                       => array('VALUE'),
 
96
                                                                         'DATETIME.ISO8601'     => array('VALUE'),
 
97
                                                                         'BASE64'                       => array('VALUE'),
 
98
                                                                         'ARRAY'                        => array('VALUE'),
 
99
                                                                         'STRUCT'                       => array('VALUE'),
 
100
                                                                         'PARAM'                        => array('PARAMS'),
 
101
                                                                         'METHODNAME'           => array('METHODCALL'),
 
102
                                                                         'PARAMS'                       => array('METHODCALL', 'METHODRESPONSE'),
 
103
                                                                         'MEMBER'                       => array('STRUCT'),
 
104
                                                                         'NAME'                         => array('MEMBER'),
 
105
                                                                         'DATA'                         => array('ARRAY'),
 
106
                                                                         'FAULT'                        => array('METHODRESPONSE'),
 
107
                                                                         'VALUE'                        => array('MEMBER', 'DATA', 'PARAM', 'FAULT')
 
108
                                                                         );
 
109
 
 
110
 
 
111
                // XML-RPC Responses
 
112
                $this->xmlrpcerr['unknown_method'] = '1';
 
113
                $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
 
114
                $this->xmlrpcerr['invalid_return'] = '2';
 
115
                $this->xmlrpcstr['invalid_return'] = 'The XML data received was either invalid or not in the correct form for XML-RPC.  Turn on debugging to examine the XML data further.';
 
116
                $this->xmlrpcerr['incorrect_params'] = '3';
 
117
                $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
 
118
                $this->xmlrpcerr['introspect_unknown'] = '4';
 
119
                $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";
 
120
                $this->xmlrpcerr['http_error'] = '5';
 
121
                $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
 
122
                $this->xmlrpcerr['no_data'] = '6';
 
123
                $this->xmlrpcstr['no_data'] ='No data received from server.';
 
124
 
 
125
                $this->initialize($config);
 
126
 
 
127
                log_message('debug', "XML-RPC Class Initialized");
 
128
        }
 
129
 
 
130
 
 
131
        //-------------------------------------
 
132
        //  Initialize Prefs
 
133
        //-------------------------------------
 
134
 
 
135
        function initialize($config = array())
 
136
        {
 
137
                if (count($config) > 0)
 
138
                {
 
139
                        foreach ($config as $key => $val)
 
140
                        {
 
141
                                if (isset($this->$key))
 
142
                                {
 
143
                                        $this->$key = $val;
 
144
                                }
 
145
                        }
 
146
                }
 
147
        }
 
148
        // END
 
149
 
 
150
        //-------------------------------------
 
151
        //  Take URL and parse it
 
152
        //-------------------------------------
 
153
 
 
154
        function server($url, $port=80)
 
155
        {
 
156
                if (substr($url, 0, 4) != "http")
 
157
                {
 
158
                        $url = "http://".$url;
 
159
                }
 
160
 
 
161
                $parts = parse_url($url);
 
162
 
 
163
                $path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
 
164
 
 
165
                if (isset($parts['query']) && $parts['query'] != '')
 
166
                {
 
167
                        $path .= '?'.$parts['query'];
 
168
                }
 
169
 
 
170
                $this->client = new XML_RPC_Client($path, $parts['host'], $port);
 
171
        }
 
172
        // END
 
173
 
 
174
        //-------------------------------------
 
175
        //  Set Timeout
 
176
        //-------------------------------------
 
177
 
 
178
        function timeout($seconds=5)
 
179
        {
 
180
                if ( ! is_null($this->client) && is_int($seconds))
 
181
                {
 
182
                        $this->client->timeout = $seconds;
 
183
                }
 
184
        }
 
185
        // END
 
186
 
 
187
        //-------------------------------------
 
188
        //  Set Methods
 
189
        //-------------------------------------
 
190
 
 
191
        function method($function)
 
192
        {
 
193
                $this->method = $function;
 
194
        }
 
195
        // END
 
196
 
 
197
        //-------------------------------------
 
198
        //  Take Array of Data and Create Objects
 
199
        //-------------------------------------
 
200
 
 
201
        function request($incoming)
 
202
        {
 
203
                if ( ! is_array($incoming))
 
204
                {
 
205
                        // Send Error
 
206
                }
 
207
 
 
208
                $this->data = array();
 
209
 
 
210
                foreach ($incoming as $key => $value)
 
211
                {
 
212
                        $this->data[$key] = $this->values_parsing($value);
 
213
                }
 
214
        }
 
215
        // END
 
216
 
 
217
 
 
218
        //-------------------------------------
 
219
        //  Set Debug
 
220
        //-------------------------------------
 
221
 
 
222
        function set_debug($flag = TRUE)
 
223
        {
 
224
                $this->debug = ($flag == TRUE) ? TRUE : FALSE;
 
225
        }
 
226
 
 
227
        //-------------------------------------
 
228
        //  Values Parsing
 
229
        //-------------------------------------
 
230
 
 
231
        function values_parsing($value, $return = FALSE)
 
232
        {
 
233
                if (is_array($value) && array_key_exists(0, $value))
 
234
                {
 
235
                        if ( ! isset($value['1']) OR ( ! isset($this->xmlrpcTypes[$value['1']])))
 
236
                        {
 
237
                                if (is_array($value[0]))
 
238
                                {
 
239
                                        $temp = new XML_RPC_Values($value['0'], 'array');
 
240
                                }
 
241
                                else
 
242
                                {
 
243
                                        $temp = new XML_RPC_Values($value['0'], 'string');
 
244
                                }
 
245
                        }
 
246
                        elseif (is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
 
247
                        {
 
248
                                while (list($k) = each($value['0']))
 
249
                                {
 
250
                                        $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);
 
251
                                }
 
252
 
 
253
                                $temp = new XML_RPC_Values($value['0'], $value['1']);
 
254
                        }
 
255
                        else
 
256
                        {
 
257
                                $temp = new XML_RPC_Values($value['0'], $value['1']);
 
258
                        }
 
259
                }
 
260
                else
 
261
                {
 
262
                        $temp = new XML_RPC_Values($value, 'string');
 
263
                }
 
264
 
 
265
                return $temp;
 
266
        }
 
267
        // END
 
268
 
 
269
 
 
270
        //-------------------------------------
 
271
        //  Sends XML-RPC Request
 
272
        //-------------------------------------
 
273
 
 
274
        function send_request()
 
275
        {
 
276
                $this->message = new XML_RPC_Message($this->method,$this->data);
 
277
                $this->message->debug = $this->debug;
 
278
 
 
279
                if ( ! $this->result = $this->client->send($this->message))
 
280
                {
 
281
                        $this->error = $this->result->errstr;
 
282
                        return FALSE;
 
283
                }
 
284
                elseif ( ! is_object($this->result->val))
 
285
                {
 
286
                        $this->error = $this->result->errstr;
 
287
                        return FALSE;
 
288
                }
 
289
 
 
290
                $this->response = $this->result->decode();
 
291
 
 
292
                return TRUE;
 
293
        }
 
294
        // END
 
295
 
 
296
        //-------------------------------------
 
297
        //  Returns Error
 
298
        //-------------------------------------
 
299
 
 
300
        function display_error()
 
301
        {
 
302
                return $this->error;
 
303
        }
 
304
        // END
 
305
 
 
306
        //-------------------------------------
 
307
        //  Returns Remote Server Response
 
308
        //-------------------------------------
 
309
 
 
310
        function display_response()
 
311
        {
 
312
                return $this->response;
 
313
        }
 
314
        // END
 
315
 
 
316
        //-------------------------------------
 
317
        //  Sends an Error Message for Server Request
 
318
        //-------------------------------------
 
319
 
 
320
        function send_error_message($number, $message)
 
321
        {
 
322
                return new XML_RPC_Response('0',$number, $message);
 
323
        }
 
324
        // END
 
325
 
 
326
 
 
327
        //-------------------------------------
 
328
        //  Send Response for Server Request
 
329
        //-------------------------------------
 
330
 
 
331
        function send_response($response)
 
332
        {
 
333
                // $response should be array of values, which will be parsed
 
334
                // based on their data and type into a valid group of XML-RPC values
 
335
 
 
336
                $response = $this->values_parsing($response);
 
337
 
 
338
                return new XML_RPC_Response($response);
 
339
        }
 
340
        // END
 
341
 
 
342
} // END XML_RPC Class
 
343
 
 
344
 
 
345
 
 
346
/**
 
347
 * XML-RPC Client class
 
348
 *
 
349
 * @category    XML-RPC
 
350
 * @author              ExpressionEngine Dev Team
 
351
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
 
352
 */
 
353
class XML_RPC_Client extends CI_Xmlrpc
 
354
{
 
355
        var $path                       = '';
 
356
        var $server                     = '';
 
357
        var $port                       = 80;
 
358
        var $errno                      = '';
 
359
        var $errstring          = '';
 
360
        var $timeout            = 5;
 
361
        var $no_multicall       = FALSE;
 
362
 
 
363
        public function __construct($path, $server, $port=80)
 
364
        {
 
365
                parent::__construct();
 
366
 
 
367
                $this->port = $port;
 
368
                $this->server = $server;
 
369
                $this->path = $path;
 
370
        }
 
371
 
 
372
        function send($msg)
 
373
        {
 
374
                if (is_array($msg))
 
375
                {
 
376
                        // Multi-call disabled
 
377
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
 
378
                        return $r;
 
379
                }
 
380
 
 
381
                return $this->sendPayload($msg);
 
382
        }
 
383
 
 
384
        function sendPayload($msg)
 
385
        {
 
386
                $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
 
387
 
 
388
                if ( ! is_resource($fp))
 
389
                {
 
390
                        error_log($this->xmlrpcstr['http_error']);
 
391
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
 
392
                        return $r;
 
393
                }
 
394
 
 
395
                if (empty($msg->payload))
 
396
                {
 
397
                        // $msg = XML_RPC_Messages
 
398
                        $msg->createPayload();
 
399
                }
 
400
 
 
401
                $r = "\r\n";
 
402
                $op  = "POST {$this->path} HTTP/1.0$r";
 
403
                $op .= "Host: {$this->server}$r";
 
404
                $op .= "Content-Type: text/xml$r";
 
405
                $op .= "User-Agent: {$this->xmlrpcName}$r";
 
406
                $op .= "Content-Length: ".strlen($msg->payload). "$r$r";
 
407
                $op .= $msg->payload;
 
408
 
 
409
 
 
410
                if ( ! fputs($fp, $op, strlen($op)))
 
411
                {
 
412
                        error_log($this->xmlrpcstr['http_error']);
 
413
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
 
414
                        return $r;
 
415
                }
 
416
                $resp = $msg->parseResponse($fp);
 
417
                fclose($fp);
 
418
                return $resp;
 
419
        }
 
420
 
 
421
} // end class XML_RPC_Client
 
422
 
 
423
 
 
424
/**
 
425
 * XML-RPC Response class
 
426
 *
 
427
 * @category    XML-RPC
 
428
 * @author              ExpressionEngine Dev Team
 
429
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
 
430
 */
 
431
class XML_RPC_Response
 
432
{
 
433
        var $val = 0;
 
434
        var $errno = 0;
 
435
        var $errstr = '';
 
436
        var $headers = array();
 
437
        var $xss_clean = TRUE;
 
438
 
 
439
        public function __construct($val, $code = 0, $fstr = '')
 
440
        {
 
441
                if ($code != 0)
 
442
                {
 
443
                        // error
 
444
                        $this->errno = $code;
 
445
                        $this->errstr = htmlentities($fstr);
 
446
                }
 
447
                else if ( ! is_object($val))
 
448
                {
 
449
                        // programmer error, not an object
 
450
                        error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");
 
451
                        $this->val = new XML_RPC_Values();
 
452
                }
 
453
                else
 
454
                {
 
455
                        $this->val = $val;
 
456
                }
 
457
        }
 
458
 
 
459
        function faultCode()
 
460
        {
 
461
                return $this->errno;
 
462
        }
 
463
 
 
464
        function faultString()
 
465
        {
 
466
                return $this->errstr;
 
467
        }
 
468
 
 
469
        function value()
 
470
        {
 
471
                return $this->val;
 
472
        }
 
473
 
 
474
        function prepare_response()
 
475
        {
 
476
                $result = "<methodResponse>\n";
 
477
                if ($this->errno)
 
478
                {
 
479
                        $result .= '<fault>
 
480
        <value>
 
481
                <struct>
 
482
                        <member>
 
483
                                <name>faultCode</name>
 
484
                                <value><int>' . $this->errno . '</int></value>
 
485
                        </member>
 
486
                        <member>
 
487
                                <name>faultString</name>
 
488
                                <value><string>' . $this->errstr . '</string></value>
 
489
                        </member>
 
490
                </struct>
 
491
        </value>
 
492
</fault>';
 
493
                }
 
494
                else
 
495
                {
 
496
                        $result .= "<params>\n<param>\n" .
 
497
                                        $this->val->serialize_class() .
 
498
                                        "</param>\n</params>";
 
499
                }
 
500
                $result .= "\n</methodResponse>";
 
501
                return $result;
 
502
        }
 
503
 
 
504
        function decode($array=FALSE)
 
505
        {
 
506
                $CI =& get_instance();
 
507
                
 
508
                if ($array !== FALSE && is_array($array))
 
509
                {
 
510
                        while (list($key) = each($array))
 
511
                        {
 
512
                                if (is_array($array[$key]))
 
513
                                {
 
514
                                        $array[$key] = $this->decode($array[$key]);
 
515
                                }
 
516
                                else
 
517
                                {
 
518
                                        $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key];
 
519
                                }
 
520
                        }
 
521
 
 
522
                        $result = $array;
 
523
                }
 
524
                else
 
525
                {
 
526
                        $result = $this->xmlrpc_decoder($this->val);
 
527
 
 
528
                        if (is_array($result))
 
529
                        {
 
530
                                $result = $this->decode($result);
 
531
                        }
 
532
                        else
 
533
                        {
 
534
                                $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
 
535
                        }
 
536
                }
 
537
 
 
538
                return $result;
 
539
        }
 
540
 
 
541
 
 
542
 
 
543
        //-------------------------------------
 
544
        //  XML-RPC Object to PHP Types
 
545
        //-------------------------------------
 
546
 
 
547
        function xmlrpc_decoder($xmlrpc_val)
 
548
        {
 
549
                $kind = $xmlrpc_val->kindOf();
 
550
 
 
551
                if ($kind == 'scalar')
 
552
                {
 
553
                        return $xmlrpc_val->scalarval();
 
554
                }
 
555
                elseif ($kind == 'array')
 
556
                {
 
557
                        reset($xmlrpc_val->me);
 
558
                        list($a,$b) = each($xmlrpc_val->me);
 
559
                        $size = count($b);
 
560
 
 
561
                        $arr = array();
 
562
 
 
563
                        for ($i = 0; $i < $size; $i++)
 
564
                        {
 
565
                                $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
 
566
                        }
 
567
                        return $arr;
 
568
                }
 
569
                elseif ($kind == 'struct')
 
570
                {
 
571
                        reset($xmlrpc_val->me['struct']);
 
572
                        $arr = array();
 
573
 
 
574
                        while (list($key,$value) = each($xmlrpc_val->me['struct']))
 
575
                        {
 
576
                                $arr[$key] = $this->xmlrpc_decoder($value);
 
577
                        }
 
578
                        return $arr;
 
579
                }
 
580
        }
 
581
 
 
582
 
 
583
        //-------------------------------------
 
584
        //  ISO-8601 time to server or UTC time
 
585
        //-------------------------------------
 
586
 
 
587
        function iso8601_decode($time, $utc=0)
 
588
        {
 
589
                // return a timet in the localtime, or UTC
 
590
                $t = 0;
 
591
                if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
 
592
                {
 
593
                        $fnc = ($utc == 1) ? 'gmmktime' : 'mktime';
 
594
                        $t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 
595
                }
 
596
                return $t;
 
597
        }
 
598
 
 
599
} // End Response Class
 
600
 
 
601
 
 
602
 
 
603
/**
 
604
 * XML-RPC Message class
 
605
 *
 
606
 * @category    XML-RPC
 
607
 * @author              ExpressionEngine Dev Team
 
608
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
 
609
 */
 
610
class XML_RPC_Message extends CI_Xmlrpc
 
611
{
 
612
        var $payload;
 
613
        var $method_name;
 
614
        var $params                     = array();
 
615
        var $xh                         = array();
 
616
 
 
617
        public function __construct($method, $pars=0)
 
618
        {
 
619
                parent::__construct();
 
620
 
 
621
                $this->method_name = $method;
 
622
                if (is_array($pars) && count($pars) > 0)
 
623
                {
 
624
                        for ($i=0; $i<count($pars); $i++)
 
625
                        {
 
626
                                // $pars[$i] = XML_RPC_Values
 
627
                                $this->params[] = $pars[$i];
 
628
                        }
 
629
                }
 
630
        }
 
631
 
 
632
        //-------------------------------------
 
633
        //  Create Payload to Send
 
634
        //-------------------------------------
 
635
 
 
636
        function createPayload()
 
637
        {
 
638
                $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";
 
639
                $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
 
640
                $this->payload .= "<params>\r\n";
 
641
 
 
642
                for ($i=0; $i<count($this->params); $i++)
 
643
                {
 
644
                        // $p = XML_RPC_Values
 
645
                        $p = $this->params[$i];
 
646
                        $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
 
647
                }
 
648
 
 
649
                $this->payload .= "</params>\r\n</methodCall>\r\n";
 
650
        }
 
651
 
 
652
        //-------------------------------------
 
653
        //  Parse External XML-RPC Server's Response
 
654
        //-------------------------------------
 
655
 
 
656
        function parseResponse($fp)
 
657
        {
 
658
                $data = '';
 
659
 
 
660
                while ($datum = fread($fp, 4096))
 
661
                {
 
662
                        $data .= $datum;
 
663
                }
 
664
 
 
665
                //-------------------------------------
 
666
                //  DISPLAY HTTP CONTENT for DEBUGGING
 
667
                //-------------------------------------
 
668
 
 
669
                if ($this->debug === TRUE)
 
670
                {
 
671
                        echo "<pre>";
 
672
                        echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
 
673
                        echo "</pre>";
 
674
                }
 
675
 
 
676
                //-------------------------------------
 
677
                //  Check for data
 
678
                //-------------------------------------
 
679
 
 
680
                if ($data == "")
 
681
                {
 
682
                        error_log($this->xmlrpcstr['no_data']);
 
683
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
 
684
                        return $r;
 
685
                }
 
686
 
 
687
 
 
688
                //-------------------------------------
 
689
                //  Check for HTTP 200 Response
 
690
                //-------------------------------------
 
691
 
 
692
                if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
 
693
                {
 
694
                        $errstr= substr($data, 0, strpos($data, "\n")-1);
 
695
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
 
696
                        return $r;
 
697
                }
 
698
 
 
699
                //-------------------------------------
 
700
                //  Create and Set Up XML Parser
 
701
                //-------------------------------------
 
702
 
 
703
                $parser = xml_parser_create($this->xmlrpc_defencoding);
 
704
 
 
705
                $this->xh[$parser]                                      = array();
 
706
                $this->xh[$parser]['isf']                       = 0;
 
707
                $this->xh[$parser]['ac']                        = '';
 
708
                $this->xh[$parser]['headers']           = array();
 
709
                $this->xh[$parser]['stack']                     = array();
 
710
                $this->xh[$parser]['valuestack']        = array();
 
711
                $this->xh[$parser]['isf_reason']        = 0;
 
712
 
 
713
                xml_set_object($parser, $this);
 
714
                xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
 
715
                xml_set_element_handler($parser, 'open_tag', 'closing_tag');
 
716
                xml_set_character_data_handler($parser, 'character_data');
 
717
                //xml_set_default_handler($parser, 'default_handler');
 
718
 
 
719
 
 
720
                //-------------------------------------
 
721
                //  GET HEADERS
 
722
                //-------------------------------------
 
723
 
 
724
                $lines = explode("\r\n", $data);
 
725
                while (($line = array_shift($lines)))
 
726
                {
 
727
                        if (strlen($line) < 1)
 
728
                        {
 
729
                                break;
 
730
                        }
 
731
                        $this->xh[$parser]['headers'][] = $line;
 
732
                }
 
733
                $data = implode("\r\n", $lines);
 
734
 
 
735
 
 
736
                //-------------------------------------
 
737
                //  PARSE XML DATA
 
738
                //-------------------------------------
 
739
 
 
740
                if ( ! xml_parse($parser, $data, count($data)))
 
741
                {
 
742
                        $errstr = sprintf('XML error: %s at line %d',
 
743
                                        xml_error_string(xml_get_error_code($parser)),
 
744
                                        xml_get_current_line_number($parser));
 
745
                        //error_log($errstr);
 
746
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
 
747
                        xml_parser_free($parser);
 
748
                        return $r;
 
749
                }
 
750
                xml_parser_free($parser);
 
751
 
 
752
                // ---------------------------------------
 
753
                //  Got Ourselves Some Badness, It Seems
 
754
                // ---------------------------------------
 
755
 
 
756
                if ($this->xh[$parser]['isf'] > 1)
 
757
                {
 
758
                        if ($this->debug === TRUE)
 
759
                        {
 
760
                                echo "---Invalid Return---\n";
 
761
                                echo $this->xh[$parser]['isf_reason'];
 
762
                                echo "---Invalid Return---\n\n";
 
763
                        }
 
764
 
 
765
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 
766
                        return $r;
 
767
                }
 
768
                elseif ( ! is_object($this->xh[$parser]['value']))
 
769
                {
 
770
                        $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 
771
                        return $r;
 
772
                }
 
773
 
 
774
                //-------------------------------------
 
775
                //  DISPLAY XML CONTENT for DEBUGGING
 
776
                //-------------------------------------
 
777
 
 
778
                if ($this->debug === TRUE)
 
779
                {
 
780
                        echo "<pre>";
 
781
 
 
782
                        if (count($this->xh[$parser]['headers'] > 0))
 
783
                        {
 
784
                                echo "---HEADERS---\n";
 
785
                                foreach ($this->xh[$parser]['headers'] as $header)
 
786
                                {
 
787
                                        echo "$header\n";
 
788
                                }
 
789
                                echo "---END HEADERS---\n\n";
 
790
                        }
 
791
 
 
792
                        echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
 
793
 
 
794
                        echo "---PARSED---\n" ;
 
795
                        var_dump($this->xh[$parser]['value']);
 
796
                        echo "\n---END PARSED---</pre>";
 
797
                }
 
798
 
 
799
                //-------------------------------------
 
800
                //  SEND RESPONSE
 
801
                //-------------------------------------
 
802
 
 
803
                $v = $this->xh[$parser]['value'];
 
804
 
 
805
                if ($this->xh[$parser]['isf'])
 
806
                {
 
807
                        $errno_v = $v->me['struct']['faultCode'];
 
808
                        $errstr_v = $v->me['struct']['faultString'];
 
809
                        $errno = $errno_v->scalarval();
 
810
 
 
811
                        if ($errno == 0)
 
812
                        {
 
813
                                // FAULT returned, errno needs to reflect that
 
814
                                $errno = -1;
 
815
                        }
 
816
 
 
817
                        $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
 
818
                }
 
819
                else
 
820
                {
 
821
                        $r = new XML_RPC_Response($v);
 
822
                }
 
823
 
 
824
                $r->headers = $this->xh[$parser]['headers'];
 
825
                return $r;
 
826
        }
 
827
 
 
828
        // ------------------------------------
 
829
        //  Begin Return Message Parsing section
 
830
        // ------------------------------------
 
831
 
 
832
        // quick explanation of components:
 
833
        //   ac - used to accumulate values
 
834
        //   isf - used to indicate a fault
 
835
        //   lv - used to indicate "looking for a value": implements
 
836
        //              the logic to allow values with no types to be strings
 
837
        //   params - used to store parameters in method calls
 
838
        //   method - used to store method name
 
839
        //       stack - array with parent tree of the xml element,
 
840
        //                       used to validate the nesting of elements
 
841
 
 
842
        //-------------------------------------
 
843
        //  Start Element Handler
 
844
        //-------------------------------------
 
845
 
 
846
        function open_tag($the_parser, $name, $attrs)
 
847
        {
 
848
                // If invalid nesting, then return
 
849
                if ($this->xh[$the_parser]['isf'] > 1) return;
 
850
 
 
851
                // Evaluate and check for correct nesting of XML elements
 
852
 
 
853
                if (count($this->xh[$the_parser]['stack']) == 0)
 
854
                {
 
855
                        if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
 
856
                        {
 
857
                                $this->xh[$the_parser]['isf'] = 2;
 
858
                                $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
 
859
                                return;
 
860
                        }
 
861
                }
 
862
                else
 
863
                {
 
864
                        // not top level element: see if parent is OK
 
865
                        if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
 
866
                        {
 
867
                                $this->xh[$the_parser]['isf'] = 2;
 
868
                                $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
 
869
                                return;
 
870
                        }
 
871
                }
 
872
 
 
873
                switch($name)
 
874
                {
 
875
                        case 'STRUCT':
 
876
                        case 'ARRAY':
 
877
                                // Creates array for child elements
 
878
 
 
879
                                $cur_val = array('value' => array(),
 
880
                                                                 'type'  => $name);
 
881
 
 
882
                                array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
 
883
                        break;
 
884
                        case 'METHODNAME':
 
885
                        case 'NAME':
 
886
                                $this->xh[$the_parser]['ac'] = '';
 
887
                        break;
 
888
                        case 'FAULT':
 
889
                                $this->xh[$the_parser]['isf'] = 1;
 
890
                        break;
 
891
                        case 'PARAM':
 
892
                                $this->xh[$the_parser]['value'] = NULL;
 
893
                        break;
 
894
                        case 'VALUE':
 
895
                                $this->xh[$the_parser]['vt'] = 'value';
 
896
                                $this->xh[$the_parser]['ac'] = '';
 
897
                                $this->xh[$the_parser]['lv'] = 1;
 
898
                        break;
 
899
                        case 'I4':
 
900
                        case 'INT':
 
901
                        case 'STRING':
 
902
                        case 'BOOLEAN':
 
903
                        case 'DOUBLE':
 
904
                        case 'DATETIME.ISO8601':
 
905
                        case 'BASE64':
 
906
                                if ($this->xh[$the_parser]['vt'] != 'value')
 
907
                                {
 
908
                                        //two data elements inside a value: an error occurred!
 
909
                                        $this->xh[$the_parser]['isf'] = 2;
 
910
                                        $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
 
911
                                        return;
 
912
                                }
 
913
 
 
914
                                $this->xh[$the_parser]['ac'] = '';
 
915
                        break;
 
916
                        case 'MEMBER':
 
917
                                // Set name of <member> to nothing to prevent errors later if no <name> is found
 
918
                                $this->xh[$the_parser]['valuestack'][0]['name'] = '';
 
919
 
 
920
                                // Set NULL value to check to see if value passed for this param/member
 
921
                                $this->xh[$the_parser]['value'] = NULL;
 
922
                        break;
 
923
                        case 'DATA':
 
924
                        case 'METHODCALL':
 
925
                        case 'METHODRESPONSE':
 
926
                        case 'PARAMS':
 
927
                                // valid elements that add little to processing
 
928
                        break;
 
929
                        default:
 
930
                                /// An Invalid Element is Found, so we have trouble
 
931
                                $this->xh[$the_parser]['isf'] = 2;
 
932
                                $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
 
933
                        break;
 
934
                }
 
935
 
 
936
                // Add current element name to stack, to allow validation of nesting
 
937
                array_unshift($this->xh[$the_parser]['stack'], $name);
 
938
 
 
939
                if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
 
940
        }
 
941
        // END
 
942
 
 
943
 
 
944
        //-------------------------------------
 
945
        //  End Element Handler
 
946
        //-------------------------------------
 
947
 
 
948
        function closing_tag($the_parser, $name)
 
949
        {
 
950
                if ($this->xh[$the_parser]['isf'] > 1) return;
 
951
 
 
952
                // Remove current element from stack and set variable
 
953
                // NOTE: If the XML validates, then we do not have to worry about
 
954
                // the opening and closing of elements.  Nesting is checked on the opening
 
955
                // tag so we be safe there as well.
 
956
 
 
957
                $curr_elem = array_shift($this->xh[$the_parser]['stack']);
 
958
 
 
959
                switch($name)
 
960
                {
 
961
                        case 'STRUCT':
 
962
                        case 'ARRAY':
 
963
                                $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
 
964
                                $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
 
965
                                $this->xh[$the_parser]['vt']    = strtolower($name);
 
966
                        break;
 
967
                        case 'NAME':
 
968
                                $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
 
969
                        break;
 
970
                        case 'BOOLEAN':
 
971
                        case 'I4':
 
972
                        case 'INT':
 
973
                        case 'STRING':
 
974
                        case 'DOUBLE':
 
975
                        case 'DATETIME.ISO8601':
 
976
                        case 'BASE64':
 
977
                                $this->xh[$the_parser]['vt'] = strtolower($name);
 
978
 
 
979
                                if ($name == 'STRING')
 
980
                                {
 
981
                                        $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 
982
                                }
 
983
                                elseif ($name=='DATETIME.ISO8601')
 
984
                                {
 
985
                                        $this->xh[$the_parser]['vt']    = $this->xmlrpcDateTime;
 
986
                                        $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 
987
                                }
 
988
                                elseif ($name=='BASE64')
 
989
                                {
 
990
                                        $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
 
991
                                }
 
992
                                elseif ($name=='BOOLEAN')
 
993
                                {
 
994
                                        // Translated BOOLEAN values to TRUE AND FALSE
 
995
                                        if ($this->xh[$the_parser]['ac'] == '1')
 
996
                                        {
 
997
                                                $this->xh[$the_parser]['value'] = TRUE;
 
998
                                        }
 
999
                                        else
 
1000
                                        {
 
1001
                                                $this->xh[$the_parser]['value'] = FALSE;
 
1002
                                        }
 
1003
                                }
 
1004
                                elseif ($name=='DOUBLE')
 
1005
                                {
 
1006
                                        // we have a DOUBLE
 
1007
                                        // we must check that only 0123456789-.<space> are characters here
 
1008
                                        if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
 
1009
                                        {
 
1010
                                                $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
 
1011
                                        }
 
1012
                                        else
 
1013
                                        {
 
1014
                                                $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
 
1015
                                        }
 
1016
                                }
 
1017
                                else
 
1018
                                {
 
1019
                                        // we have an I4/INT
 
1020
                                        // we must check that only 0123456789-<space> are characters here
 
1021
                                        if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
 
1022
                                        {
 
1023
                                                $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
 
1024
                                        }
 
1025
                                        else
 
1026
                                        {
 
1027
                                                $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
 
1028
                                        }
 
1029
                                }
 
1030
                                $this->xh[$the_parser]['ac'] = '';
 
1031
                                $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
 
1032
                        break;
 
1033
                        case 'VALUE':
 
1034
                                // This if() detects if no scalar was inside <VALUE></VALUE>
 
1035
                                if ($this->xh[$the_parser]['vt']=='value')
 
1036
                                {
 
1037
                                        $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 
1038
                                        $this->xh[$the_parser]['vt']    = $this->xmlrpcString;
 
1039
                                }
 
1040
 
 
1041
                                // build the XML-RPC value out of the data received, and substitute it
 
1042
                                $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
 
1043
 
 
1044
                                if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
 
1045
                                {
 
1046
                                        // Array
 
1047
                                        $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
 
1048
                                }
 
1049
                                else
 
1050
                                {
 
1051
                                        // Struct
 
1052
                                        $this->xh[$the_parser]['value'] = $temp;
 
1053
                                }
 
1054
                        break;
 
1055
                        case 'MEMBER':
 
1056
                                $this->xh[$the_parser]['ac']='';
 
1057
 
 
1058
                                // If value add to array in the stack for the last element built
 
1059
                                if ($this->xh[$the_parser]['value'])
 
1060
                                {
 
1061
                                        $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
 
1062
                                }
 
1063
                        break;
 
1064
                        case 'DATA':
 
1065
                                $this->xh[$the_parser]['ac']='';
 
1066
                        break;
 
1067
                        case 'PARAM':
 
1068
                                if ($this->xh[$the_parser]['value'])
 
1069
                                {
 
1070
                                        $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
 
1071
                                }
 
1072
                        break;
 
1073
                        case 'METHODNAME':
 
1074
                                $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
 
1075
                        break;
 
1076
                        case 'PARAMS':
 
1077
                        case 'FAULT':
 
1078
                        case 'METHODCALL':
 
1079
                        case 'METHORESPONSE':
 
1080
                                // We're all good kids with nuthin' to do
 
1081
                        break;
 
1082
                        default:
 
1083
                                // End of an Invalid Element.  Taken care of during the opening tag though
 
1084
                        break;
 
1085
                }
 
1086
        }
 
1087
 
 
1088
        //-------------------------------------
 
1089
        //  Parses Character Data
 
1090
        //-------------------------------------
 
1091
 
 
1092
        function character_data($the_parser, $data)
 
1093
        {
 
1094
                if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
 
1095
 
 
1096
                // If a value has not been found
 
1097
                if ($this->xh[$the_parser]['lv'] != 3)
 
1098
                {
 
1099
                        if ($this->xh[$the_parser]['lv'] == 1)
 
1100
                        {
 
1101
                                $this->xh[$the_parser]['lv'] = 2; // Found a value
 
1102
                        }
 
1103
 
 
1104
                        if ( ! @isset($this->xh[$the_parser]['ac']))
 
1105
                        {
 
1106
                                $this->xh[$the_parser]['ac'] = '';
 
1107
                        }
 
1108
 
 
1109
                        $this->xh[$the_parser]['ac'] .= $data;
 
1110
                }
 
1111
        }
 
1112
 
 
1113
 
 
1114
        function addParam($par) { $this->params[]=$par; }
 
1115
 
 
1116
        function output_parameters($array=FALSE)
 
1117
        {
 
1118
                $CI =& get_instance();
 
1119
                
 
1120
                if ($array !== FALSE && is_array($array))
 
1121
                {
 
1122
                        while (list($key) = each($array))
 
1123
                        {
 
1124
                                if (is_array($array[$key]))
 
1125
                                {
 
1126
                                        $array[$key] = $this->output_parameters($array[$key]);
 
1127
                                }
 
1128
                                else
 
1129
                                {
 
1130
                                        // 'bits' is for the MetaWeblog API image bits
 
1131
                                        // @todo - this needs to be made more general purpose
 
1132
                                        $array[$key] = ($key == 'bits' OR $this->xss_clean == FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
 
1133
                                }
 
1134
                        }
 
1135
 
 
1136
                        $parameters = $array;
 
1137
                }
 
1138
                else
 
1139
                {
 
1140
                        $parameters = array();
 
1141
 
 
1142
                        for ($i = 0; $i < count($this->params); $i++)
 
1143
                        {
 
1144
                                $a_param = $this->decode_message($this->params[$i]);
 
1145
 
 
1146
                                if (is_array($a_param))
 
1147
                                {
 
1148
                                        $parameters[] = $this->output_parameters($a_param);
 
1149
                                }
 
1150
                                else
 
1151
                                {
 
1152
                                        $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
 
1153
                                }
 
1154
                        }
 
1155
                }
 
1156
 
 
1157
                return $parameters;
 
1158
        }
 
1159
 
 
1160
 
 
1161
        function decode_message($param)
 
1162
        {
 
1163
                $kind = $param->kindOf();
 
1164
 
 
1165
                if ($kind == 'scalar')
 
1166
                {
 
1167
                        return $param->scalarval();
 
1168
                }
 
1169
                elseif ($kind == 'array')
 
1170
                {
 
1171
                        reset($param->me);
 
1172
                        list($a,$b) = each($param->me);
 
1173
 
 
1174
                        $arr = array();
 
1175
 
 
1176
                        for($i = 0; $i < count($b); $i++)
 
1177
                        {
 
1178
                                $arr[] = $this->decode_message($param->me['array'][$i]);
 
1179
                        }
 
1180
 
 
1181
                        return $arr;
 
1182
                }
 
1183
                elseif ($kind == 'struct')
 
1184
                {
 
1185
                        reset($param->me['struct']);
 
1186
 
 
1187
                        $arr = array();
 
1188
 
 
1189
                        while (list($key,$value) = each($param->me['struct']))
 
1190
                        {
 
1191
                                $arr[$key] = $this->decode_message($value);
 
1192
                        }
 
1193
 
 
1194
                        return $arr;
 
1195
                }
 
1196
        }
 
1197
 
 
1198
} // End XML_RPC_Messages class
 
1199
 
 
1200
 
 
1201
 
 
1202
/**
 
1203
 * XML-RPC Values class
 
1204
 *
 
1205
 * @category    XML-RPC
 
1206
 * @author              ExpressionEngine Dev Team
 
1207
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
 
1208
 */
 
1209
class XML_RPC_Values extends CI_Xmlrpc
 
1210
{
 
1211
        var $me         = array();
 
1212
        var $mytype     = 0;
 
1213
 
 
1214
        public function __construct($val=-1, $type='')
 
1215
        {
 
1216
                parent::__construct();
 
1217
 
 
1218
                if ($val != -1 OR $type != '')
 
1219
                {
 
1220
                        $type = $type == '' ? 'string' : $type;
 
1221
 
 
1222
                        if ($this->xmlrpcTypes[$type] == 1)
 
1223
                        {
 
1224
                                $this->addScalar($val,$type);
 
1225
                        }
 
1226
                        elseif ($this->xmlrpcTypes[$type] == 2)
 
1227
                        {
 
1228
                                $this->addArray($val);
 
1229
                        }
 
1230
                        elseif ($this->xmlrpcTypes[$type] == 3)
 
1231
                        {
 
1232
                                $this->addStruct($val);
 
1233
                        }
 
1234
                }
 
1235
        }
 
1236
 
 
1237
        function addScalar($val, $type='string')
 
1238
        {
 
1239
                $typeof = $this->xmlrpcTypes[$type];
 
1240
 
 
1241
                if ($this->mytype==1)
 
1242
                {
 
1243
                        echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
 
1244
                        return 0;
 
1245
                }
 
1246
 
 
1247
                if ($typeof != 1)
 
1248
                {
 
1249
                        echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
 
1250
                        return 0;
 
1251
                }
 
1252
 
 
1253
                if ($type == $this->xmlrpcBoolean)
 
1254
                {
 
1255
                        if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))
 
1256
                        {
 
1257
                                $val = 1;
 
1258
                        }
 
1259
                        else
 
1260
                        {
 
1261
                                $val=0;
 
1262
                        }
 
1263
                }
 
1264
 
 
1265
                if ($this->mytype == 2)
 
1266
                {
 
1267
                        // adding to an array here
 
1268
                        $ar = $this->me['array'];
 
1269
                        $ar[] = new XML_RPC_Values($val, $type);
 
1270
                        $this->me['array'] = $ar;
 
1271
                }
 
1272
                else
 
1273
                {
 
1274
                        // a scalar, so set the value and remember we're scalar
 
1275
                        $this->me[$type] = $val;
 
1276
                        $this->mytype = $typeof;
 
1277
                }
 
1278
                return 1;
 
1279
        }
 
1280
 
 
1281
        function addArray($vals)
 
1282
        {
 
1283
                if ($this->mytype != 0)
 
1284
                {
 
1285
                        echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
 
1286
                        return 0;
 
1287
                }
 
1288
 
 
1289
                $this->mytype = $this->xmlrpcTypes['array'];
 
1290
                $this->me['array'] = $vals;
 
1291
                return 1;
 
1292
        }
 
1293
 
 
1294
        function addStruct($vals)
 
1295
        {
 
1296
                if ($this->mytype != 0)
 
1297
                {
 
1298
                        echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
 
1299
                        return 0;
 
1300
                }
 
1301
                $this->mytype = $this->xmlrpcTypes['struct'];
 
1302
                $this->me['struct'] = $vals;
 
1303
                return 1;
 
1304
        }
 
1305
 
 
1306
        function kindOf()
 
1307
        {
 
1308
                switch($this->mytype)
 
1309
                {
 
1310
                        case 3:
 
1311
                                return 'struct';
 
1312
                                break;
 
1313
                        case 2:
 
1314
                                return 'array';
 
1315
                                break;
 
1316
                        case 1:
 
1317
                                return 'scalar';
 
1318
                                break;
 
1319
                        default:
 
1320
                                return 'undef';
 
1321
                }
 
1322
        }
 
1323
 
 
1324
        function serializedata($typ, $val)
 
1325
        {
 
1326
                $rs = '';
 
1327
 
 
1328
                switch($this->xmlrpcTypes[$typ])
 
1329
                {
 
1330
                        case 3:
 
1331
                                // struct
 
1332
                                $rs .= "<struct>\n";
 
1333
                                reset($val);
 
1334
                                while (list($key2, $val2) = each($val))
 
1335
                                {
 
1336
                                        $rs .= "<member>\n<name>{$key2}</name>\n";
 
1337
                                        $rs .= $this->serializeval($val2);
 
1338
                                        $rs .= "</member>\n";
 
1339
                                }
 
1340
                                $rs .= '</struct>';
 
1341
                        break;
 
1342
                        case 2:
 
1343
                                // array
 
1344
                                $rs .= "<array>\n<data>\n";
 
1345
                                for($i=0; $i < count($val); $i++)
 
1346
                                {
 
1347
                                        $rs .= $this->serializeval($val[$i]);
 
1348
                                }
 
1349
                                $rs.="</data>\n</array>\n";
 
1350
                                break;
 
1351
                        case 1:
 
1352
                                // others
 
1353
                                switch ($typ)
 
1354
                                {
 
1355
                                        case $this->xmlrpcBase64:
 
1356
                                                $rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
 
1357
                                        break;
 
1358
                                        case $this->xmlrpcBoolean:
 
1359
                                                $rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
 
1360
                                        break;
 
1361
                                        case $this->xmlrpcString:
 
1362
                                                $rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
 
1363
                                        break;
 
1364
                                        default:
 
1365
                                                $rs .= "<{$typ}>{$val}</{$typ}>\n";
 
1366
                                        break;
 
1367
                                }
 
1368
                        default:
 
1369
                        break;
 
1370
                }
 
1371
                return $rs;
 
1372
        }
 
1373
 
 
1374
        function serialize_class()
 
1375
        {
 
1376
                return $this->serializeval($this);
 
1377
        }
 
1378
 
 
1379
        function serializeval($o)
 
1380
        {
 
1381
                $ar = $o->me;
 
1382
                reset($ar);
 
1383
 
 
1384
                list($typ, $val) = each($ar);
 
1385
                $rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";
 
1386
                return $rs;
 
1387
        }
 
1388
 
 
1389
        function scalarval()
 
1390
        {
 
1391
                reset($this->me);
 
1392
                list($a,$b) = each($this->me);
 
1393
                return $b;
 
1394
        }
 
1395
 
 
1396
 
 
1397
        //-------------------------------------
 
1398
        // Encode time in ISO-8601 form.
 
1399
        //-------------------------------------
 
1400
 
 
1401
        // Useful for sending time in XML-RPC
 
1402
 
 
1403
        function iso8601_encode($time, $utc=0)
 
1404
        {
 
1405
                if ($utc == 1)
 
1406
                {
 
1407
                        $t = strftime("%Y%m%dT%H:%i:%s", $time);
 
1408
                }
 
1409
                else
 
1410
                {
 
1411
                        if (function_exists('gmstrftime'))
 
1412
                                $t = gmstrftime("%Y%m%dT%H:%i:%s", $time);
 
1413
                        else
 
1414
                                $t = strftime("%Y%m%dT%H:%i:%s", $time - date('Z'));
 
1415
                }
 
1416
                return $t;
 
1417
        }
 
1418
 
 
1419
}
 
1420
// END XML_RPC_Values Class
 
1421
 
 
1422
/* End of file Xmlrpc.php */
 
1423
/* Location: ./system/libraries/Xmlrpc.php */
 
 
b'\\ No newline at end of file'