/** * Set the Class the SOAP server will use * * @param string $class Class Name * @param string $namespace Class Namspace - Not Used * @param array $argv Arguments to instantiate the class - Not Used */ public function setClass($class, $namespace = '', $argv = null) { $uri = Zend_Uri::factory('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']); $wsdl = new Zend_Soap_Wsdl($class, $uri); $port = $wsdl->addPortType($class . 'Port'); $binding = $wsdl->addBinding($class . 'Binding', 'tns:' . $class . 'Port'); $wsdl->addSoapBinding($binding, 'rpc'); $wsdl->addService($class . 'Service', $class . 'Port', 'tns:' . $class . 'Binding', $uri); foreach ($this->_reflection->reflectClass($class)->getMethods() as $method) { foreach ($method->getPrototypes() as $prototype) { $args = array(); foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = self::getType($param->getType()); } $message = $wsdl->addMessage($method->getName() . 'Request', $args); $desc = $method->getDescription(); if (strlen($desc) > 0) { //$wsdl->addDocumentation($message, $desc); } if ($prototype->getReturnType() != "void") { $message = $wsdl->addMessage($method->getName() . 'Response', array($method->getName() . 'Return' => self::getType($prototype->getReturnType()))); } /* <wsdl:portType>'s */ $portOperation = $wsdl->addPortOperation($port, $method->getName(), 'tns:' . $method->getName() . 'Request', 'tns:' . $method->getName() . 'Response'); if (strlen($desc) > 0) { //$wsdl->addDocumentation($portOperation, $desc); } /* </wsdl:portType>'s */ /* <wsdl:binding>'s */ $operation = $wsdl->addBindingOperation($binding, $method->getName(), array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"), array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/")); $wsdl->addSoapOperation($binding, $uri->getUri() . '#' . $method->getName()); /* </wsdl:binding>'s */ $this->_functions[] = $method->getName(); } } $this->_wsdl = $wsdl; }
/** * Set the Class the SOAP server will use * * @param string $class Class Name * @param string $namespace Class Namspace - Not Used * @param array $argv Arguments to instantiate the class - Not Used */ public function setClass($class, $namespace = '', $argv = null) { $uri = $this->getUri(); $wsdl = new Zend_Soap_Wsdl($class, $uri, $this->_strategy); $port = $wsdl->addPortType($class . 'Port'); $binding = $wsdl->addBinding($class . 'Binding', 'tns:' . $class . 'Port'); $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); $wsdl->addService($class . 'Service', $class . 'Port', 'tns:' . $class . 'Binding', $uri); foreach ($this->_reflection->reflectClass($class)->getMethods() as $method) { /* <wsdl:portType>'s */ $portOperation = $wsdl->addPortOperation($port, $method->getName(), 'tns:' . $method->getName() . 'Request', 'tns:' . $method->getName() . 'Response'); $desc = $method->getDescription(); if (strlen($desc) > 0) { /** @todo check, what should be done for portoperation documentation */ //$wsdl->addDocumentation($portOperation, $desc); } /* </wsdl:portType>'s */ $this->_functions[] = $method->getName(); $selectedPrototype = null; $maxNumArgumentsOfPrototype = -1; foreach ($method->getPrototypes() as $prototype) { $numParams = count($prototype->getParameters()); if ($numParams > $maxNumArgumentsOfPrototype) { $maxNumArgumentsOfPrototype = $numParams; $selectedPrototype = $prototype; } } if ($selectedPrototype != null) { $prototype = $selectedPrototype; $args = array(); foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = $wsdl->getType($param->getType()); } $message = $wsdl->addMessage($method->getName() . 'Request', $args); if (strlen($desc) > 0) { //$wsdl->addDocumentation($message, $desc); } if ($prototype->getReturnType() != "void") { $returnName = 'return'; $message = $wsdl->addMessage($method->getName() . 'Response', array($returnName => $wsdl->getType($prototype->getReturnType()))); } /* <wsdl:binding>'s */ $operation = $wsdl->addBindingOperation($binding, $method->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); $wsdl->addSoapOperation($operation, $uri . '#' . $method->getName()); /* </wsdl:binding>'s */ } } $this->_wsdl = $wsdl; }
/** * Add a function to the WSDL document. * * @param Zend_Server_Reflection_Function_Abstract $function function to add * @param Zend_Soap_Wsdl $wsdl WSDL document * @param object $port wsdl:portType * @param object $binding wsdl:binding * @return void */ protected function _addFunctionToWsdl($function, $wsdl, $port, $binding) { $uri = $this->getUri(); // We only support one prototype: the one with the maximum number of arguments $prototype = null; $maxNumArgumentsOfPrototype = -1; foreach ($function->getPrototypes() as $tmpPrototype) { $numParams = count($tmpPrototype->getParameters()); if ($numParams > $maxNumArgumentsOfPrototype) { $maxNumArgumentsOfPrototype = $numParams; $prototype = $tmpPrototype; } } if ($prototype === null) { require_once "Zend/Soap/AutoDiscover/Exception.php"; throw new Zend_Soap_AutoDiscover_Exception("No prototypes could be found for the '" . $function->getName() . "' function"); } // Add the input message (parameters) $args = array(); if ($this->_bindingStyle['style'] == 'document') { // Document style: wrap all parameters in a sequence element $sequence = array(); foreach ($prototype->getParameters() as $param) { $sequenceElement = array('name' => $param->getName(), 'type' => $wsdl->getType($param->getType())); if ($param->isOptional()) { $sequenceElement['nillable'] = 'true'; } $sequence[] = $sequenceElement; } $element = array('name' => $function->getName(), 'sequence' => $sequence); // Add the wrapper element part, which must be named 'parameters' $args['parameters'] = array('element' => $wsdl->addElement($element)); } else { // RPC style: add each parameter as a typed part foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = array('type' => $wsdl->getType($param->getType())); } } $wsdl->addMessage($function->getName() . 'In', $args); $isOneWayMessage = false; if ($prototype->getReturnType() == "void") { $isOneWayMessage = true; } if ($isOneWayMessage == false) { // Add the output message (return value) $args = array(); if ($this->_bindingStyle['style'] == 'document') { // Document style: wrap the return value in a sequence element $sequence = array(); if ($prototype->getReturnType() != "void") { $sequence[] = array('name' => $function->getName() . 'Result', 'type' => $wsdl->getType($prototype->getReturnType())); } $element = array('name' => $function->getName() . 'Response', 'sequence' => $sequence); // Add the wrapper element part, which must be named 'parameters' $args['parameters'] = array('element' => $wsdl->addElement($element)); } else { if ($prototype->getReturnType() != "void") { // RPC style: add the return value as a typed part $args['return'] = array('type' => $wsdl->getType($prototype->getReturnType())); } } $wsdl->addMessage($function->getName() . 'Out', $args); } // Add the portType operation if ($isOneWayMessage == false) { $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', 'tns:' . $function->getName() . 'Out'); } else { $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', false); } $desc = $function->getDescription(); if (strlen($desc) > 0) { $wsdl->addDocumentation($portOperation, $desc); } // When using the RPC style, make sure the operation style includes a 'namespace' attribute (WS-I Basic Profile 1.1 R2717) if ($this->_bindingStyle['style'] == 'rpc' && !isset($this->_operationBodyStyle['namespace'])) { $this->_operationBodyStyle['namespace'] = '' . $uri; } // Add the binding operation if ($isOneWayMessage == false) { $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); } else { $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle); } $wsdl->addSoapOperation($operation, $uri . '#' . $function->getName()); // Add the function name to the list $this->_functions[] = $function->getName(); }
function testAddSoapOperation() { $wsdl = new Zend_Soap_Wsdl('MyService', 'http://localhost/MyService.php'); $wsdl->addPortType('myPortType'); $binding = $wsdl->addBinding('MyServiceBinding', 'myPortType'); $wsdl->addSoapOperation($binding, 'http://localhost/MyService.php#myOperation'); $wsdl->addBindingOperation($binding, 'operation1'); $wsdl->addBindingOperation($binding, 'operation2', array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"), array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/") ); $this->assertEquals($wsdl->toXml(), '<?xml version="1.0"?>' . PHP_EOL . '<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" ' . 'xmlns:tns="http://localhost/MyService.php" ' . 'xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ' . 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' . 'xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" ' . 'name="MyService" targetNamespace="http://localhost/MyService.php">' . '<portType name="myPortType"/>' . '<binding name="MyServiceBinding" type="myPortType">' . '<soap:operation soapAction="http://localhost/MyService.php#myOperation"/>' . '<operation name="operation1"/>' . '<operation name="operation2">' . '<input>' . '<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>' . '</input>' . '<output>' . '<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>' . '</output>' . '</operation>' . '</binding>' . '</definitions>' . PHP_EOL); }