1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * WSDL generator for the SOAP web service. 19 * 20 * @package webservice_soap 21 * @copyright 2016 Jun Pataleta 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace webservice_soap; 25 26 /** 27 * WSDL generator for the SOAP web service. 28 * 29 * @package webservice_soap 30 * @copyright 2016 Jun Pataleta 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 class wsdl { 34 /** Namespace URI for the WSDL framework. */ 35 const NS_WSDL = 'http://schemas.xmlsoap.org/wsdl/'; 36 37 /** Encoding namespace URI as defined by SOAP 1.1 */ 38 const NS_SOAP_ENC = 'http://schemas.xmlsoap.org/soap/encoding/'; 39 40 /** Namespace URI for the WSDL SOAP binding. */ 41 const NS_SOAP = 'http://schemas.xmlsoap.org/wsdl/soap/'; 42 43 /** Schema namespace URI as defined by XSD. */ 44 const NS_XSD = 'http://www.w3.org/2001/XMLSchema'; 45 46 /** WSDL namespace for the WSDL HTTP GET and POST binding. */ 47 const NS_SOAP_TRANSPORT = 'http://schemas.xmlsoap.org/soap/http'; 48 49 /** BINDING - string constant attached to the service class name to identify binding nodes. */ 50 const BINDING = 'Binding'; 51 52 /** IN - string constant attached to the function name to identify input nodes. */ 53 const IN = 'In'; 54 55 /** OUT - string constant attached to the function name to identify output nodes. */ 56 const OUT = 'Out'; 57 58 /** PORT - string constant attached to the service class name to identify port nodes. */ 59 const PORT = 'Port'; 60 61 /** SERVICE string constant attached to the service class name to identify service nodes. */ 62 const SERVICE = 'Service'; 63 64 /** @var string The name of the service class. */ 65 private $serviceclass; 66 67 /** @var string The WSDL namespace. */ 68 private $namespace; 69 70 /** @var array The WSDL's message nodes. */ 71 private $messagenodes; 72 73 /** @var \SimpleXMLElement The WSDL's binding node. */ 74 private $nodebinding; 75 76 /** @var \SimpleXMLElement The WSDL's definitions node. */ 77 private $nodedefinitions; 78 79 /** @var \SimpleXMLElement The WSDL's portType node. */ 80 private $nodeporttype; 81 82 /** @var \SimpleXMLElement The WSDL's service node. */ 83 private $nodeservice; 84 85 /** @var \SimpleXMLElement The WSDL's types node. */ 86 private $nodetypes; 87 88 /** 89 * webservice_soap_wsdl constructor. 90 * 91 * @param string $serviceclass The service class' name. 92 * @param string $namespace The WSDL namespace. 93 */ 94 public function __construct($serviceclass, $namespace) { 95 $this->serviceclass = $serviceclass; 96 $this->namespace = $namespace; 97 98 // Initialise definitions node. 99 $this->nodedefinitions = new \SimpleXMLElement('<definitions />'); 100 $this->nodedefinitions->addAttribute('xmlns', self::NS_WSDL); 101 $this->nodedefinitions->addAttribute('x:xmlns:tns', $namespace); 102 $this->nodedefinitions->addAttribute('x:xmlns:soap', self::NS_SOAP); 103 $this->nodedefinitions->addAttribute('x:xmlns:xsd', self::NS_XSD); 104 $this->nodedefinitions->addAttribute('x:xmlns:soap-enc', self::NS_SOAP_ENC); 105 $this->nodedefinitions->addAttribute('x:xmlns:wsdl', self::NS_WSDL); 106 $this->nodedefinitions->addAttribute('name', $serviceclass); 107 $this->nodedefinitions->addAttribute('targetNamespace', $namespace); 108 109 // Initialise types node. 110 $this->nodetypes = $this->nodedefinitions->addChild('types'); 111 $typeschema = $this->nodetypes->addChild('x:xsd:schema'); 112 $typeschema->addAttribute('targetNamespace', $namespace); 113 114 // Initialise the portType node. 115 $this->nodeporttype = $this->nodedefinitions->addChild('portType'); 116 $this->nodeporttype->addAttribute('name', $serviceclass . self::PORT); 117 118 // Initialise the binding node. 119 $this->nodebinding = $this->nodedefinitions->addChild('binding'); 120 $this->nodebinding->addAttribute('name', $serviceclass . self::BINDING); 121 $this->nodebinding->addAttribute('type', 'tns:' . $serviceclass . self::PORT); 122 $soapbinding = $this->nodebinding->addChild('x:soap:binding'); 123 $soapbinding->addAttribute('style', 'rpc'); 124 $soapbinding->addAttribute('transport', self::NS_SOAP_TRANSPORT); 125 126 // Initialise the service node. 127 $this->nodeservice = $this->nodedefinitions->addChild('service'); 128 $this->nodeservice->addAttribute('name', $serviceclass . self::SERVICE); 129 $serviceport = $this->nodeservice->addChild('port'); 130 $serviceport->addAttribute('name', $serviceclass . self::PORT); 131 $serviceport->addAttribute('binding', 'tns:' . $serviceclass . self::BINDING); 132 $soapaddress = $serviceport->addChild('x:soap:address'); 133 $soapaddress->addAttribute('location', $namespace); 134 135 // Initialise message nodes. 136 $this->messagenodes = array(); 137 } 138 139 /** 140 * Adds a complex type to the WSDL. 141 * 142 * @param string $classname The complex type's class name. 143 * @param array $properties An associative array containing the properties of the complex type class. 144 */ 145 public function add_complex_type($classname, $properties) { 146 $typeschema = $this->nodetypes->children(); 147 // Append the complex type. 148 $complextype = $typeschema->addChild('x:xsd:complexType'); 149 $complextype->addAttribute('name', $classname); 150 $child = $complextype->addChild('x:xsd:all'); 151 foreach ($properties as $name => $options) { 152 $param = $child->addChild('x:xsd:element'); 153 $param->addAttribute('name', $name); 154 $param->addAttribute('type', $this->get_soap_type($options['type'])); 155 if (!empty($options['nillable'])) { 156 $param->addAttribute('nillable', 'true'); 157 } 158 } 159 } 160 161 /** 162 * Registers the external service method to the WSDL. 163 * 164 * @param string $functionname The name of the web service function to be registered. 165 * @param array $inputparams Contains the function's input parameters with their associated types. 166 * @param array $outputparams Contains the function's output parameters with their associated types. 167 * @param string $documentation The function's description. 168 */ 169 public function register($functionname, $inputparams = array(), $outputparams = array(), $documentation = '') { 170 // Process portType operation nodes. 171 $porttypeoperation = $this->nodeporttype->addChild('operation'); 172 $porttypeoperation->addAttribute('name', $functionname); 173 // Documentation node. 174 $porttypeoperation->addChild('documentation', $documentation); 175 176 // Process binding operation nodes. 177 $bindingoperation = $this->nodebinding->addChild('operation'); 178 $bindingoperation->addAttribute('name', $functionname); 179 $soapoperation = $bindingoperation->addChild('x:soap:operation'); 180 $soapoperation->addAttribute('soapAction', $this->namespace . '#' . $functionname); 181 182 // Input nodes. 183 $this->process_params($functionname, $porttypeoperation, $bindingoperation, $inputparams); 184 185 // Output nodes. 186 $this->process_params($functionname, $porttypeoperation, $bindingoperation, $outputparams, true); 187 } 188 189 /** 190 * Outputs the WSDL in XML format. 191 * 192 * @return mixed The string value of the WSDL in XML format. False, otherwise. 193 */ 194 public function to_xml() { 195 // Return WSDL in XML format. 196 return $this->nodedefinitions->asXML(); 197 } 198 199 /** 200 * Utility method that returns the encoded SOAP type based on the given type string. 201 * 202 * @param string $type The input type string. 203 * @return string The encoded type for the WSDL. 204 */ 205 private function get_soap_type($type) { 206 switch($type) { 207 case 'int': 208 case 'double': 209 case 'string': 210 return 'xsd:' . $type; 211 case 'array': 212 return 'soap-enc:Array'; 213 default: 214 return 'tns:' . $type; 215 } 216 } 217 218 /** 219 * Utility method that creates input/output nodes from input/output params. 220 * 221 * @param string $functionname The name of the function being registered. 222 * @param \SimpleXMLElement $porttypeoperation The port type operation node. 223 * @param \SimpleXMLElement $bindingoperation The binding operation node. 224 * @param array $params The function's input/output parameters. 225 * @param bool $isoutput Flag to indicate if the nodes to be generated are for input or for output. 226 */ 227 private function process_params($functionname, \SimpleXMLElement $porttypeoperation, \SimpleXMLElement $bindingoperation, 228 array $params = null, $isoutput = false) { 229 // Do nothing if parameter array is empty. 230 if (empty($params)) { 231 return; 232 } 233 234 $postfix = self::IN; 235 $childtype = 'input'; 236 if ($isoutput) { 237 $postfix = self::OUT; 238 $childtype = 'output'; 239 } 240 241 // For portType operation node. 242 $child = $porttypeoperation->addChild($childtype); 243 $child->addAttribute('message', 'tns:' . $functionname . $postfix); 244 245 // For binding operation node. 246 $child = $bindingoperation->addChild($childtype); 247 $soapbody = $child->addChild('x:soap:body'); 248 $soapbody->addAttribute('use', 'encoded'); 249 $soapbody->addAttribute('encodingStyle', self::NS_SOAP_ENC); 250 $soapbody->addAttribute('namespace', $this->namespace); 251 252 // Process message nodes. 253 $messagein = $this->nodedefinitions->addChild('message'); 254 $messagein->addAttribute('name', $functionname . $postfix); 255 foreach ($params as $name => $options) { 256 $part = $messagein->addChild('part'); 257 $part->addAttribute('name', $name); 258 $part->addAttribute('type', $this->get_soap_type($options['type'])); 259 } 260 } 261 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body