/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/Xmlrpcs.php

  • Committer: gustav.hartvigsson at gmail
  • Date: 2013-04-03 11:52:56 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20130403115256-sz6zermzoom4lifc
Ignored .DS_Store files.

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
 
if ( ! class_exists('CI_Xmlrpc'))
22
 
{
23
 
        show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');
24
 
}
25
 
 
26
 
// ------------------------------------------------------------------------
27
 
 
28
 
/**
29
 
 * XML-RPC server class
30
 
 *
31
 
 * @package             CodeIgniter
32
 
 * @subpackage  Libraries
33
 
 * @category    XML-RPC
34
 
 * @author              ExpressionEngine Dev Team
35
 
 * @link                http://codeigniter.com/user_guide/libraries/xmlrpc.html
36
 
 */
37
 
class CI_Xmlrpcs extends CI_Xmlrpc
38
 
{
39
 
        var $methods            = array();      //array of methods mapped to function names and signatures
40
 
        var $debug_msg          = '';           // Debug Message
41
 
        var $system_methods = array();  // XML RPC Server methods
42
 
        var $controller_obj;
43
 
 
44
 
        var $object                     = FALSE;
45
 
 
46
 
        /**
47
 
         * Constructor
48
 
         */
49
 
        public function __construct($config=array())
50
 
        {
51
 
                parent::__construct();
52
 
                $this->set_system_methods();
53
 
 
54
 
                if (isset($config['functions']) && is_array($config['functions']))
55
 
                {
56
 
                        $this->methods = array_merge($this->methods, $config['functions']);
57
 
                }
58
 
 
59
 
                log_message('debug', "XML-RPC Server Class Initialized");
60
 
        }
61
 
 
62
 
        // --------------------------------------------------------------------
63
 
 
64
 
        /**
65
 
         * Initialize Prefs and Serve
66
 
         *
67
 
         * @access      public
68
 
         * @param       mixed
69
 
         * @return      void
70
 
         */
71
 
        function initialize($config=array())
72
 
        {
73
 
                if (isset($config['functions']) && is_array($config['functions']))
74
 
                {
75
 
                        $this->methods = array_merge($this->methods, $config['functions']);
76
 
                }
77
 
 
78
 
                if (isset($config['debug']))
79
 
                {
80
 
                        $this->debug = $config['debug'];
81
 
                }
82
 
 
83
 
                if (isset($config['object']) && is_object($config['object']))
84
 
                {
85
 
                        $this->object = $config['object'];
86
 
                }
87
 
 
88
 
                if (isset($config['xss_clean']))
89
 
                {
90
 
                        $this->xss_clean = $config['xss_clean'];
91
 
                }
92
 
        }
93
 
 
94
 
        // --------------------------------------------------------------------
95
 
 
96
 
        /**
97
 
         * Setting of System Methods
98
 
         *
99
 
         * @access      public
100
 
         * @return      void
101
 
         */
102
 
        function set_system_methods()
103
 
        {
104
 
                $this->methods = array(
105
 
                                        'system.listMethods'     => array(
106
 
                                                                                                        'function' => 'this.listMethods',
107
 
                                                                                                        'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
108
 
                                                                                                        'docstring' => 'Returns an array of available methods on this server'),
109
 
                                        'system.methodHelp'              => array(
110
 
                                                                                                        'function' => 'this.methodHelp',
111
 
                                                                                                        'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
112
 
                                                                                                        'docstring' => 'Returns a documentation string for the specified method'),
113
 
                                        'system.methodSignature' => array(
114
 
                                                                                                        'function' => 'this.methodSignature',
115
 
                                                                                                        'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
116
 
                                                                                                        'docstring' => 'Returns an array describing the return type and required parameters of a method'),
117
 
                                        'system.multicall'               => array(
118
 
                                                                                                'function' => 'this.multicall',
119
 
                                                                                                'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
120
 
                                                                                                'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
121
 
                                        );
122
 
        }
123
 
 
124
 
        // --------------------------------------------------------------------
125
 
 
126
 
        /**
127
 
         * Main Server Function
128
 
         *
129
 
         * @access      public
130
 
         * @return      void
131
 
         */
132
 
        function serve()
133
 
        {
134
 
                $r = $this->parseRequest();
135
 
                $payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";
136
 
                $payload .= $this->debug_msg;
137
 
                $payload .= $r->prepare_response();
138
 
 
139
 
                header("Content-Type: text/xml");
140
 
                header("Content-Length: ".strlen($payload));
141
 
                exit($payload);
142
 
        }
143
 
 
144
 
        // --------------------------------------------------------------------
145
 
 
146
 
        /**
147
 
         * Add Method to Class
148
 
         *
149
 
         * @access      public
150
 
         * @param       string  method name
151
 
         * @param       string  function
152
 
         * @param       string  signature
153
 
         * @param       string  docstring
154
 
         * @return      void
155
 
         */
156
 
        function add_to_map($methodname, $function, $sig, $doc)
157
 
        {
158
 
                $this->methods[$methodname] = array(
159
 
                        'function'  => $function,
160
 
                        'signature' => $sig,
161
 
                        'docstring' => $doc
162
 
                );
163
 
        }
164
 
 
165
 
        // --------------------------------------------------------------------
166
 
 
167
 
        /**
168
 
         * Parse Server Request
169
 
         *
170
 
         * @access      public
171
 
         * @param       string  data
172
 
         * @return      object  xmlrpc response
173
 
         */
174
 
        function parseRequest($data='')
175
 
        {
176
 
                global $HTTP_RAW_POST_DATA;
177
 
 
178
 
                //-------------------------------------
179
 
                //  Get Data
180
 
                //-------------------------------------
181
 
 
182
 
                if ($data == '')
183
 
                {
184
 
                        $data = $HTTP_RAW_POST_DATA;
185
 
                }
186
 
 
187
 
                //-------------------------------------
188
 
                //  Set up XML Parser
189
 
                //-------------------------------------
190
 
 
191
 
                $parser = xml_parser_create($this->xmlrpc_defencoding);
192
 
                $parser_object = new XML_RPC_Message("filler");
193
 
 
194
 
                $parser_object->xh[$parser]                                     = array();
195
 
                $parser_object->xh[$parser]['isf']                      = 0;
196
 
                $parser_object->xh[$parser]['isf_reason']       = '';
197
 
                $parser_object->xh[$parser]['params']           = array();
198
 
                $parser_object->xh[$parser]['stack']            = array();
199
 
                $parser_object->xh[$parser]['valuestack']       = array();
200
 
                $parser_object->xh[$parser]['method']           = '';
201
 
 
202
 
                xml_set_object($parser, $parser_object);
203
 
                xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
204
 
                xml_set_element_handler($parser, 'open_tag', 'closing_tag');
205
 
                xml_set_character_data_handler($parser, 'character_data');
206
 
                //xml_set_default_handler($parser, 'default_handler');
207
 
 
208
 
 
209
 
                //-------------------------------------
210
 
                //  PARSE + PROCESS XML DATA
211
 
                //-------------------------------------
212
 
 
213
 
                if ( ! xml_parse($parser, $data, 1))
214
 
                {
215
 
                        // return XML error as a faultCode
216
 
                        $r = new XML_RPC_Response(0,
217
 
                        $this->xmlrpcerrxml + xml_get_error_code($parser),
218
 
                        sprintf('XML error: %s at line %d',
219
 
                                xml_error_string(xml_get_error_code($parser)),
220
 
                                xml_get_current_line_number($parser)));
221
 
                        xml_parser_free($parser);
222
 
                }
223
 
                elseif ($parser_object->xh[$parser]['isf'])
224
 
                {
225
 
                        return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
226
 
                }
227
 
                else
228
 
                {
229
 
                        xml_parser_free($parser);
230
 
 
231
 
                        $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
232
 
                        $plist='';
233
 
 
234
 
                        for ($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
235
 
                        {
236
 
                                if ($this->debug === TRUE)
237
 
                                {
238
 
                                        $plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
239
 
                                }
240
 
 
241
 
                                $m->addParam($parser_object->xh[$parser]['params'][$i]);
242
 
                        }
243
 
 
244
 
                        if ($this->debug === TRUE)
245
 
                        {
246
 
                                echo "<pre>";
247
 
                                echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
248
 
                                echo "</pre>";
249
 
                        }
250
 
 
251
 
                        $r = $this->_execute($m);
252
 
                }
253
 
 
254
 
                //-------------------------------------
255
 
                //  SET DEBUGGING MESSAGE
256
 
                //-------------------------------------
257
 
 
258
 
                if ($this->debug === TRUE)
259
 
                {
260
 
                        $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
261
 
                }
262
 
 
263
 
                return $r;
264
 
        }
265
 
 
266
 
        // --------------------------------------------------------------------
267
 
 
268
 
        /**
269
 
         * Executes the Method
270
 
         *
271
 
         * @access      protected
272
 
         * @param       object
273
 
         * @return      mixed
274
 
         */
275
 
        function _execute($m)
276
 
        {
277
 
                $methName = $m->method_name;
278
 
 
279
 
                // Check to see if it is a system call
280
 
                $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;
281
 
 
282
 
                if ($this->xss_clean == FALSE)
283
 
                {
284
 
                        $m->xss_clean = FALSE;
285
 
                }
286
 
 
287
 
                //-------------------------------------
288
 
                //  Valid Method
289
 
                //-------------------------------------
290
 
 
291
 
                if ( ! isset($this->methods[$methName]['function']))
292
 
                {
293
 
                        return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
294
 
                }
295
 
 
296
 
                //-------------------------------------
297
 
                //  Check for Method (and Object)
298
 
                //-------------------------------------
299
 
 
300
 
                $method_parts = explode(".", $this->methods[$methName]['function']);
301
 
                $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;
302
 
 
303
 
                if ($system_call === TRUE)
304
 
                {
305
 
                        if ( ! is_callable(array($this,$method_parts['1'])))
306
 
                        {
307
 
                                return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
308
 
                        }
309
 
                }
310
 
                else
311
 
                {
312
 
                        if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))
313
 
                        {
314
 
                                return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
315
 
                        }
316
 
                        elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
317
 
                        {
318
 
                                return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
319
 
                        }
320
 
                }
321
 
 
322
 
                //-------------------------------------
323
 
                //  Checking Methods Signature
324
 
                //-------------------------------------
325
 
 
326
 
                if (isset($this->methods[$methName]['signature']))
327
 
                {
328
 
                        $sig = $this->methods[$methName]['signature'];
329
 
                        for ($i=0; $i<count($sig); $i++)
330
 
                        {
331
 
                                $current_sig = $sig[$i];
332
 
 
333
 
                                if (count($current_sig) == count($m->params)+1)
334
 
                                {
335
 
                                        for ($n=0; $n < count($m->params); $n++)
336
 
                                        {
337
 
                                                $p = $m->params[$n];
338
 
                                                $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
339
 
 
340
 
                                                if ($pt != $current_sig[$n+1])
341
 
                                                {
342
 
                                                        $pno = $n+1;
343
 
                                                        $wanted = $current_sig[$n+1];
344
 
 
345
 
                                                        return new XML_RPC_Response(0,
346
 
                                                                $this->xmlrpcerr['incorrect_params'],
347
 
                                                                $this->xmlrpcstr['incorrect_params'] .
348
 
                                                                ": Wanted {$wanted}, got {$pt} at param {$pno})");
349
 
                                                }
350
 
                                        }
351
 
                                }
352
 
                        }
353
 
                }
354
 
 
355
 
                //-------------------------------------
356
 
                //  Calls the Function
357
 
                //-------------------------------------
358
 
 
359
 
                if ($objectCall === TRUE)
360
 
                {
361
 
                        if ($method_parts[0] == "this" && $system_call == TRUE)
362
 
                        {
363
 
                                return call_user_func(array($this, $method_parts[1]), $m);
364
 
                        }
365
 
                        else
366
 
                        {
367
 
                                if ($this->object === FALSE)
368
 
                                {
369
 
                                        $CI =& get_instance();
370
 
                                        return $CI->$method_parts['1']($m);
371
 
                                }
372
 
                                else
373
 
                                {
374
 
                                        return $this->object->$method_parts['1']($m);
375
 
                                        //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
376
 
                                }
377
 
                        }
378
 
                }
379
 
                else
380
 
                {
381
 
                        return call_user_func($this->methods[$methName]['function'], $m);
382
 
                }
383
 
        }
384
 
        
385
 
        // --------------------------------------------------------------------
386
 
 
387
 
        /**
388
 
         * Server Function:  List Methods
389
 
         *
390
 
         * @access      public
391
 
         * @param       mixed
392
 
         * @return      object
393
 
         */
394
 
        function listMethods($m)
395
 
        {
396
 
                $v = new XML_RPC_Values();
397
 
                $output = array();
398
 
 
399
 
                foreach ($this->methods as $key => $value)
400
 
                {
401
 
                        $output[] = new XML_RPC_Values($key, 'string');
402
 
                }
403
 
 
404
 
                foreach ($this->system_methods as $key => $value)
405
 
                {
406
 
                        $output[]= new XML_RPC_Values($key, 'string');
407
 
                }
408
 
 
409
 
                $v->addArray($output);
410
 
                return new XML_RPC_Response($v);
411
 
        }
412
 
        
413
 
        // --------------------------------------------------------------------
414
 
 
415
 
        /**
416
 
         * Server Function:  Return Signature for Method
417
 
         *
418
 
         * @access      public
419
 
         * @param       mixed
420
 
         * @return      object
421
 
         */
422
 
        function methodSignature($m)
423
 
        {
424
 
                $parameters = $m->output_parameters();
425
 
                $method_name = $parameters[0];
426
 
 
427
 
                if (isset($this->methods[$method_name]))
428
 
                {
429
 
                        if ($this->methods[$method_name]['signature'])
430
 
                        {
431
 
                                $sigs = array();
432
 
                                $signature = $this->methods[$method_name]['signature'];
433
 
 
434
 
                                for ($i=0; $i < count($signature); $i++)
435
 
                                {
436
 
                                        $cursig = array();
437
 
                                        $inSig = $signature[$i];
438
 
                                        for ($j=0; $j<count($inSig); $j++)
439
 
                                        {
440
 
                                                $cursig[]= new XML_RPC_Values($inSig[$j], 'string');
441
 
                                        }
442
 
                                        $sigs[]= new XML_RPC_Values($cursig, 'array');
443
 
                                }
444
 
                                $r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
445
 
                        }
446
 
                        else
447
 
                        {
448
 
                                $r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
449
 
                        }
450
 
                }
451
 
                else
452
 
                {
453
 
                        $r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
454
 
                }
455
 
                return $r;
456
 
        }
457
 
 
458
 
        // --------------------------------------------------------------------
459
 
 
460
 
        /**
461
 
         * Server Function:  Doc String for Method
462
 
         *
463
 
         * @access      public
464
 
         * @param       mixed
465
 
         * @return      object
466
 
         */
467
 
        function methodHelp($m)
468
 
        {
469
 
                $parameters = $m->output_parameters();
470
 
                $method_name = $parameters[0];
471
 
 
472
 
                if (isset($this->methods[$method_name]))
473
 
                {
474
 
                        $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
475
 
 
476
 
                        return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
477
 
                }
478
 
                else
479
 
                {
480
 
                        return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
481
 
                }
482
 
        }
483
 
        
484
 
        // --------------------------------------------------------------------
485
 
 
486
 
        /**
487
 
         * Server Function:  Multi-call
488
 
         *
489
 
         * @access      public
490
 
         * @param       mixed
491
 
         * @return      object
492
 
         */
493
 
        function multicall($m)
494
 
        {
495
 
                // Disabled
496
 
                return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
497
 
 
498
 
                $parameters = $m->output_parameters();
499
 
                $calls = $parameters[0];
500
 
 
501
 
                $result = array();
502
 
 
503
 
                foreach ($calls as $value)
504
 
                {
505
 
                        //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
506
 
 
507
 
                        $m = new XML_RPC_Message($value[0]);
508
 
                        $plist='';
509
 
 
510
 
                        for ($i=0; $i < count($value[1]); $i++)
511
 
                        {
512
 
                                $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
513
 
                        }
514
 
 
515
 
                        $attempt = $this->_execute($m);
516
 
 
517
 
                        if ($attempt->faultCode() != 0)
518
 
                        {
519
 
                                return $attempt;
520
 
                        }
521
 
 
522
 
                        $result[] = new XML_RPC_Values(array($attempt->value()), 'array');
523
 
                }
524
 
 
525
 
                return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
526
 
        }
527
 
 
528
 
        // --------------------------------------------------------------------
529
 
 
530
 
        /**
531
 
         *  Multi-call Function:  Error Handling
532
 
         *
533
 
         * @access      public
534
 
         * @param       mixed
535
 
         * @return      object
536
 
         */
537
 
        function multicall_error($err)
538
 
        {
539
 
                $str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
540
 
                $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
541
 
 
542
 
                $struct['faultCode'] = new XML_RPC_Values($code, 'int');
543
 
                $struct['faultString'] = new XML_RPC_Values($str, 'string');
544
 
 
545
 
                return new XML_RPC_Values($struct, 'struct');
546
 
        }
547
 
 
548
 
        // --------------------------------------------------------------------
549
 
 
550
 
        /**
551
 
         *  Multi-call Function:  Processes method
552
 
         *
553
 
         * @access      public
554
 
         * @param       mixed
555
 
         * @return      object
556
 
         */
557
 
        function do_multicall($call)
558
 
        {
559
 
                if ($call->kindOf() != 'struct')
560
 
                {
561
 
                        return $this->multicall_error('notstruct');
562
 
                }
563
 
                elseif ( ! $methName = $call->me['struct']['methodName'])
564
 
                {
565
 
                        return $this->multicall_error('nomethod');
566
 
                }
567
 
 
568
 
                list($scalar_type,$scalar_value)=each($methName->me);
569
 
                $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
570
 
 
571
 
                if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
572
 
                {
573
 
                        return $this->multicall_error('notstring');
574
 
                }
575
 
                elseif ($scalar_value == 'system.multicall')
576
 
                {
577
 
                        return $this->multicall_error('recursion');
578
 
                }
579
 
                elseif ( ! $params = $call->me['struct']['params'])
580
 
                {
581
 
                        return $this->multicall_error('noparams');
582
 
                }
583
 
                elseif ($params->kindOf() != 'array')
584
 
                {
585
 
                        return $this->multicall_error('notarray');
586
 
                }
587
 
 
588
 
                list($a,$b)=each($params->me);
589
 
                $numParams = count($b);
590
 
 
591
 
                $msg = new XML_RPC_Message($scalar_value);
592
 
                for ($i = 0; $i < $numParams; $i++)
593
 
                {
594
 
                        $msg->params[] = $params->me['array'][$i];
595
 
                }
596
 
 
597
 
                $result = $this->_execute($msg);
598
 
 
599
 
                if ($result->faultCode() != 0)
600
 
                {
601
 
                        return $this->multicall_error($result);
602
 
                }
603
 
 
604
 
                return new XML_RPC_Values(array($result->value()), 'array');
605
 
        }
606
 
 
607
 
}
608
 
// END XML_RPC_Server class
609
 
 
610
 
 
611
 
/* End of file Xmlrpcs.php */
612
 
/* Location: ./system/libraries/Xmlrpcs.php */
 
 
b'\\ No newline at end of file'