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';
00046 class ilBMFClient extends ilBMFBase
00047 {
00063 var $_endpoint = '';
00064
00070 var $_portName = '';
00071
00072
00078 var $__endpointType = '';
00079
00085 var $xml;
00086 var $wire;
00087 var $__last_request = NULL;
00088 var $__last_response = NULL;
00089 var $__options = array('trace'=>0);
00095 var $_encoding = SOAP_DEFAULT_ENCODING;
00096
00097
00103 var $headersOut = NULL;
00109 var $headersIn = NULL;
00110
00116 var $__proxy_params = array();
00126 function ilBMFClient($endpoint, $wsdl = false, $portName = false, $proxy_params=array())
00127 {
00128 parent::ilBMFBase('Client');
00129 $this->_endpoint = $endpoint;
00130 $this->_portName = $portName;
00131 $this->__proxy_params = $proxy_params;
00132
00133
00134 if ($wsdl) {
00135 $this->__endpointType = 'wsdl';
00136
00137 $this->_wsdl = new ilBMFWSDL($this->_endpoint, $this->__proxy_params);
00138 if ($this->_wsdl->fault) {
00139 $this->_raiseSoapFault($this->_wsdl->fault);
00140 }
00141 }
00142 }
00143
00154 function setEncoding($encoding)
00155 {
00156 if (in_array($encoding, $this->_encodings)) {
00157 $this->_encoding = $encoding;
00158 return NULL;
00159 }
00160 return $this->_raiseSoapFault('Invalid Encoding');
00161 }
00162
00173 function addHeader(&$soap_value)
00174 {
00175 # add a new header to the message
00176 if (is_a($soap_value,'ibmfheader')) {
00177 $this->headersOut[] = $soap_value;
00178 } else if (gettype($soap_value) == 'array') {
00179
00180 $h = new ilBMFHeader($soap_value[0], NULL, $soap_value[1], $soap_value[2], $soap_value[3]);
00181 $this->headersOut[] = $h;
00182 } else {
00183 $this->_raiseSoapFault("Don't understand the header info you provided. Must be array or ilBMFHeader.");
00184 }
00185 }
00186
00215 function call($method, $params = array(), $namespace = false, $soapAction = false, $paramtype = array())
00216 {
00217 $soap_data = $this->__generate($method, $params, $namespace, $soapAction, $paramtype);
00218 if (PEAR::isError($soap_data)) {
00219 return $this->_raiseSoapFault($soap_data);
00220 }
00221 $soap_transport = new ilBMFTransport($this->_endpoint, $this->_encoding);
00222 if ($soap_transport->fault) {
00223 return $this->_raiseSoapFault($soap_transport->fault);
00224 }
00225
00226
00227 $transport_options = array_merge($this->__proxy_params, $this->__options);
00228
00229 $this->xml = $soap_transport->send($soap_data, $transport_options);
00230
00231
00232 #$this->__options["trace"] = 1;
00233 if ($this->__options['trace'] > 0) {
00234 $this->__last_request =& $soap_transport->transport->outgoing_payload;
00235 $this->__last_response =& $soap_transport->transport->incoming_payload;
00236 $this->wire = $this->__get_wire();
00237 # var_dump("<pre>",$this->wire,"</pre>");
00238 }
00239 if ($soap_transport->fault) {
00240 return $this->_raiseSoapFault($this->xml);
00241 }
00242
00243 $this->__attachments =& $soap_transport->transport->attachments;
00244 $this->__result_encoding = $soap_transport->result_encoding;
00245 unset($soap_transport);
00246
00247 if (isset($this->__options['result']) && $this->__options['result'] != 'parse') return $this->xml;
00248
00249 return $this->__parse($this->xml, $this->__result_encoding,$this->__attachments);
00250 }
00251
00268 function __call($method, $args, &$return_value)
00269 {
00270 if ($this->_wsdl) $this->_wsdl->matchMethod($method);
00271 $return_value = $this->call($method, $args);
00272 return TRUE;
00273 }
00274
00275 function &__getlastrequest()
00276 {
00277 return $this->__last_request;
00278 }
00279
00280 function &__getlastresponse()
00281 {
00282 return $this->__last_response;
00283 }
00284
00285 function __use($use)
00286 {
00287 $this->__options['use'] = $use;
00288 }
00289
00290 function __style($style)
00291 {
00292 $this->__options['style'] = $style;
00293 }
00294
00295 function __trace($level)
00296 {
00297 $this->__options['trace'] = $level;
00298 }
00299
00300 function &__generate($method, $params = array(), $namespace = false, $soapAction = false, $paramtype = array() )
00301 {
00302 $this->fault = null;
00303 $this->__options['input']='parse';
00304 $this->__options['result']='parse';
00305 $this->__options['parameters'] = false;
00306 if ($params && gettype($params) != 'array') {
00307 $params = array($params);
00308 }
00309 if (gettype($namespace) == 'array')
00310 {
00311 foreach ($namespace as $optname=>$opt)
00312 {
00313 $this->__options[strtolower($optname)]=$opt;
00314 }
00315 if (isset($this->__options['namespace']))
00316 $namespace = $this->__options['namespace'];
00317 else
00318 $namespace = false;
00319 }
00320 else
00321 {
00322
00323 $this->__options['soapaction'] = $soapAction;
00324 $this->__options['namespace'] = $namespace;
00325 }
00326
00327 if ($this->__endpointType == 'wsdl') {
00328 $this->_setSchemaVersion($this->_wsdl->xsd);
00329
00330 if (!$this->_portName) {
00331 $this->_portName = $this->_wsdl->getPortName($method);
00332 }
00333 if (PEAR::isError($this->_portName)) {
00334 return $this->_raiseSoapFault($this->_portName);
00335 }
00336
00337
00338 $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
00339 if (PEAR::isError($this->_endpoint)) {
00340 return $this->_raiseSoapFault($this->_endpoint);
00341 }
00342
00343
00344 $opData = $this->_wsdl->getOperationData($this->_portName, $method);
00345
00346 if (PEAR::isError($opData)) {
00347 return $this->_raiseSoapFault($opData);
00348 }
00349 $namespace = $opData['namespace'];
00350 $this->__options['style'] = $opData['style'];
00351 $this->__options['use'] = $opData['input']['use'];
00352 $this->__options['soapaction'] = $opData['soapAction'];
00353
00354
00355 if ($this->__options['input'] == 'parse') {
00356 $this->__options['parameters'] = $opData['parameters'];
00357 $nparams = array();
00358 if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) {
00359 $i = 0;
00360 reset($params);
00361 foreach ($opData['input']['parts'] as $name => $part) {
00362 $xmlns = '';
00363 $attrs = array();
00364
00365 if (isset($part['element'])) {
00366 $xmlns = $this->_wsdl->namespaces[$part['namespace']];
00367 $part = $this->_wsdl->elements[$part['namespace']][$part['type']];
00368 $name = $part['name'];
00369 }
00370 if (isset($params[$name])) {
00371 $nparams[$name] = $params[$name];
00372 } else {
00373 # we now force an associative array for parameters if using wsdl
00374 return $this->_raiseSoapFault("The named parameter $name is not in the call parameters.");
00375 }
00376 if (gettype($nparams[$name]) != 'object' ||
00377 !is_a($nparams[$name],'ilbmfvalue')) {
00378
00379 $qname = new QName($part['type']);
00380 if ($qname->ns)
00381 $type_namespace = $this->_wsdl->namespaces[$qname->ns];
00382 else if (isset($part['namespace']))
00383 $type_namespace = $this->_wsdl->namespaces[$part['namespace']];
00384 else
00385 $type_namespace = NULL;
00386 $qname->namespace = $type_namespace;
00387 $type = $qname->name;
00388 $pqname = $name;
00389 if ($xmlns) $pqname = '{'.$xmlns.'}'.$name;
00390 $nparams[$name] = new ilBMFValue($pqname, $qname->fqn(), $nparams[$name],$attrs);
00391 } else {
00392
00393 }
00394 }
00395 }
00396 $params = $nparams;
00397 }
00398 } else {
00399 $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
00400 }
00401
00402
00403 $this->_section5 = TRUE;
00404 if (isset($this->__options['use']) && $this->__options['use']=='literal') $this->_section5 = FALSE;
00405
00406 if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') {
00407 $this->__options['style'] = 'rpc';
00408 $this->docparams = true;
00409 $mqname = new QName($method, $namespace);
00410 $methodValue = new ilBMFValue($mqname->fqn(), 'Struct', $params);
00411 $soap_msg = $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding,$this->__options);
00412 } else {
00413 if (!$params) {
00414 $mqname = new QName($method, $namespace);
00415 $params = new ilBMFValue($mqname->fqn(), 'Struct', NULL);
00416 } elseif ($this->__options['input'] == 'parse') {
00417 if (is_array($params)) {
00418 $nparams = array();
00419 foreach ($params as $n => $v) {
00420 if (gettype($v) != 'object') {
00421 $nparams[] = new ilBMFValue($n, false, $v);
00422 } else {
00423 $nparams[] = $v;
00424 }
00425 }
00426 $params = $nparams;
00427 }
00428 if ($this->__options['parameters']) {
00429 $mqname = new QName($method, $namespace);
00430 $params = new ilBMFValue($mqname->fqn(), 'Struct', $params);
00431 }
00432 }
00433 $soap_msg = $this->_makeEnvelope($params, $this->headersOut, $this->_encoding,$this->__options);
00434 }
00435
00436 if (PEAR::isError($soap_msg)) {
00437 return $this->_raiseSoapFault($soap_msg);
00438 }
00439
00440
00441
00442
00443 if (count($this->__attachments)) {
00444 if ((isset($this->__options['attachments']) && $this->__options['attachments'] == 'Mime') || isset($this->__options['Mime'])) {
00445 $soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding);
00446 } else {
00447
00448 $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding);
00449 $this->__options['headers']['Content-Type'] = 'application/dime';
00450 }
00451 if (PEAR::isError($soap_msg)) {
00452 return $this->_raiseSoapFault($soap_msg);
00453 }
00454 }
00455
00456
00457 if (is_array($soap_msg)) {
00458 $soap_data = $soap_msg['body'];
00459 if (count($soap_msg['headers'])) {
00460 if (isset($this->__options['headers'])) {
00461 $this->__options['headers'] = array_merge($this->__options['headers'],$soap_msg['headers']);
00462 } else {
00463 $this->__options['headers'] = $soap_msg['headers'];
00464 }
00465 }
00466 } else {
00467 $soap_data = $soap_msg;
00468 }
00469 return $soap_data;
00470 }
00471
00472 function &__parse($response, $encoding, $attachments)
00473 {
00474
00475 $this->response = new ilBMFParser($response, $encoding, $attachments);
00476 if ($this->response->fault) {
00477 return $this->_raiseSoapFault($this->response->fault);
00478 }
00479
00480 $return = $this->response->getResponse();
00481 $headers = $this->response->getHeaders();
00482 if ($headers) {
00483 $this->headersIn = $this->__decodeResponse($headers,false);
00484 }
00485
00486 return $this->__decodeResponse($return);
00487 }
00488
00489 function &__decodeResponse($response,$shift=true)
00490 {
00491 if (!$response) return NULL;
00492
00493 if (PEAR::isError($response)) {
00494 return $this->_raiseSoapFault($response);
00495 } else if (!is_a($response,'ilbmfvalue')) {
00496 return $this->_raiseSoapFault("didn't get ilBMFValue object back from client");
00497 }
00498
00499
00500 $returnArray = $this->_decode($response);
00501
00502 if (PEAR::isError($returnArray)) {
00503 return $this->_raiseSoapFault($returnArray);
00504 }
00505 if (is_object($returnArray) && get_class($returnArray) == 'stdClass') {
00506 $returnArray = get_object_vars($returnArray);
00507 }
00508
00509 if (is_array($returnArray)) {
00510 if (isset($returnArray['faultcode']) || isset($returnArray['SOAP-ENV:faultcode'])) {
00511 $faultcode = $faultstring = $faultdetail = $faultactor = '';
00512 foreach ($returnArray as $k => $v) {
00513 if (stristr($k,'faultcode')) $faultcode = $v;
00514 if (stristr($k,'faultstring')) $faultstring = $v;
00515 if (stristr($k,'detail')) $faultdetail = $v;
00516 if (stristr($k,'faultactor')) $faultactor = $v;
00517 }
00518 return $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode);
00519 }
00520
00521 if ($shift && count($returnArray) == 1) {
00522 return array_shift($returnArray);
00523 }
00524 return $returnArray;
00525 }
00526 return $returnArray;
00527 }
00528
00529 function __get_wire()
00530 {
00531 if ($this->__options['trace'] > 0) {
00532 return "OUTGOING:\n\n".
00533 $this->__last_request.
00534 "\n\nINCOMING\n\n".
00535 preg_replace("/></",">\r\n<",$this->__last_response);
00536 }
00537 return NULL;
00538 }
00539 }
00540
00541 #if (extension_loaded('overload')) {
00542 # overload('ilBMFClient');
00543 #}
00544 ?>