25require_once dirname(__FILE__).
'/class.ilBMFBase.php';
26require_once dirname(__FILE__).
'/class.ilBMFFault.php';
27require_once
'HTTP/Request.php';
29define(
'WSDL_CACHE_MAX_AGE', 43200);
30define(
'WSDL_CACHE_USE', 0);
117 parent::ilBMFBase(
'WSDL');
118 $this->uri = $wsdl_uri;
126 reset($this->services);
127 $this->service = key($this->services);
134 if (array_key_exists(
$service, $this->services)) {
156 $parser =&
new $this->wsdlParserClass($wsdl_uri, $this, $this->docs);
158 if ($parser->fault) {
178 $targetNamespace, $service_name,
181 if ($parser->fault) {
192 return (isset($this->services[$this->service][
'ports'][$portName][
'address'][
'location']))
193 ? $this->services[
$this->service][
'ports'][$portName][
'address'][
'location']
194 : $this->
_raiseSoapFault(
"No endpoint for port for $portName", $this->uri);
199 if (isset($this->services[
$service][
'ports'])) {
200 $ports = $this->services[
$service][
'ports'];
201 foreach ($ports as $port => $portAttrs) {
202 $type = $ports[$port][
'type'];
203 if ($type ==
'soap' &&
204 isset($this->bindings[$portAttrs[
'binding']][
'operations'][$operation])) {
225 if (isset($this->services[
$service][
'ports'])) {
231 foreach ($this->services as $serviceName =>
$service) {
232 if (isset($this->services[$serviceName][
'ports'])) {
233 if ($portName = $this->
_getPortName($operation, $serviceName)) {
234 $this->service = $serviceName;
239 return $this->
_raiseSoapFault(
"No operation $operation in WSDL.", $this->uri);
248 if (!isset($this->services[$this->service][
'ports'][$portName][
'binding']) ||
249 !($binding = $this->services[$this->service][
'ports'][$portName][
'binding'])) {
250 return $this->
_raiseSoapFault(
"No binding for port $portName in WSDL.", $this->uri);
254 if (is_array($this->bindings[$binding][
'operations'][$operation])) {
255 $opData = $this->bindings[$binding][
'operations'][$operation];
258 $portType = $this->bindings[$binding][
'type'];
260 return $this->
_raiseSoapFault(
"No port type for binding $binding in WSDL.", $this->uri);
262 if (is_array($type = $this->portTypes[$portType][$operation])) {
263 if (isset($type[
'parameterOrder'])) {
264 $opData[
'parameterOrder'] = $type[
'parameterOrder'];
266 $opData[
'input'] = array_merge($opData[
'input'], $type[
'input']);
267 $opData[
'output'] = array_merge($opData[
'output'], $type[
'output']);
270 return $this->
_raiseSoapFault(
"No operation $operation for port $portName in WSDL.", $this->uri);
271 $opData[
'parameters'] =
false;
272 if (isset($this->bindings[$binding][
'operations'][$operation][
'input'][
'namespace']))
273 $opData[
'namespace'] = $this->bindings[$binding][
'operations'][$operation][
'input'][
'namespace'];
275 $inputMsg = $opData[
'input'][
'message'];
276 if (is_array($this->messages[$inputMsg])) {
277 foreach ($this->messages[$inputMsg] as $pname => $pattrs) {
278 if ($opData[
'style'] ==
'document' &&
279 $opData[
'input'][
'use'] ==
'literal' &&
280 $pname ==
'parameters') {
281 $opData[
'parameters'] =
true;
282 $opData[
'namespace'] = $this->namespaces[$pattrs[
'namespace']];
283 $el = $this->elements[$pattrs[
'namespace']][$pattrs[
'type']];
284 if (isset($el[
'elements'])) {
285 foreach ($el[
'elements'] as $elname => $elattrs) {
286 $opData[
'input'][
'parts'][$elname] = $elattrs;
290 $opData[
'input'][
'parts'][$pname] = $pattrs;
294 $outputMsg = $opData[
'output'][
'message'];
295 if (is_array($this->messages[$outputMsg])) {
296 foreach ($this->messages[$outputMsg] as $pname => $pattrs) {
297 if ($opData[
'style'] ==
'document' &&
298 $opData[
'output'][
'use'] ==
'literal' &&
299 $pname ==
'parameters') {
301 $el = $this->elements[$pattrs[
'namespace']][$pattrs[
'type']];
302 if (isset($el[
'elements'])) {
303 foreach ($el[
'elements'] as $elname => $elattrs) {
304 $opData[
'output'][
'parts'][$elname] = $elattrs;
308 $opData[
'output'][
'parts'][$pname] = $pattrs;
322 foreach ($this->services[$this->service][
'ports'] as $port => $portAttrs) {
323 foreach (array_keys($this->bindings[$portAttrs[
'binding']][
'operations']) as $op) {
324 if (strcasecmp($op, $operation) == 0) {
353 if (isset($this->elements[$nsp][$datatype])) {
354 $checkmessages = array();
356 foreach ($this->messages as $messagename => $message) {
357 foreach ($message as $partname => $part) {
358 if ($part[
'type'] == $datatype) {
359 $checkmessages[] = $messagename;
366 foreach($this->portTypes as $portname => $porttype) {
367 foreach ($porttype as $opname => $opinfo) {
368 foreach ($checkmessages as $messagename) {
369 if ($opinfo[
'input'][
'message'] == $messagename) {
387 if (!empty($this->bindings[$this->services[$this->service][
'ports'][$portName][
'binding']][
'operations'][$operation][
'soapAction'])) {
388 return $this->bindings[$this->services[
$this->service][
'ports'][$portName][
'binding']][
'operations'][$operation][
'soapAction'];
400 if (!empty($this->bindings[$this->services[$this->service][
'ports'][$portName][
'binding']][
'operations'][$operation][
'input'][
'namespace'])) {
401 return $this->bindings[$this->services[
$this->service][
'ports'][$portName][
'binding']][
'operations'][$operation][
'input'][
'namespace'];
411 $this->ns = array_flip($this->namespaces);
428 $n = count($this->ns);
438 return preg_match(
'/^[\w_:#\/]+$/', $string);
441 function _addArg(&$args, &$argarray, $argname)
446 $args .=
'$' . $argname;
453 $argarray .=
"'$argname' => $" . $argname;
459 $el = $this->elements[$_argtype[
'namespace']][$_argtype[
'type']];
460 $tns = isset($this->ns[$el[
'namespace']])
461 ? $this->ns[$el[
'namespace']]
462 : $_argtype[
'namespace'];
464 if (!empty($el[
'complex']) ||
465 (isset($el[
'type']) &&
466 isset($this->complexTypes[
$tns][$el[
'type']]))) {
468 $comments .=
" // {$_argtype['type']} is a ComplexType, refer to the WSDL for more info.\n";
469 $attrname =
"{$_argtype['type']}_attr";
470 if (isset($el[
'type']) &&
471 isset($this->complexTypes[
$tns][$el[
'type']][
'attribute'])) {
472 $comments .=
" // {$_argtype['type']} may require attributes, refer to the WSDL for more info.\n";
474 $comments .=
" \${$attrname}['xmlns'] = '{$this->namespaces[$_argtype['namespace']]}';\n";
475 $comments .=
" \${$_argtype['type']} =& new ilBMFValue('{$_argtype['type']}', false, \${$_argtype['type']}, \$$attrname);\n";
476 $this->
_addArg($args, $argarray, $_argtype[
'type']);
477 if (isset($el[
'type']) &&
478 isset($this->complexTypes[
$tns][$el[
'type']][
'attribute'])) {
482 $args .=
'$' . $attrname;
484 } elseif (isset($el[
'elements'])) {
485 foreach ($el[
'elements'] as $ename => $element) {
486 $comments .=
" \$$ename =& new ilBMFValue('{{$this->namespaces[$element['namespace']]}}$ename', '" .
487 (isset($element[
'type']) ? $element[
'type'] :
false) .
489 $this->
_addArg($args, $argarray, $ename);
492 $comments .=
" \$$_argname =& new ilBMFValue('{{$this->namespaces[$tns]}}$_argname', '{$el['type']}', \$$_argname);\n";
493 $this->
_addArg($args, $argarray, $_argname);
502 if (isset($this->complexTypes[$_argtype[
'namespace']][$_argtype[
'type']])) {
503 $comments =
" // $_argname is a ComplexType {$_argtype['type']},\n" .
504 " // refer to wsdl for more info\n";
505 if (isset($this->complexTypes[$_argtype[
'namespace']][$_argtype[
'type']][
'attribute'])) {
506 $comments .=
" // $_argname may require attributes, refer to wsdl for more info\n";
508 $wrapname =
'{' . $this->namespaces[$_argtype[
'namespace']].
'}' . $_argtype[
'type'];
509 $comments .=
" \$$_argname =& new ilBMFValue('$_argname', '$wrapname', \$$_argname);\n";
512 $this->
_addArg($args, $argarray, $_argname);
527 $multiport = count($this->services[$this->service][
'ports']) > 1;
529 reset($this->services[$this->service][
'ports']);
530 $port = current($this->services[$this->service][
'ports']);
533 if ($port[
'type'] !=
'soap') {
538 $clienturl = $port[
'address'][
'location'];
540 if ($multiport || $port) {
541 $classname =
'WebService_' . $this->service .
'_' . $port[
'name'];
545 $classname = preg_replace(
'/[ .\-\(\)]+/',
'_', $classname);
552 if (is_array($this->proxy) && count($this->proxy)) {
553 $class =
"class $classname extends ilBMFClient\n{\n" .
554 " function $classname(\$path = '$clienturl')\n {\n" .
555 " \$this->ilBMFClient(\$path, 0, 0,\n" .
558 foreach ($this->proxy as $key => $val) {
559 if (is_array($val)) {
560 $class .=
"'$key' => array(";
561 foreach ($val as $key2 => $val2) {
562 $class .=
"'$key2' => '$val2', ";
566 $class .=
"'$key' => '$val', ";
569 $class .=
"));\n }\n";
570 $class = str_replace(
', ))',
'))', $class);
572 $class =
"class $classname extends ilBMFClient\n{\n" .
573 " function $classname(\$path = '$clienturl')\n {\n" .
574 " \$this->ilBMFClient(\$path, 0);\n" .
579 $primaryBinding = $port[
'binding'];
580 $primaryBinding = preg_replace(
"/^(.*:)/",
'', $primaryBinding);
581 $portType = $this->bindings[$primaryBinding][
'type'];
582 $portType = preg_replace(
"/^(.*:)/",
'', $portType);
583 $style = $this->bindings[$primaryBinding][
'style'];
586 foreach ($this->portTypes[$portType] as $opname => $operation) {
587 $binding = $this->bindings[$primaryBinding][
'operations'][$opname];
588 if (isset($binding[
'soapAction'])) {
589 $soapaction = $binding[
'soapAction'];
593 if (isset($binding[
'style'])) {
594 $opstyle = $binding[
'style'];
598 $use = $binding[
'input'][
'use'];
599 if ($use ==
'encoded') {
602 $bindingType = $this->bindings[$primaryBinding][
'type'];
603 $ns = $this->portTypes[$bindingType][$opname][
'input'][
'namespace'];
611 foreach ($operation[
'input'] as $argname => $argtype) {
612 if ($argname ==
'message') {
613 foreach ($this->messages[$argtype] as $_argname => $_argtype) {
614 if ($opstyle ==
'document' && $use ==
'literal' &&
615 $_argtype[
'name'] ==
'parameters') {
619 $element = $_argtype[
'element'];
620 $el = $this->elements[$_argtype[
'namespace']][$_argtype[
'type']];
622 if ($el[
'complex']) {
623 $namespace = $this->namespaces[$_argtype[
'namespace']];
627 if (isset($el[
'elements'])) {
628 foreach ($el[
'elements'] as $elname => $elattrs) {
630 if (isset($this->complexTypes[$elattrs[
'namespace']][$elname])) {
631 $comments .= $this->
_complexTypeArg($args, $argarray, $_argtype, $_argname);
633 $this->
_addArg($args, $argarray, $elname);
637 if ($el[
'complex'] && $argarray) {
638 $wrapname =
'{' . $this->namespaces[$_argtype[
'namespace']].
'}' . $el[
'name'];
639 $comments .=
" \${$el['name']} =& new ilBMFValue('$wrapname', false, \$v = array($argarray));\n";
640 $argarray =
"'{$el['name']}' => \${$el['name']}";
643 if (isset($_argtype[
'element'])) {
645 $comments .= $this->
_elementArg($args, $argarray, $_argtype, $_argtype[
'type']);
648 $comments .= $this->
_complexTypeArg($args, $argarray, $_argtype, $_argname);
661 $opname_php = preg_replace(
'/[ .\-\(\)]+/',
'_', $opname);
667 $argarray =
"array($argarray)";
672 $class .=
" function &$opname_php($args)\n {\n$comments$wrappers" .
673 " \$result = \$this->call('$opname',\n" .
674 " \$v = $argarray,\n" .
675 " array('namespace' => '$namespace',\n" .
676 " 'soapaction' => '$soapaction',\n" .
677 " 'style' => '$opstyle',\n" .
679 ($this->trace?
",\n 'trace' => 1" :
'') .
"));\n" .
680 " return \$result;\n" .
692 foreach (array_keys($this->services[$this->service][
'ports']) as $key) {
706 $multiport = count($this->services[$this->service][
'ports']) > 1;
709 reset($this->services[$this->service][
'ports']);
710 $port = current($this->services[$this->service][
'ports']);
713 if ($multiport || $port) {
714 $classname =
'WebService_' . $this->service .
'_' . $port[
'name'];
720 $classname = $name .
'_' . $classname;
723 $classname = preg_replace(
'/[ .\-\(\)]+/',
'_', $classname);
724 if (!class_exists($classname)) {
726 require_once
'SOAP/Client.php';
738 isset($this->elements[$this->ns[
$namespace]][$name][
'type'])) {
740 $type = $this->elements[$this->ns[
$namespace]][$name][
'type'];
741 $ns = $this->elements[$this->ns[
$namespace]][$name][
'namespace'];
743 if (isset($this->complexTypes[
$ns][$type])) {
744 $t = $this->complexTypes[
$ns][$type];
765 if (isset(
$t[
'elements'][$child_name][
'type']))
766 return $t[
'elements'][$child_name][
'type'];
775 if ($name && $type) {
778 foreach ($this->complexTypes as
$ns => $types) {
779 if (array_key_exists($type, $types)) {
780 if (array_key_exists(
'type', $types[$type])) {
781 list($arraytype_ns, $arraytype, $array_depth) = isset($types[$type][
'arrayType'])?
783 : array($this->namespaces[$types[$type][
'namespace']],
null, 0);
784 return array($types[$type][
'type'], $arraytype, $arraytype_ns, $array_depth);
786 if (array_key_exists(
'arrayType', $types[$type])) {
787 list($arraytype_ns, $arraytype, $array_depth) =
789 return array(
'Array', $arraytype, $arraytype_ns, $array_depth);
791 if (array_key_exists(
'elements', $types[$type]) &&
792 array_key_exists($name, $types[$type][
'elements'])) {
793 $type = $types[$type][
'elements'][
'type'];
794 return array($type,
null, $this->namespaces[$types[$type][
'namespace']],
null);
799 if ($type && $type_namespace) {
804 $p = $this->ns[$type_namespace];
806 array_key_exists($p, $this->complexTypes) &&
807 array_key_exists($type, $this->complexTypes[$p])) {
808 if ($arrayType = $this->complexTypes[$p][$type][
'arrayType']) {
810 } elseif ($this->complexTypes[$p][$type][
'order']==
'sequence' &&
811 array_key_exists(
'elements', $this->complexTypes[$p][$type])) {
812 reset($this->complexTypes[$p][$type][
'elements']);
814 if (count($this->complexTypes[$p][$type][
'elements']) == 1) {
815 $arg = current($this->complexTypes[$p][$type][
'elements']);
816 $arrayType = $arg[
'type'];
819 foreach ($this->complexTypes[$p][$type][
'elements'] as $element) {
820 if ($element[
'name'] == $type) {
821 $arrayType = $element[
'type'];
822 $type = $element[
'type'];
829 return array($type, $arrayType, $type_namespace,
null);
832 return array(
null,
null,
null,
null);
848 static $trail = array();
850 $arrayType = ereg_replace(
'\[\]$',
'', $arrayType);
856 if (array_search($nsPrefix .
':' . $arrayType, $trail)) {
857 return array(
null,
null, -count($trail));
860 if (array_key_exists($nsPrefix, $this->complexTypes) &&
861 array_key_exists($arrayType, $this->complexTypes[$nsPrefix]) &&
862 array_key_exists(
'arrayType', $this->complexTypes[$nsPrefix][$arrayType])) {
863 $trail[] = $nsPrefix .
':' . $arrayType;
865 $this->complexTypes[$nsPrefix][$arrayType][
'arrayType']);
868 return array($this->namespaces[$nsPrefix], $arrayType, 0);
901 parent::ilBMFBase(
'WSDLCACHE');
902 $this->_cacheUse = $cacheUse;
903 $this->_cacheMaxAge = $cacheMaxAge;
912 $dir = getenv(
"WSDLCACHE");
913 if (!$dir) $dir =
" ./wsdlcache";
928 function get($wsdl_fname, $proxy_params = array(), $cache = 0)
930 $cachename = $md5_wsdl = $file_data =
'';
931 if ($this->_cacheUse) {
934 if (file_exists($cachename)) {
935 $wf = fopen($cachename,
'rb');
938 $file_data = fread($wf, filesize($cachename));
939 $md5_wsdl = md5($file_data);
943 if ($cache != $md5_wsdl) {
947 $fi = stat($cachename);
948 $cache_mtime = $fi[8];
950 if ($cache_mtime + $this->_cacheMaxAge < time()) {
963 if (!preg_match(
'/^(https?|file):\/\//', $wsdl_fname)) {
964 if (!file_exists($wsdl_fname)) {
965 return $this->
_raiseSoapFault(
"Unable to read local WSDL $wsdl_fname", $wsdl_fname);
967 if (function_exists(
'file_get_contents')) {
968 $file_data = file_get_contents($wsdl_fname);
970 $file_data = implode(
'',file($wsdl_fname));
973 $uri = explode(
'?', $wsdl_fname);
976 if (isset($uri[1])) {
977 $rq->addRawQueryString($uri[1]);
980 if (isset($proxy_params[
'proxy_host']) &&
981 isset($proxy_params[
'proxy_port']) &&
982 isset($proxy_params[
'proxy_user']) &&
983 isset($proxy_params[
'proxy_pass'])) {
984 $rq->setProxy($proxy_params[
'proxy_host'], $proxy_params[
'proxy_port'],
985 $proxy_params[
'proxy_user'], $proxy_params[
'proxy_pass']);
986 } elseif (isset($proxy_params[
'proxy_host']) &&
987 isset($proxy_params[
'proxy_port'])) {
988 $rq->setProxy($proxy_params[
'proxy_host'], $proxy_params[
'proxy_port']);
993 return $this->
_raiseSoapFault(
"Unable to retrieve WSDL $wsdl_fname," . $rq->getResponseCode(), $wsdl_fname);
995 $file_data = $rq->getResponseBody();
997 return $this->
_raiseSoapFault(
"Unable to retrieve WSDL $wsdl_fname, no http body", $wsdl_fname);
1001 $md5_wsdl = md5($file_data);
1003 if ($this->_cacheUse) {
1004 $fp = fopen($cachename,
"wb");
1005 fwrite($fp, $file_data);
1009 if ($this->_cacheUse && $cache && $cache != $md5_wsdl) {
1056 parent::ilBMFBase(
'WSDLPARSER');
1060 $this->docs = $docs;
1067 $fd = $this->cache->get(
$uri, $this->
wsdl->proxy);
1073 $parser = xml_parser_create();
1074 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
1075 xml_set_object($parser, $this);
1076 xml_set_element_handler($parser,
'startElement',
'endElement');
1078 xml_set_character_data_handler($parser,
'characterData');
1081 if (!xml_parse($parser, $fd,
true)) {
1082 $detail = sprintf(
'XML error on line %d: %s',
1083 xml_get_current_line_number($parser),
1084 xml_error_string(xml_get_error_code($parser)));
1085 return $this->
_raiseSoapFault(
"Unable to parse WSDL file $uri\n$detail");
1087 xml_parser_free($parser);
1097 $qname =&
new QName($name);
1100 if ($ns && ((!$this->tns && strcasecmp($qname->name,
'definitions') == 0) || $ns == $this->tns)) {
1101 $name = $qname->name;
1104 $this->currentTag = $qname->name;
1105 $this->parentElement =
'';
1106 $stack_size = count($this->element_stack);
1108 $this->parentElement = $this->element_stack[$stack_size - 1];
1110 $this->element_stack[] = $this->currentTag;
1113 switch ($this->status) {
1118 $stack_size = count($this->schema_stack);
1120 $parent_tag = $this->schema_stack[$stack_size - 1];
1123 switch ($qname->name) {
1126 if (!$parent_tag || $parent_tag ==
'types') {
1127 if (array_key_exists(
'targetNamespace', $attrs)) {
1128 $this->schema = $this->
wsdl->getNamespaceAttributeName($attrs[
'targetNamespace']);
1130 $this->schema = $this->
wsdl->getNamespaceAttributeName($this->
wsdl->tns);
1138 if ($parent_tag ==
'schema') {
1139 $this->currentComplexType = $attrs[
'name'];
1140 if (!isset($attrs[
'namespace'])) {
1144 if (array_key_exists(
'base', $attrs)) {
1145 $qn =&
new QName($attrs[
'base']);
1151 $this->schemaStatus =
'complexType';
1158 if (isset($attrs[
'type'])) {
1159 $qn =&
new QName($attrs[
'type']);
1160 $attrs[
'type'] = $qn->name;
1161 if ($qn->ns && array_key_exists($qn->ns, $this->wsdl->namespaces)) {
1162 $attrs[
'namespace'] = $qn->ns;
1167 $stack_size = count($this->schema_element_stack);
1168 if ($stack_size > 0) {
1172 if (isset($attrs[
'ref'])) {
1173 $qn =&
new QName($attrs[
'ref']);
1174 $this->currentElement = $qn->name;
1176 $this->currentElement = $attrs[
'name'];
1179 if (!isset($attrs[
'namespace'])) {
1183 if ($parent_tag ==
'schema') {
1186 $this->schemaStatus =
'element';
1187 } elseif ($this->currentComplexType) {
1189 if ((isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'order']) &&
1190 $this->wsdl->complexTypes[$this->schema][$this->currentComplexType][
'order'] ==
'sequence')
1191 && $this->wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'] ==
'Array') {
1200 case 'complexContent':
1201 case 'simpleContent':
1206 if ($this->schemaStatus ==
'complexType') {
1207 if (!empty($attrs[
'base'])) {
1208 $qn =&
new QName($attrs[
'base']);
1216 if ($qname->name ==
'extension') {
1226 if ($this->schemaStatus ==
'complexType') {
1228 if (!isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'])) {
1236 if (!isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'])) {
1243 if (!isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'])) {
1248 if ($this->schemaStatus ==
'complexType') {
1249 if (isset($attrs[
'name'])) {
1252 if (isset($attrs[
'ref'])) {
1253 $q =&
new QName($attrs[
'ref']);
1254 foreach ($attrs as $k => $v) {
1255 if ($k !=
'ref' && strstr($k, $q->name)) {
1256 $vq =&
new QName($v);
1257 if ($q->name ==
'arrayType') {
1272 $this->schema_stack[] = $qname->name;
1277 switch ($qname->name) {
1280 if (isset($attrs[
'type'])) {
1281 $qn =&
new QName($attrs[
'type']);
1282 } elseif (isset($attrs[
'element'])) {
1283 $qn =&
new QName($attrs[
'element']);
1286 $attrs[
'type'] = $qn->name;
1287 $attrs[
'namespace'] = $qn->ns;
1292 case 'documentation':
1302 switch ($qname->name) {
1306 $this->currentOperation = $attrs[
'name'];
1315 if ($this->currentOperation) {
1316 if (isset($this->
wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name])) {
1321 if (array_key_exists(
'message', $attrs)) {
1322 $qn =&
new QName($attrs[
'message']);
1329 case 'documentation':
1342 switch ($qname->name) {
1347 if (!isset($attrs[
'style'])) {
1348 $attrs[
'style'] =
'document';
1356 if (!isset($attrs[
'style'])) {
1359 if (isset($this->
wsdl->bindings[$this->currentBinding][
'operations'][$this->currentOperation])) {
1393 $header = count($this->
wsdl->bindings[$this->currentBinding]
1394 [
'operations'][$this->currentOperation][$this->opStatus][
'headers'])-1;
1399 case 'documentation':
1412 switch ($qname->name) {
1416 $this->currentOperation = $attrs[
'name'];
1424 $this->opStatus = $qname->name;
1427 case 'documentation':
1436 switch ($qname->name) {
1460 case 'urlReplacement':
1468 case 'documentation':
1480 switch ($qname->name) {
1487 case 'multipartRelated':
1494 case 'documentation':
1507 switch ($qname->name) {
1526 switch ($qname->name) {
1529 $this->currentPort = $attrs[
'name'];
1532 $qn =&
new QName($attrs[
'binding']);
1557 case 'documentation':
1566 switch ($qname->name) {
1569 if ((isset($attrs[
'location']) || isset($attrs[
'schemaLocation'])) &&
1570 !isset($this->
wsdl->imports[$attrs[
'namespace']])) {
1571 $uri = isset($attrs[
'location']) ? $attrs[
'location'] : $attrs[
'schemaLocation'];
1574 $base = @parse_url($this->uri);
1578 $this->
wsdl->imports[$attrs[
'namespace']] = $attrs;
1579 $import_parser_class = get_class($this);
1580 $import_parser =&
new $import_parser_class(
$uri, $this->
wsdl, $this->docs);
1581 if ($import_parser->fault) {
1582 unset($this->
wsdl->imports[$attrs[
'namespace']]);
1585 $this->currentImport = $attrs[
'namespace'];
1592 $this->status =
'types';
1598 if (!empty($attrs[
'targetNamespace'])) {
1599 $this->schema = $this->
wsdl->getNamespaceAttributeName($attrs[
'targetNamespace']);
1601 $this->schema = $this->
wsdl->getNamespaceAttributeName($this->
wsdl->tns);
1605 $this->schema_stack[] = $qname->name;
1606 $this->status =
'types';
1611 $this->status =
'message';
1612 if (isset($attrs[
'name'])) {
1613 $this->currentMessage = $attrs[
'name'];
1622 $this->status =
'portType';
1623 $this->currentPortType = $attrs[
'name'];
1630 if ($qname->ns && $qname->ns != $this->tns) {
1633 $this->status =
'binding';
1634 $this->currentBinding = $attrs[
'name'];
1635 $qn =&
new QName($attrs[
'type']);
1642 $this->currentService = $attrs[
'name'];
1643 $this->
wsdl->services[$this->currentService][
'ports'] = array();
1644 $this->status =
'service';
1651 $this->
wsdl->definition = $attrs;
1652 foreach ($attrs as $key => $value) {
1653 if (strstr($key,
'xmlns:') !==
false) {
1654 $qn =&
new QName($key);
1656 $this->
wsdl->namespaces[$qn->name] = $value;
1657 $this->
wsdl->ns[$value] = $qn->name;
1658 if ($key ==
'targetNamespace' ||
1660 $this->soapns[] = $qn->name;
1662 if (in_array($value, $this->_XMLSchema)) {
1663 $this->
wsdl->xsd = $value;
1668 if (isset($ns) && $ns) {
1671 return $this->
_raiseSoapFault(
"parse error, no namespace for $namespace", $this->uri);
1684 $stacksize = count($this->element_stack);
1686 if ($this->element_stack[$stacksize - 1] ==
'definitions') {
1689 array_pop($this->element_stack);
1692 if (stristr($name,
'schema')) {
1693 array_pop($this->schema_stack);
1697 if ($this->schema) {
1698 array_pop($this->schema_stack);
1699 if (count($this->schema_stack) <= 1) {
1702 if (isset($this->currentComplexType) && isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'])
1703 && $this->wsdl->complexTypes[$this->schema][$this->currentComplexType][
'type'] ==
'Array'
1704 && array_key_exists(
'elements', $this->
wsdl->complexTypes[$this->schema][$this->currentComplexType])
1705 && count($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType][
'elements']) > 1) {
1709 if (stristr($name,
'complexType')) {
1710 $this->currentComplexType =
'';
1711 if (count($this->schema_element_stack)) {
1712 $this->currentElement = array_pop($this->schema_element_stack);
1714 $this->currentElement =
'';
1716 } elseif (stristr($name,
'element')) {
1717 if (count($this->schema_element_stack)) {
1718 $this->currentElement = array_pop($this->schema_element_stack);
1720 $this->currentElement =
'';
1732 if ($this->currentTag ==
'documentation') {
1733 $data = trim(preg_replace(
'/\s+/',
' ',
$data));
1734 if (!strlen(
$data)) {
1738 switch ($this->status) {
1740 $ptr =& $this->
wsdl->services[$this->currentService];
1759 if (isset($this->currentComplexType) &&
1760 isset($this->
wsdl->complexTypes[$this->schema][$this->currentComplexType])) {
1761 if ($this->currentElement) {
1771 if (!isset($ptr[
'documentation'])) {
1772 $ptr[
'documentation'] =
'';
1774 $ptr[
'documentation'] .=
' ';
1776 $ptr[
'documentation'] .=
$data;
1788 if (!is_array($parsed)) {
1793 if (!empty($parsed[
'scheme'])) {
1794 $sep = (strtolower($parsed[
'scheme']) ==
'mailto' ?
':' :
'://');
1795 $uri = $parsed[
'scheme'] . $sep;
1798 if (isset($parsed[
'pass'])) {
1799 $uri .=
"$parsed[user]:$parsed[pass]@";
1800 } elseif (isset($parsed[
'user'])) {
1801 $uri .=
"$parsed[user]@";
1804 if (isset($parsed[
'host'])) {
1805 $uri .= $parsed[
'host'];
1807 if (isset($parsed[
'port'])) {
1808 $uri .=
":$parsed[port]";
1810 if (
$path[0] !=
'/' && isset($parsed[
'path'])) {
1811 if ($parsed[
'path'][strlen($parsed[
'path']) - 1] !=
'/') {
1812 $path = dirname($parsed[
'path']) .
'/' .
$path;
1818 $sep =
$path[0] ==
'/' ?
'' :
'/';
1827 $strArr = preg_split(
'/(\/)/', $path_str, -1, PREG_SPLIT_NO_EMPTY);
1830 for ($i = 0; $i < count($strArr); $i++) {
1831 if ($strArr[$i] !=
' ..') {
1832 if ($strArr[$i] !=
' .') {
1833 $pwdArr[$j] = $strArr[$i];
1841 $pStr = implode(
'/', $pwdArr);
1842 $pwd = (strlen($pStr) > 0) ? (
'/' . $pStr) :
'/';
1879 parent::ilBMFBase(
'WSDLOBJECTPARSER');
1887 $wsdl_ref = (is_array($objects)? $objects : array(&$objects));
1889 foreach ($wsdl_ref as $ref_item) {
1890 if (!is_object($ref_item))
1891 return $this->
_raiseSoapFault(
'Invalid web service object passed to object parser',
'urn:' . get_class($object));
1893 if ($this->
_parse($ref_item, $targetNamespace, $service_name) !=
true)
1898 if ($this->fault ==
null) {
1918 $this->
wsdl->namespaces[
'xsd'] = array_search(
'xsd', $this->_namespaces);
1919 $this->
wsdl->namespaces[
'SOAP-ENC'] = array_search(
'SOAP-ENC', $this->_namespaces);
1922 unset($this->
wsdl->ns[
'urn:' . $service_name]);
1923 $this->
wsdl->ns += array_flip($this->
wsdl->namespaces);
1937 function _parse(&$object, $schemaNamespace, $service_name)
1942 list($schPrefix, $foo) = $this->
_getTypeNs(
'{' . $schemaNamespace.
'}');
1949 foreach ($object->__typedef as $typeName => $typeValue) {
1952 list($nsPrefix, $typeName) = $this->
_getTypeNs($typeName);
1956 $this->
wsdl->complexTypes[$schPrefix][$typeName] = array(
'name' => $typeName);
1957 $thisType =& $this->
wsdl->complexTypes[$schPrefix][$typeName];
1964 if (is_array($typeValue)) {
1965 if (is_array(current($typeValue)) && count($typeValue) == 1
1966 && count(current($typeValue)) == 1) {
1969 $thisType[
'type'] =
'Array';
1970 list($nsPrefix, $typeName) = $this->
_getTypeNs(current(current($typeValue)));
1971 $thisType[
'namespace'] = $nsPrefix;
1972 $thisType[
'arrayType'] = $typeName .
'[]';
1973 } elseif (!is_array(current($typeValue))) {
1976 $thisType[
'type'] =
'Struct';
1977 $thisType[
'order'] =
'all';
1978 $thisType[
'namespace'] = $nsPrefix;
1979 $thisType[
'elements'] = array();
1981 foreach ($typeValue as $elementName => $elementType) {
1982 list($nsPrefix, $typeName) = $this->
_getTypeNs($elementType);
1983 $thisType[
'elements'][$elementName][
'name'] = $elementName;
1984 $thisType[
'elements'][$elementName][
'type'] = $typeName;
1985 $thisType[
'elements'][$elementName][
'namespace'] = $nsPrefix;
1989 return $this->
_raiseSoapFault(
"The type definition for $nsPrefix:$typeName is invalid.",
'urn:' . get_class($object));
1993 return $this->
_raiseSoapFault(
"The type definition for $nsPrefix:$typeName is invalid.",
'urn:' . get_class($object));
2000 $this->
wsdl->elements[$schPrefix] = array();
2005 foreach ($object->__dispatch_map as $operationName =>
$messages) {
2006 foreach (
$messages as $messageType => $messageParts) {
2007 unset($thisMessage);
2009 switch ($messageType) {
2011 $this->
wsdl->messages[$operationName .
'Request'] = array();
2012 $thisMessage =& $this->
wsdl->messages[$operationName .
'Request'];
2016 $this->
wsdl->messages[$operationName .
'Response'] = array();
2017 $thisMessage =& $this->
wsdl->messages[$operationName .
'Response'];
2029 if (isset($thisMessage)) {
2030 foreach ($messageParts as $partName => $partType) {
2031 list ($nsPrefix, $typeName) = $this->
_getTypeNs($partType);
2033 $thisMessage[$partName] = array(
2034 'name' => $partName,
2035 'type' => $typeName,
2036 'namespace' => $nsPrefix
2048 if (!isset($this->
wsdl->portTypes[$service_name .
'Port'])) {
2049 $this->
wsdl->portTypes[$service_name .
'Port'] = array();
2051 $thisPortType =& $this->
wsdl->portTypes[$service_name .
'Port'];
2053 foreach ($object->__dispatch_map as $operationName =>
$messages) {
2054 $thisPortType[$operationName] = array(
'name' => $operationName);
2056 foreach (
$messages as $messageType => $messageParts) {
2057 switch ($messageType) {
2059 $thisPortType[$operationName][
'input'] = array(
2060 'message' => $operationName .
'Request',
2061 'namespace' => $this->tnsPrefix);
2065 $thisPortType[$operationName][
'output'] = array(
2066 'message' => $operationName .
'Response',
2067 'namespace' => $this->tnsPrefix);
2095 $this->
wsdl->bindings[$service_name .
'Binding'] = array(
2096 'type' => $service_name .
'Port',
2097 'namespace' => $this->tnsPrefix,
2100 'operations' => array());
2101 $thisBinding =& $this->
wsdl->bindings[$service_name .
'Binding'];
2103 foreach ($this->
wsdl->portTypes[$service_name .
'Port'] as $operationName => $operationData) {
2104 $thisBinding[
'operations'][$operationName] = array(
2105 'soapAction' => $schemaNamespace .
'#' . $operationName,
2106 'style' => $thisBinding[
'style']);
2108 foreach (array(
'input',
'output') as $messageType)
2109 if (isset($operationData[$messageType])) {
2110 $thisBinding[
'operations'][$operationName][$messageType] = array(
2112 'namespace' => $schemaNamespace,
2123 $this->
wsdl->services[$service_name .
'Service'] = array(
'ports' => array());
2124 $thisService =& $this->
wsdl->services[$service_name .
'Service'][
'ports'];
2126 foreach ($this->
wsdl->bindings as $bindingName => $bindingData) {
2127 $thisService[$bindingData[
'type']] = array(
2128 'name' => $bindingData[
'type'],
2129 'binding' => $bindingName,
2130 'namespace' => $this->tnsPrefix,
2131 'address' => array(
'location' =>
2138 $this->
wsdl->set_service($service_name .
'Service');
2144 $this->
wsdl->definition = array(
2145 'name' => $service_name,
2146 'targetNamespace' => $this->
wsdl->namespaces[$this->tnsPrefix],
2167 preg_match_all(
"'\{(.*)\}'sm", $type, $m);
2168 if (isset($m[1][0]) && $m[1][0] !=
'') {
2169 if (!array_key_exists($m[1][0], $this->
wsdl->ns)) {
2170 $ns_pref =
'ns' . count($this->
wsdl->namespaces);
2171 $this->
wsdl->ns[$m[1][0]] = $ns_pref;
2172 $this->
wsdl->namespaces[$ns_pref] = $m[1][0];
2174 $typens = $this->
wsdl->ns[$m[1][0]];
2175 $type = ereg_replace($m[0][0],
'', $type);
2180 return array($typens, $type);
isError($data, $code=null)
Tell whether a value is a PEAR error.
const SOAP_XML_SCHEMA_VERSION
const SOAP_SCHEMA_ENCODING
$fault
Recent PEAR_Error object.
& _raiseSoapFault($str, $detail='', $actorURI='', $code=null, $mode=null, $options=null, $skipmsg=false)
Raises a SOAP error.
ilBMFWSDL_Cache($cacheUse=WSDL_CACHE_USE, $cacheMaxAge=WSDL_CACHE_MAX_AGE)
ilBMFWSDL_Cache constructor
_cacheDir()
_cacheDir return the path to the cache, if it doesn't exist, make it
Parses the types and methods used in web service objects into the internal data structures used by il...
ilBMFWSDL_ObjectParser(&$objects, &$wsdl, $targetNamespace, $service_name, $service_desc='')
Constructor.
$tnsPrefix
Target namespace for the WSDL document will have the following prefix.
_getTypeNs($type)
This function is adapted from Dmitri V's implementation of DISCO/WSDL generation.
$wsdl
Reference to the ilBMFWSDL object to populate.
_parse(&$object, $schemaNamespace, $service_name)
Parser - takes a single object to add to tree (non-destructive).
_generateBindingsAndServices($schemaNamespace, $service_name, $service_desc='')
Take all the abstract WSDL data and build concrete bindings and services (destructive).
_initialise($service_name)
Initialise the ilBMFWSDL tree (destructive).
startElement($parser, $name, $attrs)
start-element handler
mergeUrl($parsed, $path)
$parsed is an array returned by parse_url().
endElement($parser, $name)
end-element handler.
$currentMessage
Define internal arrays of bindings, ports, operations, messages, etc.
characterData($parser, $data)
Element content handler.
ilBMFWSDL_Parser($uri, &$wsdl, $docs=false)
constructor
_elementArg(&$args, &$argarray, &$_argtype, $_argname)
getNamespaceAttributeName($namespace)
getComplexTypeNameForElement($name, $namespace)
getNamespace($portName, $operation)
generateProxyCode($port='', $classname='')
Generates stub code from the WSDL that can be saved to a file or eval'd into existence.
getSoapAction($portName, $operation)
& _getComplexTypeForElement($name, $namespace)
parseURL($wsdl_uri, $proxy=array())
Fills the WSDL array tree with data from a WSDL file.
parse($wsdl_uri, $proxy=array())
getSchemaType($type, $name, $type_namespace)
_complexTypeArg(&$args, &$argarray, &$_argtype, $_argname)
getDataHandler($datatype, $namespace)
Given a datatype, what function handles the processing?
ilBMFWSDL($wsdl_uri=false, $proxy=array(), $cacheUse=WSDL_CACHE_USE, $cacheMaxAge=WSDL_CACHE_MAX_AGE, $docs=false)
ilBMFWSDL constructor.
getOperationData($portName, $operation)
getPortName($operation, $service=null)
Finds the name of the first port that contains an operation of name $operation.
_getDeepestArrayType($nsPrefix, $arrayType)
Recurse through the WSDL structure looking for the innermost array type of multi-dimensional arrays.
_getPortName($operation, $service)
& getProxy($port='', $name='')
parseObject(&$wsdl_obj, $targetNamespace, $service_name, $service_desc='')
Fills the WSDL array tree with data from one or more PHP class objects.
getComplexTypeChildType($ns, $name, $child_ns, $child_name)
_addArg(&$args, &$argarray, $argname)
parses a WSDL file, allows access to it's data, other utility methods
if($err=$client->getError()) $namespace
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']