diff --git a/src/AutoDiscover.php b/src/AutoDiscover.php
index dbe6f606..2f0ecea5 100644
--- a/src/AutoDiscover.php
+++ b/src/AutoDiscover.php
@@ -12,13 +12,11 @@
use Zend\Server\Reflection;
use Zend\Soap\AutoDiscover\DiscoveryStrategy\DiscoveryStrategyInterface as DiscoveryStrategy;
use Zend\Soap\AutoDiscover\DiscoveryStrategy\ReflectionDiscovery;
+use Zend\Soap\Exception;
use Zend\Soap\Wsdl;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface as ComplexTypeStrategy;
use Zend\Uri;
-/**
- * \Zend\Soap\AutoDiscover
- */
class AutoDiscover
{
/**
@@ -27,20 +25,18 @@ class AutoDiscover
protected $serviceName;
/**
- * @var \Zend\Server\Reflection
+ * @var Reflection
*/
protected $reflection = null;
/**
* Service function names
- *
* @var array
*/
protected $functions = array();
/**
* Service class name
- *
* @var string
*/
protected $class;
@@ -52,42 +48,42 @@ class AutoDiscover
/**
* Url where the WSDL file will be available at.
- *
* @var WSDL Uri
*/
protected $uri;
/**
* soap:body operation style options
- *
* @var array
*/
- protected $operationBodyStyle = array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/");
+ protected $operationBodyStyle = array(
+ 'use' => 'encoded',
+ 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"
+ );
/**
* soap:operation style
- *
* @var array
*/
- protected $bindingStyle = array('style' => 'rpc', 'transport' => 'http://schemas.xmlsoap.org/soap/http');
+ protected $bindingStyle = array(
+ 'style' => 'rpc',
+ 'transport' => 'http://schemas.xmlsoap.org/soap/http'
+ );
/**
* Name of the class to handle the WSDL creation.
- *
* @var string
*/
protected $wsdlClass = 'Zend\Soap\Wsdl';
/**
* Class Map of PHP to WSDL types.
- *
* @var array
*/
protected $classMap = array();
/**
* Discovery strategy for types and other method details.
- *
* @var DiscoveryStrategy
*/
protected $discoveryStrategy;
@@ -100,10 +96,14 @@ class AutoDiscover
* @param null|string $wsdlClass
* @param null|array $classMap
*/
- public function __construct(ComplexTypeStrategy $strategy = null, $endpointUri = null, $wsdlClass = null, array $classMap = array())
- {
+ public function __construct(
+ ComplexTypeStrategy $strategy = null,
+ $endpointUri = null,
+ $wsdlClass = null,
+ array $classMap = array()
+ ) {
$this->reflection = new Reflection();
- $this->discoveryStrategy = new ReflectionDiscovery();
+ $this->setDiscoveryStrategy(new ReflectionDiscovery());
if (null !== $strategy) {
$this->setComplexTypeStrategy($strategy);
@@ -121,7 +121,7 @@ public function __construct(ComplexTypeStrategy $strategy = null, $endpointUri =
* Set the discovery strategy for method type and other information.
*
* @param DiscoveryStrategy $discoveryStrategy
- * @return AutoDiscover
+ * @return self
*/
public function setDiscoveryStrategy(DiscoveryStrategy $discoveryStrategy)
{
@@ -130,6 +130,8 @@ public function setDiscoveryStrategy(DiscoveryStrategy $discoveryStrategy)
}
/**
+ * Get the discovery strategy.
+ *
* @return DiscoveryStrategy
*/
public function getDiscoveryStrategy()
@@ -138,7 +140,7 @@ public function getDiscoveryStrategy()
}
/**
- * Get the class map of php to wsdl qname types.
+ * Get the class map of php to wsdl mappings.
*
* @return array
*/
@@ -148,10 +150,11 @@ public function getClassMap()
}
/**
- * Set the class map of php to wsdl qname types.
+ * Set the class map of php to wsdl mappings.
*
- * @param array $classmap
- * @return AutoDiscover
+ * @param array $classmap
+ * @return self
+ * @throws Exception\InvalidArgumentException
*/
public function setClassMap($classMap)
{
@@ -162,6 +165,7 @@ public function setClassMap($classMap)
(is_object($classMap) ? get_class($classMap) : gettype($classMap))
));
}
+
$this->classMap = $classMap;
return $this;
}
@@ -170,10 +174,19 @@ public function setClassMap($classMap)
* Set service name
*
* @param string $serviceName
- * @return AutoDiscover
+ * @return self
+ * @throws Exception\InvalidArgumentException
*/
public function setServiceName($serviceName)
{
+ $matches = array();
+
+ // first character must be letter or underscore {@see http://www.w3.org/TR/wsdl#_document-n}
+ $i = preg_match('/^[a-z\_]/ims', $serviceName, $matches);
+ if ($i != 1) {
+ throw new Exception\InvalidArgumentException('Service Name must start with letter or _');
+ }
+
$this->serviceName = $serviceName;
return $this;
}
@@ -188,16 +201,11 @@ public function getServiceName()
{
if (!$this->serviceName) {
if ($this->class) {
- return $this->reflection->reflectClass($this->class)
- ->getShortName();
+ return $this->reflection->reflectClass($this->class)->getShortName();
} else {
- throw new Exception\RuntimeException(sprintf(
- "No service name given. Call %s::setServiceName().",
- __CLASS__
- ));
+ throw new Exception\RuntimeException('No service name given. Call AutoDiscover::setServiceName().');
}
}
-
return $this->serviceName;
}
@@ -206,19 +214,25 @@ public function getServiceName()
* Set the location at which the WSDL file will be available.
*
* @param Uri\Uri|string $uri
- * @return AutoDiscover
+ * @return self
* @throws Exception\InvalidArgumentException
*/
public function setUri($uri)
{
if (!is_string($uri) && !($uri instanceof Uri\Uri)) {
- throw new Exception\InvalidArgumentException(sprintf(
- 'No uri given to %s() as string or \Zend\Uri\Uri instance.',
- __METHOD__
- ));
+ throw new Exception\InvalidArgumentException(
+ 'Argument to \Zend\Soap\AutoDiscover::setUri should be string or \Zend\Uri\Uri instance.'
+ );
}
- $this->uri = $uri;
+ $uri = trim($uri);
+ $uri = htmlspecialchars($uri, ENT_QUOTES, 'UTF-8', false);
+
+ if (empty($uri)) {
+ throw new Exception\InvalidArgumentException('Uri contains invalid characters or is empty');
+ }
+
+ $this->uri = $uri;
return $this;
}
@@ -231,15 +245,13 @@ public function setUri($uri)
public function getUri()
{
if ($this->uri === null) {
- throw new Exception\RuntimeException(sprintf(
- "Missing uri. You have to explicitly configure the Endpoint Uri by calling %s::setUri().",
- __CLASS__
- ));
+ throw new Exception\RuntimeException(
+ 'Missing uri. You have to explicitly configure the Endpoint Uri by calling AutoDiscover::setUri().'
+ );
}
if (is_string($this->uri)) {
$this->uri = Uri\UriFactory::factory($this->uri);
}
-
return $this->uri;
}
@@ -247,20 +259,18 @@ public function getUri()
* Set the name of the WSDL handling class.
*
* @param string $wsdlClass
- * @return AutoDiscover
+ * @return self
* @throws Exception\InvalidArgumentException
*/
public function setWsdlClass($wsdlClass)
{
- if (!is_string($wsdlClass) && !is_subclass_of($wsdlClass, 'Zend\Soap\Wsdl')) {
- throw new Exception\InvalidArgumentException(sprintf(
- 'No %s\Wsdl subclass given to %s() as string.',
- __NAMESPACE__,
- __METHOD__
- ));
+ if (!is_string($wsdlClass) && !is_subclass_of($wsdlClass, '\Zend\Soap\Wsdl')) {
+ throw new Exception\InvalidArgumentException(
+ 'No \Zend\Soap\Wsdl subclass given to Zend\Soap\AutoDiscover::setWsdlClass as string.'
+ );
}
- $this->wsdlClass = $wsdlClass;
+ $this->wsdlClass = $wsdlClass;
return $this;
}
@@ -281,13 +291,13 @@ public function getWsdlClass()
* 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/".
*
* @param array $operationStyle
- * @return AutoDiscover
+ * @return self
* @throws Exception\InvalidArgumentException
*/
public function setOperationBodyStyle(array $operationStyle = array())
{
if (!isset($operationStyle['use'])) {
- throw new Exception\InvalidArgumentException("Key 'use' is required in Operation soap:body style.");
+ throw new Exception\InvalidArgumentException('Key "use" is required in Operation soap:body style.');
}
$this->operationBodyStyle = $operationStyle;
return $this;
@@ -299,7 +309,7 @@ public function setOperationBodyStyle(array $operationStyle = array())
* By default 'style' is 'rpc' and 'transport' is 'http://schemas.xmlsoap.org/soap/http'.
*
* @param array $bindingStyle
- * @return AutoDiscover
+ * @return self
*/
public function setBindingStyle(array $bindingStyle = array())
{
@@ -316,12 +326,11 @@ public function setBindingStyle(array $bindingStyle = array())
* Set the strategy that handles functions and classes that are added AFTER this call.
*
* @param ComplexTypeStrategy $strategy
- * @return AutoDiscover
+ * @return self
*/
public function setComplexTypeStrategy(ComplexTypeStrategy $strategy)
{
$this->strategy = $strategy;
-
return $this;
}
@@ -329,7 +338,7 @@ public function setComplexTypeStrategy(ComplexTypeStrategy $strategy)
* Set the Class the SOAP server will use
*
* @param string $class Class Name
- * @return AutoDiscover
+ * @return self
*/
public function setClass($class)
{
@@ -340,12 +349,30 @@ public function setClass($class)
/**
* Add a Single or Multiple Functions to the WSDL
*
- * @param string $function Function Name
- * @return AutoDiscover
+ * @param string $function Function Name
+ * @return self
+ * @throws Exception\InvalidArgumentException
*/
public function addFunction($function)
{
- $this->functions[] = $function;
+ if (is_array($function)) {
+ foreach($function as $row){
+ $this->addFunction($row);
+ }
+ } elseif (is_string($function)) {
+ if (function_exists($function)) {
+ $this->functions[] = $function;
+ } else {
+ throw new Exception\InvalidArgumentException(
+ 'Argument to Zend\Soap\AutoDiscover::addFunction should be a valid function name.'
+ );
+ }
+
+ } else {
+ throw new Exception\InvalidArgumentException(
+ 'Argument to Zend\Soap\AutoDiscover::addFunction should be string or array of strings.'
+ );
+ }
return $this;
}
@@ -370,14 +397,13 @@ protected function _generateFunctions()
foreach (array_unique($this->functions) as $func) {
$methods[] = $this->reflection->reflectFunction($func);
}
-
return $this->_generateWsdl($methods);
}
/**
* Generate the WSDL for a set of reflection method instances.
*
- * @param array $reflectionMethods
+ * @param array $reflectionMethods
* @return Wsdl
*/
protected function _generateWsdl(array $reflectionMethods)
@@ -385,17 +411,17 @@ protected function _generateWsdl(array $reflectionMethods)
$uri = $this->getUri();
$serviceName = $this->getServiceName();
- /** @var Wsdl $wsdl */
+
$wsdl = new $this->wsdlClass($serviceName, $uri, $this->strategy, $this->classMap);
// The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023)
$wsdl->addSchemaTypeSection();
$port = $wsdl->addPortType($serviceName . 'Port');
- $binding = $wsdl->addBinding($serviceName . 'Binding', 'tns:' . $serviceName . 'Port');
+ $binding = $wsdl->addBinding($serviceName . 'Binding', Wsdl::TYPES_NS . ':' . $serviceName . 'Port');
$wsdl->addSoapBinding($binding, $this->bindingStyle['style'], $this->bindingStyle['transport']);
- $wsdl->addService($serviceName . 'Service', $serviceName . 'Port', 'tns:' . $serviceName . 'Binding', $uri);
+ $wsdl->addService($serviceName . 'Service', $serviceName . 'Port', Wsdl::TYPES_NS . ':' . $serviceName . 'Binding', $uri);
foreach ($reflectionMethods as $method) {
$this->_addFunctionToWsdl($method, $wsdl, $port, $binding);
@@ -407,12 +433,11 @@ protected function _generateWsdl(array $reflectionMethods)
/**
* Add a function to the WSDL document.
*
- * @param $function \Zend\Server\Reflection\AbstractFunction function to add
- * @param $wsdl \Zend\Soap\Wsdl WSDL document
- * @param $port object wsdl:portType
- * @param $binding object wsdl:binding
+ * @param $function Reflection\AbstractFunction function to add
+ * @param $wsdl Wsdl WSDL document
+ * @param $port \DOMElement wsdl:portType
+ * @param $binding \DOMElement wsdl:binding
* @throws Exception\InvalidArgumentException
- * @return void
*/
protected function _addFunctionToWsdl($function, $wsdl, $port, $binding)
{
@@ -452,12 +477,15 @@ protected function _addFunctionToWsdl($function, $wsdl, $port, $binding)
}
$sequence[] = $sequenceElement;
}
+
$element = array(
- 'name' => $functionName,
- 'sequence' => $sequence
+ 'name' => $functionName,
+ '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) {
@@ -482,33 +510,47 @@ protected function _addFunctionToWsdl($function, $wsdl, $port, $binding)
'type' => $wsdl->getType($this->discoveryStrategy->getFunctionReturnType($function, $prototype))
);
}
+
$element = array(
- 'name' => $functionName . 'Response',
- 'sequence' => $sequence
+ 'name' => $functionName . 'Response',
+ 'sequence' => $sequence
);
+
// Add the wrapper element part, which must be named 'parameters'
$args['parameters'] = array('element' => $wsdl->addElement($element));
+
} elseif ($prototype->getReturnType() != "void") {
// RPC style: add the return value as a typed part
$args['return'] = array(
'type' => $wsdl->getType($this->discoveryStrategy->getFunctionReturnType($function, $prototype))
);
}
+
$wsdl->addMessage($functionName . 'Out', $args);
}
// Add the portType operation
if ($isOneWayMessage == false) {
- $portOperation = $wsdl->addPortOperation($port, $functionName, 'tns:' . $functionName . 'In', 'tns:' . $functionName . 'Out');
+ $portOperation = $wsdl->addPortOperation(
+ $port,
+ $functionName,
+ Wsdl::TYPES_NS . ':' . $functionName . 'In', Wsdl::TYPES_NS . ':' . $functionName . 'Out'
+ );
} else {
- $portOperation = $wsdl->addPortOperation($port, $functionName, 'tns:' . $functionName . 'In', false);
+ $portOperation = $wsdl->addPortOperation(
+ $port,
+ $functionName,
+ Wsdl::TYPES_NS . ':' . $functionName . 'In', false
+ );
}
$desc = $this->discoveryStrategy->getFunctionDocumentation($function);
+
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)
+ // When using the RPC style, make sure the operation style includes a 'namespace'
+ // attribute (WS-I Basic Profile 1.1 R2717)
$operationBodyStyle = $this->operationBodyStyle;
if ($this->bindingStyle['style'] == 'rpc' && !isset($operationBodyStyle['namespace'])) {
$operationBodyStyle['namespace'] = '' . $uri;
@@ -526,13 +568,13 @@ protected function _addFunctionToWsdl($function, $wsdl, $port, $binding)
/**
* Generate the WSDL file from the configured input.
*
- * @throws Exception\RuntimeException
* @return Wsdl
+ * @throws Exception\RuntimeException
*/
public function generate()
{
if ($this->class && $this->functions) {
- throw new Exception\RuntimeException("Can either dump functions or a class as a service, not both.");
+ throw new Exception\RuntimeException('Can either dump functions or a class as a service, not both.');
}
if ($this->class) {
@@ -547,9 +589,9 @@ public function generate()
/**
* Proxy to WSDL dump function
*
- * @param string $filename
+ * @param string $filename
* @return bool
- * @throws \Zend\Soap\Exception\RuntimeException
+ * @throws Exception\RuntimeException
*/
public function dump($filename)
{
@@ -560,7 +602,7 @@ public function dump($filename)
* Proxy to WSDL toXml() function
*
* @return string
- * @throws \Zend\Soap\Exception\RuntimeException
+ * @throws Exception\RuntimeException
*/
public function toXml()
{
diff --git a/src/AutoDiscover/DiscoveryStrategy/DiscoveryStrategyInterface.php b/src/AutoDiscover/DiscoveryStrategy/DiscoveryStrategyInterface.php
index 1207ec48..22f33dbf 100644
--- a/src/AutoDiscover/DiscoveryStrategy/DiscoveryStrategyInterface.php
+++ b/src/AutoDiscover/DiscoveryStrategy/DiscoveryStrategyInterface.php
@@ -14,7 +14,8 @@
use Zend\Server\Reflection\ReflectionParameter;
/**
- * Describes how types, return values and method details are detected during AutoDiscovery of a WSDL.
+ * Describes how types, return values and method details are detected during
+ * AutoDiscovery of a WSDL.
*/
interface DiscoveryStrategyInterface
{
@@ -23,7 +24,7 @@ interface DiscoveryStrategyInterface
*
* Default implementation assumes the default param doc-block tag.
*
- * @param ReflectionParameter $param
+ * @param ReflectionParameter $param
* @return string
*/
public function getFunctionParameterType(ReflectionParameter $param);
@@ -33,8 +34,8 @@ public function getFunctionParameterType(ReflectionParameter $param);
*
* Default implementation assumes the value of the return doc-block tag.
*
- * @param AbstractFunction $function
- * @param Prototype $prototype
+ * @param AbstractFunction $function
+ * @param Prototype $prototype
* @return string
*/
public function getFunctionReturnType(AbstractFunction $function, Prototype $prototype);
@@ -44,8 +45,8 @@ public function getFunctionReturnType(AbstractFunction $function, Prototype $pro
*
* Default implementation assumes one-way, when return value is "void".
*
- * @param AbstractFunction $function
- * @param Prototype $prototype
+ * @param AbstractFunction $function
+ * @param Prototype $prototype
* @return bool
*/
public function isFunctionOneWay(AbstractFunction $function, Prototype $prototype);
@@ -55,7 +56,7 @@ public function isFunctionOneWay(AbstractFunction $function, Prototype $prototyp
*
* Default implementation uses docblock description.
*
- * @param AbstractFunction $function
+ * @param AbstractFunction $function
* @return string
*/
public function getFunctionDocumentation(AbstractFunction $function);
diff --git a/src/AutoDiscover/DiscoveryStrategy/ReflectionDiscovery.php b/src/AutoDiscover/DiscoveryStrategy/ReflectionDiscovery.php
index 634b55b4..44559de9 100644
--- a/src/AutoDiscover/DiscoveryStrategy/ReflectionDiscovery.php
+++ b/src/AutoDiscover/DiscoveryStrategy/ReflectionDiscovery.php
@@ -14,26 +14,52 @@
use Zend\Server\Reflection\ReflectionParameter;
/**
- * Describes how types, return values and method details are detected during AutoDiscovery of a WSDL.
+ * Describes how types, return values and method details are detected during
+ * AutoDiscovery of a WSDL.
*/
-
class ReflectionDiscovery implements DiscoveryStrategyInterface
{
+ /**
+ * Returns description from phpdoc block
+ *
+ * @param AbstractFunction $function
+ * @return string
+ */
public function getFunctionDocumentation(AbstractFunction $function)
{
return $function->getDescription();
}
+ /**
+ * Return parameter type
+ *
+ * @param ReflectionParameter $param
+ * @return string
+ */
public function getFunctionParameterType(ReflectionParameter $param)
{
return $param->getType();
}
+ /**
+ * Return function return type
+ *
+ * @param AbstractFunction $function
+ * @param Prototype $prototype
+ * @return string
+ */
public function getFunctionReturnType(AbstractFunction $function, Prototype $prototype)
{
return $prototype->getReturnType();
}
+ /**
+ * Return true if function is one way (return nothing)
+ *
+ * @param AbstractFunction $function
+ * @param Prototype $prototype
+ * @return bool
+ */
public function isFunctionOneWay(AbstractFunction $function, Prototype $prototype)
{
return $prototype->getReturnType() == 'void';
diff --git a/src/Client.php b/src/Client.php
index 5d409e6f..ef9b9ef0 100644
--- a/src/Client.php
+++ b/src/Client.php
@@ -15,23 +15,20 @@
use Zend\Server\Client as ServerClient;
use Zend\Stdlib\ArrayUtils;
-/**
- * \Zend\Soap\Client
- */
class Client implements ServerClient
{
- /**
- * Encoding
- * @var string
- */
- protected $encoding = 'UTF-8';
-
/**
* Array of SOAP type => PHP class pairings for handling return/incoming values
* @var array
*/
protected $classmap = null;
+ /**
+ * Encoding
+ * @var string
+ */
+ protected $encoding = 'UTF-8';
+
/**
* Registered fault exceptions
* @var array
@@ -39,83 +36,82 @@ class Client implements ServerClient
protected $faultExceptions = array();
/**
- * SOAP version to use; SOAP_1_2 by default, to allow processing of headers
- * @var int
+ * Last invoked method
+ * @var string
*/
- protected $soapVersion = SOAP_1_2;
-
- /** Set of other SoapClient options */
- protected $uri = null;
- protected $location = null;
- protected $style = null;
- protected $use = null;
- protected $login = null;
- protected $password = null;
- protected $proxyHost = null;
- protected $proxyPort = null;
- protected $proxyLogin = null;
- protected $proxyPassword = null;
- protected $localCert = null;
- protected $passphrase = null;
- protected $compression = null;
- protected $connectionTimeout = null;
- protected $streamContext = null;
- protected $features = null;
- protected $cacheWsdl = null;
- protected $userAgent = null;
+ protected $lastMethod = '';
/**
- * WSDL used to access server
- * It also defines Client working mode (WSDL vs non-WSDL)
- *
- * @var string
+ * Permanent SOAP request headers (shared between requests).
+ * @var array
*/
- protected $wsdl = null;
+ protected $permanentSoapInputHeaders = array();
/**
* SoapClient object
- *
* @var SoapClient
*/
protected $soapClient;
/**
- * Last invoked method
- *
- * @var string
+ * Array of SoapHeader objects
+ * @var SoapHeader[]
*/
- protected $lastMethod = '';
+ protected $soapInputHeaders = array();
/**
- * SOAP request headers.
- *
* Array of SoapHeader objects
- *
* @var array
*/
- protected $soapInputHeaders = array();
+ protected $soapOutputHeaders = array();
/**
- * Permanent SOAP request headers (shared between requests).
- *
- * Array of SoapHeader objects
- *
- * @var array
+ * SOAP version to use; SOAP_1_2 by default, to allow processing of headers
+ * @var int
*/
- protected $permanentSoapInputHeaders = array();
+ protected $soapVersion = SOAP_1_2;
/**
- * Output SOAP headers.
- *
- * Array of SoapHeader objects
- *
* @var array
*/
- protected $soapOutputHeaders = array();
+ protected $typemap = null;
+
+ /**
+ * WSDL used to access server
+ * It also defines Client working mode (WSDL vs non-WSDL)
+ * @var string
+ */
+ protected $wsdl = null;
+
+ /**#@+
+ * @var string
+ */
+ protected $connectionTimeout = null;
+ protected $localCert = null;
+ protected $location = null;
+ protected $login = null;
+ protected $passphrase = null;
+ protected $password = null;
+ protected $proxyHost = null;
+ protected $proxyLogin = null;
+ protected $proxyPassword = null;
+ protected $proxyPort = null;
+ protected $streamContext = null;
+ protected $style = null;
+ protected $uri = null;
+ protected $use = null;
+ protected $userAgent = null;
+ /**#@-*/
+
+ /**#@+
+ * @var int
+ */
+ protected $cacheWsdl = null;
+ protected $compression = null;
+ protected $features = null;
+ /**#@-*/
/**
- * Constructor
- *
* @param string $wsdl
* @param array|Traversable $options
* @throws Exception\ExtensionNotLoadedException
@@ -137,8 +133,8 @@ public function __construct($wsdl = null, $options = null)
/**
* Set wsdl
*
- * @param string $wsdl
- * @return Client
+ * @param string $wsdl
+ * @return self
*/
public function setWSDL($wsdl)
{
@@ -164,7 +160,7 @@ public function getWSDL()
* Allows setting options as an associative array of option => value pairs.
*
* @param array|Traversable $options
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
@@ -174,75 +170,99 @@ public function setOptions($options)
}
foreach ($options as $key => $value) {
- switch ($key) {
+ switch (strtolower($key)) {
case 'classmap':
- case 'classMap':
+ case 'class_map':
$this->setClassmap($value);
break;
+
case 'encoding':
$this->setEncoding($value);
break;
+
case 'soapVersion':
case 'soap_version':
$this->setSoapVersion($value);
break;
+
case 'wsdl':
$this->setWSDL($value);
break;
+
case 'uri':
$this->setUri($value);
break;
+
case 'location':
$this->setLocation($value);
break;
+
case 'style':
$this->setStyle($value);
break;
+
case 'use':
$this->setEncodingMethod($value);
break;
+
case 'login':
$this->setHttpLogin($value);
break;
+
case 'password':
$this->setHttpPassword($value);
break;
+
case 'proxy_host':
$this->setProxyHost($value);
break;
+
case 'proxy_port':
$this->setProxyPort($value);
break;
+
case 'proxy_login':
$this->setProxyLogin($value);
break;
+
case 'proxy_password':
$this->setProxyPassword($value);
break;
+
case 'local_cert':
$this->setHttpsCertificate($value);
break;
+
case 'passphrase':
$this->setHttpsCertPassphrase($value);
break;
+
case 'compression':
$this->setCompressionOptions($value);
break;
+
case 'stream_context':
$this->setStreamContext($value);
break;
+
case 'features':
$this->setSoapFeatures($value);
break;
+
case 'cache_wsdl':
$this->setWSDLCache($value);
break;
+
case 'useragent':
- case 'userAgent':
case 'user_agent':
$this->setUserAgent($value);
break;
+ case 'type_map':
+ case 'typemap':
+ $this->setTypemap($value);
+ break;
+
// Not used now
// case 'connection_timeout':
// $this->connectionTimeout = $value;
@@ -267,6 +287,7 @@ public function getOptions()
$options = array();
$options['classmap'] = $this->getClassmap();
+ $options['typemap'] = $this->getTypemap();
$options['encoding'] = $this->getEncoding();
$options['soap_version'] = $this->getSoapVersion();
$options['wsdl'] = $this->getWSDL();
@@ -312,18 +333,19 @@ public function getOptions()
* Set SOAP version
*
* @param int $version One of the SOAP_1_1 or SOAP_1_2 constants
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException with invalid soap version argument
*/
public function setSoapVersion($version)
{
if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) {
- throw new Exception\InvalidArgumentException('Invalid soap version specified. Use SOAP_1_1 or SOAP_1_2 constants.');
+ throw new Exception\InvalidArgumentException(
+ 'Invalid soap version specified. Use SOAP_1_1 or SOAP_1_2 constants.'
+ );
}
- $this->soapVersion = $version;
-
- $this->soapClient = null;
+ $this->soapVersion = $version;
+ $this->soapClient = null;
return $this;
}
@@ -341,20 +363,19 @@ public function getSoapVersion()
* Set classmap
*
* @param array $classmap
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException for any invalid class in the class map
*/
public function setClassmap(array $classmap)
{
foreach ($classmap as $class) {
if (!class_exists($class)) {
- throw new Exception\InvalidArgumentException('Invalid class in class map');
+ throw new Exception\InvalidArgumentException('Invalid class in class map: ' . $class);
}
}
$this->classmap = $classmap;
$this->soapClient = null;
-
return $this;
}
@@ -368,11 +389,44 @@ public function getClassmap()
return $this->classmap;
}
+ /**
+ * Set typemap with xml to php type mappings with appropriate validation.
+ *
+ * @param array $typeMap
+ * @return self
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setTypemap(array $typeMap)
+ {
+ foreach ($typeMap as $type) {
+ if (!is_callable($type['from_xml'])) {
+ throw new Exception\InvalidArgumentException('Invalid from_xml callback for type: ' . $type['type_name']);
+ }
+ if (!is_callable($type['to_xml'])) {
+ throw new Exception\InvalidArgumentException('Invalid to_xml callback for type: ' . $type['type_name']);
+ }
+ }
+
+ $this->typemap = $typeMap;
+ $this->soapClient = null;
+ return $this;
+ }
+
+ /**
+ * Retrieve typemap
+ *
+ * @return array
+ */
+ public function getTypemap()
+ {
+ return $this->typemap;
+ }
+
/**
* Set encoding
*
* @param string $encoding
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException with invalid encoding argument
*/
public function setEncoding($encoding)
@@ -381,10 +435,8 @@ public function setEncoding($encoding)
throw new Exception\InvalidArgumentException('Invalid encoding specified');
}
- $this->encoding = $encoding;
-
+ $this->encoding = $encoding;
$this->soapClient = null;
-
return $this;
}
@@ -411,9 +463,7 @@ public function validateUrn($urn)
if ($scheme === false || $scheme === null) {
throw new Exception\InvalidArgumentException('Invalid URN');
}
-
return true;
-
}
/**
@@ -422,16 +472,14 @@ public function validateUrn($urn)
* URI in Web Service the target namespace
*
* @param string $uri
- * @return Client
- * @throws Exception\ExceptionInterface with invalid uri argument
+ * @return self
+ * @throws Exception\InvalidArgumentException with invalid uri argument
*/
public function setUri($uri)
{
$this->validateUrn($uri);
- $this->uri = $uri;
-
+ $this->uri = $uri;
$this->soapClient = null;
-
return $this;
}
@@ -451,16 +499,14 @@ public function getUri()
* URI in Web Service the target namespace
*
* @param string $location
- * @return Client
- * @throws Exception\ExceptionInterface with invalid uri argument
+ * @return self
+ * @throws Exception\InvalidArgumentException with invalid uri argument
*/
public function setLocation($location)
{
$this->validateUrn($location);
- $this->location = $location;
-
+ $this->location = $location;
$this->soapClient = null;
-
return $this;
}
@@ -478,19 +524,19 @@ public function getLocation()
* Set request style
*
* @param int $style One of the SOAP_RPC or SOAP_DOCUMENT constants
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException with invalid style argument
*/
public function setStyle($style)
{
if (!in_array($style, array(SOAP_RPC, SOAP_DOCUMENT))) {
- throw new Exception\InvalidArgumentException('Invalid request style specified. Use SOAP_RPC or SOAP_DOCUMENT constants.');
+ throw new Exception\InvalidArgumentException(
+ 'Invalid request style specified. Use SOAP_RPC or SOAP_DOCUMENT constants.'
+ );
}
- $this->style = $style;
-
+ $this->style = $style;
$this->soapClient = null;
-
return $this;
}
@@ -508,19 +554,19 @@ public function getStyle()
* Set message encoding method
*
* @param int $use One of the SOAP_ENCODED or SOAP_LITERAL constants
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException with invalid message encoding method argument
*/
public function setEncodingMethod($use)
{
if (!in_array($use, array(SOAP_ENCODED, SOAP_LITERAL))) {
- throw new Exception\InvalidArgumentException('Invalid message encoding method. Use SOAP_ENCODED or SOAP_LITERAL constants.');
+ throw new Exception\InvalidArgumentException(
+ 'Invalid message encoding method. Use SOAP_ENCODED or SOAP_LITERAL constants.'
+ );
}
- $this->use = $use;
-
+ $this->use = $use;
$this->soapClient = null;
-
return $this;
}
@@ -538,14 +584,12 @@ public function getEncodingMethod()
* Set HTTP login
*
* @param string $login
- * @return Client
+ * @return self
*/
public function setHttpLogin($login)
{
- $this->login = $login;
-
+ $this->login = $login;
$this->soapClient = null;
-
return $this;
}
@@ -563,14 +607,12 @@ public function getHttpLogin()
* Set HTTP password
*
* @param string $password
- * @return Client
+ * @return self
*/
public function setHttpPassword($password)
{
- $this->password = $password;
-
+ $this->password = $password;
$this->soapClient = null;
-
return $this;
}
@@ -588,14 +630,12 @@ public function getHttpPassword()
* Set proxy host
*
* @param string $proxyHost
- * @return Client
+ * @return self
*/
public function setProxyHost($proxyHost)
{
- $this->proxyHost = $proxyHost;
-
+ $this->proxyHost = $proxyHost;
$this->soapClient = null;
-
return $this;
}
@@ -613,14 +653,12 @@ public function getProxyHost()
* Set proxy port
*
* @param int $proxyPort
- * @return Client
+ * @return self
*/
public function setProxyPort($proxyPort)
{
- $this->proxyPort = (int) $proxyPort;
-
+ $this->proxyPort = (int) $proxyPort;
$this->soapClient = null;
-
return $this;
}
@@ -638,14 +676,12 @@ public function getProxyPort()
* Set proxy login
*
* @param string $proxyLogin
- * @return Client
+ * @return self
*/
public function setProxyLogin($proxyLogin)
{
$this->proxyLogin = $proxyLogin;
-
$this->soapClient = null;
-
return $this;
}
@@ -663,14 +699,12 @@ public function getProxyLogin()
* Set proxy password
*
* @param string $proxyPassword
- * @return Client
+ * @return self
*/
public function setProxyPassword($proxyPassword)
{
$this->proxyPassword = $proxyPassword;
-
- $this->soapClient = null;
-
+ $this->soapClient = null;
return $this;
}
@@ -678,7 +712,7 @@ public function setProxyPassword($proxyPassword)
* Set HTTPS client certificate path
*
* @param string $localCert local certificate path
- * @return Client
+ * @return self
* @throws Exception\InvalidArgumentException with invalid local certificate path argument
*/
public function setHttpsCertificate($localCert)
@@ -687,10 +721,8 @@ public function setHttpsCertificate($localCert)
throw new Exception\InvalidArgumentException('Invalid HTTPS client certificate path.');
}
- $this->localCert = $localCert;
-
+ $this->localCert = $localCert;
$this->soapClient = null;
-
return $this;
}
@@ -708,14 +740,12 @@ public function getHttpsCertificate()
* Set HTTPS client certificate passphrase
*
* @param string $passphrase
- * @return Client
+ * @return self
*/
public function setHttpsCertPassphrase($passphrase)
{
$this->passphrase = $passphrase;
-
$this->soapClient = null;
-
return $this;
}
@@ -733,7 +763,7 @@ public function getHttpsCertPassphrase()
* Set compression options
*
* @param int|null $compressionOptions
- * @return Client
+ * @return self
*/
public function setCompressionOptions($compressionOptions)
{
@@ -771,8 +801,8 @@ public function getProxyPassword()
* Set Stream Context
*
* @param resource $context
- * @return Client
- * @throws Exception\InvalidArgumentException if $context is not a valid stream resource
+ * @return self
+ * @throws Exception\InvalidArgumentException
*/
public function setStreamContext($context)
{
@@ -798,12 +828,11 @@ public function getStreamContext()
* Set the SOAP Feature options.
*
* @param string|int $feature
- * @return Client
+ * @return self
*/
public function setSoapFeatures($feature)
{
- $this->features = $feature;
-
+ $this->features = $feature;
$this->soapClient = null;
return $this;
}
@@ -821,16 +850,18 @@ public function getSoapFeatures()
/**
* Set the SOAP WSDL Caching Options
*
- * @param string|int|bool|null $caching
- * @return Client
+ * @param string|int|bool|null $caching
+ * @return self
*/
public function setWSDLCache($caching)
{
+ //@todo check WSDL_CACHE_* constants?
if ($caching === null) {
$this->cacheWsdl = null;
} else {
$this->cacheWsdl = (int) $caching;
}
+
return $this;
}
@@ -848,7 +879,7 @@ public function getWSDLCache()
* Set the string to use in User-Agent header
*
* @param string|null $userAgent
- * @return Client
+ * @return self
*/
public function setUserAgent($userAgent)
{
@@ -857,6 +888,7 @@ public function setUserAgent($userAgent)
} else {
$this->userAgent = (string) $userAgent;
}
+
return $this;
}
@@ -894,7 +926,6 @@ public function getLastResponse()
if ($this->soapClient !== null) {
return $this->soapClient->__getLastResponse();
}
-
return '';
}
@@ -908,7 +939,6 @@ public function getLastRequestHeaders()
if ($this->soapClient !== null) {
return $this->soapClient->__getLastRequestHeaders();
}
-
return '';
}
@@ -922,7 +952,6 @@ public function getLastResponseHeaders()
if ($this->soapClient !== null) {
return $this->soapClient->__getLastResponseHeaders();
}
-
return '';
}
@@ -941,20 +970,19 @@ public function getLastMethod()
*
* May be overridden in subclasses
*
- * @internal
- * @param Client\Common $client
- * @param string $request
- * @param string $location
- * @param string $action
- * @param int $version
- * @param int $oneWay
+ * @param Client\Common $client
+ * @param string $request
+ * @param string $location
+ * @param string $action
+ * @param int $version
+ * @param int $oneWay
* @return mixed
*/
- public function _doRequest(Client\Common $client, $request, $location, $action, $version, $oneWay = null)
+ public function _doRequest(Client\Common $client, $request, $location,$action, $version, $oneWay = null)
{
// Perform request as is
if ($oneWay === null) {
- return call_user_func(array($client,'SoapClient::__doRequest'), $request, $location, $action, $version);
+ return call_user_func(array($client, 'SoapClient::__doRequest'), $request, $location, $action, $version);
}
return call_user_func(array($client, 'SoapClient::__doRequest'), $request, $location, $action, $version, $oneWay);
}
@@ -971,17 +999,17 @@ protected function _initSoapClientObject()
if ($wsdl == null) {
if (!isset($options['location'])) {
- throw new Exception\UnexpectedValueException('\'location\' parameter is required in non-WSDL mode.');
+ throw new Exception\UnexpectedValueException('"location" parameter is required in non-WSDL mode.');
}
if (!isset($options['uri'])) {
- throw new Exception\UnexpectedValueException('\'uri\' parameter is required in non-WSDL mode.');
+ throw new Exception\UnexpectedValueException('"uri" parameter is required in non-WSDL mode.');
}
} else {
if (isset($options['use'])) {
- throw new Exception\UnexpectedValueException('\'use\' parameter only works in non-WSDL mode.');
+ throw new Exception\UnexpectedValueException('"use" parameter only works in non-WSDL mode.');
}
if (isset($options['style'])) {
- throw new Exception\UnexpectedValueException('\'style\' parameter only works in non-WSDL mode.');
+ throw new Exception\UnexpectedValueException('"style" parameter only works in non-WSDL mode.');
}
}
unset($options['wsdl']);
@@ -995,7 +1023,7 @@ protected function _initSoapClientObject()
*
* My be overridden in descendant classes
*
- * @param array $arguments
+ * @param array $arguments
* @return array
*/
protected function _preProcessArguments($arguments)
@@ -1009,7 +1037,7 @@ protected function _preProcessArguments($arguments)
*
* My be overridden in descendant classes
*
- * @param array $result
+ * @param array $result
* @return array
*/
protected function _preProcessResult($result)
@@ -1021,9 +1049,9 @@ protected function _preProcessResult($result)
/**
* Add SOAP input header
*
- * @param SoapHeader $header
+ * @param SoapHeader $header
* @param bool $permanent
- * @return Client
+ * @return self
*/
public function addSoapInputHeader(SoapHeader $header, $permanent = false)
{
@@ -1032,20 +1060,18 @@ public function addSoapInputHeader(SoapHeader $header, $permanent = false)
} else {
$this->soapInputHeaders[] = $header;
}
-
return $this;
}
/**
* Reset SOAP input headers
*
- * @return Client
+ * @return self
*/
public function resetSoapInputHeaders()
{
$this->permanentSoapInputHeaders = array();
- $this->soapInputHeaders = array();
-
+ $this->soapInputHeaders = array();
return $this;
}
@@ -1062,8 +1088,8 @@ public function getLastSoapOutputHeaderObjects()
/**
* Perform a SOAP call
*
- * @param string $name
- * @param array $arguments
+ * @param string $name
+ * @param array $arguments
* @return mixed
*/
public function __call($name, $arguments)
@@ -1076,11 +1102,13 @@ public function __call($name, $arguments)
$this->lastMethod = $name;
$soapHeaders = array_merge($this->permanentSoapInputHeaders, $this->soapInputHeaders);
- $result = $soapClient->__soapCall($name,
- $this->_preProcessArguments($arguments),
- null, /* Options are already set to the SOAP client object */
- (count($soapHeaders) > 0)? $soapHeaders : null,
- $this->soapOutputHeaders);
+ $result = $soapClient->__soapCall(
+ $name,
+ $this->_preProcessArguments($arguments),
+ null, /* Options are already set to the SOAP client object */
+ (count($soapHeaders) > 0)? $soapHeaders : null,
+ $this->soapOutputHeaders
+ );
// Reset non-permanent input headers
$this->soapInputHeaders = array();
@@ -1119,13 +1147,6 @@ public function getFunctions()
return $soapClient->__getFunctions();
}
-
- /**
- * Get used types.
- *
- * @return array
- */
-
/**
* Return a list of SOAP types
*
@@ -1142,13 +1163,14 @@ public function getTypes()
}
$soapClient = $this->getSoapClient();
-
return $soapClient->__getTypes();
}
/**
- * @param SoapClient $soapClient
- * @return Client
+ * Set SoapClient object
+ *
+ * @param SoapClient $soapClient
+ * @return self
*/
public function setSoapClient(SoapClient $soapClient)
{
@@ -1157,6 +1179,8 @@ public function setSoapClient(SoapClient $soapClient)
}
/**
+ * Get SoapClient object
+ *
* @return SoapClient
*/
public function getSoapClient()
@@ -1168,9 +1192,11 @@ public function getSoapClient()
}
/**
- * @param string $cookieName
- * @param string $cookieValue
- * @return Client
+ * Set cookie
+ *
+ * @param string $cookieName
+ * @param string $cookieValue
+ * @return self
*/
public function setCookie($cookieName, $cookieValue=null)
{
diff --git a/src/Client/Common.php b/src/Client/Common.php
index be9edae1..bf9eb5c8 100644
--- a/src/Client/Common.php
+++ b/src/Client/Common.php
@@ -9,9 +9,11 @@
namespace Zend\Soap\Client;
+use SoapClient;
+
if (extension_loaded('soap')) {
-class Common extends \SoapClient
+class Common extends SoapClient
{
/**
* doRequest() pre-processing method
@@ -30,19 +32,19 @@ class Common extends \SoapClient
public function __construct($doRequestCallback, $wsdl, $options)
{
$this->doRequestCallback = $doRequestCallback;
-
parent::__construct($wsdl, $options);
}
/**
* Performs SOAP request over HTTP.
- * Overridden to implement different transport layers, perform additional XML processing or other purpose.
+ * Overridden to implement different transport layers, perform additional
+ * XML processing or other purpose.
*
- * @param string $request
- * @param string $location
- * @param string $action
- * @param int $version
- * @param int $oneWay
+ * @param string $request
+ * @param string $location
+ * @param string $action
+ * @param int $version
+ * @param int $oneWay
* @return mixed
*/
public function __doRequest($request, $location, $action, $version, $oneWay = null)
diff --git a/src/Client/DotNet.php b/src/Client/DotNet.php
index 9228cec4..b65e167b 100644
--- a/src/Client/DotNet.php
+++ b/src/Client/DotNet.php
@@ -19,10 +19,40 @@
/**
* .NET SOAP client
*
- * Class is intended to be used with .Net Web Services.
+ * Class is intended to be used with .NET Web Services.
*/
class DotNet extends SOAPClient
{
+ /**
+ * Curl HTTP client adapter.
+ * @var CurlClient
+ */
+ protected $curlClient = null;
+
+ /**
+ * The last request headers.
+ * @var string
+ */
+ protected $lastRequestHeaders = '';
+
+ /**
+ * The last response headers.
+ * @var string
+ */
+ protected $lastResponseHeaders = '';
+
+ /**
+ * SOAP client options.
+ * @var array
+ */
+ protected $options = array();
+
+ /**
+ * Should NTLM authentication be used?
+ * @var boolean
+ */
+ protected $useNtlm = false;
+
/**
* Constructor
*
@@ -44,23 +74,28 @@ public function __construct($wsdl = null, $options = null)
* @param string $request The request body.
* @param string $location The SOAP URI.
* @param string $action The SOAP action to call.
- * @param integer $version The SOAP version to use.
- * @param integer $one_way (Optional) The number 1 if a response is not expected.
+ * @param int $version The SOAP version to use.
+ * @param int $oneWay (Optional) The number 1 if a response is not expected.
* @return string The XML SOAP response.
*/
- public function _doRequest(CommonClient $client, $request, $location, $action, $version, $one_way = null)
+ public function _doRequest(CommonClient $client, $request, $location, $action, $version, $oneWay = null)
{
if (!$this->useNtlm) {
- return parent::_doRequest($client, $request, $location, $action, $version, $one_way);
+ return parent::_doRequest($client, $request, $location, $action, $version, $oneWay);
}
$curlClient = $this->getCurlClient();
- $headers = array('Content-Type' => 'text/xml; charset=utf-8',
- 'Method' => 'POST',
- 'SOAPAction' => '"' . $action . '"',
- 'User-Agent' => 'PHP-SOAP-CURL');
- $uri = new HttpUri($location);
+ // @todo persistent connection ?
+ $headers = array(
+ 'Content-Type' => 'text/xml; charset=utf-8',
+ 'Method' => 'POST',
+ 'SOAPAction' => '"' . $action . '"',
+ 'User-Agent' => 'PHP-SOAP-CURL',
+ );
+ $uri = new HttpUri($location);
+
+ // @todo use parent set* options for ssl certificate authorization
$curlClient->setCurlOption(CURLOPT_HTTPAUTH, CURLAUTH_NTLM)
->setCurlOption(CURLOPT_SSL_VERIFYHOST, false)
->setCurlOption(CURLOPT_SSL_VERIFYPEER, false)
@@ -70,6 +105,8 @@ public function _doRequest(CommonClient $client, $request, $location, $action, $
$curlClient->connect($uri->getHost(), $uri->getPort());
$curlClient->write('POST', $uri, 1.1, $headers, $request);
$response = HttpResponse::fromString($curlClient->read());
+
+ // @todo persistent connection ?
$curlClient->close();
// Save headers
@@ -83,14 +120,13 @@ public function _doRequest(CommonClient $client, $request, $location, $action, $
/**
* Returns the cURL client that is being used.
*
- * @return \Zend\Http\Client\Adapter\Curl The cURL client.
+ * @return CurlClient
*/
public function getCurlClient()
{
if ($this->curlClient === null) {
$this->curlClient = new CurlClient();
}
-
return $this->curlClient;
}
@@ -118,7 +154,7 @@ public function getLastResponseHeaders()
* Sets the cURL client to use.
*
* @param CurlClient $curlClient The cURL client.
- * @return self Fluent interface.
+ * @return self
*/
public function setCurlClient(CurlClient $curlClient)
{
@@ -133,7 +169,7 @@ public function setCurlClient(CurlClient $curlClient)
*
* @param array|\Traversable $options Options.
* @throws \InvalidArgumentException If an unsupported option is passed.
- * @return self Fluent interface.
+ * @return self
*/
public function setOptions($options)
{
@@ -151,16 +187,18 @@ public function setOptions($options)
*
* My be overridden in descendant classes
*
- * @param array $arguments
- * @throws Exception\RuntimeException
+ * @param array $arguments
* @return array
+ * @throws Exception\RuntimeException
*/
protected function _preProcessArguments($arguments)
{
if (count($arguments) > 1 ||
(count($arguments) == 1 && !is_array(reset($arguments)))
) {
- throw new Exception\RuntimeException('.Net webservice arguments have to be grouped into array: array(\'a\' => $a, \'b\' => $b, ...).');
+ throw new Exception\RuntimeException(
+ '.Net webservice arguments have to be grouped into array: array("a" => $a, "b" => $b, ...).'
+ );
}
// Do nothing
@@ -172,13 +210,12 @@ protected function _preProcessArguments($arguments)
*
* My be overridden in descendant classes
*
- * @param object $result
+ * @param object $result
* @return mixed
*/
protected function _preProcessResult($result)
{
$resultProperty = $this->getLastMethod() . 'Result';
-
return $result->$resultProperty;
}
@@ -188,7 +225,7 @@ protected function _preProcessResult($result)
* @param array $headers The headers to flatten.
* @return string The headers string.
*/
- private function flattenHeaders(array $headers)
+ protected function flattenHeaders(array $headers)
{
$result = '';
@@ -198,39 +235,4 @@ private function flattenHeaders(array $headers)
return $result;
}
-
- /**
- * Curl HTTP client adapter.
- *
- * @var \Zend\Http\Client\Adapter\Curl
- */
- private $curlClient = null;
-
- /**
- * The last request headers.
- *
- * @var string
- */
- private $lastRequestHeaders = '';
-
- /**
- * The last response headers.
- *
- * @var string
- */
- private $lastResponseHeaders = '';
-
- /**
- * SOAP client options.
- *
- * @var array
- */
- private $options = array();
-
- /**
- * Should NTLM authentication be used?
- *
- * @var boolean
- */
- private $useNtlm = false;
}
diff --git a/src/Client/Local.php b/src/Client/Local.php
index ea712180..6c634206 100644
--- a/src/Client/Local.php
+++ b/src/Client/Local.php
@@ -13,8 +13,6 @@
use Zend\Soap\Server as SOAPServer;
/**
- * \Zend\Soap\Client\Local
- *
* Class is intended to be used as local SOAP client which works
* with a provided Server object.
*
@@ -24,15 +22,14 @@ class Local extends SOAPClient
{
/**
* Server object
- *
- * @var \Zend\Soap\Server
+ * @var SOAPServer
*/
protected $server;
/**
* Local client constructor
*
- * @param \Zend\Soap\Server $server
+ * @param SOAPServer $server
* @param string $wsdl
* @param array $options
*/
@@ -49,13 +46,12 @@ public function __construct(SOAPServer $server, $wsdl, $options = null)
/**
* Actual "do request" method.
*
- * @internal
- * @param \Zend\Soap\Client\Common $client
- * @param string $request
- * @param string $location
- * @param string $action
- * @param int $version
- * @param int $oneWay
+ * @param Common $client
+ * @param string $request
+ * @param string $location
+ * @param string $action
+ * @param int $version
+ * @param int $oneWay
* @return mixed
*/
public function _doRequest(Common $client, $request, $location, $action, $version, $oneWay = null)
diff --git a/src/Exception/BadMethodCallException.php b/src/Exception/BadMethodCallException.php
index 735857f0..30af2d0c 100644
--- a/src/Exception/BadMethodCallException.php
+++ b/src/Exception/BadMethodCallException.php
@@ -9,7 +9,10 @@
namespace Zend\Soap\Exception;
-class BadMethodCallException
- extends \BadMethodCallException
- implements ExceptionInterface
+use BadMethodCallException as SPLBadMethodCallException;
+
+/**
+ * Exception thrown when unrecognized method is called via overloading
+ */
+class BadMethodCallException extends SPLBadMethodCallException implements ExceptionInterface
{}
diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php
index f54d014b..e1bc31c0 100644
--- a/src/Exception/ExceptionInterface.php
+++ b/src/Exception/ExceptionInterface.php
@@ -9,5 +9,8 @@
namespace Zend\Soap\Exception;
+/**
+ * Common Exception interface
+ */
interface ExceptionInterface
{}
diff --git a/src/Exception/ExtensionNotLoadedException.php b/src/Exception/ExtensionNotLoadedException.php
index 272eb381..94bb9efe 100644
--- a/src/Exception/ExtensionNotLoadedException.php
+++ b/src/Exception/ExtensionNotLoadedException.php
@@ -9,5 +9,10 @@
namespace Zend\Soap\Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when SOAP PHP extension is not loaded
+ */
class ExtensionNotLoadedException extends RuntimeException
{}
diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php
index 6308e6de..c71eec6f 100644
--- a/src/Exception/InvalidArgumentException.php
+++ b/src/Exception/InvalidArgumentException.php
@@ -9,7 +9,10 @@
namespace Zend\Soap\Exception;
-class InvalidArgumentException
- extends \InvalidArgumentException
- implements ExceptionInterface
+use InvalidArgumentException as SPLInvalidArgumentException;
+
+/**
+ * Exception thrown when one or more method arguments are invalid
+ */
+class InvalidArgumentException extends SPLInvalidArgumentException implements ExceptionInterface
{}
diff --git a/src/Exception/RuntimeException.php b/src/Exception/RuntimeException.php
index 75db3716..b1290234 100644
--- a/src/Exception/RuntimeException.php
+++ b/src/Exception/RuntimeException.php
@@ -9,7 +9,10 @@
namespace Zend\Soap\Exception;
-class RuntimeException
- extends \RuntimeException
- implements ExceptionInterface
+use RuntimeException as SPLRuntimeException;
+
+/**
+ * Exception thrown when there is an error during program execution
+ */
+class RuntimeException extends SPLRuntimeException implements ExceptionInterface
{}
diff --git a/src/Exception/UnexpectedValueException.php b/src/Exception/UnexpectedValueException.php
index f5b0b2f6..a3133d35 100644
--- a/src/Exception/UnexpectedValueException.php
+++ b/src/Exception/UnexpectedValueException.php
@@ -9,7 +9,10 @@
namespace Zend\Soap\Exception;
-class UnexpectedValueException
- extends \UnexpectedValueException
- implements ExceptionInterface
+use UnexpectedValueException as SPLUnexpectedValueException;
+
+/**
+ * Exception thrown when provided arguments are invalid
+ */
+class UnexpectedValueException extends SPLUnexpectedValueException implements ExceptionInterface
{}
diff --git a/src/Server.php b/src/Server.php
index 151b3f45..5d276a26 100644
--- a/src/Server.php
+++ b/src/Server.php
@@ -9,18 +9,17 @@
namespace Zend\Soap;
+use SoapServer;
+use SoapFault;
+use Traversable;
use DOMDocument;
use DOMNode;
use SimpleXMLElement;
-use SoapFault;
-use stdClass;
-use Traversable;
+use ReflectionClass;
+use Zend\Server\Server as ZendServerServer;
use Zend\Stdlib\ArrayUtils;
-/**
- * Zend_Soap_Server
- */
-class Server implements \Zend\Server\Server
+class Server implements ZendServerServer
{
/**
* Actor URI
@@ -40,11 +39,6 @@ class Server implements \Zend\Server\Server
*/
protected $classArgs = array();
- /**
- * Object registered with this server
- */
- protected $object;
-
/**
* Array of SOAP type => PHP class pairings for handling return/incoming values
* @var array
@@ -58,32 +52,27 @@ class Server implements \Zend\Server\Server
protected $encoding;
/**
- * SOAP Server Features
- *
- * @var int
+ * Registered fault exceptions
+ * @var array
*/
- protected $features;
+ protected $faultExceptions = array();
/**
- * WSDL Caching Options of SOAP Server
- *
- * @var mixed
+ * SOAP Server Features
+ * @var int
*/
- protected $wsdlCache;
-
+ protected $features;
/**
- * Registered fault exceptions
- * @var array
+ * Functions registered with this server; may be either an array or the SOAP_FUNCTIONS_ALL constant
+ * @var array|int
*/
- protected $faultExceptions = array();
+ protected $functions = array();
/**
- * Functions registered with this server; may be either an array or the SOAP_FUNCTIONS_ALL
- * constant
- * @var array|int
+ * Object registered with this server
*/
- protected $functions = array();
+ protected $object;
/**
* Persistence mode; should be one of the SOAP persistence constants
@@ -104,8 +93,7 @@ class Server implements \Zend\Server\Server
protected $response;
/**
- * Flag: whether or not {@link handle()} should return a response instead
- * of automatically emitting it.
+ * Flag: whether or not {@link handle()} should return a response instead of automatically emitting it.
* @var bool
*/
protected $returnResponse = false;
@@ -117,10 +105,10 @@ class Server implements \Zend\Server\Server
protected $soapVersion = SOAP_1_2;
/**
- * URI or path to WSDL
- * @var string
+ * Array of type mappings
+ * @var array
*/
- protected $wsdl;
+ protected $typemap;
/**
* URI namespace for SOAP server
@@ -128,6 +116,18 @@ class Server implements \Zend\Server\Server
*/
protected $uri;
+ /**
+ * URI or path to WSDL
+ * @var string
+ */
+ protected $wsdl;
+
+ /**
+ * WSDL Caching Options of SOAP Server
+ * @var mixed
+ */
+ protected $wsdlCache;
+
/**
* Constructor
*
@@ -138,8 +138,8 @@ class Server implements \Zend\Server\Server
* If $wsdl is provided, it is passed on to {@link setWSDL()}; if any
* options are specified, they are passed on to {@link setOptions()}.
*
- * @param string $wsdl
- * @param array $options
+ * @param string $wsdl
+ * @param array $options
* @throws Exception\ExtensionNotLoadedException
*/
public function __construct($wsdl = null, array $options = null)
@@ -162,8 +162,8 @@ public function __construct($wsdl = null, array $options = null)
*
* Allows setting options as an associative array of option => value pairs.
*
- * @param array|Traversable $options
- * @return \Zend\Soap\Server
+ * @param array|\Traversable $options
+ * @return self
*/
public function setOptions($options)
{
@@ -172,33 +172,46 @@ public function setOptions($options)
}
foreach ($options as $key => $value) {
- switch ($key) {
+ switch (strtolower($key)) {
case 'actor':
$this->setActor($value);
break;
+
case 'classmap':
- case 'classMap':
+ case 'class_map':
$this->setClassmap($value);
break;
+
+ case 'typemap':
+ case 'type_map':
+ $this->setTypemap($value);
+ break;
+
case 'encoding':
$this->setEncoding($value);
break;
- case 'soapVersion':
+
+ case 'soapversion':
case 'soap_version':
$this->setSoapVersion($value);
break;
+
case 'uri':
$this->setUri($value);
break;
+
case 'wsdl':
$this->setWSDL($value);
break;
- case 'features':
- $this->setSoapFeatures($value);
- break;
+
case 'cache_wsdl':
$this->setWSDLCache($value);
break;
+
+ case 'features':
+ $this->setSoapFeatures($value);
+ break;
+
default:
break;
}
@@ -216,31 +229,35 @@ public function getOptions()
{
$options = array();
if (null !== $this->actor) {
- $options['actor'] = $this->actor;
+ $options['actor'] = $this->getActor();
}
if (null !== $this->classmap) {
- $options['classmap'] = $this->classmap;
+ $options['classmap'] = $this->getClassmap();
+ }
+
+ if (null !== $this->typemap) {
+ $options['typemap'] = $this->getTypemap();
}
if (null !== $this->encoding) {
- $options['encoding'] = $this->encoding;
+ $options['encoding'] = $this->getEncoding();
}
if (null !== $this->soapVersion) {
- $options['soap_version'] = $this->soapVersion;
+ $options['soap_version'] = $this->getSoapVersion();
}
if (null !== $this->uri) {
- $options['uri'] = $this->uri;
+ $options['uri'] = $this->getUri();
}
if (null !== $this->features) {
- $options['features'] = $this->features;
+ $options['features'] = $this->getSoapFeatures();
}
if (null !== $this->wsdlCache) {
- $options['cache_wsdl'] = $this->wsdlCache;
+ $options['cache_wsdl'] = $this->getWSDLCache();
}
return $options;
@@ -250,7 +267,7 @@ public function getOptions()
* Set encoding
*
* @param string $encoding
- * @return Server
+ * @return self
* @throws Exception\InvalidArgumentException with invalid encoding argument
*/
public function setEncoding($encoding)
@@ -277,7 +294,7 @@ public function getEncoding()
* Set SOAP version
*
* @param int $version One of the SOAP_1_1 or SOAP_1_2 constants
- * @return Server
+ * @return self
* @throws Exception\InvalidArgumentException with invalid soap version argument
*/
public function setSoapVersion($version)
@@ -323,7 +340,7 @@ public function validateUrn($urn)
* Actor is the actor URI for the server.
*
* @param string $actor
- * @return Server
+ * @return self
*/
public function setActor($actor)
{
@@ -348,7 +365,7 @@ public function getActor()
* URI in SoapServer is actually the target namespace, not a URI; $uri must begin with 'urn:'.
*
* @param string $uri
- * @return Server
+ * @return self
*/
public function setUri($uri)
{
@@ -371,7 +388,7 @@ public function getUri()
* Set classmap
*
* @param array $classmap
- * @return Server
+ * @return self
* @throws Exception\InvalidArgumentException for any invalid class in the class map
*/
public function setClassmap($classmap)
@@ -399,11 +416,47 @@ public function getClassmap()
return $this->classmap;
}
+ /**
+ * Set typemap with xml to php type mappings with appropriate validation.
+ *
+ * @param array $typeMap
+ * @return self
+ * @throws Exception\InvalidArgumentException
+ */
+ public function setTypemap($typeMap)
+ {
+ if (!is_array($typeMap)) {
+ throw new Exception\InvalidArgumentException('Typemap must be an array');
+ }
+
+ foreach ($typeMap as $type) {
+ if (!is_callable($type['from_xml'])) {
+ throw new Exception\InvalidArgumentException('Invalid from_xml callback for type: ' . $type['type_name']);
+ }
+ if (!is_callable($type['to_xml'])) {
+ throw new Exception\InvalidArgumentException('Invalid to_xml callback for type: ' . $type['type_name']);
+ }
+ }
+
+ $this->typemap = $typeMap;
+ return $this;
+ }
+
+ /**
+ * Retrieve typemap
+ *
+ * @return array
+ */
+ public function getTypemap()
+ {
+ return $this->typemap;
+ }
+
/**
* Set wsdl
*
- * @param string $wsdl URI or path to a WSDL
- * @return Server
+ * @param string $wsdl URI or path to a WSDL
+ * @return self
*/
public function setWSDL($wsdl)
{
@@ -425,7 +478,7 @@ public function getWSDL()
* Set the SOAP Feature options.
*
* @param string|int $feature
- * @return Server
+ * @return self
*/
public function setSoapFeatures($feature)
{
@@ -446,8 +499,8 @@ public function getSoapFeatures()
/**
* Set the SOAP WSDL Caching Options
*
- * @param string|int|bool $options
- * @return Server
+ * @param string|int|bool $options
+ * @return self
*/
public function setWSDLCache($options)
{
@@ -466,10 +519,10 @@ public function getWSDLCache()
/**
* Attach a function as a server method
*
- * @param array|string $function Function name, array of function names to attach,
- * or SOAP_FUNCTIONS_ALL to attach all functions
+ * @param array|string $function Function name, array of function names to attach,
+ * or SOAP_FUNCTIONS_ALL to attach all functions
* @param string $namespace Ignored
- * @return Server
+ * @return self
* @throws Exception\InvalidArgumentException on invalid functions
*/
public function addFunction($function, $namespace = '')
@@ -487,11 +540,13 @@ public function addFunction($function, $namespace = '')
throw new Exception\InvalidArgumentException('One or more invalid functions specified in array');
}
}
- $this->functions = array_merge($this->functions, $function);
+
} elseif (is_string($function) && function_exists($function)) {
$this->functions[] = $function;
+
} elseif ($function == SOAP_FUNCTIONS_ALL) {
$this->functions = SOAP_FUNCTIONS_ALL;
+
} else {
throw new Exception\InvalidArgumentException('Invalid function specified');
}
@@ -509,14 +564,14 @@ public function addFunction($function, $namespace = '')
* Accepts a class name to use when handling requests. Any additional
* arguments will be passed to that class' constructor when instantiated.
*
- * See {@link setObject()} to set preconfigured object instances as request handlers.
+ * See {@link setObject()} to set pre-configured object instances as request handlers.
*
- * @param string|object $class Class name or object instance which executes SOAP Requests at endpoint.
- * @param string $namespace
- * @param $argv
- * @return Server
- * @throws Exception\InvalidArgumentException if called more than once, or if class
- * does not exist
+ * @param string|object $class Class name or object instance which executes
+ * SOAP Requests at endpoint.
+ * @param string $namespace
+ * @param null|array $argv
+ * @return self
+ * @throws Exception\InvalidArgumentException if called more than once, or if class does not exist
*/
public function setClass($class, $namespace = '', $argv = null)
{
@@ -554,11 +609,11 @@ public function setClass($class, $namespace = '', $argv = null)
/**
* Attach an object to a server
*
- * Accepts an instanciated object to use when handling requests.
+ * Accepts an instantiated object to use when handling requests.
*
- * @param object $object
+ * @param object $object
+ * @return self
* @throws Exception\InvalidArgumentException
- * @return Server
*/
public function setObject($object)
{
@@ -576,7 +631,6 @@ public function setObject($object)
}
$this->object = $object;
-
return $this;
}
@@ -587,7 +641,6 @@ public function setObject($object)
* merged with all public methods of the class set with {@link setClass()}
* (if any).
*
- * @access public
* @return array
*/
public function getFunctions()
@@ -605,8 +658,7 @@ public function getFunctions()
/**
* Unimplemented: Load server definition
*
- * @param array $definition
- * @return void
+ * @param array $definition
* @throws Exception\RuntimeException Unimplemented
*/
public function loadFunctions($definition)
@@ -617,9 +669,9 @@ public function loadFunctions($definition)
/**
* Set server persistence
*
- * @param int $mode
+ * @param int $mode SOAP_PERSISTENCE_SESSION or SOAP_PERSISTENCE_REQUEST constants
+ * @return self
* @throws Exception\InvalidArgumentException
- * @return Server
*/
public function setPersistence($mode)
{
@@ -651,38 +703,49 @@ public function getPersistence()
* - stdClass; if so, calls __toString() and verifies XML
* - string; if so, verifies XML
*
- * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request
+ * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request
+ * @return self
* @throws Exception\InvalidArgumentException
- * @return Server
*/
protected function _setRequest($request)
{
+ $xml = null;
+
if ($request instanceof DOMDocument) {
$xml = $request->saveXML();
+
} elseif ($request instanceof DOMNode) {
$xml = $request->ownerDocument->saveXML();
+
} elseif ($request instanceof SimpleXMLElement) {
$xml = $request->asXML();
+
} elseif (is_object($request) || is_string($request)) {
if (is_object($request)) {
$xml = $request->__toString();
} else {
$xml = $request;
}
+ $xml = trim($xml);
+
libxml_disable_entity_loader(true);
+
$dom = new DOMDocument();
- if (strlen($xml) == 0 || !$dom->loadXML($xml)) {
+ $loadStatus = $dom->loadXML($xml);
+
+ // @todo check libxml errors ? validate document ?
+ if (strlen($xml) == 0 || !$loadStatus) {
throw new Exception\InvalidArgumentException('Invalid XML');
}
+
foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
- throw new Exception\InvalidArgumentException(
- 'Invalid XML: Detected use of illegal DOCTYPE'
- );
+ throw new Exception\InvalidArgumentException('Invalid XML: Detected use of illegal DOCTYPE');
}
}
libxml_disable_entity_loader(false);
}
+
$this->request = $xml;
return $this;
}
@@ -706,7 +769,7 @@ public function getLastRequest()
* The response is always available via {@link getResponse()}.
*
* @param bool $flag
- * @return Server
+ * @return self
*/
public function setReturnResponse($flag = true)
{
@@ -741,12 +804,12 @@ public function getResponse()
* SoapServer object, and then registers any functions or class with it, as
* well as persistence.
*
- * @return \SoapServer
+ * @return SoapServer
*/
protected function _getSoap()
{
$options = $this->getOptions();
- $server = new \SoapServer($this->wsdl, $options);
+ $server = new SoapServer($this->wsdl, $options);
if (!empty($this->functions)) {
$server->addFunction($this->functions);
@@ -785,7 +848,7 @@ protected function _getSoap()
* If no request is passed, pulls request using php:://input (for
* cross-platform compatibility purposes).
*
- * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request Optional request
+ * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request Optional request
* @return void|string
*/
public function handle($request = null)
@@ -812,8 +875,7 @@ public function handle($request = null)
if ($setRequestException instanceof \Exception) {
// Create SOAP fault message if we've caught a request exception
$fault = $this->fault($setRequestException->getMessage(), 'Sender');
- }
- if (!$setRequestException instanceof \Exception) {
+ } else {
ob_start();
try {
$soap->handle($this->request);
@@ -830,12 +892,14 @@ public function handle($request = null)
// Send a fault, if we have one
if ($fault instanceof SoapFault && !$this->returnResponse) {
$soap->fault($fault->faultcode, $fault->getMessage());
+
return;
}
// Echo the response, if we're not returning it
if (!$this->returnResponse) {
echo $this->response;
+
return;
}
@@ -862,17 +926,46 @@ protected function _initializeSoapErrorContext()
}
/**
- * Register a valid fault exception
+ * Validate and register fault exception
*
* @param string|array $class Exception class or array of exception classes
- * @return Server
+ * @return self
+ * @throws Exception\InvalidArgumentException
*/
public function registerFaultException($class)
{
- $this->faultExceptions = array_merge($this->faultExceptions, (array) $class);
+ if (is_array($class)) {
+ foreach($class as $row) {
+ $this->registerFaultException($row);
+ }
+
+ } elseif (is_string($class) && class_exists($class) && is_subclass_of($class, 'Exception')) {
+ $ref = new ReflectionClass($class);
+
+ $this->faultExceptions[] = $ref->getName();
+ $this->faultExceptions = array_unique($this->faultExceptions);
+ } else {
+ throw new Exception\InvalidArgumentException(
+ 'Argument for Zend\Soap\Server::registerFaultException should be string or array of strings with valid exception names'
+ );
+ }
+
return $this;
}
+ /**
+ * Checks if provided fault name is registered as valid in this server.
+ *
+ * @param $fault Name of a fault class
+ * @return bool
+ */
+ public function isRegisteredAsFaultException($fault)
+ {
+ $ref = new ReflectionClass($fault);
+ $classNames = $ref->getName();
+ return in_array($classNames, $this->faultExceptions);
+ }
+
/**
* Deregister a fault exception from the fault exception stack
*
@@ -914,11 +1007,10 @@ public function getFaultExceptions()
* @param string $code SOAP Fault Codes
* @return SoapFault
*/
- public function fault($fault = null, $code = "Receiver")
+ public function fault($fault = null, $code = 'Receiver')
{
if ($fault instanceof \Exception) {
- $class = get_class($fault);
- if (in_array($class, $this->faultExceptions)) {
+ if ($this->isRegisteredAsFaultException($fault)) {
$message = $fault->getMessage();
$eCode = $fault->getCode();
$code = empty($eCode) ? $code : $eCode;
@@ -931,12 +1023,9 @@ public function fault($fault = null, $code = "Receiver")
$message = 'Unknown error';
}
- $allowedFaultModes = array(
- 'VersionMismatch', 'MustUnderstand', 'DataEncodingUnknown',
- 'Sender', 'Receiver', 'Server'
- );
+ $allowedFaultModes = array('VersionMismatch', 'MustUnderstand', 'DataEncodingUnknown', 'Sender', 'Receiver', 'Server');
if (!in_array($code, $allowedFaultModes)) {
- $code = "Receiver";
+ $code = 'Receiver';
}
return new SoapFault($code, $message);
@@ -945,12 +1034,11 @@ public function fault($fault = null, $code = "Receiver")
/**
* Throw PHP errors as SoapFaults
*
- * @param int $errno
- * @param string $errstr
- * @param string $errfile
- * @param int $errline
- * @param array $errcontext
- * @return void
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ * @param array $errcontext
* @throws SoapFault
*/
public function handlePhpErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null)
diff --git a/src/Server/DocumentLiteralWrapper.php b/src/Server/DocumentLiteralWrapper.php
index 90b415fd..7c30208b 100644
--- a/src/Server/DocumentLiteralWrapper.php
+++ b/src/Server/DocumentLiteralWrapper.php
@@ -10,8 +10,7 @@
namespace Zend\Soap\Server;
use ReflectionObject;
-use Zend\Soap\Exception\BadMethodCallException;
-use Zend\Soap\Exception\UnexpectedValueException;
+use Zend\Soap\Exception;
/**
* Wraps WSDL Document/Literal Style service objects to hide SOAP request
@@ -60,11 +59,12 @@
* of SOAP this wrapper service handles the parsing between the formats.
*
* @example
- *
+ *
* $service = new MyCalculatorService();
* $soap = new \Zend\Soap\Server($wsdlFile);
* $soap->setObject(new \Zend\Soap\Server\DocumentLiteralWrapper($service));
* $soap->handle();
+ *
*/
class DocumentLiteralWrapper
{
@@ -92,8 +92,8 @@ public function __construct($object)
/**
* Proxy method that does the heavy document/literal decomposing.
*
- * @param string $method
- * @param array $args
+ * @param string $method
+ * @param array $args
* @return mixed
*/
public function __call($method, $args)
@@ -102,7 +102,7 @@ public function __call($method, $args)
$this->_assertServiceDelegateHasMethod($method);
$delegateArgs = $this->_parseArguments($method, $args[0]);
- $ret = call_user_func_array(array($this->object, $method), $delegateArgs);
+ $ret = call_user_func_array(array($this->object, $method), $delegateArgs);
return $this->_getResultMessage($method, $ret);
}
@@ -110,15 +110,14 @@ public function __call($method, $args)
* Parse the document/literal wrapper into arguments to call the real
* service.
*
- * @param string $method
- * @param object $document
- * @throws UnexpectedValueException
+ * @param string $method
+ * @param object $document
* @return array
+ * @throws Exception\UnexpectedValueException
*/
protected function _parseArguments($method, $document)
{
$reflMethod = $this->reflection->getMethod($method);
- /* @var \Zend\Server\Reflection\ReflectionParameter[] $params */
$params = array();
foreach ($reflMethod->getParameters() as $param) {
$params[$param->getName()] = $param;
@@ -127,8 +126,8 @@ protected function _parseArguments($method, $document)
$delegateArgs = array();
foreach (get_object_vars($document) as $argName => $argValue) {
if (!isset($params[$argName])) {
- throw new UnexpectedValueException(sprintf(
- "Received unknown argument %s which is not an argument to %s::%s()",
+ throw new Exception\UnexpectedValueException(sprintf(
+ "Received unknown argument %s which is not an argument to %s::%s",
$argName,
get_class($this->object),
$method
@@ -136,18 +135,30 @@ protected function _parseArguments($method, $document)
}
$delegateArgs[$params[$argName]->getPosition()] = $argValue;
}
+
return $delegateArgs;
}
+ /**
+ * Returns result message content
+ *
+ * @param string $method
+ * @param mixed $ret
+ * @return array
+ */
protected function _getResultMessage($method, $ret)
{
return array($method . 'Result' => $ret);
}
+ /**
+ * @param string $method
+ * @throws Exception\BadMethodCallException
+ */
protected function _assertServiceDelegateHasMethod($method)
{
if (!$this->reflection->hasMethod($method)) {
- throw new BadMethodCallException(sprintf(
+ throw new Exception\BadMethodCallException(sprintf(
"Method %s does not exist on delegate object %s",
$method,
get_class($this->object)
@@ -155,10 +166,14 @@ protected function _assertServiceDelegateHasMethod($method)
}
}
- protected function _assertOnlyOneArgument($args)
+ /**
+ * @param array $args
+ * @throws Exception\UnexpectedValueException
+ */
+ protected function _assertOnlyOneArgument(array $args)
{
if (count($args) != 1) {
- throw new UnexpectedValueException(sprintf(
+ throw new Exception\UnexpectedValueException(sprintf(
"Expecting exactly one argument that is the document/literal wrapper, got %d",
count($args)
));
diff --git a/src/Wsdl.php b/src/Wsdl.php
index 61918e47..cab0c17b 100644
--- a/src/Wsdl.php
+++ b/src/Wsdl.php
@@ -11,54 +11,55 @@
use DOMNode;
use DOMDocument;
+use DOMDocumentFragment;
use DOMElement;
+use DOMXPath;
+use Zend\Soap\Exception\InvalidArgumentException;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface as ComplexTypeStrategy;
use Zend\Uri\Uri;
-/**
- * \Zend\Soap\Wsdl
- */
class Wsdl
{
/**#@+
- * XML Namespaces.
- */
- const XML_NS = 'xmlns';
- const XML_NS_URI = 'http://www.w3.org/2000/xmlns/';
- const WSDL_NS = 'wsdl';
- const WSDL_NS_URI = 'http://schemas.xmlsoap.org/wsdl/';
- const SOAP_11_NS = 'soap';
- const SOAP_11_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap/';
- const SOAP_12_NS = 'soap12';
- const SOAP_12_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap12/';
- const SOAP_ENC_NS = 'soap-enc';
- const SOAP_ENC_URI = 'http://schemas.xmlsoap.org/soap/encoding/';
- const XSD_NS = 'xsd';
- const XSD_NS_URI = 'http://www.w3.org/2001/XMLSchema';
- const TYPES_NS = 'tns';
+ * XML Namespace uris and prefixes.
+ */
+ const XML_NS = 'xmlns';
+ const XML_NS_URI = 'http://www.w3.org/2000/xmlns/';
+ const WSDL_NS = 'wsdl';
+ const WSDL_NS_URI = 'http://schemas.xmlsoap.org/wsdl/';
+ const SOAP_11_NS = 'soap';
+ const SOAP_11_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ const SOAP_12_NS = 'soap12';
+ const SOAP_12_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap12/';
+ const SOAP_ENC_NS = 'soap-enc';
+ const SOAP_ENC_URI = 'http://schemas.xmlsoap.org/soap/encoding/';
+ const XSD_NS = 'xsd';
+ const XSD_NS_URI = 'http://www.w3.org/2001/XMLSchema';
+ const TYPES_NS = 'tns';
/**#@-*/
/**
- * @var DOMDocument DOM document Instance
+ * Map of PHP Class names to WSDL QNames.
+ * @var array
*/
- private $dom;
+ protected $classMap = array();
/**
- * @var object WSDL Root XML_Tree_Node
+ * DOM Instance
+ * @var DOMDocument
*/
- private $wsdl;
+ protected $dom;
/**
- * @var DOMElement
+ * Types defined on schema
+ * @var array
*/
- private $schema = null;
+ protected $includedTypes = array();
/**
- * Types defined on schema
- *
- * @var array
+ * @var DOMElement
*/
- private $includedTypes = array();
+ protected $schema = null;
/**
* Strategy for detection of complex types
@@ -66,71 +67,76 @@ class Wsdl
protected $strategy = null;
/**
- * Map of PHP Class names to WSDL QNames.
- *
- * @var array
+ * URI where the WSDL will be available
+ * @var string
*/
- protected $classMap = array();
+ protected $uri;
/**
- * Constructor
- *
- * @param string $name Name of the Web Service being Described
- * @param string|Uri $uri URI where the WSDL will be available
- * @param null|ComplexTypeStrategy $strategy Strategy for detection of complex types
- * @param null|array $classMap Map of PHP Class names to WSDL QNames
+ * Root XML_Tree_Node
+ * @var DOMElement WSDL
+ */
+ protected $wsdl;
+
+ /**
+ * @param string $name Name of the Web Service being Described
+ * @param string|Uri $uri URI where the WSDL will be available
+ * @param null|ComplexTypeStrategy $strategy Strategy for detection of complex types
+ * @param null|array $classMap Map of PHP Class names to WSDL QNames
* @throws Exception\RuntimeException
*/
- public function __construct($name, $uri, ComplexTypeStrategy $strategy = null, array $classMap = array())
- {
+ public function __construct(
+ $name,
+ $uri,
+ ComplexTypeStrategy $strategy = null,
+ array $classMap = array()
+ ) {
if ($uri instanceof Uri) {
$uri = $uri->toString();
}
- $this->classMap = $classMap;
- $this->dom = new DOMDocument('1.0', 'utf-8');
- $targetNamespace = $this->escapeUri($uri);
- $definitions = $this->dom->createElement('definitions');
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS, self::WSDL_NS_URI);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::TYPES_NS, $targetNamespace);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::SOAP_11_NS, self::SOAP_11_NS_URI);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::SOAP_12_NS, self::SOAP_12_NS_URI);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::XSD_NS, self::XSD_NS_URI);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::SOAP_ENC_NS, self::SOAP_ENC_URI);
- $definitions->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::WSDL_NS, self::WSDL_NS_URI);
- $definitions->setAttribute('name', $name);
- $definitions->setAttribute('targetNamespace', $targetNamespace);
- $this->dom->appendChild($definitions);
- $this->wsdl = $this->dom->documentElement;
- $this->setComplexTypeStrategy($strategy ?: new Wsdl\ComplexTypeStrategy\DefaultComplexType);
- }
- /**
- * URL encode query part of the URI if it is present.
- *
- * @param string $uri
- * @return string
- */
- protected function escapeUri($uri)
- {
- // normalize URL
- $uri = urldecode($uri);
- if (preg_match('/\?(.+)$/', $uri, $matches)) {
- $query = $matches[1];
- $uri = str_replace($query, urlencode($query), $uri);
- }
+ $this->setUri($uri);
- return $uri;
+ $this->classMap = $classMap;
+ $this->dom = $this->getDOMDocument($name, $this->getUri());
+ $this->wsdl = $this->dom->documentElement;
+
+ $this->setComplexTypeStrategy($strategy ?: new Wsdl\ComplexTypeStrategy\DefaultComplexType);
}
/**
- * Convert encoded ampersand back to decoded value, to avoid double encoding by DOMElement::setAttribute()
+ * Get the wsdl XML document with all namespaces and required attributes
*
- * @param $uri
- * @return mixed
+ * @param string $uri
+ * @param string $name
+ * @return DOMDocument
*/
- protected function decodeAmpersand($uri)
+ protected function getDOMDocument($name, $uri = null)
{
- return str_replace('&', '&', $uri);
+ $dom = new DOMDocument();
+
+ // @todo new option for debug mode ?
+ $dom->preserveWhiteSpace = false;
+ $dom->formatOutput = false;
+ $dom->resolveExternals = false;
+ $dom->encoding = 'UTF-8';
+ $dom->substituteEntities = false;
+
+ $definitions = $dom->createElementNS(self::WSDL_NS_URI, 'definitions');
+ $dom->appendChild($definitions);
+
+ $uri = $this->sanitizeUri($uri);
+ $this->setAttributeWithSanitization($definitions, 'name', $name);
+ $this->setAttributeWithSanitization($definitions, 'targetNamespace', $uri);
+
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::WSDL_NS, self::WSDL_NS_URI);
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::TYPES_NS, $uri);
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::SOAP_11_NS, self::SOAP_11_NS_URI);
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::XSD_NS, self::XSD_NS_URI);
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::SOAP_ENC_NS, self::SOAP_ENC_URI);
+ $definitions->setAttributeNS(self::XML_NS_URI, 'xmlns:'. self::SOAP_12_NS, self::SOAP_12_NS_URI);
+
+ return $dom;
}
/**
@@ -148,7 +154,7 @@ public function getTargetNamespace()
}
/**
- * Get the class map of php to wsdl qname types.
+ * Get the class map of php to wsdl mappings..
*
* @return array
*/
@@ -158,42 +164,101 @@ public function getClassMap()
}
/**
- * Set the class map of php to wsdl qname types.
+ * Set the class map of php to wsdl mappings..
+ *
+ * @return self
*/
public function setClassMap($classMap)
{
$this->classMap = $classMap;
+ return $this;
}
/**
* Set a new uri for this WSDL
*
* @param string|Uri $uri
- * @return \Zend\Soap\Wsdl
+ * @return self
*/
public function setUri($uri)
{
- if ($uri instanceof Uri) {
+ if ($uri instanceof Uri){
$uri = $uri->toString();
}
- if ($this->wsdl !== null) {
- $targetNamespace = $this->escapeUri($uri);
- $this->wsdl->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::TYPES_NS, $targetNamespace);
- $this->wsdl->setAttribute('targetNamespace', $targetNamespace);
- if ($this->schema !== null) {
- $this->schema->setAttribute('targetNamespace', $targetNamespace);
+ $uri = $this->sanitizeUri($uri);
+
+ $oldUri = $this->uri;
+ $this->uri = $uri;
+
+ if ($this->dom instanceof DOMDocument ) {
+ // namespace declarations are NOT true attributes so one must explicitly set on root element
+ // xmlns:tns = $uri
+ $this->dom->documentElement->setAttributeNS(self::XML_NS_URI, self::XML_NS . ':' . self::TYPES_NS, $uri);
+
+ $xpath = new DOMXPath($this->dom);
+ $xpath->registerNamespace('default', self::WSDL_NS_URI);
+
+ $xpath->registerNamespace(self::TYPES_NS, $uri);
+ $xpath->registerNamespace(self::SOAP_11_NS, self::SOAP_11_NS_URI);
+ $xpath->registerNamespace(self::SOAP_12_NS, self::SOAP_12_NS_URI);
+ $xpath->registerNamespace(self::XSD_NS, self::XSD_NS_URI);
+ $xpath->registerNamespace(self::SOAP_ENC_NS, self::SOAP_ENC_URI);
+ $xpath->registerNamespace(self::WSDL_NS, self::WSDL_NS_URI);
+
+ // Select only attribute nodes. Data nodes does not contain uri
+ // except for documentation node but this is for the user to decide.
+ // This list does not include xmlns:tsn attribute of document root.
+ // That attribute is changed above.
+ $attributeNodes = $xpath->query('//attribute::*[contains(., "' . $oldUri . '")]');
+
+ foreach ($attributeNodes as $node) {
+ $attributeValue = $this->dom->createTextNode(str_replace($oldUri, $uri, $node->nodeValue));
+ $node->replaceChild($attributeValue, $node->childNodes->item(0));
}
}
return $this;
}
+ /**
+ * Return WSDL uri
+ *
+ * @return string
+ */
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ /**
+ * Function for sanitizing uri
+ *
+ * @param string|Uri $uri
+ * @return string
+ * @throws Exception\InvalidArgumentException
+ */
+ public function sanitizeUri($uri)
+ {
+ if ($uri instanceof Uri) {
+ $uri = $uri->toString();
+ }
+
+ $uri = trim($uri);
+ $uri = htmlspecialchars($uri, ENT_QUOTES, 'UTF-8', false);
+
+ if (empty($uri)) {
+ throw new Exception\InvalidArgumentException('Uri contains invalid characters or is empty');
+ }
+
+ return $uri;
+ }
+
/**
* Set a strategy for complex type detection and handling
*
- * @param ComplexTypeStrategy $strategy
- * @return \Zend\Soap\Wsdl
+ * @param ComplexTypeStrategy $strategy
+ * @return self
*/
public function setComplexTypeStrategy(ComplexTypeStrategy $strategy)
{
@@ -214,165 +279,157 @@ public function getComplexTypeStrategy()
/**
* Add a {@link http://www.w3.org/TR/wsdl#_messages message} element to the WSDL
*
- * @param string $name Name for the {@link http://www.w3.org/TR/wsdl#_messages message}
- * @param array $parts An array of {@link http://www.w3.org/TR/wsdl#_message parts}
- * The array is constructed like: 'name of part' => 'part xml schema data type'
- * or 'name of part' => array('type' => 'part xml schema type')
- * or 'name of part' => array('element' => 'part xml element name')
+ * @param string $messageName Name for the {@link http://www.w3.org/TR/wsdl#_messages message}
+ * @param array $parts An array of {@link http://www.w3.org/TR/wsdl#_message parts}
+ * The array is constructed like:
+ * 'name of part' => 'part xml schema data type' or
+ * 'name of part' => array('type' => 'part xml schema type') or
+ * 'name of part' => array('element' => 'part xml element name')
* @return DOMElement The new message's XML_Tree_Node for use in {@link function addDocumentation}
*/
- public function addMessage($name, $parts)
+ public function addMessage($messageName, $parts)
{
- $message = $this->dom->createElement('message');
-
- $message->setAttribute('name', $name);
+ $message = $this->dom->createElementNS(self::WSDL_NS_URI, 'message');
+ $message->setAttribute('name', $messageName);
if (count($parts) > 0) {
foreach ($parts as $name => $type) {
- $part = $this->dom->createElement('part');
+ $part = $this->dom->createElementNS(self::WSDL_NS_URI, 'part');
+ $message->appendChild($part);
+
$part->setAttribute('name', $name);
if (is_array($type)) {
- foreach ($type as $key => $value) {
- $part->setAttribute($key, $value);
- }
+ $this->arrayToAttributes($part, $type);
} else {
- $part->setAttribute('type', $type);
+ $this->setAttributeWithSanitization($part, 'type', $type);
}
- $message->appendChild($part);
}
}
$this->wsdl->appendChild($message);
-
return $message;
}
/**
* Add a {@link http://www.w3.org/TR/wsdl#_porttypes portType} element to the WSDL
*
- * @param string $name portType element's name
- * @return DOMElement The new portType's XML_Tree_Node for use in {@link function addPortOperation} and {@link function addDocumentation}
+ * @param string $name portType element's name
+ * @return DOMElement The new portType's XML_Tree_Node for use in {@link function addPortOperation} and addDocumentation@link function addDocumentation}
*/
public function addPortType($name)
{
- $portType = $this->dom->createElement('portType');
- $portType->setAttribute('name', $name);
+ $portType = $this->dom->createElementNS(self::WSDL_NS_URI, 'portType');
$this->wsdl->appendChild($portType);
-
+ $portType->setAttribute('name', $name);
return $portType;
}
/**
* Add an {@link http://www.w3.org/TR/wsdl#request-response operation} element to a portType element
*
- * @param DOMElement $portType a portType XML_Tree_Node, from {@link function addPortType}
- * @param string $name Operation name
- * @param bool|string $input Input Message
- * @param bool|string $output Output Message
- * @param bool|string $fault Fault Message
+ * @param DOMElement $portType a portType XML_Tree_Node, from {@link function addPortType}
+ * @param string $name Operation name
+ * @param bool|string $input Input Message
+ * @param bool|string $output Output Message
+ * @param bool|string $fault Fault Message
* @return DOMElement The new operation's XML_Tree_Node for use in {@link function addDocumentation}
*/
public function addPortOperation($portType, $name, $input = false, $output = false, $fault = false)
{
- $operation = $this->dom->createElement('operation');
+ $operation = $this->dom->createElementNS(self::WSDL_NS_URI, 'operation');
+ $portType->appendChild($operation);
+
$operation->setAttribute('name', $name);
if (is_string($input) && (strlen(trim($input)) >= 1)) {
- $node = $this->dom->createElement('input');
- $node->setAttribute('message', $input);
+ $node = $this->dom->createElementNS(self::WSDL_NS_URI, 'input');
$operation->appendChild($node);
+ $node->setAttribute('message', $input);
}
+
if (is_string($output) && (strlen(trim($output)) >= 1)) {
- $node= $this->dom->createElement('output');
- $node->setAttribute('message', $output);
+ $node= $this->dom->createElementNS(self::WSDL_NS_URI, 'output');
$operation->appendChild($node);
+ $node->setAttribute('message', $output);
}
+
if (is_string($fault) && (strlen(trim($fault)) >= 1)) {
- $node = $this->dom->createElement('fault');
- $node->setAttribute('message', $fault);
+ $node = $this->dom->createElementNS(self::WSDL_NS_URI, 'fault');
$operation->appendChild($node);
+ $node->setAttribute('message', $fault);
}
- $portType->appendChild($operation);
-
return $operation;
}
/**
* Add a {@link http://www.w3.org/TR/wsdl#_bindings binding} element to WSDL
*
- * @param string $name Name of the Binding
- * @param string $portType name of the portType to bind
+ * @param string $name Name of the Binding
+ * @param string $portType name of the portType to bind
* @return DOMElement The new binding's XML_Tree_Node for use with {@link function addBindingOperation} and {@link function addDocumentation}
*/
public function addBinding($name, $portType)
{
- $binding = $this->dom->createElement('binding');
- $binding->setAttribute('name', $name);
- $binding->setAttribute('type', $portType);
-
+ $binding = $this->dom->createElementNS(self::WSDL_NS_URI, 'binding');
$this->wsdl->appendChild($binding);
+ $this->setAttribute($binding, 'name', $name);
+ $this->setAttribute($binding, 'type', $portType);
+
return $binding;
}
/**
* Add an operation to a binding element
*
- * @param DOMElement $binding A binding XML_Tree_Node returned by {@link function addBinding}
- * @param string $name
- * @param bool|array $input An array of attributes for the input element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
- * @param bool|array $output An array of attributes for the output element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
- * @param bool|array $fault An array of attributes for the fault element, allowed keys are: 'name', 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
- * @param int $soapVersion SOAP version to be used in binding operation. 1.1 used by default.
+ * @param DOMElement $binding A binding XML_Tree_Node returned by {@link function addBinding}
+ * @param string $name
+ * @param array|bool $input An array of attributes for the input element,
+ * allowed keys are: 'use', 'namespace', 'encodingStyle'.
+ * {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
+ * @param array|bool $output An array of attributes for the output element,
+ * allowed keys are: 'use', 'namespace', 'encodingStyle'.
+ * {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
+ * @param array|bool $fault An array with attributes for the fault element,
+ * allowed keys are: 'name', 'use', 'namespace', 'encodingStyle'.
+ * {@link http://www.w3.org/TR/wsdl#_soap:body More Information}
+ * @param int $soapVersion SOAP version: SOAP_1_1 or SOAP_1_2, default: SOAP_1_1
* @return DOMElement The new Operation's XML_Tree_Node for use with {@link function addSoapOperation} and {@link function addDocumentation}
*/
- public function addBindingOperation(
- $binding,
- $name,
- $input = false,
- $output = false,
- $fault = false,
- $soapVersion = SOAP_1_1
- ) {
- $operation = $this->dom->createElement('operation');
- $operation->setAttribute('name', $name);
+ public function addBindingOperation($binding, $name, $input = false, $output = false, $fault = false, $soapVersion = SOAP_1_1)
+ {
+ $operation = $this->dom->createElementNS(self::WSDL_NS_URI, 'operation');
+ $binding->appendChild($operation);
- $soapNs = $soapVersion == SOAP_1_1 ? self::SOAP_11_NS : self::SOAP_12_NS;
- if (is_array($input)) {
- $node = $this->dom->createElement('input');
- $soapNode = $this->dom->createElement($soapNs . ':body');
- foreach ($input as $name => $value) {
- $soapNode->setAttribute($name, $this->decodeAmpersand($value));
- }
- $node->appendChild($soapNode);
+ $this->setAttribute($operation, 'name', $name);
+
+ if (is_array($input) && !empty($input)) {
+ $node = $this->dom->createElementNS(self::WSDL_NS_URI, 'input');
$operation->appendChild($node);
- }
- if (is_array($output)) {
- $node = $this->dom->createElement('output');
- $soapNode = $this->dom->createElement($soapNs . ':body');
- foreach ($output as $name => $value) {
- $soapNode->setAttribute($name, $this->decodeAmpersand($value));
- }
+ $soapNode = $this->dom->createElementNS($this->getSoapNamespaceUriByVersion($soapVersion), 'body');
$node->appendChild($soapNode);
- $operation->appendChild($node);
+
+ $this->arrayToAttributes($soapNode, $input);
}
- if (is_array($fault)) {
- $node = $this->dom->createElement('fault');
- if (isset($fault['name'])) {
- $node->setAttribute('name', $fault['name']);
- }
- $soapNode = $this->dom->createElement($soapNs . ':fault');
- foreach ($fault as $name => $value) {
- $soapNode->setAttribute($name, $this->decodeAmpersand($value));
- }
- $node->appendChild($soapNode);
+ if (is_array($output) && !empty($output)) {
+ $node = $this->dom->createElementNS(self::WSDL_NS_URI, 'output');
$operation->appendChild($node);
+
+ $soapNode = $this->dom->createElementNS($this->getSoapNamespaceUriByVersion($soapVersion), 'body');
+ $node->appendChild($soapNode);
+
+ $this->arrayToAttributes($soapNode, $output);
}
- $binding->appendChild($operation);
+ if (is_array($fault) && !empty($fault)) {
+ $node = $this->dom->createElementNS(self::WSDL_NS_URI, 'fault');
+ $operation->appendChild($node);
+
+ $this->arrayToAttributes($node, $fault);
+ }
return $operation;
}
@@ -380,34 +437,29 @@ public function addBindingOperation(
/**
* Add a {@link http://www.w3.org/TR/wsdl#_soap:binding SOAP binding} element to a Binding element
*
- * @param DOMElement $binding A binding XML_Tree_Node returned by {@link function addBinding}
- * @param string $style binding style, possible values are "rpc" (the default) and "document"
- * @param string $transport Transport method (defaults to HTTP)
- * @param int $soapVersion SOAP version to be used in binding. 1.1 used by default.
+ * @param DOMElement $binding A binding XML_Tree_Node returned by {@link function addBinding}
+ * @param string $style binding style, possible values are "rpc" (the default) and "document"
+ * @param string $transport Transport method (defaults to HTTP)
+ * @param int $soapVersion SOAP version: SOAP_1_1 or SOAP_1_2, default: SOAP_1_1
* @return DOMElement
*/
- public function addSoapBinding(
- $binding,
- $style = 'document',
- $transport = 'http://schemas.xmlsoap.org/soap/http',
- $soapVersion = SOAP_1_1
- ) {
- $soapNs = $soapVersion == SOAP_1_1 ? self::SOAP_11_NS : self::SOAP_12_NS;
- $soapBinding = $this->dom->createElement($soapNs . ':binding');
+ public function addSoapBinding($binding, $style = 'document', $transport = 'http://schemas.xmlsoap.org/soap/http', $soapVersion = SOAP_1_1)
+ {
+ $soapBinding = $this->dom->createElementNS($this->getSoapNamespaceUriByVersion($soapVersion), 'binding');
+ $binding->appendChild($soapBinding);
+
$soapBinding->setAttribute('style', $style);
$soapBinding->setAttribute('transport', $transport);
- $binding->appendChild($soapBinding);
-
return $soapBinding;
}
/**
* Add a {@link http://www.w3.org/TR/wsdl#_soap:operation SOAP operation} to an operation element
*
- * @param DOMElement $operation An operation XML_Tree_Node returned by {@link function addBindingOperation}
- * @param string $soapAction SOAP Action
- * @param int $soapVersion SOAP version to be used in operation. 1.1 used by default.
+ * @param DOMElement $operation An operation XML_Tree_Node returned by {@link function addBindingOperation}
+ * @param string $soapAction SOAP Action
+ * @param int $soapVersion SOAP version: SOAP_1_1 or SOAP_1_2, default: SOAP_1_1
* @return DOMElement
*/
public function addSoapOperation($operation, $soapAction, $soapVersion = SOAP_1_1)
@@ -415,23 +467,22 @@ public function addSoapOperation($operation, $soapAction, $soapVersion = SOAP_1_
if ($soapAction instanceof Uri) {
$soapAction = $soapAction->toString();
}
- $soapNs = $soapVersion == SOAP_1_1 ? self::SOAP_11_NS : self::SOAP_12_NS;
- $soapOperation = $this->dom->createElement($soapNs . ':operation');
- $soapOperation->setAttribute('soapAction', $this->decodeAmpersand($soapAction));
-
+ $soapOperation = $this->dom->createElementNS($this->getSoapNamespaceUriByVersion($soapVersion), 'operation');
$operation->insertBefore($soapOperation, $operation->firstChild);
+ $this->setAttributeWithSanitization($soapOperation, 'soapAction', $soapAction);
+
return $soapOperation;
}
/**
* Add a {@link http://www.w3.org/TR/wsdl#_services service} element to the WSDL
*
- * @param string $name Service Name
- * @param string $portName Name of the port for the service
- * @param string $binding Binding for the port
- * @param string $location SOAP Address for the service
- * @param int $soapVersion SOAP version to be used in service. 1.1 used by default.
+ * @param string $name Service Name
+ * @param string $portName Name of the port for the service
+ * @param string $binding Binding for the port
+ * @param string $location SOAP Address for the service
+ * @param int $soapVersion SOAP version: SOAP_1_1 or SOAP_1_2, default: SOAP_1_1
* @return DOMElement The new service's XML_Tree_Node for use with {@link function addDocumentation}
*/
public function addService($name, $portName, $binding, $location, $soapVersion = SOAP_1_1)
@@ -439,22 +490,22 @@ public function addService($name, $portName, $binding, $location, $soapVersion =
if ($location instanceof Uri) {
$location = $location->toString();
}
- $service = $this->dom->createElement('service');
+ $service = $this->dom->createElementNS(WSDL::WSDL_NS_URI, 'service');
+ $this->wsdl->appendChild($service);
+
$service->setAttribute('name', $name);
- $port = $this->dom->createElement('port');
+
+ $port = $this->dom->createElementNS(WSDL::WSDL_NS_URI, 'port');
+ $service->appendChild($port);
+
$port->setAttribute('name', $portName);
$port->setAttribute('binding', $binding);
- $soapNs = $soapVersion == SOAP_1_1 ? self::SOAP_11_NS : self::SOAP_12_NS;
- $soapAddress = $this->dom->createElement($soapNs . ':address');
- $soapAddress->setAttribute('location', $this->decodeAmpersand($location));
-
+ $soapAddress = $this->dom->createElementNS($this->getSoapNamespaceUriByVersion($soapVersion), 'address');
$port->appendChild($soapAddress);
- $service->appendChild($port);
-
- $this->wsdl->appendChild($service);
+ $this->setAttributeWithSanitization($soapAddress, 'location', $location);
return $service;
}
@@ -465,8 +516,8 @@ public function addService($name, $portName, $binding, $location, $soapVersion =
* but the WSDL {@link http://schemas.xmlsoap.org/wsdl/ schema} uses 'documentation' instead.
* The {@link http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#WSDL_documentation_Element WS-I Basic Profile 1.1} recommends using 'documentation'.
*
- * @param DOMElement $inputNode An XML_Tree_Node returned by another method to add the documentation to
- * @param string $documentation Human readable documentation for the node
+ * @param DOMElement $inputNode An XML_Tree_Node returned by another method to add the documentation to
+ * @param string $documentation Human readable documentation for the node
* @return DOMElement The documentation element
*/
public function addDocumentation($inputNode, $documentation)
@@ -477,30 +528,29 @@ public function addDocumentation($inputNode, $documentation)
$node = $inputNode;
}
- $doc = $this->dom->createElement('documentation');
- $docCData = $this->dom->createTextNode(str_replace(array("\r\n", "\r"), "\n", $documentation));
- $doc->appendChild($docCData);
-
+ $doc = $this->dom->createElementNS(WSDL::WSDL_NS_URI, 'documentation');
if ($node->hasChildNodes()) {
$node->insertBefore($doc, $node->firstChild);
} else {
$node->appendChild($doc);
}
+ $docCData = $this->dom->createTextNode(str_replace(array("\r\n", "\r"), "\n", $documentation));
+ $doc->appendChild($docCData);
return $doc;
}
/**
* Add WSDL Types element
*
- * @param DOMNode $types A DOM Node with all the XML Schema types defined in it
+ * @param DOMDocument|DOMNode|DOMElement|DOMDocumentFragment $types A DOMDocument|DOMNode|DOMElement|DOMDocumentFragment with all the XML Schema types defined in it
*/
public function addTypes(DOMNode $types)
{
if ($types instanceof DOMDocument) {
- $this->dom->importNode($types->documentElement);
- $this->wsdl->appendChild($types->documentElement);
- } else {
+ $dom = $this->dom->importNode($types->documentElement);
+ $this->wsdl->appendChild($dom);
+ } elseif ($types instanceof DOMNode || $types instanceof DOMElement || $types instanceof DOMDocumentFragment ) {
$dom = $this->dom->importNode($types);
$this->wsdl->appendChild($dom);
}
@@ -509,9 +559,9 @@ public function addTypes(DOMNode $types)
/**
* Add a complex type name that is part of this WSDL and can be used in signatures.
*
- * @param string $type
- * @param string $wsdlType
- * @return \Zend\Soap\Wsdl
+ * @param string $type
+ * @param string $wsdlType
+ * @return self
*/
public function addType($type, $wsdlType)
{
@@ -541,7 +591,6 @@ public function getSchema()
if ($this->schema == null) {
$this->addSchemaTypeSection();
}
-
return $this->schema;
}
@@ -552,6 +601,7 @@ public function getSchema()
*/
public function toXML()
{
+ $this->dom->normalizeDocument();
return $this->dom->saveXML();
}
@@ -562,28 +612,32 @@ public function toXML()
*/
public function toDomDocument()
{
+ $this->dom->normalizeDocument();
return $this->dom;
}
/**
- * Echo the WSDL as XML to stdout or save the WSDL to a file
+ * Echo the WSDL as XML
*
- * @param bool|string $filename Filename to save the output (Optional)
+ * @param bool $filename
* @return bool
*/
public function dump($filename = false)
{
+ $this->dom->normalizeDocument();
+
if (!$filename) {
echo $this->toXML();
return true;
}
+
return (bool) file_put_contents($filename, $this->toXML());
}
/**
* Returns an XSD Type for the given PHP type
*
- * @param string $type PHP Type to get the XSD type for
+ * @param string $type PHP Type to get the XSD type for
* @return string
*/
public function getType($type)
@@ -591,54 +645,67 @@ public function getType($type)
switch (strtolower($type)) {
case 'string':
case 'str':
- return 'xsd:string';
+ return self::XSD_NS . ':string';
+
case 'long':
- return 'xsd:long';
+ return self::XSD_NS . ':long';
+
case 'int':
case 'integer':
- return 'xsd:int';
+ return self::XSD_NS . ':int';
+
case 'float':
- return 'xsd:float';
+ return self::XSD_NS . ':float';
+
case 'double':
- return 'xsd:double';
+ return self::XSD_NS . ':double';
+
case 'boolean':
case 'bool':
- return 'xsd:boolean';
+ return self::XSD_NS . ':boolean';
+
case 'array':
- return 'soap-enc:Array';
+ return self::SOAP_ENC_NS . ':Array';
+
case 'object':
- return 'xsd:struct';
+ return self::XSD_NS . ':struct';
+
case 'mixed':
- return 'xsd:anyType';
+ return self::XSD_NS . ':anyType';
+
case 'void':
return '';
+
default:
// delegate retrieval of complex type to current strategy
return $this->addComplexType($type);
- }
+ }
}
/**
* This function makes sure a complex types section and schema additions are set.
*
- * @return \Zend\Soap\Wsdl
+ * @return self
*/
public function addSchemaTypeSection()
{
if ($this->schema === null) {
- $this->schema = $this->dom->createElement(self::XSD_NS . ':schema');
- $this->schema->setAttribute('targetNamespace', $this->getTargetNamespace());
- $types = $this->dom->createElement('types');
- $types->appendChild($this->schema);
+ $types = $this->dom->createElementNS(self::WSDL_NS_URI, 'types');
$this->wsdl->appendChild($types);
+
+ $this->schema = $this->dom->createElementNS(WSDL::XSD_NS_URI, 'schema');
+ $types->appendChild($this->schema);
+
+ $this->setAttributeWithSanitization($this->schema, 'targetNamespace', $this->getUri());
}
+
return $this;
}
/**
* Translate PHP type into WSDL QName
*
- * @param string $type
+ * @param string $type
* @return string QName
*/
public function translateType($type)
@@ -647,22 +714,21 @@ public function translateType($type)
return $this->classMap[$type];
}
- if ($type[0] == '\\') {
- $type = substr($type, 1);
- }
+ $type = trim($type,'\\');
+ // remove namespace,
$pos = strrpos($type, '\\');
if ($pos) {
$type = substr($type, $pos+1);
}
- return str_replace('\\', '.', $type);
+ return $type;
}
/**
* Add a {@link http://www.w3.org/TR/wsdl#_types types} data type definition
*
- * @param string $type Name of the class to be specified
+ * @param string $type Name of the class to be specified
* @return string XSD Type for the given PHP type
*/
public function addComplexType($type)
@@ -674,6 +740,7 @@ public function addComplexType($type)
$strategy = $this->getComplexTypeStrategy();
$strategy->setContext($this);
+
// delegates the detection of a complex type to the current strategy
return $strategy->addComplexType($type);
}
@@ -681,36 +748,127 @@ public function addComplexType($type)
/**
* Parse an xsd:element represented as an array into a DOMElement.
*
- * @param array $element an xsd:element represented as an array
- * @throws Exception\RuntimeException if $element is not an array
+ * @param array $element an xsd:element represented as an array
* @return DOMElement parsed element
+ * @throws Exception\RuntimeException if $element is not an array
*/
- private function _parseElement($element)
+ protected function _parseElement($element)
{
if (!is_array($element)) {
throw new Exception\RuntimeException('The "element" parameter needs to be an associative array.');
}
- $elementXml = $this->dom->createElement(self::XSD_NS . ':element');
+ $elementXML = $this->dom->createElementNS(self::XSD_NS_URI, 'element');
foreach ($element as $key => $value) {
if (in_array($key, array('sequence', 'all', 'choice'))) {
if (is_array($value)) {
- $complexType = $this->dom->createElement(self::XSD_NS . ':complexType');
+ $complexType = $this->dom->createElementNS(self::XSD_NS_URI, 'complexType');
if (count($value) > 0) {
- $container = $this->dom->createElement(self::XSD_NS . ':' . $key);
- foreach ($value as $subelement) {
- $subelementXml = $this->_parseElement($subelement);
- $container->appendChild($subelementXml);
+ $container = $this->dom->createElementNS(self::XSD_NS_URI, $key);
+ foreach ($value as $subElement) {
+ $subElementXML = $this->_parseElement($subElement);
+ $container->appendChild($subElementXML);
}
$complexType->appendChild($container);
}
- $elementXml->appendChild($complexType);
+ $elementXML->appendChild($complexType);
}
} else {
- $elementXml->setAttribute($key, $value);
+ $elementXML->setAttribute($key, $value);
+ }
+ }
+
+ return $elementXML;
+ }
+
+ /**
+ * Prepare attribute value for specific attributes
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return string safe value or original $value
+ */
+ protected function sanitizeAttributeValueByName($name, $value)
+ {
+ switch (strtolower($name)) {
+ case 'targetnamespace':
+ case 'encodingstyle':
+ case 'soapaction':
+ case 'location':
+ return $this->sanitizeUri($value);
+ break;
+
+ default:
+ return $value;
+ break;
+ }
+ }
+
+ /**
+ * Convert associative array to attributes of given node using optional {@link function sanitizeAttributeValueByName}
+ *
+ * @param DOMNode $node
+ * @param array $attributes
+ * @param bool $withSanitizer
+ */
+ protected function arrayToAttributes(\DOMNode $node, array $attributes, $withSanitizer = true)
+ {
+ foreach($attributes as $attributeName => $attributeValue) {
+ if ($withSanitizer) {
+ $this->setAttributeWithSanitization($node, $attributeName, $attributeValue);
+ } else {
+ $this->setAttribute($node, $attributeName, $attributeValue);
}
}
- return $elementXml;
+ }
+
+ /**
+ * Set attribute to given node using {@link function sanitizeAttributeValueByName}
+ *
+ * @param DOMNode $node
+ * @param string $attributeName
+ * @param mixed $attributeValue
+ */
+ protected function setAttributeWithSanitization(\DOMNode $node, $attributeName, $attributeValue)
+ {
+ $attributeValue = $this->sanitizeAttributeValueByName($attributeName, $attributeValue);
+ $this->setAttribute($node, $attributeName, $attributeValue);
+ }
+
+ /**
+ * Set attribute to given node
+ *
+ * @param DOMNode $node
+ * @param string $attributeName
+ * @param mixed $attributeValue
+ */
+ protected function setAttribute(\DOMNode $node, $attributeName, $attributeValue)
+ {
+ $attributeNode = $node->ownerDocument->createAttribute($attributeName);
+ $node->appendChild($attributeNode);
+
+ $attributeNodeValue = $node->ownerDocument->createTextNode($attributeValue);
+ $attributeNode->appendChild($attributeNodeValue);
+ }
+
+ /**
+ * Return soap namespace uri according to $soapVersion
+ *
+ * @param int $soapVersion SOAP_1_1 or SOAP_1_2 constants
+ * @return string
+ * @throws Exception\InvalidArgumentException
+ */
+ protected function getSoapNamespaceUriByVersion($soapVersion)
+ {
+ if ($soapVersion != SOAP_1_1 AND $soapVersion != SOAP_1_2) {
+ throw new Exception\InvalidArgumentException('Invalid SOAP version, use constants: SOAP_1_1 or SOAP_1_2');
+ }
+
+ if ($soapVersion == SOAP_1_1) {
+ return self::SOAP_11_NS_URI;
+ }
+
+ return self::SOAP_12_NS_URI;
}
/**
@@ -728,7 +886,7 @@ private function _parseElement($element)
*
*
*
- * @param array $element an xsd:element represented as an array
+ * @param array $element an xsd:element represented as an array
* @return string xsd:element for the given element array
*/
public function addElement($element)
@@ -736,6 +894,7 @@ public function addElement($element)
$schema = $this->getSchema();
$elementXml = $this->_parseElement($element);
$schema->appendChild($elementXml);
+
return self::TYPES_NS . ':' . $element['name'];
}
}
diff --git a/src/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php b/src/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php
index 1b626f01..36bc8bfc 100644
--- a/src/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php
+++ b/src/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php
@@ -9,33 +9,33 @@
namespace Zend\Soap\Wsdl\ComplexTypeStrategy;
+use Zend\Soap\Wsdl;
+
/**
- * Abstract class for Zend_Soap_Wsdl_Strategy.
+ * Abstract class for Zend\Soap\Wsdl\Strategy.
*/
abstract class AbstractComplexTypeStrategy implements ComplexTypeStrategyInterface
{
/**
* Context object
- *
- * @var \Zend\Soap\Wsdl
+ * @var Wsdl
*/
protected $context;
/**
- * Set the Zend_Soap_Wsdl Context object this strategy resides in.
+ * Set the WSDL Context object this strategy resides in.
*
- * @param \Zend\Soap\Wsdl $context
- * @return void
+ * @param Wsdl $context
*/
- public function setContext(\Zend\Soap\Wsdl $context)
+ public function setContext(Wsdl $context)
{
$this->context = $context;
}
/**
- * Return the current Zend_Soap_Wsdl context object
+ * Return the current WSDL context object
*
- * @return \Zend\Soap\Wsdl
+ * @return Wsdl
*/
public function getContext()
{
@@ -45,16 +45,16 @@ public function getContext()
/**
* Look through registered types
*
- * @param string $phpType
+ * @param string $phpType
* @return string
*/
public function scanRegisteredTypes($phpType)
{
+
if (array_key_exists($phpType, $this->getContext()->getTypes())) {
$soapTypes = $this->getContext()->getTypes();
return $soapTypes[$phpType];
}
-
return null;
}
}
diff --git a/src/Wsdl/ComplexTypeStrategy/AnyType.php b/src/Wsdl/ComplexTypeStrategy/AnyType.php
index bca4780d..26365054 100644
--- a/src/Wsdl/ComplexTypeStrategy/AnyType.php
+++ b/src/Wsdl/ComplexTypeStrategy/AnyType.php
@@ -9,29 +9,27 @@
namespace Zend\Soap\Wsdl\ComplexTypeStrategy;
-/**
- * Zend_Soap_Wsdl_Strategy_AnyType
- */
+use Zend\Soap\Wsdl;
+
class AnyType implements ComplexTypeStrategyInterface
{
/**
* Not needed in this strategy.
*
- * @param \Zend\Soap\Wsdl $context
+ * @param Wsdl $context
*/
- public function setContext(\Zend\Soap\Wsdl $context)
+ public function setContext(Wsdl $context)
{
-
}
/**
* Returns xsd:anyType regardless of the input.
*
- * @param string $type
+ * @param string $type
* @return string
*/
public function addComplexType($type)
{
- return 'xsd:anyType';
+ return Wsdl::XSD_NS . ':anyType';
}
}
diff --git a/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeComplex.php b/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeComplex.php
index 275ae99d..b9b4a4c7 100644
--- a/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeComplex.php
+++ b/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeComplex.php
@@ -10,18 +10,17 @@
namespace Zend\Soap\Wsdl\ComplexTypeStrategy;
use Zend\Soap\Exception;
+use Zend\Soap\Wsdl;
-/**
- * ArrayOfTypeComplex strategy
- */
class ArrayOfTypeComplex extends DefaultComplexType
{
/**
- * Add an ArrayOfType based on the xsd:complexType syntax if type[] is detected in return value doc comment.
+ * Add an ArrayOfType based on the xsd:complexType syntax if type[] is
+ * detected in return value doc comment.
*
- * @param string $type
- * @throws Exception\InvalidArgumentException
+ * @param string $type
* @return string tns:xsd-type
+ * @throws Exception\InvalidArgumentException
*/
public function addComplexType($type)
{
@@ -34,22 +33,25 @@ public function addComplexType($type)
if ($nestingLevel == 0) {
return parent::addComplexType($singularType);
- } elseif ($nestingLevel == 1) {
- // The following blocks define the Array of Object structure
- return $this->_addArrayOfComplexType($singularType, $type);
- } else {
+ }
+
+ if ($nestingLevel != 1) {
throw new Exception\InvalidArgumentException(
- 'ArrayOfTypeComplex cannot return nested ArrayOfObject deeper than '
- . 'one level. Use array object properties to return deep nested data.'
+ 'ArrayOfTypeComplex cannot return nested ArrayOfObject deeper than one level. '
+ . 'Use array object properties to return deep nested data.'
);
}
+
+ // The following blocks define the Array of Object structure
+ return $this->_addArrayOfComplexType($singularType, $type);
}
/**
- * Add an ArrayOfType based on the xsd:complexType syntax if type[] is detected in return value doc comment.
+ * Add an ArrayOfType based on the xsd:complexType syntax if type[] is
+ * detected in return value doc comment.
*
- * @param string $singularType e.g. '\MyNamespace\MyClassname'
- * @param string $type e.g. '\MyNamespace\MyClassname[]'
+ * @param string $singularType e.g. '\MyNamespace\MyClassname'
+ * @param string $type e.g. '\MyNamespace\MyClassname[]'
* @return string tns:xsd-type e.g. 'tns:ArrayOfMyNamespace.MyClassname'
*/
protected function _addArrayOfComplexType($singularType, $type)
@@ -59,7 +61,7 @@ protected function _addArrayOfComplexType($singularType, $type)
}
$xsdComplexTypeName = 'ArrayOf' . $this->getContext()->translateType($singularType);
- $xsdComplexType = 'tns:' . $xsdComplexTypeName;
+ $xsdComplexType = Wsdl::TYPES_NS . ':' . $xsdComplexTypeName;
// Register type here to avoid recursion
$this->getContext()->addType($type, $xsdComplexType);
@@ -71,23 +73,27 @@ protected function _addArrayOfComplexType($singularType, $type)
// Add array type structure to WSDL document
$dom = $this->getContext()->toDomDocument();
- $complexType = $dom->createElement('xsd:complexType');
+ $complexType = $dom->createElementNS(Wsdl::XSD_NS_URI, 'complexType');
+ $this->getContext()->getSchema()->appendChild($complexType);
+
$complexType->setAttribute('name', $xsdComplexTypeName);
- $complexContent = $dom->createElement('xsd:complexContent');
+ $complexContent = $dom->createElementNS(Wsdl::XSD_NS_URI, 'complexContent');
$complexType->appendChild($complexContent);
- $xsdRestriction = $dom->createElement('xsd:restriction');
- $xsdRestriction->setAttribute('base', 'soap-enc:Array');
+ $xsdRestriction = $dom->createElementNS(Wsdl::XSD_NS_URI, 'restriction');
$complexContent->appendChild($xsdRestriction);
+ $xsdRestriction->setAttribute('base', Wsdl::SOAP_ENC_NS . ':Array');
- $xsdAttribute = $dom->createElement('xsd:attribute');
- $xsdAttribute->setAttribute('ref', 'soap-enc:arrayType');
- $xsdAttribute->setAttribute('wsdl:arrayType',
- 'tns:' . $this->getContext()->translateType($singularType) . '[]');
+ $xsdAttribute = $dom->createElementNS(Wsdl::XSD_NS_URI, 'attribute');
$xsdRestriction->appendChild($xsdAttribute);
- $this->getContext()->getSchema()->appendChild($complexType);
+ $xsdAttribute->setAttribute('ref', Wsdl::SOAP_ENC_NS . ':arrayType');
+ $xsdAttribute->setAttributeNS(
+ Wsdl::WSDL_NS_URI,
+ 'arrayType',
+ Wsdl::TYPES_NS . ':' . $this->getContext()->translateType($singularType) . '[]'
+ );
return $xsdComplexType;
}
@@ -107,7 +113,7 @@ protected function _getSingularPhpType($type)
* Return the array nesting level based on the type name
*
* @param string $type
- * @return integer
+ * @return int
*/
protected function _getNestedCount($type)
{
diff --git a/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeSequence.php b/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeSequence.php
index eec9b260..0c223bda 100644
--- a/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeSequence.php
+++ b/src/Wsdl/ComplexTypeStrategy/ArrayOfTypeSequence.php
@@ -9,15 +9,15 @@
namespace Zend\Soap\Wsdl\ComplexTypeStrategy;
-/**
- * Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence
- */
+use Zend\Soap\Wsdl;
+
class ArrayOfTypeSequence extends DefaultComplexType
{
/**
- * Add an unbounded ArrayOfType based on the xsd:sequence syntax if type[] is detected in return value doc comment.
+ * Add an unbounded ArrayOfType based on the xsd:sequence syntax if
+ * type[] is detected in return value doc comment.
*
- * @param string $type
+ * @param string $type
* @return string tns:xsd-type
*/
public function addComplexType($type)
@@ -26,6 +26,7 @@ public function addComplexType($type)
if ($nestedCounter > 0) {
$singularType = $this->_getSingularType($type);
+ $complexType = '';
for ($i = 1; $i <= $nestedCounter; $i++) {
$complexType = $this->_getTypeBasedOnNestingLevel($singularType, $i);
@@ -36,17 +37,20 @@ public function addComplexType($type)
}
return $complexType;
- } elseif (($soapType = $this->scanRegisteredTypes($type)) !== null) {
+ }
+
+ if (($soapType = $this->scanRegisteredTypes($type)) !== null) {
// Existing complex type
return $soapType;
- } else {
- // New singular complex type
- return parent::addComplexType($type);
}
+
+ // New singular complex type
+ return parent::addComplexType($type);
}
/**
- * Return the ArrayOf or simple type name based on the singular xsdtype and the nesting level
+ * Return the ArrayOf or simple type name based on the singular xsdtype
+ * and the nesting level
*
* @param string $singularType
* @param int $level
@@ -59,7 +63,7 @@ protected function _getTypeBasedOnNestingLevel($singularType, $level)
return $this->getContext()->getType($singularType);
}
- return 'tns:' . str_repeat('ArrayOf', $level) . ucfirst($this->getContext()->translateType($singularType));
+ return Wsdl::TYPES_NS . ':' . str_repeat('ArrayOf', $level) . ucfirst($this->getContext()->translateType($singularType));
}
/**
@@ -77,7 +81,7 @@ protected function _getSingularType($type)
* Return the array nesting level based on the type name
*
* @param string $type
- * @return integer
+ * @return int
*/
protected function _getNestedCount($type)
{
@@ -90,7 +94,6 @@ protected function _getNestedCount($type)
* @param string $arrayType Array type name (e.g. 'tns:ArrayOfArrayOfInt')
* @param string $childType Qualified array items type (e.g. 'xsd:int', 'tns:ArrayOfInt')
* @param string $phpArrayType PHP type (e.g. 'int[][]', '\MyNamespace\MyClassName[][][]')
- * @return void
*/
protected function _addSequenceType($arrayType, $childType, $phpArrayType)
{
@@ -106,20 +109,20 @@ protected function _addSequenceType($arrayType, $childType, $phpArrayType)
$arrayTypeName = substr($arrayType, strpos($arrayType, ':') + 1);
- $complexType = $dom->createElement('xsd:complexType');
+ $complexType = $dom->createElementNS(Wsdl::XSD_NS_URI, 'complexType');
+ $this->getContext()->getSchema()->appendChild($complexType);
+
$complexType->setAttribute('name', $arrayTypeName);
- $sequence = $dom->createElement('xsd:sequence');
+ $sequence = $dom->createElementNS(Wsdl::XSD_NS_URI, 'sequence');
+ $complexType->appendChild($sequence);
+
+ $element = $dom->createElementNS(Wsdl::XSD_NS_URI, 'element');
+ $sequence->appendChild($element);
- $element = $dom->createElement('xsd:element');
$element->setAttribute('name', 'item');
$element->setAttribute('type', $childType);
$element->setAttribute('minOccurs', 0);
$element->setAttribute('maxOccurs', 'unbounded');
- $sequence->appendChild($element);
-
- $complexType->appendChild($sequence);
-
- $this->getContext()->getSchema()->appendChild($complexType);
}
}
diff --git a/src/Wsdl/ComplexTypeStrategy/Composite.php b/src/Wsdl/ComplexTypeStrategy/Composite.php
index 9939c824..ea8f0a12 100644
--- a/src/Wsdl/ComplexTypeStrategy/Composite.php
+++ b/src/Wsdl/ComplexTypeStrategy/Composite.php
@@ -13,29 +13,23 @@
use Zend\Soap\Wsdl;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface as ComplexTypeStrategy;
-/**
- * Zend_Soap_Wsdl_Strategy_Composite
- */
class Composite implements ComplexTypeStrategy
{
/**
* Typemap of Complex Type => Strategy pairs.
- *
* @var array
*/
protected $typeMap = array();
/**
* Default Strategy of this composite
- *
* @var string|ComplexTypeStrategy
*/
protected $defaultStrategy;
/**
* Context WSDL file that this composite serves
- *
- * @var \Zend\Soap\Wsdl|null
+ * @var Wsdl|null
*/
protected $context;
@@ -45,21 +39,24 @@ class Composite implements ComplexTypeStrategy
* @param array $typeMap
* @param string|ComplexTypeStrategy $defaultStrategy
*/
- public function __construct(array $typeMap=array(), $defaultStrategy='\Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType')
- {
- foreach ($typeMap AS $type => $strategy) {
+ public function __construct(
+ array $typeMap = array(),
+ $defaultStrategy = 'Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType'
+ ) {
+ foreach ($typeMap as $type => $strategy) {
$this->connectTypeToStrategy($type, $strategy);
}
+
$this->defaultStrategy = $defaultStrategy;
}
/**
* Connect a complex type to a given strategy.
*
- * @throws Exception\InvalidArgumentException
* @param string $type
* @param string|ComplexTypeStrategy $strategy
* @return Composite
+ * @throws Exception\InvalidArgumentException
*/
public function connectTypeToStrategy($type, $strategy)
{
@@ -73,8 +70,8 @@ public function connectTypeToStrategy($type, $strategy)
/**
* Return default strategy of this composite
*
- * @throws Exception\InvalidArgumentException
* @return ComplexTypeStrategy
+ * @throws Exception\InvalidArgumentException
*/
public function getDefaultStrategy()
{
@@ -82,7 +79,7 @@ public function getDefaultStrategy()
if (is_string($strategy) && class_exists($strategy)) {
$strategy = new $strategy;
}
- if ( !($strategy instanceof ComplexTypeStrategy) ) {
+ if (!($strategy instanceof ComplexTypeStrategy)) {
throw new Exception\InvalidArgumentException(
'Default Strategy for Complex Types is not a valid strategy object.'
);
@@ -94,9 +91,9 @@ public function getDefaultStrategy()
/**
* Return specific strategy or the default strategy of this type.
*
- * @throws Exception\InvalidArgumentException
- * @param string $type
+ * @param string $type
* @return ComplexTypeStrategy
+ * @throws Exception\InvalidArgumentException
*/
public function getStrategyOfType($type)
{
@@ -107,7 +104,7 @@ public function getStrategyOfType($type)
$strategy = new $strategy();
}
- if ( !($strategy instanceof ComplexTypeStrategy) ) {
+ if (!($strategy instanceof ComplexTypeStrategy)) {
throw new Exception\InvalidArgumentException(sprintf(
'Strategy for Complex Type "%s" is not a valid strategy object.',
$type
@@ -117,13 +114,14 @@ public function getStrategyOfType($type)
} else {
$strategy = $this->getDefaultStrategy();
}
+
return $strategy;
}
/**
* Method accepts the current WSDL context file.
*
- * @param \Zend\Soap\Wsdl $context
+ * @param Wsdl $context
* @return Composite
*/
public function setContext(Wsdl $context)
@@ -135,13 +133,13 @@ public function setContext(Wsdl $context)
/**
* Create a complex type based on a strategy
*
- * @throws Exception\InvalidArgumentException
* @param string $type
* @return string XSD type
+ * @throws Exception\InvalidArgumentException
*/
public function addComplexType($type)
{
- if (!($this->context instanceof Wsdl) ) {
+ if (!($this->context instanceof Wsdl)) {
throw new Exception\InvalidArgumentException(sprintf(
'Cannot add complex type "%s", no context is set for this composite strategy.',
$type
@@ -150,6 +148,7 @@ public function addComplexType($type)
$strategy = $this->getStrategyOfType($type);
$strategy->setContext($this->context);
+
return $strategy->addComplexType($type);
}
}
diff --git a/src/Wsdl/ComplexTypeStrategy/DefaultComplexType.php b/src/Wsdl/ComplexTypeStrategy/DefaultComplexType.php
index 2a10aaf4..779cd2bf 100644
--- a/src/Wsdl/ComplexTypeStrategy/DefaultComplexType.php
+++ b/src/Wsdl/ComplexTypeStrategy/DefaultComplexType.php
@@ -9,19 +9,18 @@
namespace Zend\Soap\Wsdl\ComplexTypeStrategy;
+use ReflectionClass;
use Zend\Soap\Exception;
+use Zend\Soap\Wsdl;
-/**
- * Zend_Soap_Wsdl_Strategy_DefaultComplexType
- */
class DefaultComplexType extends AbstractComplexTypeStrategy
{
/**
* Add a complex type by recursively using all the class properties fetched via Reflection.
*
* @param string $type Name of the class to be specified
- * @throws Exception\InvalidArgumentException if class does not exist
* @return string XSD Type for the given PHP type
+ * @throws Exception\InvalidArgumentException if class does not exist
*/
public function addComplexType($type)
{
@@ -38,10 +37,10 @@ public function addComplexType($type)
}
$dom = $this->getContext()->toDomDocument();
- $class = new \ReflectionClass($type);
+ $class = new ReflectionClass($type);
$soapTypeName = $this->getContext()->translateType($type);
- $soapType = 'tns:' . $soapTypeName;
+ $soapType = Wsdl::TYPES_NS . ':' . $soapTypeName;
// Register type here to avoid recursion
$this->getContext()->addType($type, $soapType);
@@ -49,19 +48,20 @@ public function addComplexType($type)
$defaultProperties = $class->getDefaultProperties();
- $complexType = $dom->createElement('xsd:complexType');
+ $complexType = $dom->createElementNS(Wsdl::XSD_NS_URI, 'complexType');
$complexType->setAttribute('name', $soapTypeName);
- $all = $dom->createElement('xsd:all');
+ $all = $dom->createElementNS(Wsdl::XSD_NS_URI, 'all');
foreach ($class->getProperties() as $property) {
if ($property->isPublic() && preg_match_all('/@var\s+([^\s]+)/m', $property->getDocComment(), $matches)) {
/**
- * @todo check if 'xsd:element' must be used here (it may not be compatible with using 'complexType'
- * node for describing other classes used as attribute types for current class
+ * @todo check if 'xsd:element' must be used here (it may not be
+ * compatible with using 'complexType' node for describing other
+ * classes used as attribute types for current class
*/
- $element = $dom->createElement('xsd:element');
+ $element = $dom->createElementNS(Wsdl::XSD_NS_URI, 'element');
$element->setAttribute('name', $propertyName = $property->getName());
$element->setAttribute('type', $this->getContext()->getType(trim($matches[1][0])));
diff --git a/test/AutoDiscoverTest.php b/test/AutoDiscoverTest.php
index 57eded3d..d02f1ab1 100644
--- a/test/AutoDiscoverTest.php
+++ b/test/AutoDiscoverTest.php
@@ -14,6 +14,8 @@
require_once 'TestAsset/commontypes.php';
use Zend\Soap\AutoDiscover;
+use Zend\Soap\Wsdl;
+use Zend\Uri\Uri;
/** PHPUnit Test Case */
@@ -27,19 +29,67 @@
*/
class AutoDiscoverTest extends \PHPUnit_Framework_TestCase
{
- protected function createAutodiscoverService()
+
+ /**
+ * @var AutoDiscover
+ */
+ protected $server;
+
+ /**
+ * @var string
+ */
+ protected $defaultServiceName = 'MyService';
+
+ /**
+ * @var string
+ */
+ protected $defaultServiceUri = 'http://localhost/MyService.php';
+
+ /**
+ * @var \DOMDocument
+ */
+ protected $dom;
+
+ /**
+ * @var \DOMXPath
+ */
+ protected $xpath;
+
+ public function setUp()
{
- $server = new AutoDiscover();
- $server->setUri('http://localhost/my_script.php');
- $server->setServiceName('TestService');
- return $server;
+ $this->server = new AutoDiscover();
+ $this->server->setUri($this->defaultServiceUri);
+ $this->server->setServiceName($this->defaultServiceName);
}
- protected function sanitizeWsdlXmlOutputForOsCompability($xmlstring)
+ /**
+ *
+ *
+ * @param \Zend\Soap\Wsdl $wsdl
+ * @param null $documentNamespace
+ */
+ public function bindWsdl(Wsdl $wsdl, $documentNamespace = null)
{
- $xmlstring = str_replace(array("\r", "\n"), "", $xmlstring);
- $xmlstring = preg_replace('/(>[\s]{1,}<)/', '', $xmlstring);
- return $xmlstring;
+ $this->dom = new \DOMDocument();
+ $this->dom->formatOutput = true;
+ $this->dom->preserveWhiteSpace = false;
+
+ $this->dom->loadXML($wsdl->toXML());
+
+ if (empty($documentNamespace)) {
+ $documentNamespace = $this->defaultServiceUri;
+ }
+
+ $this->xpath = new \DOMXPath($this->dom);
+
+ $this->xpath->registerNamespace('unittest', Wsdl::WSDL_NS_URI);
+
+ $this->xpath->registerNamespace('tns', $documentNamespace);
+ $this->xpath->registerNamespace('soap', Wsdl::SOAP_11_NS_URI);
+ $this->xpath->registerNamespace('soap12', Wsdl::SOAP_12_NS_URI);
+ $this->xpath->registerNamespace('xsd', Wsdl::XSD_NS_URI);
+ $this->xpath->registerNamespace('soap-enc', Wsdl::SOAP_ENC_URI);
+ $this->xpath->registerNamespace('wsdl', Wsdl::WSDL_NS_URI);
}
/**
@@ -50,7 +100,8 @@ protected function sanitizeWsdlXmlOutputForOsCompability($xmlstring)
protected function assertValidWSDL(\DOMDocument $dom)
{
// this code is necessary to support some libxml stupidities.
- $file = __DIR__.'/TestAsset/validate.wsdl';
+ // @todo memory streams ?
+ $file = __DIR__ . '/TestAsset/validate.wsdl';
if (file_exists($file)) {
unlink($file);
}
@@ -59,244 +110,609 @@ protected function assertValidWSDL(\DOMDocument $dom)
$dom = new \DOMDocument();
$dom->load($file);
- $this->assertTrue($dom->schemaValidate(__DIR__ .'/schemas/wsdl.xsd'), "WSDL Did not validate");
+ $this->assertTrue(
+ $dom->schemaValidate(__DIR__ . '/schemas/wsdl.xsd'),
+ "WSDL Did not validate"
+ );
unlink($file);
}
- public function testSetClass()
+ /**
+ * @param \DOMElement $element
+ */
+ public function testDocumentNodes($element = null)
+ {
+ if (!($this->dom instanceof \DOMDocument)) {
+ return;
+ }
+
+ if (is_null($element)) {
+ $element = $this->dom->documentElement;
+ }
+
+ /** @var $node \DOMElement */
+ foreach ($element->childNodes as $node) {
+ if (in_array($node->nodeType, array(XML_ELEMENT_NODE))) {
+ $this->assertNotEmpty(
+ $node->namespaceURI, 'Document element: '
+ . $node->nodeName . ' has no valid namespace. Line: '
+ . $node->getLineNo()
+ );
+ $this->testDocumentNodes($node);
+ }
+ }
+ }
+
+ /**
+ * @dataProvider dataProviderValidUris
+ */
+ public function testAutoDiscoverConstructorUri($uri, $expectedUri)
+ {
+ $server = new AutoDiscover(null, $uri);
+
+ $this->assertEquals($expectedUri, $server->getUri()->toString());
+ }
+
+ /**
+ * @dataProvider dataProviderForAutoDiscoverConstructorStrategy
+ */
+ public function testAutoDiscoverConstructorStrategy($strategy)
+ {
+ $server = new AutoDiscover($strategy);
+
+ $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $server->setServiceName('TestService');
+ $server->setUri('http://example.com');
+ $wsdl = $server->generate();
+
+ $this->assertEquals(
+ get_class($strategy), get_class($wsdl->getComplexTypeStrategy())
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForAutoDiscoverConstructorStrategy()
+ {
+ return array(
+ array(new Wsdl\ComplexTypeStrategy\AnyType()),
+ array(new Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex()),
+ array(new Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence()),
+ array(new Wsdl\ComplexTypeStrategy\Composite()),
+ array(new Wsdl\ComplexTypeStrategy\DefaultComplexType()),
+ );
+ }
+
+ /**
+ */
+ public function testGetDiscoveryStrategy()
+ {
+ $server = new AutoDiscover();
+
+ $this->assertEquals(
+ 'Zend\Soap\AutoDiscover\DiscoveryStrategy\ReflectionDiscovery',
+ get_class($server->getDiscoveryStrategy())
+ );
+ }
+
+ /**
+ */
+ public function testAutoDiscoverConstructorWsdlClass()
+ {
+ $server = new AutoDiscover(null, null, '\Zend\Soap\Wsdl');
+
+ $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $server->setServiceName('TestService');
+ $server->setUri('http://example.com');
+ $wsdl = $server->generate();
+
+ $this->assertEquals('Zend\Soap\Wsdl', trim(get_class($wsdl), '\\'));
+ $this->assertEquals(
+ 'Zend\Soap\Wsdl', trim($server->getWsdlClass(), '\\')
+ );
+ }
+
+ /**
+ * @expectedException \Zend\Soap\Exception\InvalidArgumentException
+ */
+ public function testAutoDiscoverConstructorWsdlClassException()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $server = new AutoDiscover();
+ $server->setWsdlClass(new \stdClass());
+ }
+
+ /**
+ * @dataProvider dataProviderForSetServiceName
+ */
+ public function testSetServiceName($newName, $shouldBeValid)
+ {
+
+ if ($shouldBeValid == false) {
+ $this->setExpectedException('InvalidArgumentException');
+ }
+
+ $this->server->setServiceName($newName);
+ $this->bindWsdl($this->server->generate());
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '/wsdl:definitions[@name="' . $newName . '"]'
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForSetServiceName()
+ {
+ return array(
+ array('MyServiceName123', true),
+ array('1MyServiceName123', false),
+ array('$MyServiceName123', false),
+ array('!MyServiceName123', false),
+ array('&MyServiceName123', false),
+ array('(MyServiceName123', false),
+ array('\MyServiceName123', false),
+ );
+ }
+
+ public function testGetServiceName()
+ {
+ $server = new AutoDiscover();
- $server = $this->createAutodiscoverService();
$server->setClass('\ZendTest\Soap\TestAsset\Test');
- $dom = $server->generate()->toDomDocument();
-
- $wsdl = ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 1'
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 2'
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 3'
- . ''
- . ''
- . ''
- . 'Test Function 4'
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '';
-
- $this->assertEquals($wsdl, $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
- $this->assertValidWSDL($dom);
+
+ $this->assertEquals('Test', $server->getServiceName());
+ }
+
+ /**
+ * @expectedException \Zend\Soap\Exception\RuntimeException
+ */
+ public function testGetServiceNameException()
+ {
+ $server = new AutoDiscover();
+
+ $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+
+ $this->assertEquals('Test', $server->getServiceName());
+ }
+
+ /**
+ * @expectedException \Zend\Soap\Exception\InvalidArgumentException
+ */
+ public function testSetUriException()
+ {
+ $server = new AutoDiscover();
+
+ $server->setUri(' ');
+ }
+
+ /**
+ * @expectedException \Zend\Soap\Exception\RuntimeException
+ */
+ public function testGetUriException()
+ {
+ $server = new AutoDiscover();
+ $server->getUri();
+ }
+
+ public function testClassMap()
+ {
+
+ $classMap = array(
+ 'TestClass' => 'test_class'
+ );
+
+ $this->server->setClassMap($classMap);
+
+ $this->assertEquals($classMap, $this->server->getClassMap());
+ }
+
+ public function testSetClass()
+ {
+ $this->server->setClass('\ZendTest\Soap\TestAsset\Test');
+
+ $this->bindWsdl($this->server->generate());
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema[@targetNamespace="'
+ . $this->defaultServiceUri . '"]', 'Invalid schema definition'
+ );
+
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]',
+ 'Invalid func' . $i . ' operation definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:documentation',
+ 'Invalid func' . $i . ' port definition - documentation node'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:input[@message="tns:testFunc' . $i . 'In"]',
+ 'Invalid func' . $i . ' port definition - input node'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:output[@message="tns:testFunc' . $i . 'Out"]',
+ 'Invalid func' . $i . ' port definition - output node'
+ );
+ }
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]',
+ 'Invalid service binding definition'
+ );
+ $this->assertEquals(
+ 'tns:MyServicePort', $nodes->item(0)->getAttribute('type'),
+ 'Invalid type attribute value in service binding definition'
+ );
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/soap:binding',
+ 'Invalid service binding definition'
+ );
+ $this->assertEquals(
+ 'rpc', $nodes->item(0)->getAttribute('style'),
+ 'Invalid style attribute value in service binding definition'
+ );
+ $this->assertEquals(
+ 'http://schemas.xmlsoap.org/soap/http',
+ $nodes->item(0)->getAttribute('transport'),
+ 'Invalid transport attribute value in service binding definition'
+ );
+
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'. $i . '"]',
+ 'Invalid func' . $i . ' operation binding definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/soap:operation[@soapAction="' . $this->defaultServiceUri .
+ '#testFunc' . $i . '"]',
+ 'Invalid func' . $i . ' operation action binding definition'
+ );
+ }
+
+ $xpath
+ = '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[wsdl:input or wsdl:output]/*/soap:body';
+ $this->assertSpecificNodeNumberInXPath(8, $xpath);
+ $nodes = $this->xpath->query($xpath);
+ $this->assertAttributesOfNodes(
+ array(
+ "use" => "encoded",
+ "encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/",
+ "namespace" => "http://localhost/MyService.php"
+ ), $nodes
+ );
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:service[@name="MyServiceService"]',
+ 'Invalid service definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:service[@name="MyServiceService"]/'
+ . 'wsdl:port[@name="MyServicePort" and @binding="tns:MyServiceBinding"]',
+ 'Invalid service port definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:service[@name="MyServiceService"]/'
+ . 'wsdl:port[@name="MyServicePort" and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]',
+ 'Invalid service address definition'
+ );
+
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc1In"]',
+ 'Invalid message definition'
+ );
+ $this->assertFalse($nodes->item(0)->hasChildNodes());
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc2In"]',
+ 'Invalid message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="testFunc2In"]/wsdl:part[@name="who" and @type="xsd:string"]',
+ 'Invalid message definition'
+ );
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc2Out"]',
+ 'Invalid message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="testFunc2Out"]/wsdl:part[@name="return" and @type="xsd:string"]',
+ 'Invalid message definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc3In"]',
+ 'Invalid message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 2,
+ '//wsdl:message[@name="testFunc3In"][(wsdl:part[@name="who" and @type="xsd:string"]) or (wsdl:part[@name="when" and @type="xsd:int"])]/wsdl:part',
+ 'Invalid message definition'
+ );
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc3Out"]',
+ 'Invalid message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="testFunc3Out"]/wsdl:part[@name="return" and @type="xsd:string"]',
+ 'Invalid message definition'
+ );
+
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc4In"]',
+ 'Invalid message definition'
+ );
+ $this->assertFalse($nodes->item(0)->hasChildNodes());
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="testFunc4Out"]/wsdl:part[@name="return" and @type="xsd:string"]',
+ 'Invalid message definition'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
public function testSetClassWithDifferentStyles()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->setBindingStyle(
+ array('style' => 'document',
+ 'transport' => $this->defaultServiceUri)
+ );
+ $this->server->setOperationBodyStyle(
+ array('use' => 'literal', 'namespace' => $this->defaultServiceUri)
+ );
+ $this->server->setClass('\ZendTest\Soap\TestAsset\Test');
- $server = $this->createAutodiscoverService();
- $server->setBindingStyle(array('style' => 'document', 'transport' => 'http://framework.zend.com'));
- $server->setOperationBodyStyle(array('use' => 'literal', 'namespace' => 'http://framework.zend.com'));
- $server->setClass('\ZendTest\Soap\TestAsset\Test');
- $dom = $server->generate()->toDomDocument();
-
- $wsdl = ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 1'
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 2'
- . ''
- . ''
- . ''
- . ''
- . 'Test Function 3'
- . ''
- . ''
- . ''
- . 'Test Function 4'
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '';
-
- $this->assertEquals($wsdl, $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
- $this->assertValidWSDL($dom);
+ $this->bindWsdl($this->server->generate());
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema/xsd:element[@name="testFunc1"]',
+ 'Missing test func1 definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc1"]/xsd:complexType',
+ 'Missing test func1 type definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 0,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc1"]/xsd:complexType/*',
+ 'Test func1 does not have children'
+ );
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc1Response"]/'
+ .'xsd:complexType/xsd:sequence/xsd:element',
+ 'Test func1 return element is invalid'
+ );
+ $this->assertAttributesOfNodes(
+ array(
+ 'name' => "testFunc1Result",
+ 'type' => "xsd:string",
+ ), $nodes
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema/xsd:element[@name="testFunc2"]',
+ 'Missing test func2 definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc2"]/xsd:complexType',
+ 'Missing test func2 type definition'
+ );
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc2"]/xsd:complexType/'
+ .'xsd:sequence/xsd:element',
+ 'Test func2 does not have children'
+ );
+ $this->assertAttributesOfNodes(
+ array(
+ 'name' => "who",
+ 'type' => "xsd:string",
+ ), $nodes
+ );
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc2Response"]/'
+ .'xsd:complexType/xsd:sequence/xsd:element',
+ 'Test func2 return element is invalid'
+ );
+ $this->assertAttributesOfNodes(
+ array(
+ 'name' => "testFunc2Result",
+ 'type' => "xsd:string",
+ ), $nodes
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3"]',
+ 'Missing test func3 definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3"]/xsd:complexType',
+ 'Missing test func3 type definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 2,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3"]/xsd:complexType/'
+ .'xsd:sequence/xsd:element',
+ 'Test func3 does not have children'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3"]/xsd:complexType/'
+ .'xsd:sequence/xsd:element[@name="who" and @type="xsd:string"]',
+ 'Test func3 does not have children'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3"]/xsd:complexType/'
+ .'xsd:sequence/xsd:element[@name="when" and @type="xsd:int"]',
+ 'Test func3 does not have children'
+ );
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc3Response"]/'
+ .'xsd:complexType/xsd:sequence/xsd:element',
+ 'Test func3 return element is invalid'
+ );
+ $this->assertAttributesOfNodes(
+ array(
+ 'name' => "testFunc3Result",
+ 'type' => "xsd:string",
+ ), $nodes
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema/xsd:element[@name="testFunc4"]',
+ 'Missing test func1 definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc4"]/xsd:complexType',
+ 'Missing test func1 type definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 0,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc4"]/xsd:complexType/*',
+ 'Test func1 does not have children'
+ );
+
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:element[@name="testFunc4Response"]/'
+ .'xsd:complexType/xsd:sequence/xsd:element',
+ 'Test func1 return element is invalid'
+ );
+ $this->assertAttributesOfNodes(
+ array(
+ 'name' => "testFunc4Result",
+ 'type' => "xsd:string",
+ ), $nodes
+ );
+
+
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 3,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/*',
+ 'Missing test func' . $i . ' port definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:documentation',
+ 'Missing test func' . $i . ' port documentation'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:input[@message="tns:testFunc' . $i . 'In"]',
+ 'Missing test func' . $i . ' port input message'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/wsdl:output[@message="tns:testFunc' . $i
+ . 'Out"]',
+ 'Missing test func' . $i . ' port output message'
+ );
+ }
+
+
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 3,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/*',
+ 'Missing test func' . $i . ' binding definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'
+ . $i . '"]/soap:operation[@soapAction="'
+ . $this->defaultServiceUri . '#testFunc' . $i . '"]',
+ 'Missing test func' . $i . ' binding operation definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'
+ . $i
+ . '"]/wsdl:input/soap:body[@use="literal" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing test func' . $i . ' binding input message'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding"]/wsdl:operation[@name="testFunc'
+ . $i
+ . '"]/wsdl:output/soap:body[@use="literal" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing test func' . $i . ' binding input message'
+ );
+ }
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:service[@name="MyServiceService"]/wsdl:port[@name="MyServicePort"'
+ . ' and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]'
+ );
+
+
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc' . $i
+ . 'In"]/wsdl:part[@name="parameters" and @element="tns:testFunc' . $i . '"]',
+ 'Missing test testFunc' . $i . ' input message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFunc' . $i
+ . 'Out"]/wsdl:part[@name="parameters" and @element="tns:testFunc' . $i . 'Response"]',
+ 'Missing test testFunc' . $i . ' output message definition'
+ );
+ }
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -304,99 +720,247 @@ public function testSetClassWithDifferentStyles()
*/
public function testSetClassWithResponseReturnPartCompabilityMode()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->setClass('\ZendTest\Soap\TestAsset\Test');
+ $this->bindWsdl($this->server->generate());
- $server = $this->createAutodiscoverService();
- $server->setClass('\ZendTest\Soap\TestAsset\Test');
- $dom = $server->generate()->toDomDocument();
- $dom->save(__DIR__.'/TestAsset/setclass.wsdl');
- $this->assertContains('sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
- $this->assertContains('sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
- $this->assertContains('sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
- $this->assertContains('sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()));
+ for ($i = 1; $i <= 4; $i++) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="testFunc' . $i . 'Out"]/wsdl:part[@name="return"]'
+ );
+ }
+
- unlink(__DIR__.'/TestAsset/setclass.wsdl');
+ $this->assertValidWSDL($this->dom);
+ }
+
+ /**
+ * @expectedException \Zend\Soap\Exception\InvalidArgumentException
+ * @dataProvider dataProviderForAddFunctionException
+ */
+ public function testAddFunctionException($function)
+ {
+ $this->server->addFunction($function);
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForAddFunctionException()
+ {
+ return array(
+ array('InvalidFunction'),
+ array(1),
+ array(array(1, 2)),
+ );
}
public function testAddFunctionSimple()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->bindWsdl($this->server->generate());
- $server = $this->createAutodiscoverService();
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
- $dom = $server->generate()->toDomDocument();
-
- $name = "TestService";
-
- $wsdl = ''.
- ''.
- ''.
- ''.
- 'Test Function'.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- '';
- $this->assertEquals($wsdl, $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()), "Bad WSDL generated");
- $this->assertValidWSDL($dom);
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]',
+ 'Missing service port definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:documentation',
+ 'Missing service port definition documentation'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:input',
+ 'Missing service port definition input message'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:output',
+ 'Missing service port definition input message'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]',
+ 'Missing service binding definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . ' soap:binding[@style="rpc" and @transport="http://schemas.xmlsoap.org/soap/http"]',
+ 'Missing service binding transport definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . ' wsdl:operation[@name="TestFunc"]/soap:operation[@soapAction="'
+ . $this->defaultServiceUri . '#TestFunc"]',
+ 'Missing service operation action definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:input/soap:body[@use="encoded" '
+ . 'and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing operation input body definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:output/soap:body[@use="encoded"'
+ . 'and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing operation input body definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:service[@name="MyServiceService"]/wsdl:port[@name="MyServicePort"'
+ . ' and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing service port definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncIn"]/wsdl:part[@name="who" and @type="xsd:string"]',
+ 'Missing test testFunc input message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncOut"]/wsdl:part[@name="return" and @type="xsd:string"]',
+ 'Missing test testFunc input message definition'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
public function testAddFunctionSimpleWithDifferentStyle()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->setBindingStyle(
+ array('style' => 'document',
+ 'transport' => $this->defaultServiceUri)
+ );
+ $this->server->setOperationBodyStyle(
+ array('use' => 'literal', 'namespace' => $this->defaultServiceUri)
+ );
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->bindWsdl($this->server->generate());
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema[@targetNamespace="'
+ . $this->defaultServiceUri . '"]', 'Missing service port definition'
+ );
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema[@targetNamespace="' . $this->defaultServiceUri
+ . '"]/xsd:element[@name="TestFunc"]/xsd:complexType/xsd:sequence/'
+ . 'xsd:element[@name="who" and @type="xsd:string"]',
+ 'Missing complex type definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema[@targetNamespace="' . $this->defaultServiceUri
+ . '"]/xsd:element[@name="TestFuncResponse"]/xsd:complexType/xsd:sequence'
+ . '/xsd:element[@name="TestFuncResult" and @type="xsd:string"]',
+ 'Missing complex type definition'
+ );
- $server = $this->createAutodiscoverService();
- $server->setBindingStyle(array('style' => 'document', 'transport' => 'http://framework.zend.com'));
- $server->setOperationBodyStyle(array('use' => 'literal', 'namespace' => 'http://framework.zend.com'));
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
- $dom = $server->generate()->toDomDocument();
-
- $name = "TestService";
- $wsdl = ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- 'Test Function'.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- '';
- $this->assertEquals($wsdl, $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()), "Bad WSDL generated");
- $this->assertValidWSDL($dom);
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]',
+ 'Missing service port definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:documentation',
+ 'Missing service port definition documentation'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:input',
+ 'Missing service port definition input message'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/wsdl:output',
+ 'Missing service port definition input message'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]',
+ 'Missing service binding definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'soap:binding[@style="document" and @transport="' . $this->defaultServiceUri . '"]',
+ 'Missing service binding transport definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/soap:operation[@soapAction="'
+ . $this->defaultServiceUri . '#TestFunc"]',
+ 'Missing service operation action definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:input/soap:body[@use="literal" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing operation input body definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:output/soap:body[@use="literal" and @namespace="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing operation input body definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:service[@name="MyServiceService"]/wsdl:port[@name="MyServicePort"'
+ . ' and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing service port definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncIn"]/wsdl:part[@name="parameters" and @element="tns:TestFunc"]',
+ 'Missing test testFunc input message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncOut"]/wsdl:part[@name="parameters" and @element="tns:TestFuncResponse"]',
+ 'Missing test testFunc input message definition'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -404,184 +968,296 @@ public function testAddFunctionSimpleWithDifferentStyle()
*/
public function testAddFunctionSimpleInReturnNameCompabilityMode()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->bindWsdl($this->server->generate());
- $server = $this->createAutodiscoverService();
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema[@targetNamespace="'
+ . $this->defaultServiceUri . '"]', 'Missing service port definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]',
+ 'Missing service port definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/'
+ . 'wsdl:documentation',
+ 'Missing service port definition documentation'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/'
+ . 'wsdl:input',
+ 'Missing service port definition input message'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc"]/'
+ . 'wsdl:output',
+ 'Missing service port definition input message'
+ );
- $dom = $server->generate()->toDomDocument();
- $name = "TestService";
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]',
+ 'Missing service binding definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'soap:binding[@style="rpc" and @transport="http://schemas.xmlsoap.org/soap/http"]',
+ 'Missing service binding transport definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/soap:operation[@soapAction="'
+ . $this->defaultServiceUri . '#TestFunc"]',
+ 'Missing service operation action definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:input/soap:body[@use="encoded"'
+ . ' and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" '
+ . 'and @namespace="http://localhost/MyService.php"]',
+ 'Missing operation input body definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc"]/wsdl:output/soap:body[@use="encoded"'
+ . 'and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" and'
+ . '@namespace="http://localhost/MyService.php"]',
+ 'Missing operation input body definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:service[@name="MyServiceService"]/wsdl:port[@name="MyServicePort"'
+ . 'and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing service port definition'
+ );
+
- $wsdl = $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML());
- $this->assertContains('', $wsdl);
- $this->assertNotContains('assertValidWSDL($dom);
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncIn"]/wsdl:part[@name="who" and @type="xsd:string"]',
+ 'Missing test testFunc input message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:message[@name="TestFuncOut"]/wsdl:part[@name="return" and @type="xsd:string"]',
+ 'Missing test testFunc input message definition'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
public function testAddFunctionMultiple()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc2');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc3');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc4');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc5');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc6');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc7');
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc9');
- $server = $this->createAutodiscoverService();
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc2');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc3');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc4');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc5');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc6');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc7');
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc9');
-
- $dom = $server->generate()->toDomDocument();
-
- $name = "TestService";
-
- $wsdl = ''.
- ''.
- ''.
- ''.
- 'Test Function'.
- 'Test Function 2'.
- 'Return false'.
- 'Return true'.
- 'Return integer'.
- 'Return string'.
- 'Return array'.
- 'Multiple Args'.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- ''.
- '';
- $this->assertEquals($wsdl, $this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()), "Generated WSDL did not match expected XML");
- $this->assertValidWSDL($dom);
- }
+ $this->bindWsdl($this->server->generate());
- /**
- * @group ZF-4117
- */
- public function testChangeWsdlUriInConstructor()
- {
- $scriptUri = 'http://localhost/my_script.php';
- $server = new AutoDiscover(null, "http://example.com/service.php");
- $server->setServiceName("TestService");
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:types/xsd:schema[@targetNamespace="'
+ . $this->defaultServiceUri . '"]', 'Missing service port definition'
+ );
- $wsdlOutput = $server->toXml();
- $this->assertNotContains($scriptUri, $wsdlOutput);
- $this->assertContains("http://example.com/service.php", $wsdlOutput);
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'soap:binding[@style="rpc" and @transport="http://schemas.xmlsoap.org/soap/http"]',
+ 'Missing service port definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:service[@name="MyServiceService"]/wsdl:port[@name="MyServicePort"'
+ . ' and @binding="tns:MyServiceBinding"]/soap:address[@location="'
+ . $this->defaultServiceUri . '"]',
+ 'Missing service port definition'
+ );
+
+ foreach (array('', 2, 3, 4, 5, 6, 7, 9) as $i) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc'
+ . $i . '"]',
+ 'Missing service port definition for TestFunc' . $i . ''
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc'
+ . $i . '"]/wsdl:documentation',
+ 'Missing service port definition documentation for TestFunc'
+ . $i . ''
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc'
+ . $i . '"]/wsdl:input[@message="tns:TestFunc' . $i . 'In"]',
+ 'Missing service port definition input message for TestFunc'
+ . $i . ''
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc' . $i . '"]/soap:operation[@soapAction="'
+ . $this->defaultServiceUri . '#TestFunc' . $i . '"]',
+ 'Missing service operation action definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]/'
+ . 'wsdl:operation[@name="TestFunc' . $i . '"]/wsdl:input/soap:body'
+ . '[@use="encoded" and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'
+ . ' and @namespace="' . $this->defaultServiceUri . '"]',
+ 'Missing operation input for TestFunc' . $i . ' body definition'
+ );
+
+
+ if ($i != 2) {
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:portType[@name="MyServicePort"]/wsdl:operation[@name="TestFunc'
+ . $i . '"]/wsdl:output[@message="tns:TestFunc' . $i
+ . 'Out"]',
+ 'Missing service port definition input message for TestFunc'
+ . $i . ''
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:binding[@name="MyServiceBinding" and @type="tns:MyServicePort"]'
+ . '/wsdl:operation[@name="TestFunc'. $i . '"]/wsdl:output/soap:body'
+ . '[@use="encoded" and @encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'
+ . ' and @namespace="' . $this->defaultServiceUri . '"]',
+ 'Missing operation input for TestFunc' . $i
+ . ' body definition'
+ );
+
+
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="TestFunc' . $i . 'In"]',
+ 'Missing test testFunc' . $i . ' input message definition'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="TestFunc' . $i . 'Out"]',
+ 'Missing test testFunc' . $i . ' input message definition'
+ );
+ }
+ }
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
* @group ZF-4117
+ *
+ * @dataProvider dataProviderValidUris
*/
- public function testChangeWsdlUriViaSetUri()
+ public function testChangeWsdlUriInConstructor($uri, $expectedUri)
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $this->server->setUri($uri);
+ $this->bindWsdl($this->server->generate());
- $server = $this->createAutodiscoverService();
- $server->setUri("http://example.com/service.php");
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
- $wsdlOutput = $server->toXml();
+ $this->assertEquals(
+ $expectedUri,
+ $this->dom->documentElement->getAttribute('targetNamespace')
+ );
+ $this->assertNotContains(
+ $this->defaultServiceUri, $this->dom->saveXML()
+ );
+
- $this->assertNotContains($scriptUri, $wsdlOutput);
- $this->assertContains("http://example.com/service.php", $wsdlOutput);
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
public function testSetNonStringNonZendUriUriThrowsException()
{
- $server = $this->createAutodiscoverService();
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'No uri given to');
+ $server = new AutoDiscover();
+
+ $this->setExpectedException(
+ '\Zend\Soap\Exception\InvalidArgumentException',
+ 'Argument to \Zend\Soap\AutoDiscover::setUri should be string or \Zend\Uri\Uri instance.'
+ );
$server->setUri(array("bogus"));
}
/**
* @group ZF-4117
+ * @dataProvider dataProviderValidUris
*/
- public function testChangingWsdlUriAfterGenerationIsPossible()
- {
- $scriptUri = 'http://localhost/my_script.php';
-
- $server = $this->createAutodiscoverService();
- $server->setUri("http://example.com/service.php");
- $server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
-
- $wsdlOutput = $server->toXml();
-
- $this->assertNotContains($scriptUri, $wsdlOutput);
- $this->assertContains("http://example.com/service.php", $wsdlOutput);
-
- $server->setUri("http://example2.com/service2.php");
+ public function testChangingWsdlUriAfterGenerationIsPossible(
+ $uri, $expectedUri
+ ) {
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\TestFunc');
+ $wsdl = $this->server->generate();
+ $wsdl->setUri($uri);
+
+ $this->assertEquals(
+ $expectedUri, $wsdl->toDomDocument()->documentElement->getAttribute(
+ 'targetNamespace'
+ )
+ );
- $wsdlOutput = $server->toXml();
+ $this->assertValidWSDL($wsdl->toDomDocument());
+ $this->testDocumentNodes();
+ }
- $this->assertNotContains($scriptUri, $wsdlOutput);
- $this->assertNotContains("http://example.com/service.php", $wsdlOutput);
- $this->assertContains("http://example2.com/service2.php", $wsdlOutput);
+ /**
+ * @return array
+ */
+ public function dataProviderValidUris()
+ {
+ return array(
+ array('http://example.com/service.php',
+ 'http://example.com/service.php'),
+ array('http://example.com/?a=b&b=c',
+ 'http://example.com/?a=b&b=c'),
+ array('http://example.com/?a=b&b=c',
+ 'http://example.com/?a=b&b=c'),
+ array('urn:uuid:550e8400-e29b-41d4-a716-446655440000',
+ 'urn:uuid:550e8400-e29b-41d4-a716-446655440000'),
+ array('urn:acme:servicenamespace', 'urn:acme:servicenamespace'),
+ array(new Uri('http://example.com/service.php'),
+ 'http://example.com/service.php'),
+ array(new Uri('http://example.com/?a=b&b=c'),
+ 'http://example.com/?a=b&b=c'),
+ array(new Uri('http://example.com/?a=b&b=c'),
+ 'http://example.com/?a=b&b=c'),
+ );
}
/**
@@ -589,17 +1265,25 @@ public function testChangingWsdlUriAfterGenerationIsPossible()
* @group ZF-4125
*
*/
- public function testUsingClassWithMultipleMethodPrototypesProducesValidWsdl()
+ public function testUsingClassWithMethodsWithMultipleDefaultParameterValues(
+ )
{
- $scriptUri = 'http://localhost/my_script.php';
+ $this->server->setClass(
+ '\ZendTest\Soap\TestAsset\TestFixingMultiplePrototypes'
+ );
+ $this->bindWsdl($this->server->generate());
- $server = $this->createAutodiscoverService();
- $server->setClass('\ZendTest\Soap\TestAsset\TestFixingMultiplePrototypes');
- $wsdlOutput = $server->toXml();
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFuncIn"]'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:message[@name="testFuncOut"]'
+ );
+
- $this->assertEquals(1, substr_count($wsdlOutput, ''));
- $this->assertEquals(1, substr_count($wsdlOutput, ''));
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -607,74 +1291,97 @@ public function testUsingClassWithMultipleMethodPrototypesProducesValidWsdl()
*/
public function testComplexTypesThatAreUsedMultipleTimesAreRecoginzedOnce()
{
- $server = $this->createAutodiscoverService();
- $server->setComplexTypeStrategy(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex);
- $server->setClass('\ZendTest\Soap\TestAsset\AutoDiscoverTestClass2');
+ $this->server->setComplexTypeStrategy(
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex
+ );
+ $this->server->setClass(
+ '\ZendTest\Soap\TestAsset\AutoDiscoverTestClass2'
+ );
+ $this->bindWsdl($this->server->generate());
- $wsdlOutput = $server->toXml();
- $this->assertEquals(1,
- substr_count($wsdlOutput, 'wsdl:arrayType="tns:AutoDiscoverTestClass1[]"'),
- 'wsdl:arrayType definition of TestClass1 has to occour once.'
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//xsd:attribute[@wsdl:arrayType="tns:AutoDiscoverTestClass1[]"]',
+ 'Definition of TestClass1 has to occour once.'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="AutoDiscoverTestClass1"]',
+ 'AutoDiscoverTestClass1 has to be defined once.'
);
- $this->assertEquals(1,
- substr_count($wsdlOutput, ''),
- '\ZendTest\Soap\TestAsset\AutoDiscoverTestClass1 has to be defined once.'
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="ArrayOfAutoDiscoverTestClass1"]',
+ 'AutoDiscoverTestClass1 should be defined once.'
);
- $this->assertEquals(1,
- substr_count($wsdlOutput, ''),
- '\ZendTest\Soap\TestAsset\AutoDiscoverTestClass1 should be defined once.'
+ $nodes = $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:part[@name="test" and @type="tns:AutoDiscoverTestClass1"]',
+ 'AutoDiscoverTestClass1 appears once or more than once in the message parts section.'
);
$this->assertTrue(
- substr_count($wsdlOutput, '') >= 1,
- '\ZendTest\Soap\TestAsset\AutoDiscoverTestClass1 appears once or more than once in the message parts section.'
+ $nodes->length >= 1,
+ 'AutoDiscoverTestClass1 appears once or more than once in the message parts section.'
);
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
* @group ZF-5604
*/
- public function testReturnSameArrayOfObjectsResponseOnDifferentMethodsWhenArrayComplex()
+ public function testReturnSameArrayOfObjectsResponseOnDifferentMethodsWhenArrayComplex(
+ )
{
- $autodiscover = $this->createAutodiscoverService();
- $autodiscover->setComplexTypeStrategy(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex);
- $autodiscover->setClass('\ZendTest\Soap\TestAsset\MyService');
- $wsdl = $autodiscover->toXml();
+ $this->server->setComplexTypeStrategy(
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex
+ );
+ $this->server->setClass('\ZendTest\Soap\TestAsset\MyService');
+ $this->bindWsdl($this->server->generate());
- $this->assertEquals(1, substr_count($wsdl, ''));
- $this->assertEquals(0, substr_count($wsdl, 'tns:My_Response[]'));
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="ArrayOfMyResponse"]'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 0, '//wsdl:part[@type="tns:My_Response[]"]'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
* @group ZF-5430
*/
- public function testReturnSameArrayOfObjectsResponseOnDifferentMethodsWhenArraySequence()
+ public function testReturnSameArrayOfObjectsResponseOnDifferentMethodsWhenArraySequence(
+ )
{
- $autodiscover = $this->createAutodiscoverService();
- $autodiscover->setComplexTypeStrategy(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence);
- $autodiscover->setClass('\ZendTest\Soap\TestAsset\MyServiceSequence');
- $wsdl = $autodiscover->toXml();
+ $this->server->setComplexTypeStrategy(
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence
+ );
+ $this->server->setClass('\ZendTest\Soap\TestAsset\MyServiceSequence');
+ $this->bindWsdl($this->server->generate());
- $this->assertEquals(1, substr_count($wsdl, ''));
- $this->assertEquals(1, substr_count($wsdl, ''));
- $this->assertEquals(1, substr_count($wsdl, ''));
- $this->assertEquals(0, substr_count($wsdl, 'tns:string[]'));
- }
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="ArrayOfString"]'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="ArrayOfArrayOfString"]'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//xsd:complexType[@name="ArrayOfArrayOfArrayOfString"]'
+ );
- /**
- * @group ZF-5736
- */
- public function testAmpersandInUrlIsCorrectlyEncoded()
- {
- $autodiscover = new AutoDiscover();
- $autodiscover->setUri("http://example.com/?a=b&b=c");
- $autodiscover->setClass('\ZendTest\Soap\TestAsset\Test');
- $wsdl = $autodiscover->toXml();
+ $this->assertNotContains('tns:string[]', $this->dom->saveXML());
- $this->assertContains("http://example.com/?a=b&b=c", $wsdl);
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -682,14 +1389,20 @@ public function testAmpersandInUrlIsCorrectlyEncoded()
*/
public function testNoReturnIsOneWayCallInSetClass()
{
- $autodiscover = $this->createAutodiscoverService();
- $autodiscover->setClass('\ZendTest\Soap\TestAsset\NoReturnType');
- $wsdl = $autodiscover->toXml();
+ $this->server->setClass('\ZendTest\Soap\TestAsset\NoReturnType');
+ $this->bindWsdl($this->server->generate());
+
- $this->assertContains(
- 'pushOneWay',
- $wsdl
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:portType/wsdl:operation[@name="pushOneWay"]/wsdl:input'
+ );
+ $this->assertSpecificNodeNumberInXPath(
+ 0, '//wsdl:portType/wsdl:operation[@name="pushOneWay"]/wsdl:output'
);
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -697,15 +1410,20 @@ public function testNoReturnIsOneWayCallInSetClass()
*/
public function testNoReturnIsOneWayCallInAddFunction()
{
- $autodiscover = $this->createAutodiscoverService();
- $autodiscover->setServiceName('TestService');
- $autodiscover->addFunction('\ZendTest\Soap\TestAsset\OneWay');
- $wsdl = $autodiscover->toXml();
+ $this->server->addFunction('\ZendTest\Soap\TestAsset\OneWay');
+ $this->bindWsdl($this->server->generate());
+
- $this->assertContains(
- 'ZendTest\Soap\TestAsset\OneWay',
- $wsdl
+ $this->assertSpecificNodeNumberInXPath(
+ 1, '//wsdl:portType/wsdl:operation[@name="OneWay"]/wsdl:input'
);
+ $this->assertSpecificNodeNumberInXPath(
+ 0, '//wsdl:portType/wsdl:operation[@name="OneWay"]/wsdl:output'
+ );
+
+
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -714,20 +1432,28 @@ public function testNoReturnIsOneWayCallInAddFunction()
*/
public function testRecursiveWsdlDependencies()
{
- $autodiscover = $this->createAutodiscoverService();
- $autodiscover->setComplexTypeStrategy(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence);
- $autodiscover->setClass('\ZendTest\Soap\TestAsset\Recursion');
- $wsdl = $autodiscover->toXml();
+ $this->server->setComplexTypeStrategy(
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence
+ );
+ $this->server->setClass('\ZendTest\Soap\TestAsset\Recursion');
+
+ $this->bindWsdl($this->server->generate());
+
//
//
//
//
//
+ $this->assertSpecificNodeNumberInXPath(
+ 1,
+ '//wsdl:types/xsd:schema/xsd:complexType[@name="Recursion"]/xsd:all/'
+ . 'xsd:element[@name="recursion" and @type="tns:Recursion"]'
+ );
- $path = '//wsdl:types/xsd:schema/xsd:complexType[@name="Recursion"]/xsd:all/xsd:element[@name="recursion" and @type="tns:Recursion"]';
- $this->assertWsdlPathExists($wsdl, $path);
+ $this->assertValidWSDL($this->dom);
+ $this->testDocumentNodes();
}
/**
@@ -735,28 +1461,50 @@ public function testRecursiveWsdlDependencies()
*/
public function testHandle()
{
- $scriptUri = 'http://localhost/my_script.php';
+ $scriptUri = 'http://localhost/MyService.php';
- $server = $this->createAutodiscoverService();
- $server->setClass('\ZendTest\Soap\TestAsset\Test');
+ $this->server->setClass('\ZendTest\Soap\TestAsset\Test');
ob_start();
- $server->handle();
+ $this->server->handle();
$actualWsdl = ob_get_clean();
$this->assertNotEmpty($actualWsdl, "WSDL content was not outputted.");
$this->assertContains($scriptUri, $actualWsdl, "Script URL was not found in WSDL content.");
}
- public function assertWsdlPathExists($xml, $path)
+ /**
+ * @param int $n
+ * @param string $xpath
+ * @param string $msg
+ *
+ * @return \DOMNodeList
+ */
+ public function assertSpecificNodeNumberInXPath($n, $xpath, $msg = null)
+ {
+
+ $nodes = $this->xpath->query($xpath);
+ if (!($nodes instanceof \DOMNodeList)) {
+ $this->fail('Nodes not found. Invalid XPath expression ?');
+ }
+ $this->assertEquals($n, $nodes->length, $msg . "\nXPath: " . $xpath);
+
+ return $nodes;
+ }
+
+ public function assertAttributesOfNodes($attributes, $nodeList)
{
- $doc = new \DOMDocument('UTF-8');
- $doc->loadXML($xml);
- $xpath = new \DOMXPath($doc);
- $xpath->registerNamespace('wsdl', 'http://schemas.xmlsoap.org/wsdl/');
+ $c = count($attributes);
- $nodes = $xpath->query($path);
+ $keys = array_keys($attributes);
- $this->assertTrue($nodes->length >= 1, "Could not assert that XML Document contains a node that matches the XPath Expression: " . $path);
+ foreach ($nodeList as $node) {
+ for ($i = 0; $i < $c; $i++) {
+ $this->assertEquals(
+ $attributes[$keys[$i]], $node->getAttribute($keys[$i]),
+ 'Invalid attribute value.'
+ );
+ }
+ }
}
}
diff --git a/test/ClientTest.php b/test/ClientTest.php
index 2c3a7222..c4305336 100644
--- a/test/ClientTest.php
+++ b/test/ClientTest.php
@@ -12,8 +12,10 @@
require_once __DIR__ . '/TestAsset/commontypes.php';
+use Zend\Soap\AutoDiscover;
use Zend\Soap\Client;
use Zend\Soap\Server;
+use Zend\Soap\Wsdl;
/**
* @category Zend
@@ -41,6 +43,21 @@ public function testSetOptions()
$ctx = stream_context_create();
+ $typeMap = array(
+ array(
+ 'type_name' => 'dateTime',
+ 'type_ns' => 'http://www.w3.org/2001/XMLSchema',
+ 'from_xml' => 'strtotime',
+ 'to_xml' => 'strtotime',
+ ),
+ array(
+ 'type_name' => 'date',
+ 'type_ns' => 'http://www.w3.org/2001/XMLSchema',
+ 'from_xml' => 'strtotime',
+ 'to_xml' => 'strtotime',
+ )
+ );
+
$nonWSDLOptions = array('soap_version' => SOAP_1_1,
'classmap' => array('TestData1' => '\ZendTest\Soap\TestAsset\TestData1',
'TestData2' => '\ZendTest\Soap\TestAsset\TestData2',),
@@ -65,7 +82,9 @@ public function testSetOptions()
'cache_wsdl' => 8,
'features' => 4,
- 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5);
+ 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5,
+ 'typemap' => $typeMap
+ );
$client->setOptions($nonWSDLOptions);
$this->assertTrue($client->getOptions() == $nonWSDLOptions);
@@ -96,7 +115,9 @@ public function testSetOptions()
'stream_context' => $ctx,
- 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5);
+ 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5,
+ 'typemap' => $typeMap
+ );
$client1->setOptions($wsdlOptions);
$this->assertTrue($client1->getOptions() == $wsdlOptions);
@@ -108,6 +129,21 @@ public function testGetOptions()
$this->assertTrue($client->getOptions() == array('encoding' => 'UTF-8', 'soap_version' => SOAP_1_2));
+ $typeMap = array(
+ array(
+ 'type_name' => 'dateTime',
+ 'type_ns' => 'http://www.w3.org/2001/XMLSchema',
+ 'from_xml' => 'strtotime',
+ 'to_xml' => 'strtotime',
+ ),
+ array(
+ 'type_name' => 'date',
+ 'type_ns' => 'http://www.w3.org/2001/XMLSchema',
+ 'from_xml' => 'strtotime',
+ 'to_xml' => 'strtotime',
+ )
+ );
+
$options = array('soap_version' => SOAP_1_1,
'wsdl' => __DIR__.'/TestAsset/wsdl_example.wsdl',
@@ -130,7 +166,9 @@ public function testGetOptions()
'local_cert' => __DIR__.'/TestAsset/cert_file',
'passphrase' => 'some pass phrase',
- 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5);
+ 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5,
+ 'typemap' => $typeMap
+ );
$client->setOptions($options);
$this->assertTrue($client->getOptions() == $options);
@@ -243,24 +281,50 @@ public function testGetFunctions()
}
/**
- * @todo Implement testGetTypes().
*/
public function testGetTypes()
{
- // Remove the following line when you implement this test.
- $this->markTestIncomplete(
- "This test has not been implemented yet."
- );
+ $wsdlFilename = __DIR__ . '/TestAsset/GetTypesWsdlTest.wsdl';
+
+ $autodiscover = new AutoDiscover();
+ $autodiscover->setServiceName('ExampleService');
+ $autodiscover->setComplexTypeStrategy(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex);
+ $autodiscover->setClass('\ZendTest\Soap\TestAsset\AutoDiscoverTestClass2');
+ $autodiscover->setUri('http://example.com');
+ $wsdl = $autodiscover->generate();
+ $wsdl->dump($wsdlFilename);
+
+ $server = new Server($wsdlFilename);
+ $server->setClass('\ZendTest\Soap\TestAsset\AutoDiscoverTestClass2');
+
+ $client = new Client\Local($server, $wsdlFilename);
+ $soapClient = $client->getSoapClient();
+
+ $typesArray = $soapClient->__getTypes();
+
+ $this->assertCount(2, $typesArray);
+
+ $count = 0;
+ foreach ($typesArray as $element) {
+ if (strpos($element, 'struct AutoDiscoverTestClass1') === 0 OR strpos($element, 'AutoDiscoverTestClass1 ArrayOfAutoDiscoverTestClass1') === 0) {
+ $count++;
+ }
+ }
+ $this->assertEquals(2, $count, 'Invalid types');
+
+ unlink($wsdlFilename);
}
+ /**
+ * @outputBuffering enabled
+ */
public function testGetLastRequest()
{
- if (headers_sent()) {
- $this->markTestSkipped('Cannot run testGetLastRequest() when headers have already been sent; enable output buffering to run this test');
+ if (headers_sent($file, $line)) {
+ $this->markTestSkipped('Cannot run testGetLastRequest() when headers have already been sent. Output started in '.$file.'@'.$line.' enable output buffering to run this test');
return;
}
-
$server = new Server(__DIR__ . '/TestAsset/wsdl_example.wsdl');
$server->setClass('\ZendTest\Soap\TestAsset\TestClass');
@@ -520,4 +584,27 @@ public function testSetSoapClient()
$this->assertSame($clientMock, $soap->getSoapClient());
}
+
+ /**
+ * @expectedException \Zend\Soap\Exception\UnexpectedValueException
+ * @dataProvider dataProviderForInitSoapClientObjectException
+ */
+ public function testInitSoapClientObjectException($wsdl, $options)
+ {
+ $client = new Client($wsdl, $options);
+ $client->getSoapClient();
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForInitSoapClientObjectException()
+ {
+ return array(
+ array(null, array()),
+ array(null, array('location'=>'http://example.com')),
+ array(__DIR__ . './TestAsset/wsdl_example.wsdl', array('use'=>SOAP_ENCODED)),
+ array(__DIR__ . './TestAsset/wsdl_example.wsdl', array('style'=>SOAP_DOCUMENT))
+ );
+ }
}
diff --git a/test/ServerTest.php b/test/ServerTest.php
index db828304..1a127b6b 100644
--- a/test/ServerTest.php
+++ b/test/ServerTest.php
@@ -12,6 +12,7 @@
require_once __DIR__ . '/TestAsset/commontypes.php';
+use Zend\Soap\AutoDiscover;
use Zend\Soap\Server;
/**
@@ -494,8 +495,7 @@ public function testGetLastRequest()
$server->setClass('\ZendTest\Soap\TestAsset\ServerTestClass');
$request =
- '' . "\n"
- . 'World'
. ''
. ''
- . '' . "\n";
+ . '';
$response = $server->handle($request);
@@ -648,81 +648,116 @@ public function testHandle()
$this->assertEquals($expectedResponse, $server1->handle($request));
}
- public function testRegisterFaultException()
+ /**
+ * @dataProvider dataProviderForRegisterFaultException
+ *
+ * @param string|array $exception
+ */
+ public function testRegisterFaultException($exception)
{
$server = new Server();
- $server->registerFaultException("Zend_Soap_Server_Exception");
- $server->registerFaultException(array("OutOfBoundsException", "BogusException"));
+ $server->registerFaultException($exception);
- $this->assertEquals(array(
- 'Zend_Soap_Server_Exception',
- 'OutOfBoundsException',
- 'BogusException',
- ), $server->getFaultExceptions());
+ if (!is_array($exception)) {
+ $this->assertContains($exception, $server->getFaultExceptions());
+ } else {
+ foreach($exception as $row) {
+ $this->assertContains($row, $server->getFaultExceptions());
+ }
+ }
}
- public function testDeregisterFaultException()
+ /**
+ * @dataProvider dataProviderForRegisterFaultException
+ *
+ * @param string|array $exception
+ */
+ public function testDeregisterFaultException($exception)
{
$server = new Server();
- $server->registerFaultException(array("OutOfBoundsException", "BogusException"));
- $ret = $server->deregisterFaultException("BogusException");
- $this->assertTrue($ret);
+ $server->registerFaultException($exception);
+ if (is_array($exception)) {
+ $exception = array_shift($exception);
+ }
- $this->assertEquals(array(
- 'OutOfBoundsException',
- ), $server->getFaultExceptions());
+ $this->assertTrue($server->deregisterFaultException($exception));
- $ret = $server->deregisterFaultException("NonRegisteredException");
- $this->assertFalse($ret);
+ $this->assertNotContains($exception, $server->getFaultExceptions());
}
- public function testGetFaultExceptions()
+ /**
+ * @dataProvider dataProviderForRegisterFaultException
+ *
+ * @param string|array $exception
+ */
+ public function testIsRegisteredAsFaultException($exception)
{
+
$server = new Server();
+ $server->registerFaultException($exception);
+
- $this->assertEquals(array(), $server->getFaultExceptions());
- $server->registerFaultException("Exception");
- $this->assertEquals(array("Exception"), $server->getFaultExceptions());
+ if (!is_array($exception)) {
+ $this->assertTrue($server->isRegisteredAsFaultException($exception));
+ } else {
+ foreach($exception as $row) {
+ $this->assertTrue($server->isRegisteredAsFaultException($row));
+ }
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForRegisterFaultException()
+ {
+ return array(
+ array('Zend\Soap\Exception\InvalidArgumentException'),
+ array('InvalidArgumentException'),
+ array('Zend\Server\Exception\RuntimeException'),
+ array(array('Zend\Server\Exception\RuntimeException')),
+ array(array('Zend\Server\Exception\RuntimeException', 'InvalidArgumentException')),
+ );
}
public function testFaultWithTextMessage()
{
$server = new Server();
- $fault = $server->fault("Faultmessage!");
+ $fault = $server->fault('FaultMessage!');
- $this->assertTrue($fault instanceof \SOAPFault);
- $this->assertContains("Faultmessage!", $fault->getMessage());
+ $this->assertTrue($fault instanceof \SoapFault);
+ $this->assertContains('FaultMessage!', $fault->getMessage());
}
public function testFaultWithUnregisteredException()
{
$server = new Server();
- $fault = $server->fault(new \Exception("MyException"));
+ $fault = $server->fault(new \Exception('MyException'));
- $this->assertTrue($fault instanceof \SOAPFault);
- $this->assertContains("Unknown error", $fault->getMessage());
- $this->assertNotContains("MyException", $fault->getMessage());
+ $this->assertTrue($fault instanceof \SoapFault);
+ $this->assertContains('Unknown error', $fault->getMessage());
+ $this->assertNotContains('MyException', $fault->getMessage());
}
public function testFaultWithRegisteredException()
{
$server = new Server();
- $server->registerFaultException("Exception");
- $fault = $server->fault(new \Exception("MyException"));
-
- $this->assertTrue($fault instanceof \SOAPFault);
- $this->assertNotContains("Unknown error", $fault->getMessage());
- $this->assertContains("MyException", $fault->getMessage());
+ $server->registerFaultException('\Zend\Soap\Exception\RuntimeException');
+ $server->registerFaultException('\Zend\Soap\Exception\InvalidArgumentException');
+ $fault = $server->fault(new \Zend\Soap\Exception\RuntimeException('MyException'));
+ $this->assertTrue($fault instanceof \SoapFault);
+ $this->assertNotContains('Unknown error', $fault->getMessage());
+ $this->assertContains('MyException', $fault->getMessage());
}
- public function testFautlWithBogusInput()
+ public function testFaultWithBogusInput()
{
$server = new Server();
- $fault = $server->fault(array("Here", "There", "Bogus"));
+ $fault = $server->fault(array('Here', 'There', 'Bogus'));
- $this->assertContains("Unknown error", $fault->getMessage());
+ $this->assertContains('Unknown error', $fault->getMessage());
}
/**
@@ -731,22 +766,49 @@ public function testFautlWithBogusInput()
public function testFaultWithIntegerFailureCodeDoesNotBreakClassSoapFault()
{
$server = new Server();
- $fault = $server->fault("Faultmessage!", 5000);
+ $fault = $server->fault("FaultMessage!", 5000);
- $this->assertTrue($fault instanceof \SOAPFault);
+ $this->assertTrue($fault instanceof \SoapFault);
}
/**
- * @todo Implement testHandlePhpErrors().
+ * @expectedException \SoapFault
*/
public function testHandlePhpErrors()
{
- $server = new Server();
+ if (headers_sent()) {
+ $this->markTestSkipped('Cannot run ' . __METHOD__ . '() when headers have already been sent; enable output buffering to run this test');
+ return;
+ }
- // Remove the following line when you implement this test.
- $this->markTestIncomplete(
- "This test has not been implemented yet."
- );
+ $wsdlFilename = __DIR__ . '/TestAsset/testHandlePhpErrors.wsdl';
+ $autodiscover = new AutoDiscover();
+ $autodiscover->setOperationBodyStyle(array(
+ 'use' => 'literal',
+ ));
+
+ $autodiscover->setBindingStyle(array(
+ 'style' => 'document',
+ 'transport' => 'http://schemas.xmlsoap.org/soap/http'
+ ));
+
+
+ $autodiscover->setServiceName('ExampleService');
+ $autodiscover->setUri('http://example.com');
+
+
+ $autodiscover->setClass('\ZendTest\Soap\TestAsset\errorClass');
+
+ $wsdl = $autodiscover->generate();
+ $wsdl->dump($wsdlFilename);
+
+ $server = new Server($wsdlFilename);
+
+ $server->setClass('\ZendTest\Soap\TestAsset\errorClass');
+
+ $client = new \Zend\Soap\Client\Local($server, $wsdlFilename);
+ $client->triggerError();
+ unlink($wsdlFilename);
}
public function testLoadFunctionsIsNotImplemented()
@@ -874,6 +936,7 @@ public function testShouldThrowExceptionIfHandledRequestContainsDoctype()
. ''
. '' . "\n";
$response = $server->handle($request);
+
$this->assertContains('Invalid XML', $response->getMessage());
}
diff --git a/test/TestAsset/MockCallUserFunc.php b/test/TestAsset/MockCallUserFunc.php
index 6e7275df..11af2921 100644
--- a/test/TestAsset/MockCallUserFunc.php
+++ b/test/TestAsset/MockCallUserFunc.php
@@ -18,7 +18,7 @@ class MockCallUserFunc
/**
* Whether to mock the call_user_func function.
*
- * @var boolean
+ * @var bool
*/
public static $mock = false;
diff --git a/test/TestAsset/commontypes.php b/test/TestAsset/commontypes.php
index 0317eb33..1e96fbb2 100644
--- a/test/TestAsset/commontypes.php
+++ b/test/TestAsset/commontypes.php
@@ -634,3 +634,62 @@ public function __doRequest($request, $location, $action, $version, $one_way = 0
}
}
+
+class SequenceTest
+{
+ /**
+ * @var int
+ */
+ public $var = 5;
+}
+
+
+
+class Book
+{
+ /**
+ * @var int
+ */
+ public $somevar;
+}
+class Cookie
+{
+ /**
+ * @var int
+ */
+ public $othervar;
+}
+class Anything
+{
+}
+
+
+
+class PublicPrivateProtected
+{
+ const PROTECTED_VAR_NAME = 'bar';
+ const PRIVATE_VAR_NAME = 'baz';
+
+ /**
+ * @var string
+ */
+ public $foo;
+
+ /**
+ * @var string
+ */
+ protected $bar;
+
+ /**
+ * @var string
+ */
+ private $baz;
+}
+
+class errorClass
+{
+ public function triggerError()
+ {
+ trigger_error('TestError', E_USER_ERROR);
+ }
+}
diff --git a/test/TestAsset/testHandlePhpErrors.wsdl b/test/TestAsset/testHandlePhpErrors.wsdl
new file mode 100644
index 00000000..b44c6037
--- /dev/null
+++ b/test/TestAsset/testHandlePhpErrors.wsdl
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+ triggerError
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestAsset/wsdl_example.wsdl b/test/TestAsset/wsdl_example.wsdl
index 129f28de..41412402 100644
--- a/test/TestAsset/wsdl_example.wsdl
+++ b/test/TestAsset/wsdl_example.wsdl
@@ -1,2 +1,89 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Wsdl/ArrayOfTypeComplexStrategyTest.php b/test/Wsdl/ArrayOfTypeComplexStrategyTest.php
index 72405fb1..289951f0 100644
--- a/test/Wsdl/ArrayOfTypeComplexStrategyTest.php
+++ b/test/Wsdl/ArrayOfTypeComplexStrategyTest.php
@@ -10,10 +10,11 @@
namespace ZendTest\Soap\Wsdl;
-require_once __DIR__."/../TestAsset/commontypes.php";
+require_once __DIR__ . "/../TestAsset/commontypes.php";
use Zend\Soap\Wsdl;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex;
+use ZendTest\Soap\WsdlTestHelper;
/**
* @category Zend
@@ -22,29 +23,29 @@
* @group Zend_Soap
* @group Zend_Soap_Wsdl
*/
-class ArrayOfTypeComplexStrategyTest extends \PHPUnit_Framework_TestCase
+class ArrayOfTypeComplexStrategyTest extends WsdlTestHelper
{
- /** @var \Zend\Soap\Wsdl */
- private $wsdl;
-
- /** @var \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex */
- private $strategy;
public function setUp()
{
$this->strategy = new ArrayOfTypeComplex();
- $this->wsdl = new Wsdl('MyService', 'http://localhost/MyService.php', $this->strategy);
+
+ parent::setUp();
}
public function testNestingObjectsDeepMakesNoSenseThrowingException()
{
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'ArrayOfTypeComplex cannot return nested ArrayOfObject deeper than one level');
+ $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException',
+ 'ArrayOfTypeComplex cannot return nested ArrayOfObject deeper than one level'
+ );
$this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTest[][]');
}
public function testAddComplexTypeOfNonExistingClassThrowsException()
{
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'Cannot add a complex type \ZendTest\Soap\TestAsset\UnknownClass that is not an object or where class');
+ $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException',
+ 'Cannot add a complex type \ZendTest\Soap\TestAsset\UnknownClass that is not an object or where class'
+ );
$this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\UnknownClass[]');
}
@@ -53,30 +54,42 @@ public function testAddComplexTypeOfNonExistingClassThrowsException()
*/
public function testArrayOfSimpleObject()
{
+ $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTest[]');
$return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTest[]');
$this->assertEquals("tns:ArrayOfComplexTest", $return);
- $wsdl = $this->wsdl->toXML();
+ // single element
+ $nodes = $this->xpath->query('//wsdl:types/*/xsd:complexType[@name="ComplexTest"]/xsd:all/xsd:element');
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex type in wsdl.');
+
+ $this->assertEquals('var', $nodes->item(0)->getAttribute('name'), 'Invalid attribute name');
+ $this->assertEquals('xsd:int', $nodes->item(0)->getAttribute('type'), 'Invalid type name');
- $this->assertContains(
- '',
- $wsdl,
- $wsdl
+ // array of elements
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ArrayOfComplexTest"]/xsd:complexContent/xsd:restriction'
+ );
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex type array definition in wsdl.');
+ $this->assertEquals('soap-enc:Array', $nodes->item(0)->getAttribute('base'),
+ 'Invalid base encoding in complex type.'
);
- $this->assertContains(
- '',
- $wsdl
+ $nodes = $this->xpath->query('xsd:attribute', $nodes->item(0));
+
+ $this->assertEquals('soap-enc:arrayType', $nodes->item(0)->getAttribute('ref'),
+ 'Invalid attribute reference value in complex type.'
+ );
+ $this->assertEquals('tns:ComplexTest[]', $nodes->item(0)->getAttributeNS(Wsdl::WSDL_NS_URI, 'arrayType'),
+ 'Invalid array type reference.'
);
+
+ $this->testDocumentNodes();
}
public function testThatOverridingStrategyIsReset()
{
$return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTest[]');
$this->assertEquals("tns:ArrayOfComplexTest", $return);
- // $this->assertTrue($this->wsdl->getComplexTypeStrategy() instanceof \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplexStrategy);
-
- $wsdl = $this->wsdl->toXML();
}
/**
@@ -87,18 +100,47 @@ public function testArrayOfComplexObjects()
$return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectStructure[]');
$this->assertEquals("tns:ArrayOfComplexObjectStructure", $return);
- $wsdl = $this->wsdl->toXML();
-
- $this->assertContains(
- '',
- $wsdl,
- $wsdl
+ $nodes = $this->xpath->query(
+ '//wsdl:types/xsd:schema/xsd:complexType[@name="ComplexObjectStructure"]/xsd:all'
+ );
+ $this->assertEquals(4, $nodes->item(0)->childNodes->length, 'Invalid complex object definition.');
+
+ foreach (array(
+ 'boolean' => 'xsd:boolean',
+ 'string' => 'xsd:string',
+ 'int' => 'xsd:int',
+ 'array' => 'soap-enc:Array'
+ ) as $name => $type) {
+ $node = $this->xpath->query('xsd:element[@name="'.$name.'"]', $nodes->item(0));
+ $this->assertEquals($name, $node->item(0)->getAttribute('name'),
+ 'Invalid name attribute value in complex object definition'
+ );
+ $this->assertEquals($type, $node->item(0)->getAttribute('type'),
+ 'Invalid type name in complex object definition'
+ );
+ }
+
+ // array of elements
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ArrayOfComplexObjectStructure"]/xsd:complexContent/xsd:restriction'
);
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex type array definition in wsdl.');
+ $this->assertEquals('soap-enc:Array', $nodes->item(0)->getAttribute('base'),
+ 'Invalid base encoding in complex type.'
+ );
+
+ $nodes = $this->xpath->query('xsd:attribute', $nodes->item(0));
- $this->assertContains(
- '',
- $wsdl
+ $this->assertEquals('soap-enc:arrayType', $nodes->item(0)->getAttribute('ref'),
+ 'Invalid attribute reference value in complex type.'
);
+ $this->assertEquals('tns:ComplexObjectStructure[]',
+ $nodes->item(0)->getAttributeNS(Wsdl::WSDL_NS_URI, 'arrayType'),
+ 'Invalid array type reference.'
+ );
+
+
+ $this->testDocumentNodes();
}
public function testArrayOfObjectWithObject()
@@ -106,23 +148,50 @@ public function testArrayOfObjectWithObject()
$return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
$this->assertEquals("tns:ArrayOfComplexObjectWithObjectStructure", $return);
- $wsdl = $this->wsdl->toXML();
+ // single element
+ $nodes = $this->xpath->query('//wsdl:types/*/xsd:complexType[@name="ComplexTest"]/xsd:all/xsd:element');
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex type in wsdl.');
+
+ $this->assertEquals('var', $nodes->item(0)->getAttribute('name'), 'Invalid attribute name');
+ $this->assertEquals('xsd:int', $nodes->item(0)->getAttribute('type'), 'Invalid type name');
- $this->assertContains(
- '',
- $wsdl
+ // single object element
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ComplexObjectWithObjectStructure"]/xsd:all/xsd:element'
);
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex object in wsdl.');
- $this->assertContains(
- '',
- $wsdl,
- $wsdl
+ $this->assertEquals('object', $nodes->item(0)->getAttribute('name'),
+ 'Invalid attribute name'
+ );
+ $this->assertEquals('tns:ComplexTest', $nodes->item(0)->getAttribute('type'),
+ 'Invalid type name'
);
+ $this->assertEquals('true', $nodes->item(0)->getAttribute('nillable'),
+ 'Invalid nillable attribute value'
+ );
+
+ // array of elements
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ArrayOfComplexObjectWithObjectStructure"]/'
+ .'xsd:complexContent/xsd:restriction'
+ );
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex type array definition in wsdl.');
+ $this->assertEquals('soap-enc:Array', $nodes->item(0)->getAttribute('base'),
+ 'Invalid base encoding in complex type.'
+ );
+
+ $nodes = $this->xpath->query('xsd:attribute', $nodes->item(0));
- $this->assertContains(
- '',
- $wsdl
+ $this->assertEquals('soap-enc:arrayType', $nodes->item(0)->getAttribute('ref'),
+ 'Invalid attribute reference value in complex type.'
+ );
+ $this->assertEquals('tns:ComplexObjectWithObjectStructure[]',
+ $nodes->item(0)->getAttributeNS(Wsdl::WSDL_NS_URI, 'arrayType'),
+ 'Invalid array type reference.'
);
+
+ $this->testDocumentNodes();
}
/**
@@ -130,20 +199,26 @@ public function testArrayOfObjectWithObject()
*/
public function testAddingTypesMultipleTimesIsSavedOnlyOnce()
{
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
-
- $wsdl = $this->wsdl->toXML();
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
- $this->assertEquals(1,
- substr_count($wsdl, 'wsdl:arrayType="tns:ComplexObjectWithObjectStructure[]"')
+ // this xpath is proper version of simpler: //*[wsdl:arrayType="tns:ComplexObjectWithObjectStructure[]"] - namespaces in attributes and xpath
+ $nodes = $this->xpath->query('//*[@*[namespace-uri()="'.Wsdl::WSDL_NS_URI
+ .'" and local-name()="arrayType"]="tns:ComplexObjectWithObjectStructure[]"]'
);
- $this->assertEquals(1,
- substr_count($wsdl, '')
+ $this->assertEquals(1, $nodes->length,
+ 'Invalid array of complex type array type reference detected'
);
- $this->assertEquals(1,
- substr_count($wsdl, '')
+
+ $nodes = $this->xpath->query(
+ '//xsd:complexType[@name="ArrayOfComplexObjectWithObjectStructure"]'
);
+ $this->assertEquals(1, $nodes->length, 'Invalid array complex type detected');
+
+ $nodes = $this->xpath->query('//xsd:complexType[@name="ComplexTest"]');
+ $this->assertEquals(1, $nodes->length, 'Invalid complex type detected');
+
+ $this->testDocumentNodes();
}
/**
@@ -151,30 +226,26 @@ public function testAddingTypesMultipleTimesIsSavedOnlyOnce()
*/
public function testAddingSingularThenArrayTypeIsRecognizedCorretly()
{
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure');
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
-
- $wsdl = $this->wsdl->toXML();
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure');
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexObjectWithObjectStructure[]');
- $this->assertEquals(1,
- substr_count($wsdl, 'wsdl:arrayType="tns:ComplexObjectWithObjectStructure[]"')
+ // this xpath is proper version of simpler: //*[wsdl:arrayType="tns:ComplexObjectWithObjectStructure[]"] - namespaces in attributes and xpath
+ $nodes = $this->xpath->query('//*[@*[namespace-uri()="'.Wsdl::WSDL_NS_URI.
+ '" and local-name()="arrayType"]="tns:ComplexObjectWithObjectStructure[]"]'
);
- $this->assertEquals(1,
- substr_count($wsdl, '')
+ $this->assertEquals(1, $nodes->length,
+ 'Invalid array of complex type array type reference detected'
);
- $this->assertEquals(1,
- substr_count($wsdl, '')
+
+ $nodes = $this->xpath->query(
+ '//xsd:complexType[@name="ArrayOfComplexObjectWithObjectStructure"]'
);
- }
+ $this->assertEquals(1, $nodes->length, 'Invalid array complex type detected');
- /**
- * @group ZF-5149
- */
- public function testArrayOfComplexNestedObjectsIsCoveredByStrategy()
- {
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTypeA');
- $wsdl = $this->wsdl->toXml();
- $this->assertTrue(is_string($wsdl)); // no exception was thrown
+ $nodes = $this->xpath->query('//xsd:complexType[@name="ComplexTest"]');
+ $this->assertEquals(1, $nodes->length, 'Invalid complex type detected');
+
+ $this->testDocumentNodes();
}
/**
@@ -183,19 +254,63 @@ public function testArrayOfComplexNestedObjectsIsCoveredByStrategy()
public function testArrayOfComplexNestedObjectsIsCoveredByStrategyAndAddsAllTypesRecursivly()
{
$return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTypeA');
- $wsdl = $this->wsdl->toXml();
+ $this->assertEquals("tns:ComplexTypeA", $return);
+
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="ComplexTypeB"]/xsd:all');
+ $this->assertEquals(2, $nodes->item(0)->childNodes->length, 'Invalid complex object definition.');
+
+ foreach (array(
+ 'bar' => 'xsd:string',
+ 'foo' => 'xsd:string',
+ ) as $name => $type) {
+ $node = $this->xpath->query('xsd:element[@name="'.$name.'"]', $nodes->item(0));
+ $this->assertEquals($name, $node->item(0)->getAttribute('name'),
+ 'Invalid name attribute value in complex object definition'
+ );
+ $this->assertEquals($type, $node->item(0)->getAttribute('type'),
+ 'Invalid type name in complex object definition'
+ );
+ $this->assertEquals('true', $node->item(0)->getAttribute('nillable'),
+ 'Invalid nillable attribute value'
+ );
+ }
+
+ // single object element
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ComplexTypeA"]/xsd:all/xsd:element'
+ );
+ $this->assertEquals(1, $nodes->length, 'Unable to find complex object in wsdl.');
- $this->assertEquals(1,
- substr_count($wsdl, ''),
- 'No definition of complex type A found.'
+ $this->assertEquals('baz',
+ $nodes->item(0)->getAttribute('name'), 'Invalid attribute name'
+ );
+ $this->assertEquals('tns:ArrayOfComplexTypeB',
+ $nodes->item(0)->getAttribute('type'), 'Invalid type name'
);
- $this->assertEquals(1,
- substr_count($wsdl, ''),
- 'No definition of complex type B array found.'
+
+ // array of elements
+ $nodes = $this->xpath->query(
+ '//wsdl:types/*/xsd:complexType[@name="ArrayOfComplexTypeB"]/xsd:complexContent/xsd:restriction'
);
- $this->assertEquals(1,
- substr_count($wsdl, 'wsdl:arrayType="tns:ComplexTypeB[]"'),
- 'No usage of Complex Type B array found.'
+ $this->assertEquals(1, $nodes->length,
+ 'Unable to find complex type array definition in wsdl.'
);
+ $this->assertEquals('soap-enc:Array', $nodes->item(0)->getAttribute('base'),
+ 'Invalid base encoding in complex type.'
+ );
+
+ $nodes = $this->xpath->query('xsd:attribute', $nodes->item(0));
+
+ $this->assertEquals('soap-enc:arrayType',
+ $nodes->item(0)->getAttribute('ref'),
+ 'Invalid attribute reference value in complex type.'
+ );
+ $this->assertEquals('tns:ComplexTypeB[]',
+ $nodes->item(0)->getAttributeNS(Wsdl::WSDL_NS_URI, 'arrayType'),
+ 'Invalid array type reference.'
+ );
+
+ $this->testDocumentNodes();
}
}
diff --git a/test/Wsdl/ArrayOfTypeSequenceStrategyTest.php b/test/Wsdl/ArrayOfTypeSequenceStrategyTest.php
index 69898f91..3a45834c 100644
--- a/test/Wsdl/ArrayOfTypeSequenceStrategyTest.php
+++ b/test/Wsdl/ArrayOfTypeSequenceStrategyTest.php
@@ -10,6 +10,8 @@
namespace ZendTest\Soap\Wsdl;
+use ZendTest\Soap\WsdlTestHelper;
+
require_once __DIR__ . '/../TestAsset/commontypes.php';
/**
@@ -19,118 +21,234 @@
* @group Zend_Soap
* @group Zend_Soap_Wsdl
*/
-class ArrayOfTypeSequenceStrategyTest extends \PHPUnit_Framework_TestCase
+class ArrayOfTypeSequenceStrategyTest extends WsdlTestHelper
{
- private $wsdl;
- private $strategy;
-
public function setUp()
{
$this->strategy = new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence();
- $this->wsdl = new \Zend\Soap\Wsdl('MyService', 'http://localhost/MyService.php', $this->strategy);
+
+ parent::setUp();
}
- public function testFunctionReturningSimpleArrayOfInts()
+ /**
+ * @dataProvider dataProviderForFunctionReturningSimpleArrayOfBasicTypes
+ *
+ * @param $type
+ * @param $arrayTypeName
+ */
+ public function testFunctionReturningSimpleArrayOfBasicTypes($type, $arrayTypeName)
{
- $this->wsdl->addComplexType('int[]');
+ $this->wsdl->addComplexType($type.'[]');
+ // test duplicates also
+ $this->wsdl->addComplexType($type.'[]');
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="'.$arrayTypeName.'"]');
+ $this->assertEquals(1, $nodes->length, 'Missing complex type declaration');
- $this->assertContains(
- ''.
- ''.
- '',
- $this->wsdl->toXML()
+ $nodes = $this->xpath->query('xsd:sequence/xsd:element', $nodes->item(0));
+ $this->assertEquals(1, $nodes->length, 'Missing complex type element declaration');
+
+ $this->assertEquals('item', $nodes->item(0)->getAttribute('name'),
+ 'Wrong complex type element name attribute'
+ );
+ $this->assertEquals('xsd:'.$type, $nodes->item(0)->getAttribute('type'),
+ 'Wrong complex type type attribute value'
+ );
+ $this->assertEquals('0', $nodes->item(0)->getAttribute('minOccurs'),
+ 'Wrong complex type minOccurs attribute value'
);
+ $this->assertEquals('unbounded', $nodes->item(0)->getAttribute('maxOccurs'),
+ 'Wrong complex type maxOccurs attribute value'
+ );
+
+ $this->testDocumentNodes();
}
- public function testFunctionReturningSimpleArrayOfString()
+ public function dataProviderForFunctionReturningSimpleArrayOfBasicTypes()
{
- $this->wsdl->addComplexType('string[]');
-
- $this->assertContains(
- ''.
- ''.
- '',
- $this->wsdl->toXML()
+ return array(
+ array('int', 'ArrayOfInt'),
+ array('string', 'ArrayOfString'),
+ array('boolean', 'ArrayOfBoolean'),
+ array('float', 'ArrayOfFloat'),
+ array('double', 'ArrayOfDouble'),
);
}
- public function testFunctionReturningNestedArrayOfString()
+ /**
+ * @dataProvider dataProviderForNestedTypesDefinitions
+ *
+ * @param $stringDefinition
+ * @param $nestedTypeNames
+ */
+ public function testNestedTypesDefinitions($stringDefinition, $definedTypeName, $nestedTypeNames)
{
- $return = $this->wsdl->addComplexType('string[][]');
- $this->assertEquals('tns:ArrayOfArrayOfString', $return);
+ $return = $this->wsdl->addComplexType($stringDefinition);
+ $this->assertEquals('tns:'.$definedTypeName, $return);
- $wsdl = $this->wsdl->toXML();
+ foreach ($nestedTypeNames as $nestedTypeName => $typeName) {
- // Check for ArrayOfArrayOfString
- $this->assertContains(
- '',
- $wsdl
- );
- // Check for ArrayOfString
- $this->assertContains(
- '',
- $wsdl
- );
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="'.$nestedTypeName.'"]');
+ $this->assertEquals(1, $nodes->length, 'Invalid first level of nested element definition');
+
+ $nodes = $this->xpath->query('xsd:sequence/xsd:element', $nodes->item(0));
+ $this->assertEquals(1, $nodes->length, 'Invalid element in first level of nested element definition');
+
+ $this->assertEquals('item', $nodes->item(0)->getAttribute('name'),
+ 'Wrong complex type element name attribute'
+ );
+ $this->assertEquals('0', $nodes->item(0)->getAttribute('minOccurs'),
+ 'Wrong complex type minOccurs attribute value'
+ );
+ $this->assertEquals('unbounded', $nodes->item(0)->getAttribute('maxOccurs'),
+ 'Wrong complex type maxOccurs attribute value'
+ );
+ $this->assertEquals($typeName, $nodes->item(0)->getAttribute('type'),
+ 'Wrong complex type type attribute value'
+ );
+ }
+
+ $this->testDocumentNodes();
}
- public function testFunctionReturningMultipleNestedArrayOfType()
+ /**
+ * @return array
+ */
+ public function dataProviderForNestedTypesDefinitions()
{
- $return = $this->wsdl->addComplexType('string[][][]');
- $this->assertEquals('tns:ArrayOfArrayOfArrayOfString', $return);
+ return array(
+ array(
+ 'string[][]',
+ 'ArrayOfArrayOfString',
+ array(
+ 'ArrayOfString' =>'xsd:string',
+ 'ArrayOfArrayOfString' =>'tns:ArrayOfString'
+ )
+ ),
- $wsdl = $this->wsdl->toXML();
+ array(
+ 'string[][][]',
+ 'ArrayOfArrayOfArrayOfString',
+ array(
+ 'ArrayOfString' =>'xsd:string',
+ 'ArrayOfArrayOfString' =>'tns:ArrayOfString',
+ 'ArrayOfArrayOfArrayOfString' =>'tns:ArrayOfArrayOfString'
+ )
+ ),
- // Check for ArrayOfArrayOfArrayOfString
- $this->assertContains(
- '',
- $wsdl
- );
- // Check for ArrayOfArrayOfString
- $this->assertContains(
- '',
- $wsdl
- );
- // Check for ArrayOfString
- $this->assertContains(
- '',
- $wsdl
+ array(
+ 'string[][][][]',
+ 'ArrayOfArrayOfArrayOfArrayOfString',
+ array(
+ 'ArrayOfString' =>'xsd:string',
+ 'ArrayOfArrayOfString' =>'tns:ArrayOfString',
+ 'ArrayOfArrayOfArrayOfString' =>'tns:ArrayOfArrayOfString',
+ 'ArrayOfArrayOfArrayOfArrayOfString' =>'tns:ArrayOfArrayOfArrayOfString'
+ )
+ ),
+
+ array(
+ 'int[][]',
+ 'ArrayOfArrayOfInt',
+ array(
+ 'ArrayOfInt' =>'xsd:int',
+ 'ArrayOfArrayOfInt' =>'tns:ArrayOfInt'
+ )
+ ),
);
}
-
public function testAddComplexTypeObject()
{
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\Wsdl\SequenceTest');
+ $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\SequenceTest');
$this->assertEquals('tns:SequenceTest', $return);
- $wsdl = $this->wsdl->toXML();
+ $nodes = $this->xpath->query('//xsd:complexType[@name="SequenceTest"]');
+ $this->assertEquals(1, $nodes->length, 'Missing complex type: SequenceTest');
- $this->assertContains(
- '',
- $wsdl
- );
+ $nodes = $this->xpath->query('xsd:all/xsd:element', $nodes->item(0));
+ $this->assertEquals(1, $nodes->length, 'Missing element definition in complex type: SequenceTest');
+
+ $this->assertEquals('var', $nodes->item(0)->getAttribute('name'), 'Invalid name attribute value');
+ $this->assertEquals('xsd:int', $nodes->item(0)->getAttribute('type'), 'Invalid type attribute value');
+
+ $this->testDocumentNodes();
}
public function testAddComplexTypeArrayOfObject()
{
+ $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTypeA[]');
+ $this->assertEquals('tns:ArrayOfComplexTypeA', $return);
+
+
+ // class a
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="ComplexTypeA"]');
+ $this->assertEquals(1, $nodes->length, 'Missing complex type definition.');
+
+ $nodes = $this->xpath->query('xsd:all/xsd:element', $nodes->item(0));
+
+ $this->assertEquals(1, $nodes->length, 'Missing complex type element declaration');
+
+ $this->assertEquals('baz', $nodes->item(0)->getAttribute('name'),
+ 'Wrong complex type element name attribute'
+ );
+ $this->assertEquals('tns:ArrayOfComplexTypeB', $nodes->item(0)->getAttribute('type'),
+ 'Wrong complex type type attribute value'
+ );
+
+
+ // class b
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="ComplexTypeB"]');
+ $this->assertEquals(1, $nodes->length, 'Missing complex type definition.');
+
+ foreach (array(
+ 'bar' => 'xsd:string',
+ 'foo' => 'xsd:string',
+ ) as $name => $type) {
+ $node = $this->xpath->query('xsd:all/xsd:element[@name="'.$name.'"]', $nodes->item(0));
+
+ $this->assertEquals($name, $node->item(0)->getAttribute('name'),
+ 'Invalid name attribute value in complex object definition'
+ );
+ $this->assertEquals($type, $node->item(0)->getAttribute('type'),
+ 'Invalid type name in complex object definition'
+ );
+ $this->assertEquals('true', $node->item(0)->getAttribute('nillable'),
+ 'Invalid nillable attribute value'
+ );
+ }
+
- $return = $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\ComplexTypeA[]');
+ // array of class a and class b
+ foreach(array(
+ 'ArrayOfComplexTypeB' => 'ComplexTypeB',
+ 'ArrayOfComplexTypeA' => 'ComplexTypeA'
+ ) as $arrayTypeName => $typeName) {
- $this->assertEquals('tns:ArrayOfComplexTypeA', $return);
+ $nodes = $this->xpath->query(
+ '//wsdl:types/xsd:schema/xsd:complexType[@name="'.$arrayTypeName.'"]'
+ );
+ $this->assertEquals(1, $nodes->length, 'Missing complex type definition.');
- $wsdl = $this->wsdl->toXML();
+ $nodes = $this->xpath->query('xsd:sequence/xsd:element', $nodes->item(0));
+ $this->assertEquals(1, $nodes->length, 'Missing complex type element declaration');
- $this->assertContains(
- '',
- $wsdl,
- $wsdl
- );
+ $this->assertEquals('item', $nodes->item(0)->getAttribute('name'),
+ 'Wrong complex type element name attribute'
+ );
+ $this->assertEquals('tns:'.$typeName, $nodes->item(0)->getAttribute('type'),
+ 'Wrong complex type type attribute value'
+ );
+ $this->assertEquals('0', $nodes->item(0)->getAttribute('minOccurs'),
+ 'Wrong complex type minOccurs attribute value'
+ );
+ $this->assertEquals('unbounded', $nodes->item(0)->getAttribute('maxOccurs'),
+ 'Wrong complex type maxOccurs attribute value'
+ );
+ }
- $this->assertContains(
- '',
- $wsdl
- );
+ $this->testDocumentNodes();
}
public function testAddComplexTypeOfNonExistingClassThrowsException()
@@ -139,11 +257,3 @@ public function testAddComplexTypeOfNonExistingClassThrowsException()
$this->wsdl->addComplexType('ZendTest\Soap\Wsdl\UnknownClass[]');
}
}
-
-class SequenceTest
-{
- /**
- * @var int
- */
- public $var = 5;
-}
diff --git a/test/Wsdl/CompositeStrategyTest.php b/test/Wsdl/CompositeStrategyTest.php
index e9d71476..f239d080 100644
--- a/test/Wsdl/CompositeStrategyTest.php
+++ b/test/Wsdl/CompositeStrategyTest.php
@@ -8,13 +8,14 @@
* @package Zend_Soap
*/
-namespace ZendTest\Soap\Wsdl;
+namespace ZendTest\Soap\Wsdl\ComplexTypeStrategy;
use Zend\Soap\Wsdl\ComplexTypeStrategy;
use Zend\Soap\Wsdl;
use Zend\Soap\Wsdl\ComplexTypeStrategy\Composite;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex;
use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence;
+use ZendTest\Soap\WsdlTestHelper;
/**
* @package Zend_Soap
@@ -32,8 +33,14 @@
* @group Zend_Soap
* @group Zend_Soap_Wsdl
*/
-class CompositeStrategyTest extends \PHPUnit_Framework_TestCase
+class CompositeStrategyTest extends WsdlTestHelper
{
+
+ public function setUp()
+ {
+ // override parent setup because it is needed only in one method
+ }
+
public function testCompositeApiAddingStragiesToTypes()
{
$strategy = new Composite(array(), new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence);
@@ -50,7 +57,9 @@ public function testConstructorTypeMapSyntax()
{
$typeMap = array('Book' => '\Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex');
- $strategy = new ComplexTypeStrategy\Composite($typeMap, new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence);
+ $strategy = new ComplexTypeStrategy\Composite($typeMap,
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence
+ );
$bookStrategy = $strategy->getStrategyOfType('Book');
$cookieStrategy = $strategy->getStrategyOfType('Cookie');
@@ -63,7 +72,9 @@ public function testCompositeThrowsExceptionOnInvalidType()
{
$strategy = new ComplexTypeStrategy\Composite();
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'Invalid type given to Composite Type Map');
+ $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException',
+ 'Invalid type given to Composite Type Map'
+ );
$strategy->connectTypeToStrategy(array(), 'strategy');
}
@@ -72,8 +83,10 @@ public function testCompositeThrowsExceptionOnInvalidStrategy()
$strategy = new ComplexTypeStrategy\Composite(array(), 'invalid');
$strategy->connectTypeToStrategy('Book', 'strategy');
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'Strategy for Complex Type "Book" is not a valid strategy');
- $book = $strategy->getStrategyOfType('Book');
+ $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException',
+ 'Strategy for Complex Type "Book" is not a valid strategy'
+ );
+ $strategy->getStrategyOfType('Book');
}
public function testCompositeThrowsExceptionOnInvalidStrategyPart2()
@@ -81,24 +94,29 @@ public function testCompositeThrowsExceptionOnInvalidStrategyPart2()
$strategy = new ComplexTypeStrategy\Composite(array(), 'invalid');
$strategy->connectTypeToStrategy('Book', 'strategy');
- $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'Default Strategy for Complex Types is not a valid strategy object');
- $book = $strategy->getStrategyOfType('Anything');
+ $this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException',
+ 'Default Strategy for Complex Types is not a valid strategy object'
+ );
+ $strategy->getStrategyOfType('Anything');
}
-
-
public function testCompositeDelegatesAddingComplexTypesToSubStrategies()
{
- $strategy = new ComplexTypeStrategy\Composite(array(), new \Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType);
- $strategy->connectTypeToStrategy('\ZendTest\Soap\Wsdl\Book', new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex);
- $strategy->connectTypeToStrategy('\ZendTest\Soap\Wsdl\Cookie', new \Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType);
+ $this->strategy = new ComplexTypeStrategy\Composite(array(), new \Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType);
+ $this->strategy->connectTypeToStrategy('\ZendTest\Soap\TestAsset\Book',
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex
+ );
+ $this->strategy->connectTypeToStrategy('\ZendTest\Soap\TestAsset\Cookie',
+ new \Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType
+ );
+
+ parent::setUp();
- $wsdl = new Wsdl('SomeService', 'http://example.com');
- $strategy->setContext($wsdl);
+ $this->assertEquals('tns:Book', $this->strategy->addComplexType('\ZendTest\Soap\TestAsset\Book'));
+ $this->assertEquals('tns:Cookie', $this->strategy->addComplexType('\ZendTest\Soap\TestAsset\Cookie'));
+ $this->assertEquals('xsd:anyType', $this->strategy->addComplexType('\ZendTest\Soap\TestAsset\Anything'));
- $this->assertEquals('tns:Book', $strategy->addComplexType('\ZendTest\Soap\Wsdl\Book'));
- $this->assertEquals('tns:Cookie', $strategy->addComplexType('\ZendTest\Soap\Wsdl\Cookie'));
- $this->assertEquals('xsd:anyType', $strategy->addComplexType('\ZendTest\Soap\Wsdl\Anything'));
+ $this->testDocumentNodes();
}
public function testCompositeRequiresContextForAddingComplexTypesOtherwiseThrowsException()
@@ -108,22 +126,16 @@ public function testCompositeRequiresContextForAddingComplexTypesOtherwiseThrows
$this->setExpectedException('Zend\Soap\Exception\InvalidArgumentException', 'Cannot add complex type "Test"');
$strategy->addComplexType('Test');
}
-}
-class Book
-{
/**
- * @var int
+ *
*/
- public $somevar;
-}
-class Cookie
-{
- /**
- * @var int
- */
- public $othervar;
-}
-class Anything
-{
+ public function testGetDefaultStrategy()
+ {
+ $strategyClass = 'Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType';
+
+ $strategy = new Composite(array(), $strategyClass);
+
+ $this->assertEquals($strategyClass, get_class($strategy->getDefaultStrategy()));
+ }
}
diff --git a/test/Wsdl/DefaultComplexTypeTest.php b/test/Wsdl/DefaultComplexTypeTest.php
index 39479d76..1914ba14 100644
--- a/test/Wsdl/DefaultComplexTypeTest.php
+++ b/test/Wsdl/DefaultComplexTypeTest.php
@@ -12,6 +12,10 @@
use Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType;
use Zend\Soap\Wsdl;
+use ZendTest\Soap\TestAsset\PublicPrivateProtected;
+use ZendTest\Soap\WsdlTestHelper;
+
+require_once __DIR__ . '/../TestAsset/commontypes.php';
/**
* @category Zend
@@ -20,24 +24,18 @@
* @group Zend_Soap
* @group Zend_Soap_Wsdl
*/
-class DefaultComplexTypeTest extends \PHPUnit_Framework_TestCase
+class DefaultComplexTypeTest extends WsdlTestHelper
{
/**
- * @var Zend_Soap_Wsdl
+ * @var DefaultComplexType
*/
- private $wsdl;
-
- /**
- * @var Zend_Soap_Wsdl_Strategy_DefaultComplexType
- */
- private $strategy;
+ protected $strategy;
public function setUp()
{
$this->strategy = new DefaultComplexType();
- $this->wsdl = new Wsdl("TestService", "http://framework.zend.com/soap/unittests");
- $this->wsdl->setComplexTypeStrategy($this->strategy);
- $this->strategy->setContext($this->wsdl);
+
+ parent::setUp();
}
/**
@@ -45,31 +43,14 @@ public function setUp()
*/
public function testOnlyPublicPropertiesAreDiscoveredByStrategy()
{
- $this->strategy->addComplexType('\ZendTest\Soap\Wsdl\PublicPrivateProtected');
+ $this->strategy->addComplexType('ZendTest\Soap\TestAsset\PublicPrivateProtected');
- $xml = $this->wsdl->toXML();
- $this->assertNotContains( PublicPrivateProtected::PROTECTED_VAR_NAME, $xml);
- $this->assertNotContains( PublicPrivateProtected::PRIVATE_VAR_NAME, $xml);
- }
-}
+ $nodes = $this->xpath->query('//xsd:element[@name="'.(PublicPrivateProtected::PROTECTED_VAR_NAME).'"]');
+ $this->assertEquals(0, $nodes->length, 'Document should not contain protected fields');
-class PublicPrivateProtected
-{
- const PROTECTED_VAR_NAME = 'bar';
- const PRIVATE_VAR_NAME = 'baz';
+ $nodes = $this->xpath->query('//xsd:element[@name="'.(PublicPrivateProtected::PRIVATE_VAR_NAME).'"]');
+ $this->assertEquals(0, $nodes->length, 'Document should not contain private fields');
- /**
- * @var string
- */
- public $foo;
-
- /**
- * @var string
- */
- protected $bar;
-
- /**
- * @var string
- */
- private $baz;
+ $this->testDocumentNodes();
+ }
}
diff --git a/test/WsdlTest.php b/test/WsdlTest.php
index 2d752a06..d50e0d3e 100644
--- a/test/WsdlTest.php
+++ b/test/WsdlTest.php
@@ -9,394 +9,467 @@
*/
namespace ZendTest\Soap;
-
use Zend\Soap\Wsdl;
-use Zend\Soap\Wsdl\ComplexTypeStrategy;
+
+use Zend\Uri\Uri;
/**
- * Test cases for Zend_Soap_Wsdl
+ * Zend_Soap_Server
*
* @category Zend
* @package Zend_Soap
* @subpackage UnitTests
* @group Zend_Soap
* @group Zend_Soap_Wsdl
- */
-class WsdlTest extends \PHPUnit_Framework_TestCase
+ **/
+class WsdlTest extends WsdlTestHelper
{
- protected function sanitizeWsdlXmlOutputForOsCompability($xmlstring)
+
+ public function testConstructor()
{
- $xmlstring = str_replace(array("\r", "\n"), "", $xmlstring);
- $xmlstring = preg_replace('/(>[\s]{1,}<)/', '', $xmlstring);
- return $xmlstring;
+ $this->assertEquals(Wsdl::WSDL_NS_URI, $this->dom->lookupNamespaceUri(null));
+ $this->assertEquals(Wsdl::SOAP_11_NS_URI, $this->dom->lookupNamespaceUri('soap'));
+ $this->assertEquals(Wsdl::SOAP_12_NS_URI, $this->dom->lookupNamespaceUri('soap12'));
+ $this->assertEquals($this->defaultServiceUri, $this->dom->lookupNamespaceUri('tns'));
+ $this->assertEquals(Wsdl::SOAP_11_NS_URI, $this->dom->lookupNamespaceUri('soap'));
+ $this->assertEquals(Wsdl::XSD_NS_URI, $this->dom->lookupNamespaceUri('xsd'));
+ $this->assertEquals(Wsdl::SOAP_ENC_URI, $this->dom->lookupNamespaceUri('soap-enc'));
+ $this->assertEquals(Wsdl::WSDL_NS_URI, $this->dom->lookupNamespaceUri('wsdl'));
+
+ $this->assertEquals(Wsdl::WSDL_NS_URI, $this->dom->documentElement->namespaceURI);
+
+ $this->assertEquals($this->defaultServiceName, $this->dom->documentElement->getAttribute('name'));
+ $this->assertEquals($this->defaultServiceUri, $this->dom->documentElement->getAttribute('targetNamespace'));
+
+ $this->testDocumentNodes();
}
- public function swallowIncludeNotices($errno, $errstr)
+ /**
+ * @dataProvider dataProviderForURITesting
+ *
+ * @param string $uri
+ */
+ public function testSetUriChangesDomDocumentWsdlStructureTnsAndTargetNamespaceAttributes($uri, $expectedUri)
{
- if ($errno != E_WARNING || !strstr($errstr, 'failed')) {
- return false;
+ if ($uri instanceof Uri) {
+ $uri = $uri->toString();
}
+
+ $this->wsdl->setUri($uri);
+
+ $this->testDocumentNodes();
+
+ $this->assertEquals($expectedUri, $this->dom->lookupNamespaceUri('tns'));
+ $this->assertEquals($expectedUri, $this->dom->documentElement->getAttribute('targetNamespace'));
}
- public function testConstructor()
+ /**
+ * @dataProvider dataProviderForURITesting
+ *
+ * @param string $uri
+ */
+ public function testSetUriWithZendUriChangesDomDocumentWsdlStructureTnsAndTargetNamespaceAttributes($uri, $expectedUri)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $this->wsdl->setUri(new Uri($uri));
+ $this->testDocumentNodes();
+
+ $this->assertEquals($expectedUri, $this->dom->lookupNamespaceUri('tns'));
+ $this->assertEquals($expectedUri, $this->dom->documentElement->getAttribute('targetNamespace'));
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- '' );
}
- public function testSetUriChangesDomDocumentWsdlStructureTnsAndTargetNamespaceAttributes()
+ /**
+ * @dataProvider dataProviderForURITesting
+ *
+ * @param string $uri
+ */
+ public function testObjectConstructionWithDifferentURI($uri, $expectedUri)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $wsdl->setUri('http://localhost/MyNewService.php');
+ $wsdl = new Wsdl($this->defaultServiceName, $uri);
+
+ $dom = $this->registerNamespaces($wsdl->toDomDocument(), $uri);
+ $this->testDocumentNodes();
+
+ $this->assertEquals($expectedUri, $dom->lookupNamespaceUri('tns'));
+ $this->assertEquals($expectedUri, $dom->documentElement->getAttribute('targetNamespace'));
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- '' );
}
- public function testAddMessage()
+ /**
+ * Data provider for uri testing
+ *
+ * @return array
+ */
+ public function dataProviderForURITesting()
+ {
+ return array(
+ array('http://localhost/MyService.php', 'http://localhost/MyService.php'),
+ array('http://localhost/MyNewService.php', 'http://localhost/MyNewService.php'),
+ array(new Uri('http://localhost/MyService.php'), 'http://localhost/MyService.php'),
+ /**
+ * @bug ZF-5736
+ */
+ array('http://localhost/MyService.php?a=b&b=c', 'http://localhost/MyService.php?a=b&b=c'),
+
+ /**
+ * @bug ZF-5736
+ */
+ array('http://localhost/MyService.php?a=b&b=c', 'http://localhost/MyService.php?a=b&b=c'),
+ );
+ }
+
+ /**
+ * @dataProvider dataProviderForAddMessage
+ *
+ * @param array $parameters message parameters
+ */
+ public function testAddMessage($parameters)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $messageParts = array();
+ foreach($parameters as $i => $parameter) {
+ $messageParts['parameter'.$i] = $this->wsdl->getType($parameter);
+ }
+
+ $messageName = 'myMessage';
+ $this->wsdl->addMessage($messageName, $messageParts);
+ $this->testDocumentNodes();
+
+ $messageNodes = $this->xpath->query('//wsdl:definitions/wsdl:message');
+
+ $this->assertGreaterThan(0, $messageNodes->length, 'Missing message node in definitions node.');
+
+ $this->assertEquals($messageName, $messageNodes->item(0)->getAttribute('name'));
+
+ foreach ($messageParts as $parameterName => $parameterType) {
+ $part = $this->xpath->query('wsdl:part[@name="'.$parameterName.'"]', $messageNodes->item(0));
+ $this->assertEquals($parameterType, $part->item(0)->getAttribute('type'));
+ }
+
+ }
+
+ /**
+ * @dataProvider dataProviderForAddMessage
+ *
+ * @param array $parameters complex message parameters
+ */
+ public function testAddComplexMessage($parameters)
+ {
$messageParts = array();
- $messageParts['parameter1'] = $wsdl->getType('int');
- $messageParts['parameter2'] = $wsdl->getType('string');
- $messageParts['parameter3'] = $wsdl->getType('mixed');
-
- $wsdl->addMessage('myMessage', $messageParts);
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
+ foreach($parameters as $i => $parameter) {
+ $messageParts['parameter'.$i] = array(
+ 'type' => $this->wsdl->getType($parameter),
+ 'name' => 'parameter'.$i
+ );
+ }
+
+ $messageName = 'myMessage';
+
+ $this->wsdl->addMessage($messageName, $messageParts);
+ $this->testDocumentNodes();
+
+ $messageNodes = $this->xpath->query('//wsdl:definitions/wsdl:message');
+
+ $this->assertGreaterThan(0, $messageNodes->length, 'Missing message node in definitions node.');
+
+ foreach ($messageParts as $parameterName => $parameterDefinition) {
+ $part = $this->xpath->query('wsdl:part[@name="'.$parameterName.'"]', $messageNodes->item(0));
+ $this->assertEquals($parameterDefinition['type'], $part->item(0)->getAttribute('type'));
+ $this->assertEquals($parameterDefinition['name'], $part->item(0)->getAttribute('name'));
+ }
+
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForAddMessage()
+ {
+ return array(
+ array(array('int', 'int', 'int')),
+ array(array('string', 'string', 'string', 'string')),
+ array(array('mixed')),
+ array(array('int', 'int', 'string', 'string')),
+ array(array('int', 'string', 'int', 'string')),
+ );
}
public function testAddPortType()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addPortType('myPortType');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . '' );
- }
-
- public function testAddPortOperation()
- {
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $portType = $wsdl->addPortType('myPortType');
-
- $wsdl->addPortOperation($portType, 'operation1');
- $wsdl->addPortOperation($portType, 'operation2', 'tns:operation2Request', 'tns:operation2Response');
- $wsdl->addPortOperation($portType, 'operation3', 'tns:operation3Request', 'tns:operation3Response', 'tns:operation3Fault');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
+ $portName = 'myPortType';
+ $this->wsdl->addPortType($portName);
+
+ $this->testDocumentNodes();
+
+ $portTypeNodes = $this->xpath->query('//wsdl:definitions/wsdl:portType');
+
+ $this->assertGreaterThan(0, $portTypeNodes->length, 'Missing portType node in definitions node.');
+
+ $this->assertTrue($portTypeNodes->item(0)->hasAttribute('name'));
+ $this->assertEquals($portName, $portTypeNodes->item(0)->getAttribute('name'));
+ }
+
+ /**
+ * @dataProvider dataProviderForAddPortOperation
+ *
+ * @param string $operationName
+ */
+ public function testAddPortOperation($operationName, $inputRequest = null, $outputResponse = null, $fail = null)
+ {
+ $portName = 'myPortType';
+ $portType = $this->wsdl->addPortType($portName);
+
+ $this->wsdl->addPortOperation($portType, $operationName, $inputRequest, $outputResponse, $fail);
+
+ $this->testDocumentNodes();
+
+ $portTypeNodes = $this->xpath->query('//wsdl:definitions/wsdl:portType[@name="'.$portName.'"]');
+ $this->assertGreaterThan(0, $portTypeNodes->length, 'Missing portType node in definitions node.');
+
+ $operationNodes = $this->xpath->query('wsdl:operation[@name="'.$operationName.'"]', $portTypeNodes->item(0));
+ $this->assertGreaterThan(0, $operationNodes->length);
+
+ if (empty($inputRequest) AND empty($outputResponse) AND empty($fail)) {
+ $this->assertFalse($operationNodes->item(0)->hasChildNodes());
+ } else {
+ $this->assertTrue($operationNodes->item(0)->hasChildNodes());
+ }
+
+ if (!empty($inputRequest)) {
+ $inputNodes = $operationNodes->item(0)->getElementsByTagName('input');
+ $this->assertEquals($inputRequest, $inputNodes->item(0)->getAttribute('message'));
+ }
+
+ if (!empty($outputResponse)) {
+ $outputNodes = $operationNodes->item(0)->getElementsByTagName('output');
+ $this->assertEquals($outputResponse, $outputNodes->item(0)->getAttribute('message'));
+ }
+
+ if (!empty($fail)) {
+ $faultNodes = $operationNodes->item(0)->getElementsByTagName('fault');
+ $this->assertEquals($fail, $faultNodes->item(0)->getAttribute('message'));
+ }
+ }
+
+ /**
+ *
+ */
+ public function dataProviderForAddPortOperation()
+ {
+ return array(
+ array('operation'),
+ array('operation', 'tns:operationRequest', 'tns:operationResponse'),
+ array('operation', 'tns:operationRequest', 'tns:operationResponse', 'tns:operationFault'),
+ array('operation', 'tns:operationRequest', null, 'tns:operationFault'),
+ array('operation', null, null, 'tns:operationFault'),
+ array('operation', null, 'tns:operationResponse', 'tns:operationFault'),
+ array('operation', null, 'tns:operationResponse'),
+ );
}
public function testAddBinding()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addPortType('myPortType');
- $wsdl->addBinding('MyServiceBinding', 'myPortType');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . '' );
- }
-
- public function testAddBindingOperation()
- {
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addPortType('myPortType');
- $binding = $wsdl->addBinding('MyServiceBinding', 'myPortType');
-
- $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/")
- );
- $wsdl->addBindingOperation($binding,
- 'operation3',
- array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"),
- array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"),
- array('name' => 'MyFault','use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/")
- );
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
- }
-
- public function testAddSoapBinding()
- {
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addPortType('myPortType');
- $binding = $wsdl->addBinding('MyServiceBinding', 'myPortType');
-
- $wsdl->addSoapBinding($binding);
-
- $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($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
-
- $wsdl1 = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl1->addPortType('myPortType');
- $binding = $wsdl1->addBinding('MyServiceBinding', 'myPortType');
-
- $wsdl1->addSoapBinding($binding, 'rpc');
-
- $wsdl1->addBindingOperation($binding, 'operation1');
- $wsdl1->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($this->sanitizeWsdlXmlOutputForOsCompability($wsdl1->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
- }
-
-
- public function testAddSoapOperation()
- {
- $wsdl = new 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($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
- }
-
- public function testAddService()
- {
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addPortType('myPortType');
- $wsdl->addBinding('MyServiceBinding', 'myPortType');
-
- $wsdl->addService('Service1', 'myPortType', 'MyServiceBinding', 'http://localhost/MyService.php');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
+ $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
+
+ $this->testDocumentNodes();
+
+ $bindingNodes = $this->xpath->query('//wsdl:definitions/wsdl:binding');
+
+ if ($bindingNodes->length === 0) {
+ $this->fail('Missing binding node in definitions node.'.$bindingNodes->length);
+ }
+
+ $this->assertEquals('MyServiceBinding', $bindingNodes->item(0)->getAttribute('name'));
+ $this->assertEquals('myPortType', $bindingNodes->item(0)->getAttribute('type'));
+
}
/**
- * @dataProvider ampersandInUrlDataProvider()
+ * @dataProvider dataProviderForAddBindingOperation
+ *
+ * @param $operationName
+ * @param null $input
+ * @param null $inputEncoding
+ * @param null $output
+ * @param null $outputEncoding
+ * @param null $fault
+ * @param null $faultEncoding
+ * @param null $faultName
+ */
+ public function testAddBindingOperation($operationName,
+ $input = null, $inputEncoding = null,
+ $output = null, $outputEncoding = null,
+ $fault = null, $faultEncoding = null, $faultName = null)
+ {
+ $binding = $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
+
+ $inputArray = array();
+ if (!empty($input) AND !empty($inputEncoding)) {
+ $inputArray = array('use' => $input, 'encodingStyle' => $inputEncoding);
+ }
+
+ $outputArray = array();
+ if (!empty($output) AND !empty($outputEncoding)) {
+ $outputArray = array('use' => $output, 'encodingStyle' => $outputEncoding);
+ }
+
+ $faultArray = array();
+ if (!empty($fault) AND !empty($faultEncoding) AND !empty($faultName)) {
+ $faultArray = array('use' => $fault, 'encodingStyle' => $faultEncoding, 'name'=>$faultName);
+ }
+
+ $this->wsdl->addBindingOperation($binding,
+ $operationName,
+ $inputArray,
+ $outputArray,
+ $faultArray
+ );
+
+ $this->testDocumentNodes();
+
+ $bindingNodes = $this->xpath->query('//wsdl:binding');
+
+ $this->assertGreaterThan(0, $bindingNodes->length, 'Missing binding node in definition.');
+
+ $this->assertEquals('MyServiceBinding', $bindingNodes->item(0)->getAttribute('name'));
+ $this->assertEquals('myPortType', $bindingNodes->item(0)->getAttribute('type'));
+
+ $operationNodes = $this->xpath->query('wsdl:operation[@name="'.$operationName.'"]', $bindingNodes->item(0));
+ $this->assertEquals(1, $operationNodes->length, 'Missing operation node in definition.');
+
+ if (empty($inputArray) AND empty($outputArray) AND empty($faultArray)) {
+ $this->assertFalse($operationNodes->item(0)->hasChildNodes());
+ }
+
+ foreach (array(
+ '//wsdl:input/soap:body' => $inputArray,
+ '//wsdl:output/soap:body' => $outputArray,
+ '//wsdl:fault' => $faultArray
+ ) as $query => $ar) {
+
+ if (!empty($ar)) {
+ $nodes = $this->xpath->query($query);
+
+ $this->assertGreaterThan(0, $nodes->length, 'Missing operation body.');
+
+ foreach ($ar as $key => $val) {
+ $this->assertEquals($ar[$key], $nodes->item(0)->getAttribute($key),
+ 'Bad attribute in operation definition: '.$key);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public function dataProviderForAddBindingOperation()
+ {
+
+ $enc = 'http://schemas.xmlsoap.org/soap/encoding/';
+
+ return array(
+ array('operation'),
+ array('operation', 'encoded', $enc, 'encoded', $enc, 'encoded', $enc, 'myFaultName'),
+ array('operation', null, null, 'encoded', $enc, 'encoded', $enc, 'myFaultName'),
+ array('operation', null, null, 'encoded', $enc, 'encoded'),
+ array('operation', 'encoded', $enc),
+ array('operation', null, null, null, null, 'encoded', $enc, 'myFaultName'),
+ array('operation', 'encoded1', $enc.'1', 'encoded2', $enc.'2', 'encoded3', $enc.'3', 'myFaultName'),
+
+ );
+ }
+
+ /**
+ * @dataProvider dataProviderForSoapBindingStyle
+ */
+ public function testAddSoapBinding($style)
+ {
+ $this->wsdl->addPortType('myPortType');
+ $binding = $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
+
+ $this->wsdl->addSoapBinding($binding, $style);
+
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//soap:binding');
+
+ $this->assertGreaterThan(0, $nodes->length);
+ $this->assertEquals($style, $nodes->item(0)->getAttribute('style'));
+ }
+
+ public function dataProviderForSoapBindingStyle()
+ {
+ return array(
+ array('document'),
+ array('rpc'),
+ );
+ }
+
+ /**
+ * @dataProvider dataProviderForAddSoapOperation
+ */
+ public function testAddSoapOperation($operationUrl)
+ {
+ $this->wsdl->addPortType('myPortType');
+ $binding = $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
+
+ $this->wsdl->addSoapOperation($binding, $operationUrl);
+
+ $this->testDocumentNodes();
+
+ $node = $this->xpath->query('//soap:operation');
+ $this->assertGreaterThan(0, $node->length);
+ $this->assertEquals($operationUrl, $node->item(0)->getAttribute('soapAction'));
+ }
+
+ public function dataProviderForAddSoapOperation()
+ {
+ return array(
+ array('http://localhost/MyService.php#myOperation'),
+ array(new Uri('http://localhost/MyService.php#myOperation'))
+ );
+ }
+
+ /**
+ * @dataProvider dataProviderForAddService
+ */
+ public function testAddService($serviceUrl)
+ {
+ $this->wsdl->addPortType('myPortType');
+ $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
+
+ $this->wsdl->addService('Service1', 'myPortType', 'MyServiceBinding', $serviceUrl);
+
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//wsdl:service[@name="Service1"]/wsdl:port/soap:address');
+ $this->assertGreaterThan(0, $nodes->length);
+
+ $this->assertEquals($serviceUrl, $nodes->item(0)->getAttribute('location'));
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderForAddService()
+ {
+ return array(
+ array('http://localhost/MyService.php'),
+ array(new Uri('http://localhost/MyService.php'))
+ );
+ }
+
+ /**
+ * @dataProvider ampersandInUrlDataProvider
*/
public function testAddBindingOperationWithAmpersandInUrl($actualUrl, $expectedUrl)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $wsdl->addPortType('myPortType');
- $binding = $wsdl->addBinding('MyServiceBinding', 'myPortType');
+ $this->wsdl->addPortType('myPortType');
+ $binding = $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
- $wsdl->addBindingOperation(
+ $this->wsdl->addBindingOperation(
$binding,
'operation1',
array('use' => 'encoded', 'encodingStyle' => $actualUrl),
@@ -404,18 +477,10 @@ public function testAddBindingOperationWithAmpersandInUrl($actualUrl, $expectedU
array('name' => 'MyFault','use' => 'encoded', 'encodingStyle' => $actualUrl)
);
- $expectedXml = ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '';
- $this->assertContains($expectedXml, $wsdl->toXML());
+ $nodes = $this->xpath->query('//wsdl:binding[@type="myPortType" and @name="MyServiceBinding"]/wsdl:operation[@name="operation1"]/wsdl:input/soap:body');
+
+ $this->assertGreaterThanOrEqual(1, $nodes->length);
+ $this->assertEquals($expectedUrl, $nodes->item(0)->getAttribute('encodingStyle'));
}
/**
@@ -423,15 +488,16 @@ public function testAddBindingOperationWithAmpersandInUrl($actualUrl, $expectedU
*/
public function testAddSoapOperationWithAmpersandInUrl($actualUrl, $expectedUrl)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $this->wsdl->addPortType('myPortType');
+ $binding = $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
- $wsdl->addPortType('myPortType');
- $binding = $wsdl->addBinding('MyServiceBinding', 'myPortType');
+ $this->wsdl->addSoapOperation($binding, $actualUrl);
- $wsdl->addSoapOperation($binding, $actualUrl);
+ $this->testDocumentNodes();
- $expectedXml = '';
- $this->assertContains($expectedXml, $wsdl->toXML());
+ $nodes = $this->xpath->query('//wsdl:binding/soap:operation');
+ $this->assertGreaterThanOrEqual(1, $nodes->length);
+ $this->assertEquals($expectedUrl, $nodes->item(0)->getAttribute('soapAction'));
}
/**
@@ -439,19 +505,16 @@ public function testAddSoapOperationWithAmpersandInUrl($actualUrl, $expectedUrl)
*/
public function testAddServiceWithAmpersandInUrl($actualUrl, $expectedUrl)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $this->wsdl->addPortType('myPortType');
+ $this->wsdl->addBinding('MyServiceBinding', 'myPortType');
- $wsdl->addPortType('myPortType');
- $wsdl->addBinding('MyServiceBinding', 'myPortType');
+ $this->wsdl->addService('Service1', 'myPortType', 'MyServiceBinding', $actualUrl);
- $wsdl->addService('Service1', 'myPortType', 'MyServiceBinding', $actualUrl);
+ $this->testDocumentNodes();
- $expectedXml = ''
- . ''
- . ''
- . ''
- . '';
- $this->assertContains($expectedXml, $wsdl->toXML());
+ $nodes = $this->xpath->query('//wsdl:port/soap:address');
+ $this->assertGreaterThanOrEqual(1, $nodes->length);
+ $this->assertEquals($expectedUrl, $nodes->item(0)->getAttribute('location'));
}
public function ampersandInUrlDataProvider()
@@ -472,250 +535,260 @@ public function ampersandInUrlDataProvider()
);
}
+
+ /**
+ *
+ */
public function testAddDocumentation()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $doc = 'This is a description for Port Type node.';
+ $this->wsdl->addDocumentation($this->wsdl, $doc);
- $portType = $wsdl->addPortType('myPortType');
+ $this->testDocumentNodes();
- $wsdl->addDocumentation($portType, 'This is a description for Port Type node.');
+ $nodes = $this->wsdl->toDomDocument()->childNodes;
+ $this->assertEquals(1, $nodes->length);
+ $this->assertEquals($doc, $nodes->item(0)->nodeValue);
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . 'This is a description for Port Type node.'
- . ''
- . '' );
}
- public function testAddDocumentationToSetInsertsBefore()
+ public function testAddDocumentationToSomeElmenet()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $portType = $this->wsdl->addPortType('myPortType');
+
+ $doc = 'This is a description for Port Type node.';
+ $this->wsdl->addDocumentation($portType, $doc);
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//wsdl:portType[@name="myPortType"]/wsdl:documentation');
+ $this->assertEquals(1, $nodes->length);
+ $this->assertEquals($doc, $nodes->item(0)->nodeValue);
+ }
+
+ public function testAddDocumentationToSetInsertsBefore()
+ {
$messageParts = array();
- $messageParts['parameter1'] = $wsdl->getType('int');
- $messageParts['parameter2'] = $wsdl->getType('string');
- $messageParts['parameter3'] = $wsdl->getType('mixed');
+ $messageParts['parameter1'] = $this->wsdl->getType('int');
+ $messageParts['parameter2'] = $this->wsdl->getType('string');
+ $messageParts['parameter3'] = $this->wsdl->getType('mixed');
- $message = $wsdl->addMessage('myMessage', $messageParts);
- $wsdl->addDocumentation($message, "foo");
+ $message = $this->wsdl->addMessage('myMessage', $messageParts);
+ $this->wsdl->addDocumentation($message, "foo");
+
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//wsdl:message[@name="myMessage"]/*[1]');
+ $this->assertEquals('documentation', $nodes->item(0)->nodeName);
- $this->assertEquals(
- '' .
- ''
- . ''
- . 'foo'
- . ''
- . ''
- . ''
- . ''
- . '',
- $this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml())
- );
}
- public function testToXml()
+ public function testDumpToFile()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $file = tempnam(sys_get_temp_dir(), 'zfunittest');
+
+ $dumpStatus = $this->wsdl->dump($file);
+
+ $fileContent = file_get_contents($file);
+ unlink($file);
+
+ $this->assertTrue($dumpStatus, 'WSDL Dump fail');
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- '' );
+ $this->checkXMLContent($fileContent);
}
- public function testToDomDocument()
+ public function testDumpToOutput()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $dom = $wsdl->toDomDocument();
+ ob_start();
+ $dumpStatus = $this->wsdl->dump();
+ $screenContent = ob_get_clean();
- $this->assertTrue($dom instanceOf \DOMDocument);
+ $this->assertTrue($dumpStatus, 'Dump to output failed');
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($dom->saveXML()),
- '' .
- '' );
+ $this->checkXMLContent($screenContent);
}
- public function testDump()
+ public function checkXMLContent($content)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ libxml_use_internal_errors(true);
+ libxml_disable_entity_loader(false);
+ $xml = new \DOMDocument();
+ $xml->preserveWhiteSpace = false;
+ $xml->encoding = 'UTF-8';
+ $xml->formatOutput = false;
+ $xml->loadXML($content);
- ob_start();
- $wsdl->dump();
- $wsdlDump = ob_get_clean();
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdlDump),
- '' .
- '' );
-
- $wsdl->dump(__DIR__ . '/TestAsset/dumped.wsdl');
- $dumpedContent = file_get_contents(__DIR__ . '/TestAsset/dumped.wsdl');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($dumpedContent),
- '' .
- '' );
-
- unlink(__DIR__ . '/TestAsset/dumped.wsdl');
+ $errors = libxml_get_errors();
+ $this->assertEmpty($errors, 'Libxml parsing errors: '.print_r($errors, 1));
+
+ $this->dom = $this->registerNamespaces($xml);
+
+ $this->testConstructor();
+
+ $this->testDocumentNodes();
}
public function testGetType()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $this->assertEquals('xsd:string', $wsdl->getType('string'), 'xsd:string detection failed.');
- $this->assertEquals('xsd:string', $wsdl->getType('str'), 'xsd:string detection failed.');
- $this->assertEquals('xsd:int', $wsdl->getType('int'), 'xsd:int detection failed.');
- $this->assertEquals('xsd:int', $wsdl->getType('integer'), 'xsd:int detection failed.');
- $this->assertEquals('xsd:float', $wsdl->getType('float'), 'xsd:float detection failed.');
- $this->assertEquals('xsd:double', $wsdl->getType('double'), 'xsd:double detection failed.');
- $this->assertEquals('xsd:boolean', $wsdl->getType('boolean'), 'xsd:boolean detection failed.');
- $this->assertEquals('xsd:boolean', $wsdl->getType('bool'), 'xsd:boolean detection failed.');
- $this->assertEquals('soap-enc:Array', $wsdl->getType('array'), 'soap-enc:Array detection failed.');
- $this->assertEquals('xsd:struct', $wsdl->getType('object'), 'xsd:struct detection failed.');
- $this->assertEquals('xsd:anyType', $wsdl->getType('mixed'), 'xsd:anyType detection failed.');
- $this->assertEquals('', $wsdl->getType('void'), 'void detection failed.');
+ $this->assertEquals('xsd:string', $this->wsdl->getType('string'), 'xsd:string detection failed.');
+ $this->assertEquals('xsd:string', $this->wsdl->getType('str'), 'xsd:string detection failed.');
+ $this->assertEquals('xsd:int', $this->wsdl->getType('int'), 'xsd:int detection failed.');
+ $this->assertEquals('xsd:int', $this->wsdl->getType('integer'), 'xsd:int detection failed.');
+ $this->assertEquals('xsd:float', $this->wsdl->getType('float'), 'xsd:float detection failed.');
+ $this->assertEquals('xsd:double', $this->wsdl->getType('double'), 'xsd:double detection failed.');
+ $this->assertEquals('xsd:boolean', $this->wsdl->getType('boolean'), 'xsd:boolean detection failed.');
+ $this->assertEquals('xsd:boolean', $this->wsdl->getType('bool'), 'xsd:boolean detection failed.');
+ $this->assertEquals('soap-enc:Array', $this->wsdl->getType('array'), 'soap-enc:Array detection failed.');
+ $this->assertEquals('xsd:struct', $this->wsdl->getType('object'), 'xsd:struct detection failed.');
+ $this->assertEquals('xsd:anyType', $this->wsdl->getType('mixed'), 'xsd:anyType detection failed.');
+ $this->assertEquals('', $this->wsdl->getType('void'), 'void detection failed.');
}
public function testGetComplexTypeBasedOnStrategiesBackwardsCompabilityBoolean()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $this->assertEquals('tns:WsdlTestClass', $wsdl->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
- $this->assertTrue($wsdl->getComplexTypeStrategy() instanceof ComplexTypeStrategy\DefaultComplexType);
-
-// $wsdl2 = new Wsdl('MyService', 'http://localhost/MyService.php', false);
-// $this->assertEquals('xsd:anyType', $wsdl2->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
-// $this->assertTrue($wsdl2->getComplexTypeStrategy() instanceof ComplexTypeStrategy\AnyType);
+ $this->assertEquals('tns:WsdlTestClass', $this->wsdl->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
+ $this->assertTrue($this->wsdl->getComplexTypeStrategy() instanceof Wsdl\ComplexTypeStrategy\DefaultComplexType);
}
public function testGetComplexTypeBasedOnStrategiesStringNames()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php', new \Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType);
- $this->assertEquals('tns:WsdlTestClass', $wsdl->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
- $this->assertTrue($wsdl->getComplexTypeStrategy() instanceof ComplexTypeStrategy\DefaultComplexType);
+ $this->wsdl = new Wsdl($this->defaultServiceName, 'http://localhost/MyService.php', new Wsdl\ComplexTypeStrategy\DefaultComplexType);
+ $this->assertEquals('tns:WsdlTestClass', $this->wsdl->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
+ $this->assertTrue($this->wsdl->getComplexTypeStrategy() instanceof Wsdl\ComplexTypeStrategy\DefaultComplexType);
- $wsdl2 = new Wsdl('MyService', 'http://localhost/MyService.php', new \Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType);
+ $wsdl2 = new Wsdl($this->defaultServiceName, $this->defaultServiceUri, new Wsdl\ComplexTypeStrategy\AnyType);
$this->assertEquals('xsd:anyType', $wsdl2->getType('\ZendTest\Soap\TestAsset\WsdlTestClass'));
- $this->assertTrue($wsdl2->getComplexTypeStrategy() instanceof ComplexTypeStrategy\AnyType);
+ $this->assertTrue($wsdl2->getComplexTypeStrategy() instanceof Wsdl\ComplexTypeStrategy\AnyType);
}
public function testAddingSameComplexTypeMoreThanOnceIsIgnored()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $wsdl->addType('\ZendTest\Soap\TestAsset\WsdlTestClass', 'tns:SomeTypeName');
- $wsdl->addType('\ZendTest\Soap\TestAsset\WsdlTestClass', 'tns:AnotherTypeName');
- $types = $wsdl->getTypes();
+ $this->wsdl->addType('\ZendTest\Soap\TestAsset\WsdlTestClass', 'tns:SomeTypeName');
+ $this->wsdl->addType('\ZendTest\Soap\TestAsset\WsdlTestClass', 'tns:AnotherTypeName');
+ $types = $this->wsdl->getTypes();
$this->assertEquals(1, count($types));
- $this->assertEquals(array('\ZendTest\Soap\TestAsset\WsdlTestClass' => 'tns:SomeTypeName'),
- $types);
+ $this->assertEquals(
+ array(
+ '\ZendTest\Soap\TestAsset\WsdlTestClass' => 'tns:SomeTypeName'
+ ),
+ $types
+ );
+
+ $this->testDocumentNodes();
}
public function testUsingSameComplexTypeTwiceLeadsToReuseOfDefinition()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
- $this->assertEquals(array('\ZendTest\Soap\TestAsset\WsdlTestClass' =>
- 'tns:WsdlTestClass'),
- $wsdl->getTypes());
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
+ $this->assertEquals(
+ array(
+ '\ZendTest\Soap\TestAsset\WsdlTestClass' => 'tns:WsdlTestClass'
+ ),
+ $this->wsdl->getTypes()
+ );
- $wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
- $this->assertEquals(array('\ZendTest\Soap\TestAsset\WsdlTestClass' =>
- 'tns:WsdlTestClass'),
- $wsdl->getTypes());
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
+ $this->assertEquals(
+ array(
+ '\ZendTest\Soap\TestAsset\WsdlTestClass' => 'tns:WsdlTestClass'
+ ),
+ $this->wsdl->getTypes()
+ );
+
+ $this->testDocumentNodes();
+ }
+
+ public function testGetSchema()
+ {
+ $schema = $this->wsdl->getSchema();
+
+ $this->assertEquals($this->defaultServiceUri, $schema->getAttribute('targetNamespace'));
}
public function testAddComplexType()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
-
- $wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
-
- $this->assertEquals($this->sanitizeWsdlXmlOutputForOsCompability($wsdl->toXml()),
- '' .
- ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . ''
- . '' );
+ $this->wsdl->addComplexType('\ZendTest\Soap\TestAsset\WsdlTestClass');
+
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType/xsd:all/*');
+
+ $this->assertGreaterThan(0, $nodes->length, 'Unable to find object properties in wsdl');
+ }
+
+ public function testAddTypesFromDocument()
+ {
+ $dom = new \DOMDocument();
+ $types = $dom->createElementNS(WSDL::WSDL_NS_URI, 'types');
+ $dom->appendChild($types);
+
+ $this->wsdl->addTypes($dom);
+
+ $nodes = $this->xpath->query('//wsdl:types');
+ $this->assertGreaterThanOrEqual(1, $nodes->length);
+
+ $this->testDocumentNodes();
+ }
+
+ public function testAddTypesFromNode()
+ {
+ $dom = $this->dom->createElementNS(WSDL::WSDL_NS_URI, 'types');
+
+ $this->wsdl->addTypes($dom);
+
+ $nodes = $this->xpath->query('//wsdl:types');
+ $this->assertGreaterThanOrEqual(1, $nodes->length);
+
+ $this->testDocumentNodes();
+ }
+
+ public function testTranslateTypeFromClassMap()
+ {
+ $this->wsdl->setClassMap(array(
+ 'SomeType'=>'SomeOtherType'
+ ));
+
+ $this->assertEquals('SomeOtherType', $this->wsdl->translateType('SomeType'));
}
/**
- * @group ZF-3910
+ * @dataProvider dataProviderForTranslateType
*/
- public function testCaseOfDocBlockParamsDosNotMatterForSoapTypeDetectionZf3910()
+ public function testTranslateType($type, $expected)
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
+ $this->assertEquals($expected, $this->wsdl->translateType($type));
+ }
- $this->assertEquals("xsd:string", $wsdl->getType("StrIng"));
- $this->assertEquals("xsd:string", $wsdl->getType("sTr"));
- $this->assertEquals("xsd:int", $wsdl->getType("iNt"));
- $this->assertEquals("xsd:int", $wsdl->getType("INTEGER"));
- $this->assertEquals("xsd:float", $wsdl->getType("FLOAT"));
- $this->assertEquals("xsd:double", $wsdl->getType("douBLE"));
+ /**
+ * @return array
+ */
+ public function dataProviderForTranslateType()
+ {
+ return array(
+ array('\\SomeType','SomeType'),
+ array('SomeType\\','SomeType'),
+ array('\\SomeType\\','SomeType'),
+ array('\\SomeNamespace\SomeType\\','SomeType'),
+ array('\\SomeNamespace\SomeType\\SomeOtherType','SomeOtherType'),
+ array('\\SomeNamespace\SomeType\\SomeOtherType\\YetAnotherType','YetAnotherType'),
+ );
}
+
/**
+ * @group ZF-3910
* @group ZF-11937
*/
- public function testWsdlGetTypeWillAllowLongType()
+ public function testCaseOfDocBlockParamsDosNotMatterForSoapTypeDetectionZf3910()
{
- $wsdl = new Wsdl('MyService', 'http://localhost/MyService.php');
- $this->assertEquals("xsd:long", $wsdl->getType("long"));
+ $this->assertEquals("xsd:string", $this->wsdl->getType("StrIng"));
+ $this->assertEquals("xsd:string", $this->wsdl->getType("sTr"));
+ $this->assertEquals("xsd:int", $this->wsdl->getType("iNt"));
+ $this->assertEquals("xsd:int", $this->wsdl->getType("INTEGER"));
+ $this->assertEquals("xsd:float", $this->wsdl->getType("FLOAT"));
+ $this->assertEquals("xsd:double", $this->wsdl->getType("douBLE"));
+
+ $this->assertEquals("xsd:long", $this->wsdl->getType("long"));
}
/**
@@ -723,37 +796,69 @@ public function testWsdlGetTypeWillAllowLongType()
*/
public function testMultipleSequenceDefinitionsOfSameTypeWillBeRecognizedOnceBySequenceStrategy()
{
- $wsdl = new Wsdl("MyService", "http://localhost/MyService.php");
- $wsdl->setComplexTypeStrategy(new ComplexTypeStrategy\ArrayOfTypeSequence());
+ $this->wsdl->setComplexTypeStrategy(new Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence());
- $wsdl->addComplexType("string[]");
- $wsdl->addComplexType("int[]");
- $wsdl->addComplexType("string[]");
+ $this->wsdl->addComplexType("string[]");
+ $this->wsdl->addComplexType("int[]");
+ $this->wsdl->addComplexType("string[]");
+ $this->wsdl->addComplexType("int[]");
+
+ $this->testDocumentNodes();
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="ArrayOfString"]');
+ $this->assertEquals(1, $nodes->length, "ArrayOfString should appear only once.");
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:complexType[@name="ArrayOfInt"]');
+ $this->assertEquals(1, $nodes->length, "ArrayOfInt should appear only once.");
- $xml = $wsdl->toXml();
- $this->assertEquals(1, substr_count($xml, "ArrayOfString"), "ArrayOfString should appear only once.");
- $this->assertEquals(1, substr_count($xml, "ArrayOfInt"), "ArrayOfInt should appear only once.");
}
- const URI_WITH_EXPANDED_AMP = "http://localhost/MyService.php?a%3Db%26b%3Dc";
- const URI_WITHOUT_EXPANDED_AMP = "http://localhost/MyService.php?a=b&b=c";
+ public function testClassMap()
+ {
+ $this->wsdl->setClassMap(array('foo'=>'bar'));
+
+ $this->assertArrayHasKey('foo', $this->wsdl->getClassMap());
+ }
/**
- * @group ZF-5736
+ * @expectedException RuntimeException
*/
- public function testHtmlAmpersandInUrlInConstructorIsEncodedCorrectly()
+ public function testAddElementException ()
{
- $wsdl = new Wsdl("MyService", self::URI_WITHOUT_EXPANDED_AMP);
- $this->assertContains(self::URI_WITH_EXPANDED_AMP, $wsdl->toXML());
+ $this->wsdl->addElement(1);
}
- /**
- * @group ZF-5736
- */
- public function testHtmlAmpersandInUrlInSetUriIsEncodedCorrectly()
+ public function testAddElement()
{
- $wsdl = new Wsdl("MyService", "http://example.com");
- $wsdl->setUri(self::URI_WITHOUT_EXPANDED_AMP);
- $this->assertContains(self::URI_WITH_EXPANDED_AMP, $wsdl->toXML());
+ $element = array(
+ 'name' => 'MyElement',
+ 'sequence' => array(
+ array('name' => 'myString', 'type' => 'string'),
+ array('name' => 'myInt', 'type' => 'int')
+ )
+ );
+
+ $newElementName = $this->wsdl->addElement($element);
+
+ $this->testDocumentNodes();
+
+ $this->assertEquals('tns:'.$element['name'], $newElementName);
+
+ $nodes = $this->xpath->query('//wsdl:types/xsd:schema/xsd:element[@name="'.$element['name'].'"]/xsd:complexType');
+
+ $this->assertEquals(1, $nodes->length);
+
+ $this->assertEquals('sequence', $nodes->item(0)->firstChild->localName);
+
+ $n = 0;
+ foreach($element['sequence'] as $elementDefinition) {
+ $n++;
+ $elementNode = $this->xpath->query('xsd:element[@name="'.$elementDefinition['name'].'"]', $nodes->item(0)->firstChild);
+ $this->assertEquals($elementDefinition['type'], $elementNode->item(0)->getAttribute('type'));
+ }
+
+ $this->assertEquals(count($element['sequence']), $n);
}
+
+
}
diff --git a/test/WsdlTestHelper.php b/test/WsdlTestHelper.php
new file mode 100644
index 00000000..409b7690
--- /dev/null
+++ b/test/WsdlTestHelper.php
@@ -0,0 +1,121 @@
+strategy) OR !($this->strategy instanceof ComplexTypeStrategyInterface)) {
+ $this->strategy = new Wsdl\ComplexTypeStrategy\DefaultComplexType();
+ }
+
+ $this->wsdl = new Wsdl($this->defaultServiceName, $this->defaultServiceUri, $this->strategy);
+
+ if ($this->strategy instanceof ComplexTypeStrategyInterface) {
+ $this->strategy->setContext($this->wsdl);
+ }
+
+ $this->dom = $this->wsdl->toDomDocument();
+ $this->dom = $this->registerNamespaces($this->dom);
+ }
+
+ /**
+ * @param \DOMDocument $obj
+ * @param string $documentNamespace
+ * @return \DOMDocument
+ */
+ public function registerNamespaces($obj, $documentNamespace = null)
+ {
+
+ if (empty($documentNamespace)) {
+ $documentNamespace = $this->defaultServiceUri;
+ }
+
+ $this->xpath = new \DOMXPath($obj);
+ $this->xpath->registerNamespace('unittest', Wsdl::WSDL_NS_URI);
+
+ $this->xpath->registerNamespace('tns', $documentNamespace);
+ $this->xpath->registerNamespace('soap', Wsdl::SOAP_11_NS_URI);
+ $this->xpath->registerNamespace('soap12', Wsdl::SOAP_12_NS_URI);
+ $this->xpath->registerNamespace('xsd', Wsdl::XSD_NS_URI);
+ $this->xpath->registerNamespace('soap-enc', Wsdl::SOAP_ENC_URI);
+ $this->xpath->registerNamespace('wsdl', Wsdl::WSDL_NS_URI);
+
+ return $obj;
+ }
+
+ /**
+ * @param \DOMElement $element
+ */
+ public function testDocumentNodes($element = null)
+ {
+ if (!($this->wsdl instanceof Wsdl)) {
+ return;
+ }
+
+ if (is_null($element)) {
+ $element = $this->wsdl->toDomDocument()->documentElement;
+ }
+
+ /** @var $node \DOMElement */
+ foreach ($element->childNodes as $node) {
+ if (in_array($node->nodeType, array(XML_ELEMENT_NODE))) {
+ $this->assertNotEmpty($node->namespaceURI, 'Document element: ' . $node->nodeName . ' has no valid namespace. Line: ' . $node->getLineNo());
+ $this->testDocumentNodes($node);
+ }
+ }
+ }
+}
diff --git a/test/_files/wsdl_example.wsdl b/test/_files/wsdl_example.wsdl
index 4eaa8761..19dc6878 100644
--- a/test/_files/wsdl_example.wsdl
+++ b/test/_files/wsdl_example.wsdl
@@ -1,2 +1,89 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/schemas/wsdl.xsd b/test/schemas/wsdl.xsd
index 0546b338..4832b6f5 100644
--- a/test/schemas/wsdl.xsd
+++ b/test/schemas/wsdl.xsd
@@ -1,39 +1,39 @@
-
-
+-->
-
+
@@ -51,7 +51,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -61,7 +61,7 @@ No other rights are granted by implication, estoppel or otherwise.
This type is extended by component types to allow attributes from other namespaces to be added.
-
+
@@ -118,7 +118,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -133,7 +133,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -149,7 +149,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -159,15 +159,15 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
-
+
-
+
-
+
-
+
@@ -175,22 +175,22 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
-
+
-
+
-
+
-
+
@@ -198,13 +198,13 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
-
+
-
+
-
+
@@ -214,16 +214,16 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
-
+
-
-
-
+
+
+
@@ -231,14 +231,14 @@ No other rights are granted by implication, estoppel or otherwise.
-
-
-
-
+
+
+
+
-
+
@@ -257,7 +257,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -270,7 +270,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -279,7 +279,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -302,7 +302,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -314,7 +314,7 @@ No other rights are granted by implication, estoppel or otherwise.
-
+
@@ -331,4 +331,4 @@ No other rights are granted by implication, estoppel or otherwise.
-
\ No newline at end of file
+