home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Services / Webservice.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  32.5 KB  |  870 lines

  1. <?php
  2.  
  3. ini_set('error_reporting',E_ALL);
  4. ini_set('error_log','/var/www/error.log');
  5.  
  6. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  7.  
  8. /**
  9.  * Easy Web Service (SOAP) creation
  10.  *
  11.  * PHP 5
  12.  *
  13.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  14.  * that is available through the world-wide-web at the following URI:
  15.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  16.  * the PHP License and are unable to obtain it through the web, please
  17.  * send a note to license@php.net so we can mail you a copy immediately.
  18.  *
  19.  * @category   Services
  20.  * @package    Webservice
  21.  * @author     Manfred Weber <weber@mayflower.de>
  22.  * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
  23.  * @copyright  2005 The PHP Group
  24.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  25.  * @version    CVS: $Id: Webservice.php,v 1.14 2006/12/28 10:52:33 crafics Exp $
  26.  * @link       http://dschini.org/Services/
  27.  */
  28.  
  29. // {{{ abstract class Services_WebService
  30.  
  31. /**
  32.  * PEAR::Services_Webservice
  33.  *
  34.  * The PEAR::Services_WebService class creates web services from your classes
  35.  *
  36.  * @author  Manfred Weber <weber@mayflower.de>
  37.  * @package Webservices
  38.  * @version
  39.  */
  40. abstract class Services_Webservice
  41. {
  42.     /**
  43.      * Namespace of the webservice
  44.      *
  45.      * @var    string
  46.      * @access public
  47.      */
  48.     public $namespace;
  49.  
  50.     /**
  51.      * Description of the webservice
  52.      *
  53.      * @var    string
  54.      * @access public
  55.      */
  56.     public $description;
  57.  
  58.     /**
  59.      * Protocol of the webservice
  60.      *
  61.      * @var    string
  62.      * @access public
  63.      */
  64.     public $protocol;
  65.  
  66.  
  67.     /**
  68.      * SOAP-server options of the webservice
  69.      *
  70.      * @var    array
  71.      * @access public
  72.      */
  73.     public $soapServerOptions = array();
  74.  
  75.     /**
  76.      * SOAP schema related URIs
  77.      *
  78.      * @access private
  79.      */
  80.     const SOAP_XML_SCHEMA_VERSION  = 'http://www.w3.org/2001/XMLSchema';
  81.     const SOAP_XML_SCHEMA_INSTANCE = 'http://www.w3.org/2001/XMLSchema-instance';
  82.     const SOAP_SCHEMA_ENCODING   = 'http://schemas.xmlsoap.org/soap/encoding/';
  83.     const SOAP_XML_SCHEMA_MIME   = 'http://schemas.xmlsoap.org/wsdl/mime/';
  84.     const SOAP_ENVELOP           = 'http://schemas.xmlsoap.org/soap/envelope/';
  85.     const SCHEMA_SOAP_HTTP       = 'http://schemas.xmlsoap.org/soap/http';
  86.     const SCHEMA_SOAP            = 'http://schemas.xmlsoap.org/wsdl/soap/';
  87.     const SCHEMA_WSDL            = 'http://schemas.xmlsoap.org/wsdl/';
  88.     const SCHEMA_WSDL_HTTP       = 'http://schemas.xmlsoap.org/wsdl/http/';
  89.     const SCHEMA_DISCO           = 'http://schemas.xmlsoap.org/disco/';
  90.     const SCHEMA_DISCO_SCL       = 'http://schemas.xmlsoap.org/disco/scl/';
  91.     const SCHEMA_DISCO_SOAP      = 'http://schemas.xmlsoap.org/disco/soap/';
  92.  
  93.     /**
  94.      * Simple WSDL types
  95.      *
  96.      * @var    array
  97.      * @access private
  98.      */
  99.     private $simpleTypes = array(
  100.         'string', 'int', 'float', 'bool', 'double', 'integer', 'boolean',
  101.         'varstring', 'varint', 'varfloat', 'varbool', 'vardouble',
  102.         'varinteger', 'varboolean');
  103.  
  104.     /**
  105.      * classes are parsed into struct
  106.      *
  107.      * @var    array
  108.      * @access private
  109.      */
  110.     private $wsdlStruct;
  111.  
  112.     /**
  113.      * disco dom root node
  114.      * the disco dom object
  115.      *
  116.      * @var    object
  117.      * @access private
  118.      */
  119.     private $disco;
  120.  
  121.     /**
  122.      * wsdl dom root node
  123.      * the wsdl dom object
  124.      *
  125.      * @var    object
  126.      * @access private
  127.      */
  128.     private $wsdl;
  129.  
  130.     /**
  131.      * wsdl-definitions dom node
  132.      *
  133.      * @var    object
  134.      * @access private
  135.      */
  136.     private $wsdl_definitions;
  137.  
  138.     /**
  139.      * Name of the class from which to create a webservice from
  140.      *
  141.      * @var    string
  142.      * @access private
  143.      */
  144.     private $classname;
  145.  
  146.     /**
  147.      * exclude these methods from webservice
  148.      *
  149.      * @var    array
  150.      * @access private
  151.      */
  152.     private $preventMethods;
  153.  
  154.     /**
  155.      * error namespace
  156.      *
  157.      * @var    bool
  158.      * @access private
  159.      */
  160.     private $warningNamespace;
  161.  
  162.     /**
  163.      * error description
  164.      *
  165.      * @var    bool
  166.      * @access private
  167.      */
  168.     private $errorDescription;
  169.  
  170.     /**
  171.      * constructor
  172.      *
  173.      * @var    string
  174.      * @var    string
  175.      * @var    array
  176.      * @access public
  177.      */
  178.     public function __construct($namespace, $description, $options)
  179.     {
  180.         if (isset($namespace) && $namespace != '') {
  181.             $this->warningNamespace   = false;
  182.             $this->errorDescription = false;
  183.             //$namespace .= (substr($namespace, -1) == '/') ? '' : '/';
  184.         } else {
  185.             $this->warningNamespace   = true;
  186.             $this->errorDescription = true;
  187.             $namespace = 'http://example.org/';
  188.         }
  189.         $this->namespace   = $namespace;
  190.         $this->description = ($description != '') ? $description : 'my example service description';
  191.         $this->soapServerOptions = (isset($options) && count($options) > 0) ? $options : array(
  192.             'uri' => $this->namespace,
  193.             'encoding' => SOAP_ENCODED);
  194.         $this->wsdlStruct = array();
  195.         $this->preventMethods = array(
  196.             '__construct',
  197.             '__destruct',
  198.             'handle');
  199.         $this->protocol = 'http';
  200.     }
  201.  
  202.     // }}}
  203.     // {{{ handle()
  204.     /**
  205.      * handle
  206.      *
  207.      * @access public
  208.      */
  209.     public function handle()
  210.     {
  211.         switch (strtolower($_SERVER['QUERY_STRING'])){
  212.             case 'wsdl':
  213.                 $this->intoStruct();
  214.                 $this->handleWSDL();
  215.                 break;
  216.             case 'disco':
  217.                 $this->intoStruct();
  218.                 $this->handleDISCO();
  219.                 break;
  220.             default:
  221.                 $this->intoStruct();
  222.                 if (isset($_SERVER['HTTP_SOAPACTION'])) {
  223.                     $this->createServer();
  224.                 } else {
  225.                     $this->handleINFO();
  226.                 }
  227.                 break;
  228.         }
  229.     }
  230.  
  231.     // }}}
  232.     // {{{ createServer()
  233.     /**
  234.      * create the soap-server
  235.      *
  236.      * @access private
  237.      */
  238.     private function createServer()
  239.     {
  240.         $server = new SoapServer(null, $this->soapServerOptions);
  241.         $server->SetClass($this->classname);
  242.         $server->handle();
  243.     }
  244.  
  245.     // }}}
  246.     // {{{ handleWSDL()
  247.     /**
  248.      * handle wsdl
  249.      *
  250.      * @access private
  251.      */
  252.     private function handleWSDL()
  253.     {
  254.         header('Content-Type: text/xml');
  255.         $this->wsdl = new DOMDocument('1.0' ,'utf-8');
  256.         $this->createWSDL_definitions();
  257.         $this->createWSDL_types();
  258.         $this->createWSDL_messages();
  259.         $this->createWSDL_portType();
  260.         $this->createWSDL_binding();
  261.         $this->createWSDL_service();
  262.         echo $this->wsdl->saveXML();
  263.     }
  264.  
  265.     // }}}
  266.     // {{{ createDISCO()
  267.     /**
  268.      * handle disco
  269.      *
  270.      * @access private
  271.      */
  272.     private function handleDISCO()
  273.     {
  274.         header('Content-Type: text/xml');
  275.         $this->disco = new DOMDocument('1.0' ,'utf-8');
  276.         $disco_discovery = $this->disco->createElement('discovery');
  277.         $disco_discovery->setAttribute('xmlns:xsi', self::SOAP_XML_SCHEMA_INSTANCE);
  278.         $disco_discovery->setAttribute('xmlns:xsd', self::SOAP_XML_SCHEMA_VERSION);
  279.         $disco_discovery->setAttribute('xmlns', self::SCHEMA_DISCO );
  280.         $disco_contractref = $this->disco->createElement('contractRef');
  281.         $urlBase = $this->protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
  282.         $disco_contractref->setAttribute('ref', $urlBase . '?wsdl');
  283.         $disco_contractref->setAttribute('docRef', $urlBase);
  284.         $disco_contractref->setAttribute('xmlns', self::SCHEMA_DISCO_SCL);
  285.         $disco_soap = $this->disco->createElement('soap');
  286.         $disco_soap->setAttribute('address', $urlBase);
  287.         $disco_soap->setAttribute('xmlns:q1', $this->namespace);
  288.         $disco_soap->setAttribute('binding', 'q1:' . $this->classname);
  289.         $disco_soap->setAttribute('xmlns', self::SCHEMA_DISCO_SCL);
  290.         $disco_contractref->appendChild($disco_soap);
  291.         $disco_discovery->appendChild($disco_contractref);
  292.         $this->disco->appendChild($disco_discovery);
  293.         echo $this->disco->saveXML();
  294.     }
  295.  
  296.     // }}}
  297.     // {{{ handleINFO()
  298.     /**
  299.      * handle info-site
  300.      *
  301.      * @access private
  302.      */
  303.     private function handleINFO()
  304.     {
  305.         header('Content-Type: text/html');
  306.  
  307.         $css = '
  308. body {
  309.     margin: 0px;
  310.     padding: 10px;
  311.     font-family: sans-serif;
  312. }
  313. #header {
  314.     background-color: #339900;
  315.     color: #FFFFFF;
  316.     padding: 5px 10px;
  317.     margin: -10px;
  318. }
  319. h1 {
  320.     font-size: xx-large;
  321.     color: #CCFF99;
  322. }
  323. #header p {
  324.     font-size: large;
  325. }
  326.  
  327. dt {
  328.     margin-top: 1em;
  329. }
  330.  
  331. .description {
  332.     padding-left: 1.5em;
  333.     margin-bottom: 1.5em;
  334. }
  335.  
  336. a:link {
  337.     color: #006600;
  338. }
  339.  
  340. a:visited {
  341.     color: #030;
  342. }
  343.  
  344. a:hover {
  345.     color: #003300;
  346. }
  347. ';
  348.  
  349.         echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  350.   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  351. <html>
  352. <head>
  353. <title>' . $this->classname . ' WebService</title>
  354. <meta name="generator" content="PEAR::Services_Webservice" />
  355. <style type="text/css">
  356. ' . $css . '
  357. </style>
  358. </head>
  359. <body>
  360. <div id="header">
  361. <h1>' . $this->classname . '</h1>
  362. <p>' . htmlspecialchars($this->description) . '</p>
  363. </div>
  364. <p>The following operations are supported. For a formal definition, please review the <a href="' . htmlentities($_SERVER['PHP_SELF']) . '?WSDL">Service Description</a>.</p>
  365. <ul>';
  366.  
  367.         foreach ($this->wsdlStruct[$this->classname]['method'] as $methodName => $method) {
  368.             $paramValue = array();
  369.             foreach ($method['var'] AS $methodVars) {
  370.                 if (isset($methodVars['param'])) {
  371.                     $paramValue[] = $methodVars['type']
  372.                                      . str_repeat('[]', $methodVars['length']);
  373.                 }
  374.             }
  375.             $returnValue = array();
  376.             foreach ($method['var'] AS $methodVars) {
  377.                 if (isset($methodVars['return'])) {
  378.                     $returnValue[] = $methodVars['type']
  379.                                      . str_repeat('[]', $methodVars['length']);
  380.                 }
  381.             }
  382.             echo sprintf('<li><samp><var class="returnedValue">%s</var> <b class="functionName">%s</b>( <var class="parameter">%s</var> )</samp>%s</li>'
  383.                     , implode(',', $returnValue)
  384.                     , $methodName
  385.                     , implode('</var> , <var class="parameter">', $paramValue)
  386.                     , ((empty($method['description'])) ? '' : ('<br /><span class="description">' . htmlspecialchars($method['description']) . '</span>')));
  387.         }
  388.         echo '</ul>
  389. <p><a href="' . htmlentities($_SERVER['PHP_SELF']) . '?DISCO">DISCO</a> makes it possible for clients to reflect against endpoints to discover services and their associated <acronym title="Web Service Description Language">WSDL</acronym> documents.</p>';
  390.  
  391.         if ($this->warningNamespace == true
  392.             || $this->namespace == 'http://example.org/') {
  393.             echo '
  394. <p class="warning"><strong>This web service is using http://example.org/ as its default namespace.<br />
  395. Recommendation: Change the default namespace before the <acronym title="eXtensible Markup Language">XML</acronym> Web service is made public.</strong></p>
  396.  
  397. <p>Each XML Web service needs a unique namespace in order for client applications to distinguish it from other services on the Web. http://example.org/ is available for XML Web services that are under development, but published XML Web services should use a more permanent namespace.<br />
  398. Your XML Web service should be identified by a namespace that you control. For example, you can use your company`s Internet domain name as part of the namespace. Although many XML Web service namespaces look like <acronym title="Uniform Resource Locators">URLs</acronym>, they need not point to actual resources on the Web. (XML Web service namespaces are <acronym title="Uniform Resouce Identifiers">URIs</acronym>.)</p>
  399.  
  400. <p>For more details on XML namespaces, see the <acronym title="World Wide Web Consortium">W3C</acronym> recommendation on <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</a>.<br />
  401. For more details on <acronym title="Web Service Description Language">WSDL</acronym>, see the <a href="http://www.w3.org/TR/wsdl">WSDL Specification</a>.<br />
  402. For more details on URIs, see <a href="http://www.ietf.org/rfc/rfc2396.txt"><acronym title="Request For Comment">RFC</acronym> 2396</a>.</p>
  403. <p><small>Powered by PEAR <a href="http://pear.php.net/">http://pear.php.net</a></small></p>
  404. </body>
  405. </html>';
  406.  
  407.         }
  408.     }
  409.  
  410.     // }}}
  411.     // {{{ intoStruct()
  412.     /**
  413.      * parse classes into struct
  414.      *
  415.      * @access private
  416.      */
  417.     protected function intoStruct()
  418.     {
  419.         $class = new ReflectionObject($this);
  420.         $this->classname = $class->getName();
  421.         $this->classMethodsIntoStruct();
  422.         $this->classStructDispatch();
  423.     }
  424.  
  425.     // }}}
  426.     // {{{ classStructDispatch()
  427.     /**
  428.      * dispatch types
  429.      *
  430.      * @access private
  431.      */
  432.     protected function classStructDispatch()
  433.     {
  434.         foreach ($this->wsdlStruct[$this->classname]['method'] as $method) {
  435.             foreach ($method['var'] as $var){
  436.                 if (($var['class'] == 1 && $var['length'] == 0)
  437.                     || ($var['class'] == 1 && $var['length'] > 0)) {
  438.                     $this->classPropertiesIntoStruct($var['type']);
  439.                 }
  440.                 if (($var['array'] == 1 && $var['length'] > 0)
  441.                     || ($var['class'] == 1 && $var['length'] > 0)) {
  442.                     $_typensSource = '';
  443.                     for ($i = $var['length']; $i > 0; --$i) {
  444.                         $_typensSource .= 'ArrayOf';
  445.                         $this->wsdlStruct['array'][$_typensSource . $var['type']] = substr($_typensSource, 0, strlen($_typensSource) - 7) . $var['type'];
  446.                     }
  447.                 }
  448.             }
  449.         }
  450.     }
  451.  
  452.     // }}}
  453.     // {{{ classPropertiesIntoStruct()
  454.     /**
  455.      * parse classes properties into struct
  456.      *
  457.      * @var    string
  458.      * @access private
  459.      */
  460.     protected function classPropertiesIntoStruct($className)
  461.     {
  462.         if (!isset($this->wsdlStruct[$className])) {
  463.             $class = new ReflectionClass($className);
  464.             $properties = $class->getProperties();
  465.             $this->wsdlStruct['class'][$className]['property'] = array();
  466.             for ($i = 0; $i < count($properties); ++$i) {
  467.                 if ($properties[$i]->isPublic()) {
  468.                     preg_match_all('~@var\s(\S+)~', $properties[$i]->getDocComment(), $var);
  469.  
  470.                     $_cleanType = str_replace('[]', '', $var[1][0], $_length);
  471.                     $_typens    = str_repeat('ArrayOf', $_length);
  472.  
  473.                     $this->wsdlStruct['class'][$className]['property'][$properties[$i]->getName()]['type'] =
  474.                             $_cleanType;
  475.                     $this->wsdlStruct['class'][$className]['property'][$properties[$i]->getName()]['wsdltype'] =
  476.                             $_typens.$_cleanType;
  477.                     $this->wsdlStruct['class'][$className]['property'][$properties[$i]->getName()]['length'] =
  478.                             $_length;
  479.                     $this->wsdlStruct['class'][$className]['property'][$properties[$i]->getName()]['array'] =
  480.                             ($_length > 0 && in_array($_cleanType, $this->simpleTypes))
  481.                             ? true : false;
  482.                     $isObject = (!in_array($_cleanType, $this->simpleTypes) && new ReflectionClass($_cleanType))
  483.                             ? true : false;
  484.                     $this->wsdlStruct['class'][$className]['property'][$properties[$i]->getName()]['class'] =
  485.                             $isObject;
  486.                     if ($isObject == true) {
  487.                         $this->classPropertiesIntoStruct($_cleanType);
  488.                     }
  489.                     if ($_length > 0) {
  490.                         $_typensSource = '';
  491.                         for ($j = $_length; $j > 0;  --$j) {
  492.                             $_typensSource .= 'ArrayOf';
  493.                             $this->wsdlStruct['array'][$_typensSource.$_cleanType] =
  494.                                     substr($_typensSource, 0, strlen($_typensSource) - 7) . $_cleanType;
  495.                         }
  496.                     }
  497.                 }
  498.             }
  499.         }
  500.     }
  501.  
  502.     // }}}
  503.     // {{{ classMethodsIntoStruct()
  504.     /**
  505.      * parse classes methods into struct
  506.      *
  507.      * @access private
  508.      */
  509.     protected function classMethodsIntoStruct()
  510.     {
  511.         $class = new ReflectionClass($this->classname);
  512.         $methods = $class->getMethods();
  513.         // params
  514.         foreach ($methods AS $method) {
  515.             if ($method->isPublic()
  516.                 && !in_array($method->getName(), $this->preventMethods)) {
  517.                 $docComments = $method->getDocComment();
  518.                 $_docComments_Description = trim(str_replace('/**', '', substr($docComments, 0, strpos($docComments, '@'))));
  519.                 $docComments_Description = trim(substr($_docComments_Description, strpos($_docComments_Description, '*') + 1, strpos($_docComments_Description, '*', 1) - 1));
  520.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['description'] = $docComments_Description;
  521.                 preg_match_all('~@param\s(\S+)~', $docComments, $param);
  522.                 preg_match_all('~@return\s(\S+)~', $method->getDocComment(), $return);
  523.                 $params = $method->getParameters();
  524.                 for ($i = 0; $i < count($params); ++$i) {
  525.                     $_class = $params[$i]->getClass();
  526.                     $_type  = ($_class) ? $_class->getName() : $param[1][$i];
  527.  
  528.                     $_cleanType = str_replace('[]', '', $_type, $_length);
  529.                     $_typens    = str_repeat('ArrayOf', $_length);
  530.  
  531.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['name'] =
  532.                             $params[$i]->getName();
  533.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['wsdltype'] =
  534.                             $_typens . $_cleanType;
  535.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['type'] =
  536.                             $_cleanType;
  537.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['length'] =
  538.                             $_length;
  539.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['array'] =
  540.                             ($_length > 0 && in_array($_cleanType, $this->simpleTypes))
  541.                             ? true : false;
  542.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['class'] =
  543.                             (!in_array($_cleanType, $this->simpleTypes) && new ReflectionClass($_cleanType))
  544.                             ? true : false;
  545.                     $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['param'] = true;
  546.                 }
  547.                 // return
  548.                 if (isset($return[1][0])) {
  549.                     $_cleanType = str_replace('[]', '', $return[1][0], $_length);
  550.                 } else {
  551.                     $_cleanType = 'void';
  552.                     $_length = 0;
  553.                 }
  554.                 $_typens = str_repeat('ArrayOf', $_length);
  555.  
  556.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['wsdltype'] =
  557.                         $_typens.$_cleanType;
  558.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['type'] = $_cleanType;
  559.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['length'] = $_length;
  560.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['array'] =
  561.                         ($_length > 0 && $_cleanType != 'void' && in_array($_cleanType, $this->simpleTypes)) ? true : false;
  562.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['class'] =
  563.                         ($_cleanType != 'void' && !in_array($_cleanType, $this->simpleTypes) && new ReflectionClass($_cleanType))
  564.                         ? true : false;
  565.                 $this->wsdlStruct[$this->classname]['method'][$method->getName()]['var'][$i]['return'] = true;
  566.             }
  567.         }
  568.     }
  569.  
  570.     // }}}
  571.     // {{{ createWSDL_definitions()
  572.     /**
  573.      * Create the definition node
  574.      *
  575.      * @return void
  576.      */
  577.     protected function createWSDL_definitions()
  578.     {
  579.         /*
  580.         <definitions name="myService"
  581.             targetNamespace="urn:myService"
  582.             xmlns:typens="urn:myService"
  583.             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  584.             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  585.             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  586.             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  587.             xmlns="http://schemas.xmlsoap.org/wsdl/">
  588.         */
  589.         
  590.         $this->wsdl_definitions = $this->wsdl->createElement('definitions');
  591.         $this->wsdl_definitions->setAttribute('name', $this->classname);
  592.         $this->wsdl_definitions->setAttribute('targetNamespace', 'urn:'.$this->classname);
  593.         $this->wsdl_definitions->setAttribute('xmlns:typens', 'urn:'.$this->classname);
  594.         $this->wsdl_definitions->setAttribute('xmlns:xsd', self::SOAP_XML_SCHEMA_VERSION);
  595.         $this->wsdl_definitions->setAttribute('xmlns:soap', self::SCHEMA_SOAP);
  596.         $this->wsdl_definitions->setAttribute('xmlns:soapenc', self::SOAP_SCHEMA_ENCODING);
  597.         $this->wsdl_definitions->setAttribute('xmlns:wsdl', self::SCHEMA_WSDL);
  598.         $this->wsdl_definitions->setAttribute('xmlns', self::SCHEMA_WSDL);
  599.         
  600.         //$this->wsdl_definitions->setAttribute('xmlns:mime', self::SOAP_XML_SCHEMA_MIME);
  601.         //$this->wsdl_definitions->setAttribute('xmlns:tns', $this->namespace);
  602.         //$this->wsdl_definitions->setAttribute('xmlns:http', self::SCHEMA_WSDL_HTTP);
  603.         
  604.         $this->wsdl->appendChild($this->wsdl_definitions);
  605.     }
  606.  
  607.     // }}}
  608.     // {{{ createWSDL_types()
  609.     /**
  610.      * Create the types node
  611.      *
  612.      * @return void
  613.      */
  614.     protected function createWSDL_types()
  615.     {
  616.         /*
  617.         <types>
  618.             <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:myService"/>
  619.         </types>
  620.         */
  621.         $types  = $this->wsdl->createElement('types');
  622.         $schema = $this->wsdl->createElement('xsd:schema');
  623.         $schema->setAttribute('xmlns', self::SOAP_XML_SCHEMA_VERSION );
  624.         $schema->setAttribute('targetNamespace', 'urn:'.$this->classname);
  625.         $types->appendChild($schema);
  626.  
  627.         // array
  628.         /*
  629.         <xsd:complexType name="ArrayOfclassC">
  630.             <xsd:complexContent>
  631.                 <xsd:restriction base="soapenc:Array">
  632.                     <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:classC[]"/>
  633.                 </xsd:restriction>
  634.             </xsd:complexContent>
  635.         </xsd:complexType>
  636.         */
  637.         if (isset($this->wsdlStruct['array'])) {
  638.  
  639.             foreach ($this->wsdlStruct['array'] as $source => $target) {
  640.                 
  641.                 //<s:complexType name="ArrayOfArrayOfInt">
  642.                 //<s:sequence>
  643.                 //<s:element minOccurs="0" maxOccurs="unbounded" name="ArrayOfInt" nillable="true" type="tns:ArrayOfInt"/>
  644.                 //</s:sequence>
  645.                 
  646.                 $complexType     = $this->wsdl->createElement('xsd:complexType');
  647.                 $complexContent = $this->wsdl->createElement('xsd:complexContent');
  648.                 $restriction     = $this->wsdl->createElement('xsd:restriction');
  649.                 $attribute         = $this->wsdl->createElement('xsd:attribute');
  650.                 $restriction->appendChild($attribute);
  651.                 $complexContent->appendChild($restriction);
  652.                 $complexType->appendChild($complexContent);
  653.                 $schema->appendChild($complexType);
  654.                 
  655.                 $complexType->setAttribute('name', $source);
  656.                 $restriction->setAttribute('base', 'soapenc:Array');
  657.                 $attribute->setAttribute('ref', 'soapenc:arrayType');
  658.  
  659.                 try {
  660.                     $class = new ReflectionClass($target);
  661.                 }catch (Exception $e){}
  662.                 
  663.                 if(in_array($target, $this->simpleTypes)){
  664.                     $attribute->setAttribute('wsdl:arrayType', 'xsd:'.$target.'[]');
  665.                 }elseif(isset($class)){
  666.                     $attribute->setAttribute('wsdl:arrayType', 'typens:'.$target.'[]');
  667.                 }else{
  668.                     $attribute->setAttribute('wsdl:arrayType', 'typens:'.$target.'[]');
  669.                 }
  670.                 unset($class);
  671.                 
  672.             }
  673.         }
  674.         
  675.         // class
  676.         /*
  677.         <xsd:complexType name="classB">
  678.             <xsd:all>
  679.                 <xsd:element name="classCArray" type="typens:ArrayOfclassC" />
  680.             </xsd:all>
  681.         </xsd:complexType>
  682.         */
  683.         if (isset($this->wsdlStruct['class'])) {
  684.             foreach ($this->wsdlStruct['class'] as $className=>$classProperty) {
  685.                 $complextype = $this->wsdl->createElement('xsd:complexType');
  686.                 $complextype->setAttribute('name', $className);
  687.                 $sequence = $this->wsdl->createElement('xsd:all');
  688.                 $complextype->appendChild($sequence);
  689.                 $schema->appendChild($complextype);
  690.                 foreach ($classProperty['property'] as $classPropertyName => $classPropertyValue) {
  691.                     $element = $this->wsdl->createElement('xsd:element');
  692.                     $element->setAttribute('name', $classPropertyName);
  693.                     $element->setAttribute('type', ((in_array($classPropertyValue['wsdltype'], $this->simpleTypes)) 
  694.                                                             ? 'xsd:' 
  695.                                                             : 'typens:') . $classPropertyValue['wsdltype']);
  696.                     $sequence->appendChild($element);
  697.                 }
  698.             }
  699.         }
  700.  
  701.         $this->wsdl_definitions->appendChild($types);
  702.     }
  703.  
  704.     // }}}
  705.     // {{{ createWSDL_messages()
  706.     /**
  707.      * Create the messages node
  708.      *
  709.      * @return void
  710.      */
  711.     protected function createWSDL_messages()
  712.     {
  713.         /*
  714.         <message name="hello">
  715.             <part name="i" type="xsd:int"/>
  716.             <part name="j" type="xsd:string"/>
  717.         </message>
  718.         <message name="helloResponse">
  719.             <part name="helloResponse" type="xsd:string"/>
  720.         </message>
  721.         */
  722.         foreach ($this->wsdlStruct[$this->classname]['method'] AS $methodName => $method){
  723.             $messageInput = $this->wsdl->createElement('message');
  724.             $messageInput->setAttribute('name', $methodName);
  725.             $messageOutput = $this->wsdl->createElement('message');
  726.             $messageOutput->setAttribute('name', $methodName . 'Response');
  727.             $this->wsdl_definitions->appendChild($messageInput);
  728.             $this->wsdl_definitions->appendChild($messageOutput);
  729.  
  730.             foreach ($method['var'] as $methodVars) {                
  731.                 if (isset($methodVars['param'])) {
  732.                     $part = $this->wsdl->createElement('part');
  733.                     $part->setAttribute('name', $methodVars['name']);
  734.                     $part->setAttribute('type', (($methodVars['array'] != 1 && $methodVars['class'] != 1)
  735.                         ? 'xsd:' : 'typens:') . $methodVars['wsdltype']);
  736.                     $messageInput->appendChild($part);
  737.                 }
  738.                 if (isset($methodVars['return'])) {
  739.                     $part = $this->wsdl->createElement('part');
  740.                     $part->setAttribute('name', $methodName.'Response'); //$methodVars['wsdltype']);
  741.                     $part->setAttribute('type', (($methodVars['array'] != 1 && $methodVars['class'] != 1)
  742.                         ? 'xsd:' : 'typens:') . $methodVars['wsdltype']);
  743.                     $messageOutput->appendChild($part);
  744.                 }
  745.             }
  746.         }
  747.     }
  748.  
  749.     // }}}
  750.     // {{{ createWSDL_binding()
  751.     /**
  752.      * Create the binding node
  753.      *
  754.      * @return void
  755.      */
  756.     protected function createWSDL_binding()
  757.     {
  758.         /*
  759.         <binding name="myServiceBinding" type="typens:myServicePort">    
  760.             <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  761.                 <operation name="hello">
  762.                     <soap:operation soapAction="urn:myServiceAction"/>
  763.                     <input>
  764.                         <soap:body use="encoded" namespace="urn:myService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  765.                     </input>
  766.                     <output>
  767.                         <soap:body use="encoded" namespace="urn:myService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  768.                     </output>
  769.             </operation>
  770.         </binding>
  771.         */
  772.         $binding = $this->wsdl->createElement('binding');
  773.         $binding->setAttribute('name', $this->classname . 'Binding');
  774.         $binding->setAttribute('type', 'typens:' . $this->classname . 'Port');
  775.         $soap_binding = $this->wsdl->createElement('soap:binding');
  776.         $soap_binding->setAttribute('style', 'rpc');
  777.         $soap_binding->setAttribute('transport', self::SCHEMA_SOAP_HTTP);
  778.         $binding->appendChild($soap_binding);
  779.         foreach ($this->wsdlStruct[$this->classname]['method'] AS $methodName => $methodVars) {
  780.             $operation = $this->wsdl->createElement('operation');
  781.             $operation->setAttribute('name', $methodName);
  782.             $binding->appendChild($operation);
  783.             $soap_operation = $this->wsdl->createElement('soap:operation');
  784.             $soap_operation->setAttribute('soapAction', 'urn:'.$this->classname.'Action');
  785.             $operation->appendChild($soap_operation);            
  786.             $input  = $this->wsdl->createElement('input');
  787.             $output = $this->wsdl->createElement('output');
  788.             $operation->appendChild($input);
  789.             $operation->appendChild($output);
  790.             $soap_body = $this->wsdl->createElement('soap:body');
  791.             $soap_body->setAttribute('use', 'encoded');
  792.             $soap_body->setAttribute('namespace', 'urn:'.$this->namespace);
  793.             $soap_body->setAttribute('encodingStyle', self::SOAP_SCHEMA_ENCODING );
  794.             $input->appendChild($soap_body);
  795.             $soap_body = $this->wsdl->createElement('soap:body');
  796.             $soap_body->setAttribute('use', 'encoded');
  797.             $soap_body->setAttribute('namespace', 'urn:'.$this->namespace);
  798.             $soap_body->setAttribute('encodingStyle', self::SOAP_SCHEMA_ENCODING );
  799.             $output->appendChild($soap_body);
  800.         }
  801.         $this->wsdl_definitions->appendChild($binding);
  802.     }
  803.  
  804.     // }}}
  805.     // {{{ createWSDL_portType()
  806.     /**
  807.      * Create the portType node
  808.      *
  809.      * @return void
  810.      */
  811.     protected function createWSDL_portType()
  812.     {
  813.         /*
  814.         <portType name="myServicePort">
  815.             <operation name="hello">
  816.                 <input message="typens:hello"/>
  817.                 <output message="typens:helloResponse"/>
  818.             </operation>
  819.         </portType>
  820.         */
  821.         $portType = $this->wsdl->createElement('portType');
  822.         $portType->setAttribute('name', $this->classname.'Port');
  823.         foreach ($this->wsdlStruct[$this->classname]['method'] AS $methodName => $methodVars) {
  824.             $operation = $this->wsdl->createElement('operation');
  825.             $operation->setAttribute('name', $methodName);
  826.             $portType->appendChild($operation);
  827.  
  828.             $documentation = $this->wsdl->createElement('documentation');
  829.             $documentation->appendChild($this->wsdl->createTextNode($methodVars['description']));
  830.             $operation->appendChild($documentation);
  831.  
  832.             $input  = $this->wsdl->createElement('input');
  833.             $output = $this->wsdl->createElement('output');
  834.             $input->setAttribute('message', 'typens:' . $methodName );
  835.             $output->setAttribute('message', 'typens:' . $methodName . 'Response');
  836.             $operation->appendChild($input);
  837.             $operation->appendChild($output);
  838.         }
  839.         $this->wsdl_definitions->appendChild($portType);
  840.     }
  841.  
  842.     // }}}
  843.     // {{{ createWSDL_service()
  844.     /**
  845.      * Create the service node
  846.      *
  847.      * @return void
  848.      */
  849.     protected function createWSDL_service()
  850.     {
  851.         /*
  852.         <service name="myService">
  853.             <port name="myServicePort" binding="typens:myServiceBinding">
  854.                 <soap:address location="http://dschini.org/test1.php"/>
  855.             </port>
  856.         </service>
  857.         */
  858.         $service = $this->wsdl->createElement('service');
  859.         $service->setAttribute('name', $this->classname);
  860.         $port = $this->wsdl->createElement('port');
  861.         $port->setAttribute('name', $this->classname . 'Port');
  862.         $port->setAttribute('binding', 'typens:' . $this->classname . 'Binding');
  863.         $adress = $this->wsdl->createElement('soap:address');
  864.         $adress->setAttribute('location', $this->protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
  865.         $port->appendChild($adress);
  866.         $service->appendChild($port);
  867.         $this->wsdl_definitions->appendChild($service);
  868.     }
  869. }
  870. ?>