• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

payment/bmf/lib/SOAP/class.ilBMFClient.php

Go to the documentation of this file.
00001 <?php
00025 require_once dirname(__FILE__).'/class.ilBMFValue.php';
00026 require_once dirname(__FILE__).'/class.ilBMFBase.php';
00027 require_once dirname(__FILE__).'/class.ilBMFTransport.php';
00028 require_once dirname(__FILE__).'/class.ilBMFWSDL.php';
00029 require_once dirname(__FILE__).'/class.ilBMFFault.php';
00030 require_once dirname(__FILE__).'/class.ilBMFParser.php';
00031 
00032 // Arnaud: the following code was taken from DataObject and adapted to suit
00033 
00034 // this will be horrifically slow!!!!
00035 // NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer
00036 // these two are BC/FC handlers for call in PHP4/5
00037 
00038 if (!class_exists('ilBMFClient_Overload')) {
00039     if (substr(phpversion(), 0, 1) == 5) {
00040         class ilBMFClient_Overload extends ilBMFBase {
00041             function __call($method, $args)
00042             {
00043                 $return = null;
00044                 $this->_call($method, $args, $return);
00045                 return $return;
00046             }
00047         }
00048     } else {
00049         if (!function_exists('clone')) {
00050             eval('function clone($t) { return $t; }');
00051         }
00052         eval('
00053             class ilBMFClient_Overload extends ilBMFBase {
00054                 function __call($method, $args, &$return)
00055                 {
00056                     return $this->_call($method, $args, $return);
00057                 }
00058             }');
00059     }
00060 }
00061 
00081 class ilBMFClient extends ilBMFClient_Overload
00082 {
00098     var $_endpoint = '';
00099 
00105     var $_portName = '';
00106 
00112     var $__endpointType = '';
00113 
00119     var $xml;
00120 
00126     var $wire;
00127     var $__last_request = null;
00128     var $__last_response = null;
00129 
00135     var $__options = array('trace'=>0);
00136 
00142     var $_encoding = SOAP_DEFAULT_ENCODING;
00143 
00149     var $headersOut = null;
00150 
00156     var $headersIn = null;
00157 
00163     var $__proxy_params = array();
00164 
00165     var $_soap_transport = null;
00166 
00178     function ilBMFClient($endpoint, $wsdl = false, $portName = false,
00179                          $proxy_params = array())
00180     {
00181         parent::ilBMFBase('Client');
00182 
00183         $this->_endpoint = $endpoint;
00184         $this->_portName = $portName;
00185         $this->__proxy_params = $proxy_params;
00186 
00187         // This hack should perhaps be removed as it might cause unexpected
00188         // behaviour.
00189         $wsdl = $wsdl
00190             ? $wsdl
00191             : strtolower(substr($endpoint, -4)) == 'wsdl';
00192 
00193         // make values
00194         if ($wsdl) {
00195             $this->__endpointType = 'wsdl';
00196             // instantiate wsdl class
00197             $this->_wsdl =& new ilBMFWSDL($this->_endpoint,
00198                                           $this->__proxy_params);
00199             if ($this->_wsdl->fault) {
00200                 $this->_raiseSoapFault($this->_wsdl->fault);
00201             }
00202         }
00203     }
00204 
00205     function _reset()
00206     {
00207         $this->xml = null;
00208         $this->wire = null;
00209         $this->__last_request = null;
00210         $this->__last_response = null;
00211         $this->headersIn = null;
00212         $this->headersOut = null;
00213     }
00214 
00226     function setEncoding($encoding)
00227     {
00228         if (in_array($encoding, $this->_encodings)) {
00229             $this->_encoding = $encoding;
00230             return;
00231         }
00232         return $this->_raiseSoapFault('Invalid Encoding');
00233     }
00234 
00245     function addHeader(&$soap_value)
00246     {
00247         // Add a new header to the message.
00248         if (is_a($soap_value, 'ilBMFHeader')) {
00249             $this->headersOut[] =& $soap_value;
00250         } elseif (is_array($soap_value)) {
00251             // name, value, namespace, mustunderstand, actor
00252             $this->headersOut[] =& new ilBMFHeader($soap_value[0],
00253                                                    null,
00254                                                    $soap_value[1],
00255                                                    $soap_value[2],
00256                                                    $soap_value[3]);;
00257         } else {
00258             $this->_raiseSoapFault('Invalid parameter provided to addHeader().  Must be an array or a SOAP_Header.');
00259         }
00260     }
00261 
00290     function &call($method, &$params, $namespace = false, $soapAction = false)
00291     {
00292         $this->headersIn = null;
00293         $this->__last_request = null;
00294         $this->__last_response = null;
00295         $this->wire = null;
00296         $this->xml = null;
00297 
00298         $soap_data =& $this->__generate($method, $params, $namespace, $soapAction);
00299         if (PEAR::isError($soap_data)) {
00300             $fault =& $this->_raiseSoapFault($soap_data);
00301             return $fault;
00302         }
00303 
00304         // __generate() may have changed the endpoint if the WSDL has more
00305         // than one service, so we need to see if we need to generate a new
00306         // transport to hook to a different URI.  Since the transport protocol
00307         // can also change, we need to get an entirely new object.  This could
00308         // probably be optimized.
00309         if (!$this->_soap_transport ||
00310             $this->_endpoint != $this->_soap_transport->url) {
00311             $this->_soap_transport =& ilBMFTransport::getTransport($this->_endpoint);
00312             if (PEAR::isError($this->_soap_transport)) {
00313                 $fault =& $this->_soap_transport;
00314                 $this->_soap_transport = null;
00315                 $fault =& $this->_raiseSoapFault($fault);
00316                 return $fault;
00317             }
00318         }
00319         $this->_soap_transport->encoding = $this->_encoding;
00320 
00321         // Send the message.
00322         $transport_options = array_merge_recursive($this->__proxy_params,
00323                                                    $this->__options);
00324         $this->xml = $this->_soap_transport->send($soap_data, $transport_options);
00325 
00326         // Save the wire information for debugging.
00327         if ($this->__options['trace'] > 0) {
00328             $this->__last_request =& $this->_soap_transport->outgoing_payload;
00329             $this->__last_response =& $this->_soap_transport->incoming_payload;
00330             $this->wire = $this->__get_wire();
00331         }
00332         if ($this->_soap_transport->fault) {
00333             $fault =& $this->_raiseSoapFault($this->xml);
00334             return $fault;
00335         }
00336 
00337         $this->__attachments =& $this->_soap_transport->attachments;
00338         $this->__result_encoding = $this->_soap_transport->result_encoding;
00339 
00340         if (isset($this->__options['result']) &&
00341             $this->__options['result'] != 'parse') {
00342             return $this->xml;
00343         }
00344 
00345         $result = &$this->__parse($this->xml, $this->__result_encoding, $this->__attachments);
00346 
00347         return $result;
00348     }
00349 
00368     function setOpt($category, $option, $value = null)
00369     {
00370         if (!is_null($value)) {
00371             if (!isset($this->__options[$category])) {
00372                 $this->__options[$category] = array();
00373             }
00374             $this->__options[$category][$option] = $value;
00375         } else {
00376             $this->__options[$category] = $option;
00377         }
00378     }
00379 
00399     function _call($method, $params, &$return_value)
00400     {
00401         // Overloading lowercases the method name, we need to look into the
00402         // wsdl and try to find the correct method name to get the correct
00403         // case for the call.
00404         if ($this->_wsdl) {
00405             $this->_wsdl->matchMethod($method);
00406         }
00407 
00408         $return_value =& $this->call($method, $params);
00409 
00410         return true;
00411     }
00412 
00413     function &__getlastrequest()
00414     {
00415         $request =& $this->__last_request;
00416         return $request;
00417     }
00418 
00419     function &__getlastresponse()
00420     {
00421         $response =& $this->__last_response;
00422         return $response;
00423     }
00424 
00425     function __use($use)
00426     {
00427         $this->__options['use'] = $use;
00428     }
00429 
00430     function __style($style)
00431     {
00432         $this->__options['style'] = $style;
00433     }
00434 
00435     function __trace($level)
00436     {
00437         $this->__options['trace'] = $level;
00438     }
00439 
00440     function &__generate($method, &$params, $namespace = false,
00441                          $soapAction = false)
00442     {
00443         $this->fault = null;
00444         $this->__options['input']='parse';
00445         $this->__options['result']='parse';
00446         $this->__options['parameters'] = false;
00447 
00448         if ($params && gettype($params) != 'array') {
00449             $params = array($params);
00450         }
00451 
00452         if (gettype($namespace) == 'array') {
00453             foreach ($namespace as $optname => $opt) {
00454                 $this->__options[strtolower($optname)] = $opt;
00455             }
00456             if (isset($this->__options['namespace'])) {
00457                 $namespace = $this->__options['namespace'];
00458             } else {
00459                 $namespace = false;
00460             }
00461         } else {
00462             // We'll place $soapAction into our array for usage in the
00463             // transport.
00464             $this->__options['soapaction'] = $soapAction;
00465             $this->__options['namespace'] = $namespace;
00466         }
00467 
00468         if ($this->__endpointType == 'wsdl') {
00469             $this->_setSchemaVersion($this->_wsdl->xsd);
00470 
00471             // Get port name.
00472             if (!$this->_portName) {
00473                 $this->_portName = $this->_wsdl->getPortName($method);
00474             }
00475             if (PEAR::isError($this->_portName)) {
00476                 $fault =& $this->_raiseSoapFault($this->_portName);
00477                 return $fault;
00478             }
00479 
00480             // Get endpoint.
00481             $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
00482             if (PEAR::isError($this->_endpoint)) {
00483                 $fault =& $this->_raiseSoapFault($this->_endpoint);
00484                 return $fault;
00485             }
00486 
00487             // Get operation data.
00488             $opData = $this->_wsdl->getOperationData($this->_portName, $method);
00489 
00490             if (PEAR::isError($opData)) {
00491                 $fault =& $this->_raiseSoapFault($opData);
00492                 return $fault;
00493             }
00494             $namespace = $opData['namespace'];
00495             $this->__options['style'] = $opData['style'];
00496             $this->__options['use'] = $opData['input']['use'];
00497             $this->__options['soapaction'] = $opData['soapAction'];
00498 
00499             // Set input parameters.
00500             if ($this->__options['input'] == 'parse') {
00501                 $this->__options['parameters'] = $opData['parameters'];
00502                 $nparams = array();
00503                 if (isset($opData['input']['parts']) &&
00504                     count($opData['input']['parts'])) {
00505                     $i = 0;
00506                     foreach ($opData['input']['parts'] as $name => $part) {
00507                         $xmlns = '';
00508                         $attrs = array();
00509                         // Is the name a complex type?
00510                         if (isset($part['element'])) {
00511                             $xmlns = $this->_wsdl->namespaces[$part['namespace']];
00512                             $part = $this->_wsdl->elements[$part['namespace']][$part['type']];
00513                             $name = $part['name'];
00514                         }
00515                         if (isset($params[$name]) ||
00516                             $this->_wsdl->getDataHandler($name, $part['namespace'])) {
00517                             $nparams[$name] =& $params[$name];
00518                         } else {
00519                             // We now force an associative array for
00520                             // parameters if using WSDL.
00521                             $fault =& $this->_raiseSoapFault("The named parameter $name is not in the call parameters.");
00522                             return $fault;
00523                         }
00524                         if (gettype($nparams[$name]) != 'object' ||
00525                             !is_a($nparams[$name], 'ilBMFValue')) {
00526                             // Type is likely a qname, split it apart, and get
00527                             // the type namespace from WSDL.
00528                             $qname =& new QName($part['type']);
00529                             if ($qname->ns) {
00530                                 $type_namespace = $this->_wsdl->namespaces[$qname->ns];
00531                             } elseif (isset($part['namespace'])) {
00532                                 $type_namespace = $this->_wsdl->namespaces[$part['namespace']];
00533                             } else {
00534                                 $type_namespace = null;
00535                             }
00536                             $qname->namespace = $type_namespace;
00537                             $type = $qname->name;
00538                             $pqname = $name;
00539                             if ($xmlns) {
00540                                 $pqname = '{' . $xmlns . '}' . $name;
00541                             }
00542                             $nparams[$name] =& new ilBMFValue($pqname,
00543                                                               $qname->fqn(),
00544                                                               $nparams[$name],
00545                                                               $attrs);
00546                         } else {
00547                             // WSDL fixups to the SOAP value.
00548                         }
00549                     }
00550                 }
00551                 $params =& $nparams;
00552                 unset($nparams);
00553             }
00554         } else {
00555             $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
00556         }
00557 
00558         // Serialize the message.
00559         $this->_section5 = (!isset($this->__options['use']) ||
00560                             $this->__options['use'] != 'literal');
00561 
00562         if (!isset($this->__options['style']) ||
00563             $this->__options['style'] == 'rpc') {
00564             $this->__options['style'] = 'rpc';
00565             $this->docparams = true;
00566             $mqname =& new QName($method, $namespace);
00567             $methodValue =& new ilBMFValue($mqname->fqn(), 'Struct', $params);
00568             $soap_msg = $this->_makeEnvelope($methodValue,
00569                                              $this->headersOut,
00570                                              $this->_encoding,
00571                                              $this->__options);
00572         } else {
00573             if (!$params) {
00574                 $mqname =& new QName($method, $namespace);
00575                 $mynull = null;
00576                 $params =& new ilBMFValue($mqname->fqn(), 'Struct', $mynull);
00577             } elseif ($this->__options['input'] == 'parse') {
00578                 if (is_array($params)) {
00579                     $nparams = array();
00580                     $keys = array_keys($params);
00581                     foreach ($keys as $k) {
00582                         if (gettype($params[$k]) != 'object') {
00583                             $nparams[] =& new ilBMFValue($k,
00584                                                          false,
00585                                                          $params[$k]);
00586                         } else {
00587                             $nparams[] =& $params[$k];
00588                         }
00589                     }
00590                     $params =& $nparams;
00591                 }
00592                 if ($this->__options['parameters']) {
00593                     $mqname =& new QName($method, $namespace);
00594                     $params =& new ilBMFValue($mqname->fqn(),
00595                                               'Struct',
00596                                               $params);
00597                 }
00598             }
00599             $soap_msg = $this->_makeEnvelope($params,
00600                                              $this->headersOut,
00601                                              $this->_encoding,
00602                                              $this->__options);
00603         }
00604         unset($this->headersOut);
00605 
00606         if (PEAR::isError($soap_msg)) {
00607             $fault =& $this->_raiseSoapFault($soap_msg);
00608             return $fault;
00609         }
00610 
00611         // Handle MIME or DIME encoding.
00612         // TODO: DIME encoding should move to the transport, do it here for
00613         // now and for ease of getting it done.
00614         if (count($this->__attachments)) {
00615             if ((isset($this->__options['attachments']) &&
00616                  $this->__options['attachments'] == 'Mime') ||
00617                 isset($this->__options['Mime'])) {
00618                 $soap_msg =& $this->_makeMimeMessage($soap_msg,
00619                                                      $this->_encoding);
00620             } else {
00621                 // default is dime
00622                 $soap_msg =& $this->_makeDIMEMessage($soap_msg,
00623                                                      $this->_encoding);
00624                 $this->__options['headers']['Content-Type'] = 'application/dime';
00625             }
00626             if (PEAR::isError($soap_msg)) {
00627                 $fault =& $this->_raiseSoapFault($soap_msg);
00628                 return $fault;
00629             }
00630         }
00631 
00632         // Instantiate client.
00633         if (is_array($soap_msg)) {
00634             $soap_data =& $soap_msg['body'];
00635             if (count($soap_msg['headers'])) {
00636                 if (isset($this->__options['headers'])) {
00637                     $this->__options['headers'] = array_merge($this->__options['headers'], $soap_msg['headers']);
00638                 } else {
00639                     $this->__options['headers'] = $soap_msg['headers'];
00640                 }
00641             }
00642         } else {
00643             $soap_data =& $soap_msg;
00644         }
00645 
00646         return $soap_data;
00647     }
00648 
00649     function &__parse(&$response, $encoding, &$attachments)
00650     {
00651         // Parse the response.
00652         $response =& new ilBMFParser($response, $encoding, $attachments);
00653         if ($response->fault) {
00654             $fault =& $this->_raiseSoapFault($response->fault);
00655             return $fault;
00656         }
00657 
00658         // Return array of parameters.
00659         $return =& $response->getResponse();
00660         $headers =& $response->getHeaders();
00661         if ($headers) {
00662             $this->headersIn =& $this->__decodeResponse($headers, false);
00663         }
00664 
00665         $decoded = &$this->__decodeResponse($return);
00666         return $decoded;
00667     }
00668 
00669     function &__decodeResponse(&$response, $shift = true)
00670     {
00671         if (!$response) {
00672             $decoded = null;
00673             return $decoded;
00674         }
00675 
00676         // Check for valid response.
00677         if (PEAR::isError($response)) {
00678             $fault =& $this->_raiseSoapFault($response);
00679             return $fault;
00680         } elseif (!is_a($response, 'ilbmfvalue')) {
00681             $fault =& $this->_raiseSoapFault("Didn't get ilBMFValue object back from client");
00682             return $fault;
00683         }
00684 
00685         // Decode to native php datatype.
00686         $returnArray =& $this->_decode($response);
00687 
00688         // Fault?
00689         if (PEAR::isError($returnArray)) {
00690             $fault =& $this->_raiseSoapFault($returnArray);
00691             return $fault;
00692         }
00693 
00694         if (is_object($returnArray) &&
00695             strcasecmp(get_class($returnArray), 'stdClass') == 0) {
00696             $returnArray = get_object_vars($returnArray);
00697         }
00698         if (is_array($returnArray)) {
00699             if (isset($returnArray['faultcode']) ||
00700                 isset($returnArray['SOAP-ENV:faultcode'])) {
00701                 $faultcode = $faultstring = $faultdetail = $faultactor = '';
00702                 foreach ($returnArray as $k => $v) {
00703                     if (stristr($k, 'faultcode')) $faultcode = $v;
00704                     if (stristr($k, 'faultstring')) $faultstring = $v;
00705                     if (stristr($k, 'detail')) $faultdetail = $v;
00706                     if (stristr($k, 'faultactor')) $faultactor = $v;
00707                 }
00708                 $fault =& $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode);
00709                 return $fault;
00710             }
00711             // Return array of return values.
00712             if ($shift && count($returnArray) == 1) {
00713                 $decoded = array_shift($returnArray);
00714                 return $decoded;
00715             }
00716             return $returnArray;
00717         }
00718         return $returnArray;
00719     }
00720 
00721     function __get_wire()
00722     {
00723         if ($this->__options['trace'] > 0 &&
00724             ($this->__last_request || $this->__last_response)) {
00725             return "OUTGOING:\n\n" .
00726                 $this->__last_request .
00727                 "\n\nINCOMING\n\n" .
00728                 preg_replace("/></",">\r\n<", $this->__last_response);
00729         }
00730 
00731         return null;
00732     }
00733 
00734 }

Generated on Fri Dec 13 2013 17:56:54 for ILIAS Release_3_9_x_branch .rev 46835 by  doxygen 1.7.1