SOAP
[ class tree: SOAP ] [ index: SOAP ] [ all elements ]

Source for file Disco.php

Documentation is available at Disco.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Dmitri Vinogradov <dimitri@vinogradov.de>                    |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Disco.php,v 1.8 2003/09/08 17:30:29 arnaud Exp $
  20.  
  21. require_once 'SOAP/Base.php';
  22.  
  23. class SOAP_DISCO_Server extends SOAP_Base_Object
  24. {
  25.     var $namespaces     = array(SCHEMA_WSDL => 'wsdl', SCHEMA_SOAP => 'soap');
  26.     var $import_ns      = array();
  27.     var $wsdl           = '';
  28.     var $disco          = '';
  29.     var $_wsdl          = array();
  30.     var $_disco         = array();
  31.     var $_service_name  = '';
  32.     var $_service_ns    = '';
  33.     var $_service_desc  = '';
  34.     var $_portname      = '';
  35.     var $_bindingname   = '';
  36.     var $soap_server    = NULL;
  37.  
  38.  
  39.     function SOAP_DISCO_Server($soap_server, $service_name, $service_desc = '', $import_ns = null)
  40.     {
  41.         parent::SOAP_Base_Object('Server');
  42.  
  43.         if ( !is_object($soap_server)
  44.             || !get_class($soap_server) == 'soap_server') return;
  45.  
  46.         $this->_service_name = $service_name;
  47.         $this->_service_ns = "urn:$service_name";
  48.         $this->_service_desc = $service_desc;
  49.         $this->import_ns = isset($import_ns) ? $import_ns : $this->import_ns;
  50.         $this->soap_server = $soap_server;
  51.         $this->host = isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'localhost';
  52.     }
  53.  
  54.     function getDISCO()
  55.     {
  56.         $this->_generate_DISCO();
  57.         return $this->disco;
  58.     }
  59.  
  60.     function getWSDL()
  61.     {
  62.         $this->_generate_WSDL();
  63.         return $this->wsdl;
  64.     }
  65.  
  66.     function _generate_DISCO()
  67.     {
  68.         # DISCO
  69.         $this->_disco['disco:discovery']['attr']['xmlns:disco'] = SCHEMA_DISCO;
  70.         $this->_disco['disco:discovery']['attr']['xmlns:scl'] = SCHEMA_DISCO_SCL;
  71.         $this->_disco['disco:discovery']['scl:contractRef']['attr']['ref'] =
  72.                                     (array_key_exists('HTTPS',$_SERVER) && $_SERVER['HTTPS']=='on')
  73.                                     ? 'https://' . $this->host . $_SERVER['PHP_SELF'] . '?wsdl'
  74.                                     : 'http://'  . $this->host . $_SERVER['PHP_SELF'] . '?wsdl';
  75.  
  76.         # generate disco xml
  77.         $this->_generate_DISCO_XML($this->_disco);
  78.     }
  79.  
  80.     function _generate_WSDL()
  81.     {
  82.         # WSDL
  83.         if (is_array($this->soap_server->_namespaces)) {
  84.             # need to get: typens, xsd & SOAP-ENC
  85.             $flipped = array_flip($this->soap_server->_namespaces);
  86.             $this->namespaces[$this->_service_ns] = 'tns';
  87.             $this->namespaces[$flipped['xsd']] = 'xsd';
  88.             $this->namespaces[$flipped['SOAP-ENC']] = 'SOAP-ENC';
  89.         }
  90.  
  91.         # DEFINITIONS
  92.         $this->_wsdl['definitions']['attr']['name'] = $this->_service_name;
  93.         $this->_wsdl['definitions']['attr']['targetNamespace'] = $this->_service_ns;
  94.         foreach ($this->namespaces as $ns => $prefix) {
  95.             $this->_wsdl['definitions']['attr']['xmlns:' . $prefix] = $ns;
  96.         }
  97.         $this->_wsdl['definitions']['attr']['xmlns'] = SCHEMA_WSDL;
  98.  
  99.         # import namespaces
  100.         # seems to not work yet: wsdl.exe fom .NET cant handle imported complete wsdl-definitions
  101.         #
  102.         if (count($this->import_ns)>0) {
  103.             $i = 0;
  104.             foreach ($this->import_ns as $_ns => $_location) {
  105.                 $this->_wsdl['definitions']['import'][$i]['attr']['location'] = $_location;
  106.                 $this->_wsdl['definitions']['import'][$i]['attr']['namespace'] = $_ns;
  107.                 $i++;
  108.             }
  109.         }
  110.         $this->_wsdl['definitions']['types']['attr']['xmlns']='http://schemas.xmlsoap.org/wsdl/';
  111.         $this->_wsdl['definitions']['types']['schema']=array();
  112.         # PORTTYPE-NAME
  113.         $this->_portname = $this->_service_name . 'Port';
  114.         $this->_wsdl['definitions']['portType']['attr']['name'] = $this->_portname;
  115.  
  116.         # BINDING-NAME
  117.         $this->_bindingname = $this->_service_name . 'Binding';
  118.         $this->_wsdl['definitions']['binding']['attr']['name'] = $this->_bindingname;
  119.         $this->_wsdl['definitions']['binding']['attr']['type'] = 'tns:' . $this->_portname;
  120.         $this->_wsdl['definitions']['binding']['soap:binding']['attr']['style'] = 'rpc';
  121.         $this->_wsdl['definitions']['binding']['soap:binding']['attr']['transport'] = SCHEMA_SOAP_HTTP;
  122.  
  123.         # SERVICE
  124.         $this->_wsdl['definitions']['service']['attr']['name'] = $this->_service_name . 'Service';
  125.         $this->_wsdl['definitions']['service']['documentation']['attr'] = '';
  126.         $this->_wsdl['definitions']['service']['documentation'] = htmlentities($this->_service_desc);
  127.         $this->_wsdl['definitions']['service']['port']['attr']['name'] = $this->_portname;
  128.         $this->_wsdl['definitions']['service']['port']['attr']['binding'] = 'tns:' . $this->_bindingname;
  129.         $this->_wsdl['definitions']['service']['port']['soap:address']['attr']['location'] =
  130.                                     (array_key_exists('HTTPS',$_SERVER) && $_SERVER['HTTPS']=='on')
  131.                                     ? 'https://' . $this->host . $_SERVER['PHP_SELF']
  132.                                     : 'http://'  . $this->host . $_SERVER['PHP_SELF'];
  133.  
  134.         #
  135.         $dispatch_keys = array_keys($this->soap_server->dispatch_objects);
  136.         $dc = count($dispatch_keys);
  137.         for ($di=0; $di < $dc; $di++) {
  138.             $namespace = $dispatch_keys[$di];
  139.             $namespace_objects =& $this->soap_server->dispatch_objects[$namespace];
  140.             $oc = count($namespace_objects);
  141.             for ($oi = 0; $oi < $oc; $oi++) {
  142.                 $object = $namespace_objects[$oi];
  143.                 # types definitions
  144.                 $this->addSchemaFromMap($object->__typedef);
  145.                 # MESSAGES
  146.                 $this->addMethodsFromMap($object->__dispatch_map,$namespace,get_class($object));
  147.             }
  148.         }
  149.         if (isset($server->dispatch_map))
  150.             $this->addMethodsFromMap($server->dispatch_map,$namespace);
  151.  
  152.  
  153.         # generate wsdl
  154.         $this->_generate_WSDL_XML($this->_wsdl);
  155.     }
  156.  
  157.     function &_getSchema($namespace) {
  158.         # SCHEMA
  159.         $c = count($this->_wsdl['definitions']['types']['schema']);
  160.         for($i = 0; $i < $c; $i++) {
  161.             if ($this->_wsdl['definitions']['types']['schema'][$i]['attr']['targetNamespace'] == $namespace)
  162.                 return $this->_wsdl['definitions']['types']['schema'][$i];
  163.         }
  164.         # don't have this namespace
  165.         $schema = array();
  166.         $schema['attr'] = array();
  167.         $schema['complexType'] = array();
  168.         $schema['attr']['xmlns'] = array_search('xsd',$this->namespaces);
  169.         $schema['attr']['targetNamespace'] = $namespace;
  170.         $this->_wsdl['definitions']['types']['schema'][] =& $schema;
  171.         return $schema;
  172.     }
  173.  
  174.     function addSchemaFromMap(&$map) {
  175.         if (!$map) return;
  176.         foreach ($map as $_type_name => $_type_def) {
  177.             list($typens,$type) = $this->_getTypeNs($_type_name);
  178.             if ($typens == 'xsd') {
  179.                 // cannot add to xsd, lets use method_namespace
  180.                 $typens = 'tns';
  181.             }
  182.             $schema =& $this->_getSchema(array_search($typens,$this->namespaces));
  183.             if (!$this->_ifComplexTypeExists($schema['complexType'], $type)) {
  184.                 $ctype =& $schema['complexType'][];
  185.                 $ctype['attr']['name'] = $type;
  186.                 foreach ($_type_def as $_varname => $_vartype) {
  187.                     if (!is_int($_varname)) {
  188.                         list($_vartypens,$_vartype) = $this->_getTypeNs($_vartype);
  189.                         $ctype['all']['attr'] = '';
  190.                         $el =& $ctype['all']['element'][];
  191.                         $el['attr']['name'] = $_varname;
  192.                         $el['attr']['type'] = $_vartypens . ':' . $_vartype;
  193.                     } else {
  194.                         $ctype['complexContent']['attr'] = '';
  195.                         $ctype['complexContent']['restriction']['attr']['base'] = 'SOAP-ENC:Array';
  196.                         foreach ($_vartype as $array_var => $array_type) {
  197.                             list($_vartypens,$_vartype) = $this->_getTypeNs($array_type);
  198.                             $ctype['complexContent']['restriction']['attribute']['attr']['ref'] = 'SOAP-ENC:arrayType';
  199.                             $ctype['complexContent']['restriction']['attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]';
  200.                         }
  201.                     }
  202.                 }
  203.             }
  204.         }
  205.     }
  206.  
  207.     function addMethodsFromMap(&$map, $namespace, $classname = null)
  208.     {
  209.         if (!$map) {
  210.             return;
  211.         }
  212.  
  213.         foreach ($map as $method_name => $method_types) {
  214.             if (array_key_exists('namespace',$method_types)) {
  215.                 $method_namespace = $method_types['namespace'];
  216.             } else {
  217.                 $method_namespace = $namespace;
  218.             }
  219.             # INPUT
  220.             if (isset($method_types['in']) && is_array($method_types['in'])) {
  221.                 $input_message =& $this->_wsdl['definitions']['message'][];
  222.                 $input_message['attr']['name'] = $method_name . 'Request';
  223.                 foreach ($method_types['in'] as $name => $type) {
  224.                     list($typens,$type) = $this->_getTypeNs($type);
  225.                     $part =& $input_message['part'][];
  226.                     $part['attr']['name'] = $name;
  227.                     $part['attr']['type'] = $typens . ':' . $type;
  228.                 }
  229.             }
  230.  
  231.             # OUTPUT
  232.             if (isset($method_types['out']) && is_array($method_types['out'])) {
  233.                 $output_message =& $this->_wsdl['definitions']['message'][];
  234.                 $output_message['attr']['name'] = $method_name . 'Response';
  235.                 foreach ($method_types['out'] as $name => $type) {
  236.                     list($typens,$type) = $this->_getTypeNs($type);
  237.                     $part =& $output_message['part'][];
  238.                     $part['attr']['name'] = $name;
  239.                     $part['attr']['type'] = $typens . ':' . $type;
  240.                 }
  241.             }
  242.  
  243.             # PORTTYPES
  244.             $operation =& $this->_wsdl['definitions']['portType']['operation'][];
  245.  
  246.             $operation['attr']['name'] = $method_name;
  247.  
  248.             # INPUT
  249.             $operation['input']['attr']['message'] = 'tns:'
  250.                             . $input_message['attr']['name'];
  251.  
  252.             # OUTPUT
  253.             $operation['output']['attr']['message'] = 'tns:'
  254.                             . $output_message['attr']['name'];
  255.  
  256.             # BINDING
  257.             $binding =& $this->_wsdl['definitions']['binding']['operation'][];
  258.             $binding['attr']['name'] = $method_name;
  259.             $action = $method_namespace . '#' . ($classname?$classname . '#':'') . $method_name;
  260.             $binding['soap:operation']['attr']['soapAction'] = $action;
  261.  
  262.             # INPUT
  263.             $binding['input']['attr'] = '';
  264.             $binding['input']['soap:body']['attr']['use'] = 'encoded';
  265.             $binding['input']['soap:body']['attr']['namespace'] = $method_namespace;
  266.             $binding['input']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING;
  267.  
  268.             # OUTPUT
  269.             $binding['output']['attr'] = '';
  270.             $binding['output']['soap:body']['attr']['use'] = 'encoded';
  271.             $binding['output']['soap:body']['attr']['namespace'] = $method_namespace;
  272.             $binding['output']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING;
  273.         }
  274.     }
  275.  
  276.     function _generate_DISCO_XML($disco_array) {
  277.         $disco = '<?xml version="1.0"?>';
  278.         foreach ($disco_array as $key => $val) {
  279.             $disco .= $this->_arrayToNode($key,$val);
  280.         }
  281.         $this->disco = $disco;
  282.     }
  283.  
  284.     function _generate_WSDL_XML($wsdl_array) {
  285.         $wsdl = '<?xml version="1.0"?>';
  286.         foreach ($wsdl_array as $key => $val) {
  287.             $wsdl .= $this->_arrayToNode($key,$val);
  288.         }
  289.         $this->wsdl = $wsdl;
  290.     }
  291.  
  292.     function _arrayToNode($node_name = '', $array) {
  293.         $return = '';
  294.         if (is_array($array)) {
  295.             # we have a node if there's key 'attr'
  296.             if (array_key_exists('attr',$array)) {
  297.                 $return .= "<$node_name";
  298.                 if (is_array($array['attr'])) {
  299.                     foreach ($array['attr'] as $attr_name => $attr_value) {
  300.                         $return .= " $attr_name=\"$attr_value\"";
  301.                     }
  302.                 }
  303.  
  304.                 # unset 'attr' and proceed other childs...
  305.                 unset($array['attr']);
  306.  
  307.                 if (count($array) > 0) {
  308.                     $i = 0;
  309.                     foreach ($array as $child_node_name => $child_node_value) {
  310.                         $return .= $i == 0 ? ">\n" : '';
  311.                         $return .= $this->_arrayToNode($child_node_name,$child_node_value);
  312.                         $i++;
  313.                     }
  314.                     $return .= "</$node_name>\n";
  315.                 } else {
  316.                     $return .= " />\n";
  317.                 }
  318.             } else {
  319.                 # we have no 'attr' key in array - so it's list of nodes with the same name ...
  320.                 foreach ($array as $child_node_name => $child_node_value) {
  321.                     $return .= $this->_arrayToNode($node_name,$child_node_value);
  322.                 }
  323.             }
  324.         } else {
  325.             # $array is not an array
  326.             if ($array !='') {
  327.                 # and its not empty
  328.                 $return .= "<$node_name>$array</$node_name>\n";
  329.             } else {
  330.                 # and its empty...
  331.                 $return .= "<$node_name />\n";
  332.             }
  333.         }
  334.         return $return;
  335.     }
  336.  
  337.     function _getTypeNs($type) {
  338.         preg_match_all("'\{(.*)\}'sm",$type,$m);
  339.         if (isset($m[1][0]) && $m[1][0] != '') {
  340.             if (!array_key_exists($m[1][0],$this->namespaces)) {
  341.                 $ns_pref = 'ns' . count($this->namespaces);
  342.                 $this->namespaces[$m[1][0]] = $ns_pref;
  343.                 $this->_wsdl['definitions']['attr']['xmlns:' . $ns_pref] = $m[1][0];
  344.             }
  345.             $typens = $this->namespaces[$m[1][0]];
  346.             $type = ereg_replace($m[0][0],'',$type);
  347.         } else {
  348.             $typens = 'xsd';
  349.         }
  350.         return array($typens,$type);
  351.     }
  352.  
  353.     function _ifComplexTypeExists($typesArray, $type_name) {
  354.         if (is_array($typesArray)) {
  355.             foreach ($typesArray as $index => $type_data) {
  356.                 if ($typesArray[$index]['attr']['name'] == $type_name) {
  357.                     return true;
  358.                 }
  359.             }
  360.         }
  361.         return false;
  362.     }
  363. }
  364. ?>

Documentation generated on Mon, 11 Mar 2019 13:59:45 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.