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

Source for file Disco.php

Documentation is available at Disco.php

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

Documentation generated on Mon, 04 Aug 2008 20:00:17 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.