Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 require_once dirname(__FILE__).'/class.ilBMFBase.php';
00022
00023 class ilBMFDISCO_Server extends ilBMFBase_Object
00024 {
00025 var $namespaces = array(SCHEMA_WSDL => 'wsdl', SCHEMA_SOAP => 'soap');
00026 var $import_ns = array();
00027 var $wsdl = '';
00028 var $disco = '';
00029 var $_wsdl = array();
00030 var $_disco = array();
00031 var $_service_name = '';
00032 var $_service_ns = '';
00033 var $_service_desc = '';
00034 var $_portname = '';
00035 var $_bindingname = '';
00036 var $soap_server = NULL;
00037
00038
00039 function ilBMFDISCO_Server($soap_server, $service_name, $service_desc = '', $import_ns = null)
00040 {
00041 parent::ilBMFBase_Object('Server');
00042
00043 if ( !is_object($soap_server)
00044 || !get_class($soap_server) == 'ilbmfserver') return;
00045
00046 $this->_service_name = $service_name;
00047 $this->_service_ns = "urn:$service_name";
00048 $this->_service_desc = $service_desc;
00049 $this->import_ns = isset($import_ns) ? $import_ns : $this->import_ns;
00050 $this->soap_server = $soap_server;
00051 $this->host = isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'localhost';
00052 }
00053
00054 function getDISCO()
00055 {
00056 $this->_generate_DISCO();
00057 return $this->disco;
00058 }
00059
00060 function getWSDL()
00061 {
00062 $this->_generate_WSDL();
00063 return $this->wsdl;
00064 }
00065
00066 function _generate_DISCO()
00067 {
00068 # DISCO
00069 $this->_disco['disco:discovery']['attr']['xmlns:disco'] = SCHEMA_DISCO;
00070 $this->_disco['disco:discovery']['attr']['xmlns:scl'] = SCHEMA_DISCO_SCL;
00071 $this->_disco['disco:discovery']['scl:contractRef']['attr']['ref'] =
00072 (array_key_exists('HTTPS',$_SERVER) && $_SERVER['HTTPS']=='on')
00073 ? 'https://' . $this->host . $_SERVER['PHP_SELF'] . '?wsdl'
00074 : 'http://' . $this->host . $_SERVER['PHP_SELF'] . '?wsdl';
00075
00076 # generate disco xml
00077 $this->_generate_DISCO_XML($this->_disco);
00078 }
00079
00080 function _generate_WSDL()
00081 {
00082 # WSDL
00083 if (is_array($this->soap_server->_namespaces)) {
00084 # need to get: typens, xsd & SOAP-ENC
00085 $flipped = array_flip($this->soap_server->_namespaces);
00086 $this->namespaces[$this->_service_ns] = 'tns';
00087 $this->namespaces[$flipped['xsd']] = 'xsd';
00088 $this->namespaces[$flipped['SOAP-ENC']] = 'SOAP-ENC';
00089 }
00090
00091 # DEFINITIONS
00092 $this->_wsdl['definitions']['attr']['name'] = $this->_service_name;
00093 $this->_wsdl['definitions']['attr']['targetNamespace'] = $this->_service_ns;
00094 foreach ($this->namespaces as $ns => $prefix) {
00095 $this->_wsdl['definitions']['attr']['xmlns:' . $prefix] = $ns;
00096 }
00097 $this->_wsdl['definitions']['attr']['xmlns'] = SCHEMA_WSDL;
00098
00099 # import namespaces
00100 # seems to not work yet: wsdl.exe fom .NET cant handle imported complete wsdl-definitions
00101 #
00102 if (count($this->import_ns)>0) {
00103 $i = 0;
00104 foreach ($this->import_ns as $_ns => $_location) {
00105 $this->_wsdl['definitions']['import'][$i]['attr']['location'] = $_location;
00106 $this->_wsdl['definitions']['import'][$i]['attr']['namespace'] = $_ns;
00107 $i++;
00108 }
00109 }
00110 $this->_wsdl['definitions']['types']['attr']['xmlns']='http://schemas.xmlsoap.org/wsdl/';
00111 $this->_wsdl['definitions']['types']['schema']=array();
00112 # PORTTYPE-NAME
00113 $this->_portname = $this->_service_name . 'Port';
00114 $this->_wsdl['definitions']['portType']['attr']['name'] = $this->_portname;
00115
00116 # BINDING-NAME
00117 $this->_bindingname = $this->_service_name . 'Binding';
00118 $this->_wsdl['definitions']['binding']['attr']['name'] = $this->_bindingname;
00119 $this->_wsdl['definitions']['binding']['attr']['type'] = 'tns:' . $this->_portname;
00120 $this->_wsdl['definitions']['binding']['soap:binding']['attr']['style'] = 'rpc';
00121 $this->_wsdl['definitions']['binding']['soap:binding']['attr']['transport'] = SCHEMA_SOAP_HTTP;
00122
00123 # SERVICE
00124 $this->_wsdl['definitions']['service']['attr']['name'] = $this->_service_name . 'Service';
00125 $this->_wsdl['definitions']['service']['documentation']['attr'] = '';
00126 $this->_wsdl['definitions']['service']['documentation'] = htmlentities($this->_service_desc);
00127 $this->_wsdl['definitions']['service']['port']['attr']['name'] = $this->_portname;
00128 $this->_wsdl['definitions']['service']['port']['attr']['binding'] = 'tns:' . $this->_bindingname;
00129 $this->_wsdl['definitions']['service']['port']['soap:address']['attr']['location'] =
00130 (array_key_exists('HTTPS',$_SERVER) && $_SERVER['HTTPS']=='on')
00131 ? 'https://' . $this->host . $_SERVER['PHP_SELF']
00132 : 'http://' . $this->host . $_SERVER['PHP_SELF'];
00133
00134 #
00135 $dispatch_keys = array_keys($this->soap_server->dispatch_objects);
00136 $dc = count($dispatch_keys);
00137 for ($di=0; $di < $dc; $di++) {
00138 $namespace = $dispatch_keys[$di];
00139 $namespace_objects =& $this->soap_server->dispatch_objects[$namespace];
00140 $oc = count($namespace_objects);
00141 for ($oi = 0; $oi < $oc; $oi++) {
00142 $object = $namespace_objects[$oi];
00143 # types definitions
00144 $this->addSchemaFromMap($object->__typedef);
00145 # MESSAGES
00146 $this->addMethodsFromMap($object->__dispatch_map,$namespace,get_class($object));
00147 }
00148 }
00149 if (isset($server->dispatch_map))
00150 $this->addMethodsFromMap($server->dispatch_map,$namespace);
00151
00152
00153 # generate wsdl
00154 $this->_generate_WSDL_XML($this->_wsdl);
00155 }
00156
00157 function &_getSchema($namespace) {
00158 # SCHEMA
00159 $c = count($this->_wsdl['definitions']['types']['schema']);
00160 for($i = 0; $i < $c; $i++) {
00161 if ($this->_wsdl['definitions']['types']['schema'][$i]['attr']['targetNamespace'] == $namespace)
00162 return $this->_wsdl['definitions']['types']['schema'][$i];
00163 }
00164 # don't have this namespace
00165 $schema = array();
00166 $schema['attr'] = array();
00167 $schema['complexType'] = array();
00168 $schema['attr']['xmlns'] = array_search('xsd',$this->namespaces);
00169 $schema['attr']['targetNamespace'] = $namespace;
00170 $this->_wsdl['definitions']['types']['schema'][] =& $schema;
00171 return $schema;
00172 }
00173
00174 function addSchemaFromMap(&$map) {
00175 if (!$map) return;
00176 foreach ($map as $_type_name => $_type_def) {
00177 list($typens,$type) = $this->_getTypeNs($_type_name);
00178 if ($typens == 'xsd') {
00179
00180 $typens = 'tns';
00181 }
00182 $schema =& $this->_getSchema(array_search($typens,$this->namespaces));
00183 if (!$this->_ifComplexTypeExists($schema['complexType'], $type)) {
00184 $ctype =& $schema['complexType'][];
00185 $ctype['attr']['name'] = $type;
00186 foreach ($_type_def as $_varname => $_vartype) {
00187 if (!is_int($_varname)) {
00188 list($_vartypens,$_vartype) = $this->_getTypeNs($_vartype);
00189 $ctype['all']['attr'] = '';
00190 $el =& $ctype['all']['element'][];
00191 $el['attr']['name'] = $_varname;
00192 $el['attr']['type'] = $_vartypens . ':' . $_vartype;
00193 } else {
00194 $ctype['complexContent']['attr'] = '';
00195 $ctype['complexContent']['restriction']['attr']['base'] = 'SOAP-ENC:Array';
00196 foreach ($_vartype as $array_var => $array_type) {
00197 list($_vartypens,$_vartype) = $this->_getTypeNs($array_type);
00198 $ctype['complexContent']['restriction']['attribute']['attr']['ref'] = 'SOAP-ENC:arrayType';
00199 $ctype['complexContent']['restriction']['attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]';
00200 }
00201 }
00202 }
00203 }
00204 }
00205 }
00206
00207 function addMethodsFromMap(&$map, $namespace, $classname = null)
00208 {
00209 if (!$map) {
00210 return;
00211 }
00212
00213 foreach ($map as $method_name => $method_types) {
00214 if (array_key_exists('namespace',$method_types)) {
00215 $method_namespace = $method_types['namespace'];
00216 } else {
00217 $method_namespace = $namespace;
00218 }
00219 # INPUT
00220 if (isset($method_types['in']) && is_array($method_types['in'])) {
00221 $input_message =& $this->_wsdl['definitions']['message'][];
00222 $input_message['attr']['name'] = $method_name . 'Request';
00223 foreach ($method_types['in'] as $name => $type) {
00224 list($typens,$type) = $this->_getTypeNs($type);
00225 $part =& $input_message['part'][];
00226 $part['attr']['name'] = $name;
00227 $part['attr']['type'] = $typens . ':' . $type;
00228 }
00229 }
00230
00231 # OUTPUT
00232 if (isset($method_types['out']) && is_array($method_types['out'])) {
00233 $output_message =& $this->_wsdl['definitions']['message'][];
00234 $output_message['attr']['name'] = $method_name . 'Response';
00235 foreach ($method_types['out'] as $name => $type) {
00236 list($typens,$type) = $this->_getTypeNs($type);
00237 $part =& $output_message['part'][];
00238 $part['attr']['name'] = $name;
00239 $part['attr']['type'] = $typens . ':' . $type;
00240 }
00241 }
00242
00243 # PORTTYPES
00244 $operation =& $this->_wsdl['definitions']['portType']['operation'][];
00245
00246 $operation['attr']['name'] = $method_name;
00247
00248 # INPUT
00249 $operation['input']['attr']['message'] = 'tns:'
00250 . $input_message['attr']['name'];
00251
00252 # OUTPUT
00253 $operation['output']['attr']['message'] = 'tns:'
00254 . $output_message['attr']['name'];
00255
00256 # BINDING
00257 $binding =& $this->_wsdl['definitions']['binding']['operation'][];
00258 $binding['attr']['name'] = $method_name;
00259 $action = $method_namespace . '#' . ($classname?$classname . '#':'') . $method_name;
00260 $binding['soap:operation']['attr']['soapAction'] = $action;
00261
00262 # INPUT
00263 $binding['input']['attr'] = '';
00264 $binding['input']['soap:body']['attr']['use'] = 'encoded';
00265 $binding['input']['soap:body']['attr']['namespace'] = $method_namespace;
00266 $binding['input']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING;
00267
00268 # OUTPUT
00269 $binding['output']['attr'] = '';
00270 $binding['output']['soap:body']['attr']['use'] = 'encoded';
00271 $binding['output']['soap:body']['attr']['namespace'] = $method_namespace;
00272 $binding['output']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING;
00273 }
00274 }
00275
00276 function _generate_DISCO_XML($disco_array) {
00277 $disco = '<?xml version="1.0"?>';
00278 foreach ($disco_array as $key => $val) {
00279 $disco .= $this->_arrayToNode($key,$val);
00280 }
00281 $this->disco = $disco;
00282 }
00283
00284 function _generate_WSDL_XML($wsdl_array) {
00285 $wsdl = '<?xml version="1.0"?>';
00286 foreach ($wsdl_array as $key => $val) {
00287 $wsdl .= $this->_arrayToNode($key,$val);
00288 }
00289 $this->wsdl = $wsdl;
00290 }
00291
00292 function _arrayToNode($node_name = '', $array) {
00293 $return = '';
00294 if (is_array($array)) {
00295 # we have a node if there's key 'attr'
00296 if (array_key_exists('attr',$array)) {
00297 $return .= "<$node_name";
00298 if (is_array($array['attr'])) {
00299 foreach ($array['attr'] as $attr_name => $attr_value) {
00300 $return .= " $attr_name=\"$attr_value\"";
00301 }
00302 }
00303
00304 # unset 'attr' and proceed other childs...
00305 unset($array['attr']);
00306
00307 if (count($array) > 0) {
00308 $i = 0;
00309 foreach ($array as $child_node_name => $child_node_value) {
00310 $return .= $i == 0 ? ">\n" : '';
00311 $return .= $this->_arrayToNode($child_node_name,$child_node_value);
00312 $i++;
00313 }
00314 $return .= "</$node_name>\n";
00315 } else {
00316 $return .= " />\n";
00317 }
00318 } else {
00319 # we have no 'attr' key in array - so it's list of nodes with the same name ...
00320 foreach ($array as $child_node_name => $child_node_value) {
00321 $return .= $this->_arrayToNode($node_name,$child_node_value);
00322 }
00323 }
00324 } else {
00325 # $array is not an array
00326 if ($array !='') {
00327 # and its not empty
00328 $return .= "<$node_name>$array</$node_name>\n";
00329 } else {
00330 # and its empty...
00331 $return .= "<$node_name />\n";
00332 }
00333 }
00334 return $return;
00335 }
00336
00337 function _getTypeNs($type) {
00338 preg_match_all("'\{(.*)\}'sm",$type,$m);
00339 if (isset($m[1][0]) && $m[1][0] != '') {
00340 if (!array_key_exists($m[1][0],$this->namespaces)) {
00341 $ns_pref = 'ns' . count($this->namespaces);
00342 $this->namespaces[$m[1][0]] = $ns_pref;
00343 $this->_wsdl['definitions']['attr']['xmlns:' . $ns_pref] = $m[1][0];
00344 }
00345 $typens = $this->namespaces[$m[1][0]];
00346 $type = ereg_replace($m[0][0],'',$type);
00347 } else {
00348 $typens = 'xsd';
00349 }
00350 return array($typens,$type);
00351 }
00352
00353 function _ifComplexTypeExists($typesArray, $type_name) {
00354 if (is_array($typesArray)) {
00355 foreach ($typesArray as $index => $type_data) {
00356 if ($typesArray[$index]['attr']['name'] == $type_name) {
00357 return true;
00358 }
00359 }
00360 }
00361 return false;
00362 }
00363 }
00364 ?>