XML_RPC_Message Class Reference

Inheritance diagram for XML_RPC_Message:
Collaboration diagram for XML_RPC_Message:

List of all members.


Public Member Functions

 XML_RPC_Message ($method, $pars=0)
 createPayload ()
 parseResponse ($fp)
 open_tag ($the_parser, $name, $attrs)
 closing_tag ($the_parser, $name)
 character_data ($the_parser, $data)
 addParam ($par)
 output_parameters ($array=FALSE)
 decode_message ($param)

Public Attributes

 $payload
 $method_name
 $params = array()
 $xh = array()

Detailed Description

Definition at line 610 of file Xmlrpc.php.


Member Function Documentation

XML_RPC_Message::addParam ( par  ) 

Definition at line 1114 of file Xmlrpc.php.

01114 { $this->params[]=$par; }

XML_RPC_Message::character_data ( the_parser,
data 
)

Definition at line 1092 of file Xmlrpc.php.

References CI_Xmlrpc::$data.

01093         {
01094                 if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
01095                 
01096                 // If a value has not been found
01097                 if ($this->xh[$the_parser]['lv'] != 3)
01098                 {
01099                         if ($this->xh[$the_parser]['lv'] == 1)
01100                         {
01101                                 $this->xh[$the_parser]['lv'] = 2; // Found a value
01102                         }
01103                                 
01104                         if( ! @isset($this->xh[$the_parser]['ac']))
01105                         {
01106                                 $this->xh[$the_parser]['ac'] = '';
01107                         }
01108                                 
01109                         $this->xh[$the_parser]['ac'] .= $data;
01110                 }
01111         }

XML_RPC_Message::closing_tag ( the_parser,
name 
)

Definition at line 948 of file Xmlrpc.php.

00949         {
00950                 if ($this->xh[$the_parser]['isf'] > 1) return;
00951                 
00952                 // Remove current element from stack and set variable
00953                 // NOTE: If the XML validates, then we do not have to worry about
00954                 // the opening and closing of elements.  Nesting is checked on the opening
00955                 // tag so we be safe there as well.
00956                 
00957                 $curr_elem = array_shift($this->xh[$the_parser]['stack']);
00958         
00959                 switch($name)
00960                 {
00961                         case 'STRUCT':
00962                         case 'ARRAY':
00963                                 $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
00964                                 $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
00965                                 $this->xh[$the_parser]['vt']    = strtolower($name);
00966                         break;
00967                         case 'NAME':
00968                                 $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
00969                         break;
00970                         case 'BOOLEAN':
00971                         case 'I4':
00972                         case 'INT':
00973                         case 'STRING':
00974                         case 'DOUBLE':
00975                         case 'DATETIME.ISO8601':
00976                         case 'BASE64':
00977                                 $this->xh[$the_parser]['vt'] = strtolower($name);
00978                                 
00979                                 if ($name == 'STRING')
00980                                 {
00981                                         $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
00982                                 }
00983                                 elseif ($name=='DATETIME.ISO8601')
00984                                 {
00985                                         $this->xh[$the_parser]['vt']    = $this->xmlrpcDateTime;
00986                                         $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
00987                                 }
00988                                 elseif ($name=='BASE64')
00989                                 {
00990                                         $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
00991                                 }
00992                                 elseif ($name=='BOOLEAN')
00993                                 {
00994                                         // Translated BOOLEAN values to TRUE AND FALSE
00995                                         if ($this->xh[$the_parser]['ac'] == '1')
00996                                         {
00997                                                 $this->xh[$the_parser]['value'] = TRUE;
00998                                         }
00999                                         else
01000                                         {
01001                                                 $this->xh[$the_parser]['value'] = FALSE;
01002                                         }
01003                                 }
01004                                 elseif ($name=='DOUBLE')
01005                                 {
01006                                         // we have a DOUBLE
01007                                         // we must check that only 0123456789-.<space> are characters here
01008                                         if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
01009                                         {
01010                                                 $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
01011                                         }
01012                                         else
01013                                         {
01014                                                 $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
01015                                         }
01016                                 }
01017                                 else
01018                                 {
01019                                         // we have an I4/INT
01020                                         // we must check that only 0123456789-<space> are characters here
01021                                         if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
01022                                         {
01023                                                 $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
01024                                         }
01025                                         else
01026                                         {
01027                                                 $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
01028                                         }
01029                                 }
01030                                 $this->xh[$the_parser]['ac'] = '';
01031                                 $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
01032                         break;
01033                         case 'VALUE':
01034                                 // This if() detects if no scalar was inside <VALUE></VALUE>
01035                                 if ($this->xh[$the_parser]['vt']=='value')
01036                                 {
01037                                         $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
01038                                         $this->xh[$the_parser]['vt']    = $this->xmlrpcString;
01039                                 }
01040                                 
01041                                 // build the XML-RPC value out of the data received, and substitute it
01042                                 $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
01043                                 
01044                                 if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
01045                                 {
01046                                         // Array
01047                                         $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
01048                                 }
01049                                 else
01050                                 {
01051                                         // Struct
01052                                         $this->xh[$the_parser]['value'] = $temp;
01053                                 }
01054                         break;
01055                         case 'MEMBER':
01056                                 $this->xh[$the_parser]['ac']='';
01057                                 
01058                                 // If value add to array in the stack for the last element built
01059                                 if ($this->xh[$the_parser]['value'])
01060                                 {
01061                                         $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
01062                                 }
01063                         break;
01064                         case 'DATA':
01065                                 $this->xh[$the_parser]['ac']='';
01066                         break;
01067                         case 'PARAM':
01068                                 if ($this->xh[$the_parser]['value'])
01069                                 {
01070                                         $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
01071                                 }
01072                         break;
01073                         case 'METHODNAME':
01074                                 $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
01075                         break;
01076                         case 'PARAMS':
01077                         case 'FAULT':
01078                         case 'METHODCALL':
01079                         case 'METHORESPONSE':
01080                                 // We're all good kids with nuthin' to do
01081                         break;
01082                         default:
01083                                 // End of an Invalid Element.  Taken care of during the opening tag though
01084                         break;
01085                 }
01086         }

XML_RPC_Message::createPayload (  ) 

Definition at line 636 of file Xmlrpc.php.

00637         {
00638                 $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";
00639                 $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
00640                 $this->payload .= "<params>\r\n";
00641                 
00642                 for($i=0; $i<sizeof($this->params); $i++)
00643                 {
00644                         // $p = XML_RPC_Values
00645                         $p = $this->params[$i];
00646                         $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
00647                 }
00648                 
00649                 $this->payload .= "</params>\r\n</methodCall>\r\n";
00650         }

XML_RPC_Message::decode_message ( param  ) 

Definition at line 1159 of file Xmlrpc.php.

Referenced by output_parameters().

01160         {
01161                 $kind = $param->kindOf();
01162 
01163                 if($kind == 'scalar')
01164                 {
01165                         return $param->scalarval();
01166                 }
01167                 elseif($kind == 'array')
01168                 {
01169                         reset($param->me);
01170                         list($a,$b) = each($param->me);
01171                         
01172                         $arr = array();
01173 
01174                         for($i = 0; $i < sizeof($b); $i++)
01175                         {
01176                                 $arr[] = $this->decode_message($param->me['array'][$i]);
01177                         }
01178                         
01179                         return $arr;
01180                 }
01181                 elseif($kind == 'struct')
01182                 {
01183                         reset($param->me['struct']);
01184                         
01185                         $arr = array();
01186 
01187                         while(list($key,$value) = each($param->me['struct']))
01188                         {
01189                                 $arr[$key] = $this->decode_message($value);
01190                         }
01191                         
01192                         return $arr;
01193                 }
01194         }

Here is the caller graph for this function:

XML_RPC_Message::open_tag ( the_parser,
name,
attrs 
)

An Invalid Element is Found, so we have trouble

Definition at line 846 of file Xmlrpc.php.

00847         {
00848                 // If invalid nesting, then return
00849                 if ($this->xh[$the_parser]['isf'] > 1) return;
00850                 
00851                 // Evaluate and check for correct nesting of XML elements
00852                 
00853                 if (count($this->xh[$the_parser]['stack']) == 0)
00854                 {
00855                         if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
00856                         {
00857                                 $this->xh[$the_parser]['isf'] = 2;
00858                                 $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
00859                                 return;
00860                         }
00861                 }
00862                 else
00863                 {
00864                         // not top level element: see if parent is OK
00865                         if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
00866                         {
00867                                 $this->xh[$the_parser]['isf'] = 2;
00868                                 $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
00869                                 return;
00870                         }
00871                 }
00872                 
00873                 switch($name)
00874                 {
00875                         case 'STRUCT':
00876                         case 'ARRAY':
00877                                 // Creates array for child elements
00878                                 
00879                                 $cur_val = array('value' => array(),
00880                                                                  'type'  => $name);
00881                                                                 
00882                                 array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
00883                         break;
00884                         case 'METHODNAME':
00885                         case 'NAME':
00886                                 $this->xh[$the_parser]['ac'] = '';
00887                         break;
00888                         case 'FAULT':
00889                                 $this->xh[$the_parser]['isf'] = 1;
00890                         break;
00891                         case 'PARAM':
00892                                 $this->xh[$the_parser]['value'] = null;
00893                         break;
00894                         case 'VALUE':
00895                                 $this->xh[$the_parser]['vt'] = 'value';
00896                                 $this->xh[$the_parser]['ac'] = '';
00897                                 $this->xh[$the_parser]['lv'] = 1;
00898                         break;
00899                         case 'I4':
00900                         case 'INT':
00901                         case 'STRING':
00902                         case 'BOOLEAN':
00903                         case 'DOUBLE':
00904                         case 'DATETIME.ISO8601':
00905                         case 'BASE64':
00906                                 if ($this->xh[$the_parser]['vt'] != 'value')
00907                                 {
00908                                         //two data elements inside a value: an error occurred!
00909                                         $this->xh[$the_parser]['isf'] = 2;
00910                                         $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
00911                                         return;
00912                                 }
00913                                 
00914                                 $this->xh[$the_parser]['ac'] = '';
00915                         break;
00916                         case 'MEMBER':
00917                                 // Set name of <member> to nothing to prevent errors later if no <name> is found
00918                                 $this->xh[$the_parser]['valuestack'][0]['name'] = '';
00919                                 
00920                                 // Set NULL value to check to see if value passed for this param/member
00921                                 $this->xh[$the_parser]['value'] = null;
00922                         break;
00923                         case 'DATA':
00924                         case 'METHODCALL':
00925                         case 'METHODRESPONSE':
00926                         case 'PARAMS':
00927                                 // valid elements that add little to processing
00928                         break;
00929                         default:
00930                                 /// An Invalid Element is Found, so we have trouble
00931                                 $this->xh[$the_parser]['isf'] = 2;
00932                                 $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
00933                         break;
00934                 }
00935                 
00936                 // Add current element name to stack, to allow validation of nesting
00937                 array_unshift($this->xh[$the_parser]['stack'], $name);
00938 
00939                 if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
00940         }

XML_RPC_Message::output_parameters ( array = FALSE  ) 

Definition at line 1116 of file Xmlrpc.php.

References $CI, decode_message(), and get_instance().

01117         {
01118                 $CI =& get_instance();  
01119 
01120                 if ($array !== FALSE && is_array($array))
01121                 {
01122                         while (list($key) = each($array))
01123                         {
01124                                 if (is_array($array[$key]))
01125                                 {
01126                                         $array[$key] = $this->output_parameters($array[$key]);
01127                                 }
01128                                 else
01129                                 {
01130                                         $array[$key] = $CI->input->xss_clean($array[$key]);
01131                                 }
01132                         }
01133                         
01134                         $parameters = $array;
01135                 }
01136                 else
01137                 {
01138                         $parameters = array();
01139                 
01140                         for ($i = 0; $i < sizeof($this->params); $i++)
01141                         {
01142                                 $a_param = $this->decode_message($this->params[$i]);
01143                                 
01144                                 if (is_array($a_param))
01145                                 {
01146                                         $parameters[] = $this->output_parameters($a_param);
01147                                 }
01148                                 else
01149                                 {
01150                                         $parameters[] = $CI->input->xss_clean($a_param);
01151                                 }
01152                         }       
01153                 }
01154                 
01155                 return $parameters;
01156         }

Here is the call graph for this function:

XML_RPC_Message::parseResponse ( fp  ) 

Definition at line 656 of file Xmlrpc.php.

References CI_Xmlrpc::$data.

00657         {
00658                 $data = '';
00659                 
00660                 while($datum = fread($fp, 4096))
00661                 {
00662                         $data .= $datum;
00663                 }
00664                 
00665                 //-------------------------------------
00666                 //  DISPLAY HTTP CONTENT for DEBUGGING
00667                 //-------------------------------------
00668                 
00669                 if ($this->debug === TRUE)
00670                 {
00671                         echo "<pre>";
00672                         echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
00673                         echo "</pre>";
00674                 }
00675                 
00676                 //-------------------------------------
00677                 //  Check for data
00678                 //-------------------------------------
00679 
00680                 if($data == "")
00681                 {
00682                         error_log($this->xmlrpcstr['no_data']);
00683                         $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
00684                         return $r;
00685                 }
00686                 
00687                 
00688                 //-------------------------------------
00689                 //  Check for HTTP 200 Response
00690                 //-------------------------------------
00691                 
00692                 if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
00693                 {
00694                         $errstr= substr($data, 0, strpos($data, "\n")-1);
00695                         $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
00696                         return $r;
00697                 }
00698                 
00699                 //-------------------------------------
00700                 //  Create and Set Up XML Parser
00701                 //-------------------------------------
00702         
00703                 $parser = xml_parser_create($this->xmlrpc_defencoding);
00704 
00705                 $this->xh[$parser]                               = array();
00706                 $this->xh[$parser]['isf']                = 0;
00707                 $this->xh[$parser]['ac']                 = '';
00708                 $this->xh[$parser]['headers']    = array();
00709                 $this->xh[$parser]['stack']              = array();
00710                 $this->xh[$parser]['valuestack'] = array();
00711                 $this->xh[$parser]['isf_reason'] = 0;
00712 
00713                 xml_set_object($parser, $this);
00714                 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
00715                 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
00716                 xml_set_character_data_handler($parser, 'character_data');
00717                 //xml_set_default_handler($parser, 'default_handler');
00718 
00719 
00720                 //-------------------------------------
00721                 //  GET HEADERS
00722                 //-------------------------------------
00723                 
00724                 $lines = explode("\r\n", $data);
00725                 while (($line = array_shift($lines)))
00726                 {
00727                         if (strlen($line) < 1)
00728                         {
00729                                 break;
00730                         }
00731                         $this->xh[$parser]['headers'][] = $line;
00732                 }
00733                 $data = implode("\r\n", $lines);
00734                 
00735                 
00736                 //-------------------------------------
00737                 //  PARSE XML DATA
00738                 //-------------------------------------         
00739 
00740                 if ( ! xml_parse($parser, $data, sizeof($data)))
00741                 {
00742                         $errstr = sprintf('XML error: %s at line %d',
00743                                         xml_error_string(xml_get_error_code($parser)),
00744                                         xml_get_current_line_number($parser));
00745                         //error_log($errstr);
00746                         $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
00747                         xml_parser_free($parser);
00748                         return $r;
00749                 }
00750                 xml_parser_free($parser);
00751                 
00752                 // ---------------------------------------
00753                 //  Got Ourselves Some Badness, It Seems
00754                 // ---------------------------------------
00755                 
00756                 if ($this->xh[$parser]['isf'] > 1)
00757                 {
00758                         if ($this->debug === TRUE)
00759                         {
00760                                 echo "---Invalid Return---\n";
00761                                 echo $this->xh[$parser]['isf_reason'];
00762                                 echo "---Invalid Return---\n\n";
00763                         }
00764                                 
00765                         $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
00766                         return $r;
00767                 }
00768                 elseif ( ! is_object($this->xh[$parser]['value']))
00769                 {
00770                         $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
00771                         return $r;
00772                 }
00773                 
00774                 //-------------------------------------
00775                 //  DISPLAY XML CONTENT for DEBUGGING
00776                 //-------------------------------------         
00777                 
00778                 if ($this->debug === TRUE)
00779                 {
00780                         echo "<pre>";
00781                         
00782                         if (count($this->xh[$parser]['headers'] > 0))
00783                         {
00784                                 echo "---HEADERS---\n";
00785                                 foreach ($this->xh[$parser]['headers'] as $header)
00786                                 {
00787                                         echo "$header\n";
00788                                 }
00789                                 echo "---END HEADERS---\n\n";
00790                         }
00791                         
00792                         echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
00793                         
00794                         echo "---PARSED---\n" ;
00795                         var_dump($this->xh[$parser]['value']);
00796                         echo "\n---END PARSED---</pre>";
00797                 }
00798                 
00799                 //-------------------------------------
00800                 //  SEND RESPONSE
00801                 //-------------------------------------
00802                 
00803                 $v = $this->xh[$parser]['value'];
00804                         
00805                 if ($this->xh[$parser]['isf'])
00806                 {
00807                         $errno_v = $v->me['struct']['faultCode'];
00808                         $errstr_v = $v->me['struct']['faultString'];
00809                         $errno = $errno_v->scalarval();
00810 
00811                         if ($errno == 0)
00812                         {
00813                                 // FAULT returned, errno needs to reflect that
00814                                 $errno = -1;
00815                         }
00816 
00817                         $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
00818                 }
00819                 else
00820                 {
00821                         $r = new XML_RPC_Response($v);
00822                 }
00823 
00824                 $r->headers = $this->xh[$parser]['headers'];
00825                 return $r;
00826         }

XML_RPC_Message::XML_RPC_Message ( method,
pars = 0 
)

Definition at line 617 of file Xmlrpc.php.

References CI_Xmlrpc::$method, and CI_Xmlrpc::CI_Xmlrpc().

00618         {
00619                 parent::CI_Xmlrpc();
00620                 
00621                 $this->method_name = $method;
00622                 if (is_array($pars) && sizeof($pars) > 0)
00623                 {
00624                         for($i=0; $i<sizeof($pars); $i++)
00625                         {
00626                                 // $pars[$i] = XML_RPC_Values
00627                                 $this->params[] = $pars[$i];
00628                         }
00629                 }
00630         }

Here is the call graph for this function:


Member Data Documentation

XML_RPC_Message::$method_name

Definition at line 613 of file Xmlrpc.php.

XML_RPC_Message::$params = array()

Definition at line 614 of file Xmlrpc.php.

XML_RPC_Message::$payload

Definition at line 612 of file Xmlrpc.php.

XML_RPC_Message::$xh = array()

Definition at line 615 of file Xmlrpc.php.


The documentation for this class was generated from the following file: