/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: Erik Wikström
  • Date: 2013-04-09 09:09:31 UTC
  • mfrom: (21 lenasys)
  • mto: (21.1.1 lenasys)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: wikxen@gmail.com-20130409090931-9jcs9kzg8et0912g
Remerged! Changed password hashes to VARCHAR(32)

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'