00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 require_once dirname(__FILE__).'/class.ilBMFValue.php';
00024 require_once dirname(__FILE__).'/class.ilBMFBase.php';
00025 require_once dirname(__FILE__).'/class.ilBMFTransport.php';
00026 require_once dirname(__FILE__).'/class.ilBMFWSDL.php';
00027 require_once dirname(__FILE__).'/class.ilBMFFault.php';
00028 require_once dirname(__FILE__).'/class.ilBMFParser.php';
00029
00030
00031
00032
00033
00034
00035
00036
00037 if (substr(phpversion(), 0, 1) == 5) {
00038 class ilBMFClient_Overload extends ilBMFBase
00039 {
00040 function __call($method, $args)
00041 {
00042 $return = null;
00043 $this->_call($method, $args, $return);
00044 return $return;
00045 }
00046 }
00047 } else {
00048 if (!function_exists('clone')) {
00049 eval('function clone($t) { return $t; }');
00050 }
00051 eval('
00052 class ilBMFClient_Overload extends ilBMFBase {
00053 function __call($method, $args, &$return) {
00054 return $this->_call($method, $args, $return);
00055 }
00056 }
00057 ');
00058 }
00059
00060
00078 class ilBMFClient extends ilBMFClient_Overload
00079 {
00095 var $_endpoint = '';
00096
00102 var $_portName = '';
00103
00104
00110 var $__endpointType = '';
00111
00117 var $xml;
00118 var $wire;
00119 var $__last_request = null;
00120 var $__last_response = null;
00121
00127 var $__options = array('trace'=>0);
00128
00134 var $_encoding = SOAP_DEFAULT_ENCODING;
00135
00136
00142 var $headersOut = null;
00148 var $headersIn = null;
00149
00155 var $__proxy_params = array();
00156
00157 var $_soap_transport = NULL;
00167 function ilBMFClient($endpoint, $wsdl = false, $portName = false, $proxy_params=array())
00168 {
00169 parent::ilBMFBase('Client');
00170 $this->_endpoint = $endpoint;
00171 $this->_portName = $portName;
00172 $this->__proxy_params = $proxy_params;
00173
00174 $wsdl = $wsdl?$wsdl:strcasecmp('wsdl',substr($endpoint,strlen($endpoint)-4))==0;
00175
00176
00177 if ($wsdl) {
00178 $this->__endpointType = 'wsdl';
00179
00180 $this->_wsdl =& new ilBMFWSDL($this->_endpoint, $this->__proxy_params);
00181 if ($this->_wsdl->fault) {
00182 $this->_raiseSoapFault($this->_wsdl->fault);
00183 }
00184 }
00185 }
00186
00187 function _reset()
00188 {
00189 $this->xml = NULL;
00190 $this->wire = NULL;
00191 $this->__last_request = NULL;
00192 $this->__last_response = NULL;
00193 $this->headersIn = NULL;
00194 $this->headersOut = NULL;
00195 }
00196
00206 function setEncoding($encoding)
00207 {
00208 if (in_array($encoding, $this->_encodings)) {
00209 $this->_encoding = $encoding;
00210 return NULL;
00211 }
00212 return $this->_raiseSoapFault('Invalid Encoding');
00213 }
00214
00224 function addHeader(&$soap_value)
00225 {
00226 # add a new header to the message
00227 if (is_a($soap_value,'soap_header')) {
00228 $this->headersOut[] =& $soap_value;
00229 } else if (gettype($soap_value) == 'array') {
00230
00231 $this->headersOut[] =& new SOAP_Header($soap_value[0], NULL, $soap_value[1], $soap_value[2], $soap_value[3]);;
00232 } else {
00233 $this->_raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header.");
00234 }
00235 }
00236
00265 function &call($method, &$params, $namespace = false, $soapAction = false)
00266 {
00267 $this->headersIn = null;
00268 $this->__last_request = null;
00269 $this->__last_response = null;
00270 $this->wire = null;
00271 $this->xml = NULL;
00272
00273 $soap_data =& $this->__generate($method, $params, $namespace, $soapAction);
00274 if (PEAR::isError($soap_data)) {
00275 return $this->_raiseSoapFault($soap_data);
00276 }
00277
00278
00279
00280
00281
00282
00283 if (!$this->_soap_transport || $this->_endpoint != $this->_soap_transport->url) {
00284 $this->_soap_transport =& ilBMFTransport::getTransport($this->_endpoint);
00285 if (PEAR::isError($this->_soap_transport)) {
00286 $fault =& $this->_soap_transport;
00287 $this->_soap_transport = NULL;
00288 return $this->_raiseSoapFault($fault);
00289 }
00290 }
00291 $this->_soap_transport->encoding = $this->_encoding;
00292
00293
00294 $transport_options = array_merge_recursive($this->__proxy_params, $this->__options);
00295 $this->xml =& $this->_soap_transport->send($soap_data, $transport_options);
00296
00297
00298 if ($this->__options['trace'] > 0) {
00299 $this->__last_request =& $this->_soap_transport->outgoing_payload;
00300 $this->__last_response =& $this->_soap_transport->incoming_payload;
00301 $this->wire =& $this->__get_wire();
00302 }
00303 if ($this->_soap_transport->fault) {
00304 return $this->_raiseSoapFault($this->xml);
00305 }
00306
00307 $this->__attachments =& $this->_soap_transport->attachments;
00308 $this->__result_encoding = $this->_soap_transport->result_encoding;
00309
00310 if (isset($this->__options['result']) && $this->__options['result'] != 'parse') return $this->xml;
00311
00312 return $this->__parse($this->xml, $this->__result_encoding,$this->__attachments);
00313 }
00314
00328 function setOpt($category, $option, $value = null)
00329 {
00330 if (!is_null($value)) {
00331 if (!isset($this->__options[$category])) {
00332 $this->__options[$category] = array();
00333 }
00334 $this->__options[$category][$option] = $value;
00335 } else {
00336 $this->__options[$category] = $option;
00337 }
00338 }
00339
00354 function _call($method, $args, &$return_value)
00355 {
00356
00357
00358
00359
00360 if ($this->_wsdl) {
00361 $this->_wsdl->matchMethod($method);
00362 }
00363 $return_value =& $this->call($method, $args);
00364 return true;
00365 }
00366
00367 function &__getlastrequest()
00368 {
00369 return $this->__last_request;
00370 }
00371
00372 function &__getlastresponse()
00373 {
00374 return $this->__last_response;
00375 }
00376
00377 function __use($use)
00378 {
00379 $this->__options['use'] = $use;
00380 }
00381
00382 function __style($style)
00383 {
00384 $this->__options['style'] = $style;
00385 }
00386
00387 function __trace($level)
00388 {
00389 $this->__options['trace'] = $level;
00390 }
00391
00392 function &__generate($method, &$params, $namespace = false, $soapAction = false)
00393 {
00394 $this->fault = null;
00395 $this->__options['input']='parse';
00396 $this->__options['result']='parse';
00397 $this->__options['parameters'] = false;
00398 if ($params && gettype($params) != 'array') {
00399 $params = array($params);
00400 }
00401 if (gettype($namespace) == 'array') {
00402 foreach ($namespace as $optname=>$opt) {
00403 $this->__options[strtolower($optname)]=$opt;
00404 }
00405 if (isset($this->__options['namespace'])) $namespace = $this->__options['namespace'];
00406 else $namespace = false;
00407 } else {
00408
00409 $this->__options['soapaction'] = $soapAction;
00410 $this->__options['namespace'] = $namespace;
00411 }
00412
00413 if ($this->__endpointType == 'wsdl') {
00414 $this->_setSchemaVersion($this->_wsdl->xsd);
00415
00416 if (!$this->_portName) {
00417 $this->_portName = $this->_wsdl->getPortName($method);
00418 }
00419 if (PEAR::isError($this->_portName)) {
00420 return $this->_raiseSoapFault($this->_portName);
00421 }
00422
00423
00424 $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
00425 if (PEAR::isError($this->_endpoint)) {
00426 return $this->_raiseSoapFault($this->_endpoint);
00427 }
00428
00429
00430 $opData = $this->_wsdl->getOperationData($this->_portName, $method);
00431
00432 if (PEAR::isError($opData)) {
00433 return $this->_raiseSoapFault($opData);
00434 }
00435 $namespace = $opData['namespace'];
00436 $this->__options['style'] = $opData['style'];
00437 $this->__options['use'] = $opData['input']['use'];
00438 $this->__options['soapaction'] = $opData['soapAction'];
00439
00440
00441 if ($this->__options['input'] == 'parse') {
00442 $this->__options['parameters'] = $opData['parameters'];
00443 $nparams = array();
00444 if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) {
00445 $i = 0;
00446 reset($params);
00447 foreach ($opData['input']['parts'] as $name => $part) {
00448 $xmlns = '';
00449 $attrs = array();
00450
00451 if (isset($part['element'])) {
00452 $xmlns = $this->_wsdl->namespaces[$part['namespace']];
00453 $part = $this->_wsdl->elements[$part['namespace']][$part['type']];
00454 $name = $part['name'];
00455 }
00456 if (array_key_exists($name,$params) ||
00457 $this->_wsdl->getDataHandler($name,$part['namespace'])) {
00458 $nparams[$name] =& $params[$name];
00459 } else {
00460 # we now force an associative array for parameters if using wsdl
00461 return $this->_raiseSoapFault("The named parameter $name is not in the call parameters.");
00462 }
00463 if (gettype($nparams[$name]) != 'object' ||
00464 !is_a($nparams[$name],'ilbmfvalue')) {
00465
00466 $qname =& new ilBMFQName($part['type']);
00467 if ($qname->ns)
00468 $type_namespace = $this->_wsdl->namespaces[$qname->ns];
00469 else if (isset($part['namespace']))
00470 $type_namespace = $this->_wsdl->namespaces[$part['namespace']];
00471 else
00472 $type_namespace = NULL;
00473 $qname->namespace = $type_namespace;
00474 $type = $qname->name;
00475 $pqname = $name;
00476 if ($xmlns) $pqname = '{'.$xmlns.'}'.$name;
00477 $nparams[$name] =& new ilBMFValue($pqname, $qname->fqn(), $nparams[$name],$attrs);
00478 } else {
00479
00480 }
00481 }
00482 }
00483 $params =& $nparams;
00484 unset($nparams);
00485 }
00486 } else {
00487 $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
00488 }
00489
00490
00491 $this->_section5 = TRUE;
00492 if (isset($this->__options['use']) && $this->__options['use']=='literal') $this->_section5 = FALSE;
00493
00494 if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') {
00495 $this->__options['style'] = 'rpc';
00496 $this->docparams = true;
00497 $mqname =& new ilBMFQName($method, $namespace);
00498 $methodValue =& new ilBMFValue($mqname->fqn(), 'Struct', $params);
00499 $soap_msg =& $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding,$this->__options);
00500 } else {
00501 if (!$params) {
00502 $mqname =& new ilBMFQName($method, $namespace);
00503 $mynull = NULL;
00504 $params =& new ilBMFValue($mqname->fqn(), 'Struct', $mynull);
00505 } elseif ($this->__options['input'] == 'parse') {
00506 if (is_array($params)) {
00507 $nparams = array();
00508 $keys = array_keys($params);
00509 foreach ($keys as $k) {
00510 if (gettype($params[$k]) != 'object') {
00511 $nparams[] =& new ilBMFValue($k, false, $params[$k]);
00512 } else {
00513 $nparams[] =& $params[$k];
00514 }
00515 }
00516 $params =& $nparams;
00517 }
00518 if ($this->__options['parameters']) {
00519 $mqname =& new ilBMFQName($method, $namespace);
00520 $params =& new ilBMFValue($mqname->fqn(), 'Struct', $params);
00521 }
00522 }
00523 $soap_msg =& $this->_makeEnvelope($params, $this->headersOut, $this->_encoding,$this->__options);
00524 }
00525 unset($this->headersOut);
00526
00527 if (PEAR::isError($soap_msg)) {
00528 return $this->_raiseSoapFault($soap_msg);
00529 }
00530
00531
00532
00533
00534 if (count($this->__attachments)) {
00535 if ((isset($this->__options['attachments']) && $this->__options['attachments'] == 'Mime') || isset($this->__options['Mime'])) {
00536 $soap_msg =& $this->_makeMimeMessage($soap_msg, $this->_encoding);
00537 } else {
00538
00539 $soap_msg =& $this->_makeDIMEMessage($soap_msg, $this->_encoding);
00540 $this->__options['headers']['Content-Type'] = 'application/dime';
00541 }
00542 if (PEAR::isError($soap_msg)) {
00543 return $this->_raiseSoapFault($soap_msg);
00544 }
00545 }
00546
00547
00548 if (is_array($soap_msg)) {
00549 $soap_data =& $soap_msg['body'];
00550 if (count($soap_msg['headers'])) {
00551 if (isset($this->__options['headers'])) {
00552 $this->__options['headers'] = array_merge($this->__options['headers'],$soap_msg['headers']);
00553 } else {
00554 $this->__options['headers'] = $soap_msg['headers'];
00555 }
00556 }
00557 } else {
00558 $soap_data =& $soap_msg;
00559 }
00560 return $soap_data;
00561 }
00562
00563 function &__parse(&$response, $encoding, &$attachments)
00564 {
00565
00566 $response =& new ilBMFParser($response, $encoding, $attachments);
00567 if ($response->fault) {
00568 return $this->_raiseSoapFault($response->fault);
00569 }
00570
00571 $return =& $response->getResponse();
00572 $headers =& $response->getHeaders();
00573 if ($headers) {
00574 $this->headersIn =& $this->__decodeResponse($headers,false);
00575 }
00576 return $this->__decodeResponse($return);
00577 }
00578
00579 function &__decodeResponse(&$response,$shift=true)
00580 {
00581 if (!$response) return NULL;
00582
00583 if (PEAR::isError($response)) {
00584 return $this->_raiseSoapFault($response);
00585 } else if (!is_a($response,'ilbmfvalue')) {
00586 return $this->_raiseSoapFault("didn't get ilBMFValue object back from client");
00587 }
00588
00589
00590 $returnArray =& $this->_decode($response);
00591
00592 if (PEAR::isError($returnArray)) {
00593 return $this->_raiseSoapFault($returnArray);
00594 }
00595 if (is_object($returnArray) && strcasecmp(get_class($returnArray),'stdClass') == 0) {
00596 $returnArray = get_object_vars($returnArray);
00597 }
00598 if (is_array($returnArray)) {
00599 if (isset($returnArray['faultcode']) || isset($returnArray['SOAP-ENV:faultcode'])) {
00600 $faultcode = $faultstring = $faultdetail = $faultactor = '';
00601 foreach ($returnArray as $k => $v) {
00602 if (stristr($k,'faultcode')) $faultcode = $v;
00603 if (stristr($k,'faultstring')) $faultstring = $v;
00604 if (stristr($k,'detail')) $faultdetail = $v;
00605 if (stristr($k,'faultactor')) $faultactor = $v;
00606 }
00607 return $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode);
00608 }
00609
00610 if ($shift && count($returnArray) == 1) {
00611 return array_shift($returnArray);
00612 }
00613 return $returnArray;
00614 }
00615 return $returnArray;
00616 }
00617
00618 function __get_wire()
00619 {
00620 if ($this->__options['trace'] > 0 && ($this->__last_request || $this->__last_response)) {
00621 return "OUTGOING:\n\n".
00622 $this->__last_request.
00623 "\n\nINCOMING\n\n".
00624 preg_replace("/></",">\r\n<",$this->__last_response);
00625 }
00626 return NULL;
00627 }
00628 }
00629
00630 #if (extension_loaded('overload')) {
00631 # overload('ilBMFClient');
00632 #}
00633 ?>