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
00033
00034
00035
00036
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
00188
00189 $wsdl = $wsdl
00190 ? $wsdl
00191 : strtolower(substr($endpoint, -4)) == 'wsdl';
00192
00193
00194 if ($wsdl) {
00195 $this->__endpointType = 'wsdl';
00196
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
00248 if (is_a($soap_value, 'ilBMFHeader')) {
00249 $this->headersOut[] =& $soap_value;
00250 } elseif (is_array($soap_value)) {
00251
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
00305
00306
00307
00308
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
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
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
00402
00403
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
00463
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
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
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
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
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
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
00520
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
00527
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
00548 }
00549 }
00550 }
00551 $params =& $nparams;
00552 unset($nparams);
00553 }
00554 } else {
00555 $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
00556 }
00557
00558
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
00612
00613
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
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
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
00652 $response =& new ilBMFParser($response, $encoding, $attachments);
00653 if ($response->fault) {
00654 $fault =& $this->_raiseSoapFault($response->fault);
00655 return $fault;
00656 }
00657
00658
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
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
00686 $returnArray =& $this->_decode($response);
00687
00688
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
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 }