diff --git a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php
index d65e434..01cd065 100644
--- a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php
+++ b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php
@@ -64,6 +64,7 @@ class SoapWebServiceController extends ContainerAware
$this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request'));
$this->soapServer = $webServiceContext
->getServerBuilder()
+ ->withSoapVersion11()
->withHandler($this)
->build()
;
diff --git a/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php b/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php
index 3db1218..1536d8d 100644
--- a/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php
+++ b/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php
@@ -148,9 +148,9 @@ class BeSimpleSoapExtension extends Extension
$options = $container
->getDefinition('besimple.soap.context.'.$bindingSuffix)
- ->getArgument(5);
+ ->getArgument(2);
- $definition->replaceArgument(5, array_merge($options, $config));
+ $definition->replaceArgument(2, array_merge($options, $config));
}
private function getCacheType($type)
diff --git a/src/BeSimple/SoapBundle/Resources/config/loaders.xml b/src/BeSimple/SoapBundle/Resources/config/loaders.xml
index 4347f94..4b609ba 100644
--- a/src/BeSimple/SoapBundle/Resources/config/loaders.xml
+++ b/src/BeSimple/SoapBundle/Resources/config/loaders.xml
@@ -29,10 +29,13 @@
+
+
+
diff --git a/src/BeSimple/SoapBundle/Resources/config/webservice.xml b/src/BeSimple/SoapBundle/Resources/config/webservice.xml
index cd1a689..8170b1f 100644
--- a/src/BeSimple/SoapBundle/Resources/config/webservice.xml
+++ b/src/BeSimple/SoapBundle/Resources/config/webservice.xml
@@ -13,8 +13,7 @@
BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder
BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestHeaderMessageBinder
BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder
- BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper
- BeSimple\SoapBundle\Converter\TypeRepository
+ BeSimple\SoapCommon\Definition\Type\TypeRepository
BeSimple\SoapServer\Classmap
@@ -28,9 +27,6 @@
-
-
-
%besimple.soap.cache.dir%
@@ -45,9 +41,6 @@
-
-
-
%besimple.soap.cache.dir%
@@ -60,42 +53,35 @@
-
-
-
-
- %besimple.soap.definition.dumper.options.stylesheet%
-
-
-
+
xsd
http://www.w3.org/2001/XMLSchema
-
+
string
xsd:string
-
+
boolean
xsd:boolean
-
+
int
xsd:int
-
+
float
xsd:float
-
+
date
xsd:date
-
+
dateTime
xsd:dateTime
diff --git a/src/BeSimple/SoapBundle/ServiceBinding/MessageBinderInterface.php b/src/BeSimple/SoapBundle/ServiceBinding/MessageBinderInterface.php
index 85ca02f..7cda7d4 100644
--- a/src/BeSimple/SoapBundle/ServiceBinding/MessageBinderInterface.php
+++ b/src/BeSimple/SoapBundle/ServiceBinding/MessageBinderInterface.php
@@ -11,6 +11,7 @@
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
/**
* @author Christian Kerl
@@ -23,5 +24,5 @@ interface MessageBinderInterface
*
* @return mixed
*/
- function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array());
-}
\ No newline at end of file
+ function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository);
+}
diff --git a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php
index 15fcf0c..05fe83d 100644
--- a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php
+++ b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php
@@ -11,6 +11,7 @@
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
/**
* @author Francis Besset
@@ -24,10 +25,11 @@ class RpcLiteralRequestHeaderMessageBinder extends RpcLiteralRequestMessageBinde
$this->header = $header;
}
- public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
+ public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
{
+ $this->typeRepository = $typeRepository;
$headerDefinition = $messageDefinition->getHeaders()->get($this->header);
- return $this->processType($headerDefinition->getType()->getPhpType(), $message, $definitionComplexTypes);
+ return $this->processType($headerDefinition->getType(), $message);
}
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php
index 6f8b36e..872adc0 100644
--- a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php
+++ b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php
@@ -15,6 +15,9 @@ namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType;
+use BeSimple\SoapCommon\Definition\Type\ArrayOfType;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
use BeSimple\SoapCommon\Util\MessageBinder;
/**
@@ -23,19 +26,20 @@ use BeSimple\SoapCommon\Util\MessageBinder;
*/
class RpcLiteralRequestMessageBinder implements MessageBinderInterface
{
- private $messageRefs = array();
- private $definitionComplexTypes;
+ protected $typeRepository;
- public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
+ private $messageRefs = array();
+
+ public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
{
- $this->definitionComplexTypes = $definitionComplexTypes;
+ $this->typeRepository = $typeRepository;
$result = array();
$i = 0;
- foreach ($messageDefinition->getArguments() as $argument) {
+ foreach ($messageDefinition->getInput()->all() as $argument) {
if (isset($message[$i])) {
- $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i]);
+ $result[$argument->getName()] = $this->processType($argument->getType(), $message[$i]);
}
$i++;
@@ -48,15 +52,21 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface
{
$isArray = false;
- if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) {
+ $type = $this->typeRepository->getType($phpType);
+ if ($type instanceof ArrayOfType) {
$isArray = true;
- $array = array();
- $phpType = $match[1];
+ $arrayType = $type;
+
+ $type = $this->typeRepository->getType($type->get('item')->getType());
}
// @TODO Fix array reference
- if (isset($this->definitionComplexTypes[$phpType])) {
+ if ($type instanceof ComplexType) {
+ $phpType = $type->getPhpType();
+
if ($isArray) {
+ $array = array();
+
if (isset($message->item)) {
foreach ($message->item as $complexType) {
$array[] = $this->checkComplexType($phpType, $complexType);
@@ -98,12 +108,12 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface
$this->messageRefs[$hash] = $message;
$messageBinder = new MessageBinder($message);
- foreach ($this->definitionComplexTypes[$phpType]['properties'] as $type) {
+ foreach ($this->typeRepository->getType($phpType)->all() as $type) {
$property = $type->getName();
$value = $messageBinder->readProperty($property);
if (null !== $value) {
- $value = $this->processType($type->getValue(), $value);
+ $value = $this->processType($type->getType(), $value);
$messageBinder->writeProperty($property, $value);
}
diff --git a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php
index 34d1edd..6e600c8 100644
--- a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php
+++ b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php
@@ -15,6 +15,9 @@ namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType;
use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType;
+use BeSimple\SoapCommon\Definition\Type\ArrayOfType;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
use BeSimple\SoapCommon\Util\MessageBinder;
/**
@@ -23,26 +26,32 @@ use BeSimple\SoapCommon\Util\MessageBinder;
*/
class RpcLiteralResponseMessageBinder implements MessageBinderInterface
{
+ protected $typeRepository;
+
private $messageRefs = array();
- private $definitionComplexTypes;
- public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array())
+ public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
{
- $this->definitionComplexTypes = $definitionComplexTypes;
+ $this->typeRepository = $typeRepository;
- return $this->processType($messageDefinition->getReturn()->getPhpType(), $message);
+ return $this->processType($messageDefinition->getOutput()->get('return')->getType(), $message);
}
private function processType($phpType, $message)
{
$isArray = false;
- if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) {
+ $type = $this->typeRepository->getType($phpType);
+ if ($type instanceof ArrayOfType) {
$isArray = true;
- $phpType = $match[1];
+ $arrayType = $type;
+
+ $type = $this->typeRepository->getType($type->get('item')->getType());
}
- if (isset($this->definitionComplexTypes[$phpType])) {
+ if ($type instanceof ComplexType) {
+ $phpType = $type->getPhpType();
+
if ($isArray) {
$array = array();
@@ -83,12 +92,12 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface
}
$messageBinder = new MessageBinder($message);
- foreach ($this->definitionComplexTypes[$phpType]['properties'] as $type) {
+ foreach ($this->typeRepository->getType($phpType)->all() as $type) {
$property = $type->getName();
$value = $messageBinder->readProperty($property);
if (null !== $value) {
- $value = $this->processType($type->getValue(), $value);
+ $value = $this->processType($type->getType(), $value);
$messageBinder->writeProperty($property, $value);
}
diff --git a/src/BeSimple/SoapBundle/ServiceBinding/ServiceBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/ServiceBinder.php
index e9e4254..c31f4fd 100644
--- a/src/BeSimple/SoapBundle/ServiceBinding/ServiceBinder.php
+++ b/src/BeSimple/SoapBundle/ServiceBinding/ServiceBinder.php
@@ -11,7 +11,7 @@
namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Header;
-use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
+use BeSimple\SoapBundle\ServiceDefinition\Definition;
use BeSimple\SoapBundle\Soap\SoapHeader;
/**
@@ -40,12 +40,12 @@ class ServiceBinder
private $responseMessageBinder;
/**
- * @param ServiceDefinition $definition
+ * @param Definition $definition
* @param MessageBinderInterface $requestHeaderMessageBinder
* @param MessageBinderInterface $requestMessageBinder
* @param MessageBinderInterface $responseMessageBinder
*/
- public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) {
+ public function __construct(Definition $definition, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) {
$this->definition = $definition;
$this->requestHeaderMessageBinder = $requestHeaderMessageBinder;
@@ -62,7 +62,7 @@ class ServiceBinder
*/
public function isServiceHeader($method, $header)
{
- return $this->definition->getMethods()->get($method)->getHeaders()->has($header);
+ return $this->definition->getMethod($method)->getHeader($header);
}
/**
@@ -72,7 +72,7 @@ class ServiceBinder
*/
public function isServiceMethod($method)
{
- return $this->definition->getMethods()->has($method);
+ return null !== $this->definition->getMethod($method);
}
/**
@@ -84,11 +84,11 @@ class ServiceBinder
*/
public function processServiceHeader($method, $header, $data)
{
- $methodDefinition = $this->definition->getMethods()->get($method);
- $headerDefinition = $methodDefinition->getHeaders()->get($header);
+ $methodDefinition = $this->definition->getMethod($method);
+ $headerDefinition = $methodDefinition->getHeader($header);
$this->requestHeaderMessageBinder->setHeader($header);
- $data = $this->requestHeaderMessageBinder->processMessage($methodDefinition, $data, $this->definition->getDefinitionComplexTypes());
+ $data = $this->requestHeaderMessageBinder->processMessage($methodDefinition, $data, $this->definition->getTypeRepository());
return new SoapHeader($this->definition->getNamespace(), $headerDefinition->getName(), $data);
}
@@ -101,11 +101,11 @@ class ServiceBinder
*/
public function processServiceMethodArguments($method, $arguments)
{
- $methodDefinition = $this->definition->getMethods()->get($method);
+ $methodDefinition = $this->definition->getMethod($method);
return array_merge(
array('_controller' => $methodDefinition->getController()),
- $this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getDefinitionComplexTypes())
+ $this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getTypeRepository())
);
}
@@ -117,8 +117,8 @@ class ServiceBinder
*/
public function processServiceMethodReturnValue($name, $return)
{
- $methodDefinition = $this->definition->getMethods()->get($name);
+ $methodDefinition = $this->definition->getMethod($name);
- return $this->responseMessageBinder->processMessage($methodDefinition, $return, $this->definition->getDefinitionComplexTypes());
+ return $this->responseMessageBinder->processMessage($methodDefinition, $return, $this->definition->getTypeRepository());
}
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Argument.php b/src/BeSimple/SoapBundle/ServiceDefinition/Argument.php
deleted file mode 100644
index b1f8849..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Argument.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition;
-
-class Argument
-{
- private $name;
- private $type;
-
- public function __construct($name = null, Type $type = null)
- {
- $this->setName($name);
- $this->setType($type);
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function setName($name)
- {
- $this->name = $name;
- }
-
- public function getType()
- {
- return $this->type;
- }
-
- public function setType(Type $type)
- {
- $this->type = $type;
- }
-}
\ No newline at end of file
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php
index 2d78bbe..d0ae464 100644
--- a/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php
@@ -1,8 +1,10 @@
+ * (c) Francis Besset
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
@@ -48,4 +50,4 @@ class ComplexType
{
$this->isNillable = (bool) $isNillable;
}
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Definition.php b/src/BeSimple/SoapBundle/ServiceDefinition/Definition.php
new file mode 100644
index 0000000..4afd642
--- /dev/null
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/Definition.php
@@ -0,0 +1,46 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapBundle\ServiceDefinition;
+
+use BeSimple\SoapCommon\Definition\Definition as BaseDefinition;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+
+/**
+ * @author Christian Kerl
+ * @author Francis Besset
+ */
+class Definition extends BaseDefinition
+{
+ private $complexTypes;
+
+ public function __construct(TypeRepository $typeRepository)
+ {
+ $this->typeRepository = $typeRepository;
+
+ $this->setOptions(array());
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+
+ return $this;
+ }
+
+ public function setNamespace($namespace)
+ {
+ $this->namespace = $namespace;
+
+ return $this;
+ }
+}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/DumperInterface.php b/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/DumperInterface.php
deleted file mode 100644
index 3b8b257..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/DumperInterface.php
+++ /dev/null
@@ -1,18 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Dumper;
-
-use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
-
-interface DumperInterface
-{
- function dumpServiceDefinition(ServiceDefinition $definition, $endpoint);
-}
\ No newline at end of file
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/Wsdl.php b/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/Wsdl.php
deleted file mode 100644
index e8e4721..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/Wsdl.php
+++ /dev/null
@@ -1,80 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Dumper;
-
-use BeSimple\SoapBundle\Converter\TypeRepository;
-use BeSimple\SoapBundle\ServiceDefinition\Type;
-use Zend\Soap\Wsdl as BaseWsdl;
-
-/**
- * @author Francis Besset
- */
-class Wsdl extends BaseWsdl
-{
- private $typeRepository;
-
- public function __construct(TypeRepository $typeRepository, $name, $uri, $strategy = true)
- {
- $this->typeRepository = $typeRepository;
-
- parent::__construct($name, $uri, $strategy);
- }
-
- public function getType($type)
- {
- if ($type instanceof Type) {
- return $type->getXmlType();
- }
-
- if ('\\' === $type[0]) {
- $type = substr($type, 1);
- }
-
- if (!$xmlType = $this->typeRepository->getXmlTypeMapping($type)) {
- $xmlType = $this->addComplexType($type);
- }
-
- return $xmlType;
- }
-
- /**
- * Translate PHP type into WSDL QName
- *
- * @param string $type
- * @return string QName
- */
- public function translateType($type)
- {
- if (isset($this->classMap[$type])) {
- return $this->classMap[$type];
- }
-
- return str_replace('\\', '.', $type);
- }
-
- public function addBindingOperationHeader(\DOMElement $bindingOperation, array $headers, array $baseBinding)
- {
- foreach ($headers as $header) {
- $inputNode = $bindingOperation->getElementsByTagName('input')->item(0);
-
- $headerNode = $this->toDomDocument()->createElement('soap:header');
- $headerNode->setAttribute('part', $header);
-
- foreach ($baseBinding as $name => $value) {
- $headerNode->setAttribute($name, $value);
- }
-
- $inputNode->appendChild($headerNode);
- }
-
- return $bindingOperation;
- }
-}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlDumper.php b/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlDumper.php
deleted file mode 100644
index abe64c3..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlDumper.php
+++ /dev/null
@@ -1,177 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Dumper;
-
-use BeSimple\SoapBundle\Converter\TypeRepository;
-use BeSimple\SoapBundle\ServiceDefinition\Method;
-use BeSimple\SoapBundle\ServiceDefinition\Type;
-use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
-use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader;
-use BeSimple\SoapBundle\Util\Assert;
-use BeSimple\SoapBundle\Util\QName;
-
-/**
- * @author Christian Kerl
- */
-class WsdlDumper implements DumperInterface
-{
- private $loader;
- private $typeRepository;
- private $options;
-
- private $wsdl;
- private $definition;
-
- public function __construct(AnnotationComplexTypeLoader $loader, TypeRepository $typeRepository, array $options)
- {
- $this->loader = $loader;
- $this->typeRepository = $typeRepository;
- $this->options = $options;
- }
-
- public function dumpServiceDefinition(ServiceDefinition $definition, $endpoint)
- {
- Assert::thatArgumentNotNull('definition', $definition);
-
- $this->definition = $definition;
- $this->wsdl = new Wsdl($this->typeRepository, $definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy($this->loader, $definition));
- $port = $this->wsdl->addPortType($this->getPortTypeName());
- $binding = $this->wsdl->addBinding($this->getBindingName(), $this->qualify($this->getPortTypeName()));
-
- $this->wsdl->addSoapBinding($binding, 'rpc');
- $this->wsdl->addService($this->getServiceName(), $this->getPortName(), $this->qualify($this->getBindingName()), $endpoint);
-
- foreach ($definition->getMethods() as $method) {
- $requestHeaderParts =
- $requestParts =
- $responseParts = array();
-
- foreach ($method->getHeaders() as $header) {
- $requestHeaderParts[$header->getName()] = $this->wsdl->getType($header->getType()->getPhpType());
- }
-
- foreach ($method->getArguments() as $argument) {
- $requestParts[$argument->getName()] = $this->wsdl->getType($argument->getType()->getPhpType());
- }
-
- if ($method->getReturn() !== null) {
- $responseParts['return'] = $this->wsdl->getType($method->getReturn()->getPhpType());
- }
-
- if (!empty($requestHeaderParts)) {
- $this->wsdl->addMessage($this->getRequestHeaderMessageName($method), $requestHeaderParts);
- }
- $this->wsdl->addMessage($this->getRequestMessageName($method), $requestParts);
- $this->wsdl->addMessage($this->getResponseMessageName($method), $responseParts);
-
- $portOperation = $this->wsdl->addPortOperation(
- $port,
- $method->getName(),
- $this->qualify($this->getRequestMessageName($method)),
- $this->qualify($this->getResponseMessageName($method))
- );
-
- $baseBinding =
- $inputBinding =
- $outputBinding = array(
- 'use' => 'literal',
- 'namespace' => $definition->getNamespace(),
- 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/',
- );
-
- if (!empty($requestParts)) {
- $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts)));
-
- $inputBinding['parts'] = implode(' ', array_keys($requestParts));
- }
-
- if (!empty($responseParts)) {
- $outputBinding['parts'] = implode(' ', array_keys($responseParts));
- }
-
- $bindingOperation = $this->wsdl->addBindingOperation(
- $binding,
- $method->getName(),
- $inputBinding,
- $outputBinding
- );
- $bindingOperation = $this->wsdl->addBindingOperationHeader(
- $bindingOperation,
- array_keys($requestHeaderParts),
- array_merge(array('message' => $this->qualify($this->getRequestHeaderMessageName($method))), $baseBinding)
- );
-
- $this->wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method));
- }
-
- $this->definition = null;
-
- $dom = $this->wsdl->toDomDocument();
- $dom->formatOutput = true;
-
- if ($this->options['stylesheet']) {
- $stylesheet = $dom->createProcessingInstruction('xml-stylesheet', sprintf('type="text/xsl" href="%s"', $this->options['stylesheet']));
-
- $dom->insertBefore($stylesheet, $dom->documentElement);
- }
-
- return $this->wsdl->toXml();
- }
-
- protected function qualify($name, $namespace = null)
- {
- if($namespace === null) {
- $namespace = $this->definition->getNamespace();
- }
-
- return $this->wsdl->toDomDocument()->lookupPrefix($namespace).':'.$name;
- }
-
- protected function getPortName()
- {
- return $this->definition->getName().'Port';
- }
-
- protected function getPortTypeName()
- {
- return $this->definition->getName().'PortType';
- }
-
- protected function getBindingName()
- {
- return $this->definition->getName().'Binding';
- }
-
- protected function getServiceName()
- {
- return $this->definition->getName().'Service';
- }
-
- protected function getRequestHeaderMessageName(Method $method)
- {
- return $method->getName().'Header';
- }
-
- protected function getRequestMessageName(Method $method)
- {
- return $method->getName().'Request';
- }
-
- protected function getResponseMessageName(Method $method)
- {
- return $method->getName().'Response';
- }
-
- protected function getSoapOperationName(Method $method)
- {
- return $this->definition->getNamespace().$method->getName();
- }
-}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlTypeStrategy.php
deleted file mode 100644
index 96207ea..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Dumper/WsdlTypeStrategy.php
+++ /dev/null
@@ -1,95 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Dumper;
-
-use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
-use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader;
-use BeSimple\SoapBundle\ServiceDefinition\Strategy\ComplexType;
-use BeSimple\SoapBundle\Util\String;
-
-use Zend\Soap\Exception;
-use Zend\Soap\Wsdl as BaseWsdl;
-use Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface;
-use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence;
-
-class WsdlTypeStrategy implements ComplexTypeStrategyInterface
-{
- /**
- * Context WSDL file
- *
- * @var \Zend\Soap\Wsdl|null
- */
- private $context;
-
- private $loader;
- private $definition;
-
- private $typeStrategy;
- private $arrayStrategy;
-
- public function __construct(AnnotationComplexTypeLoader $loader, ServiceDefinition $definition)
- {
- $this->loader = $loader;
- $this->definition = $definition;
- }
-
- /**
- * Method accepts the current WSDL context file.
- *
- * @param \Zend\Soap\Wsdl $context
- */
- public function setContext(BaseWsdl $context)
- {
- $this->context = $context;
-
- return $this;
- }
-
- /**
- * Create a complex type based on a strategy
- *
- * @param string $type
- *
- * @return string XSD type
- *
- * @throws \Zend\Soap\WsdlException
- */
- public function addComplexType($type)
- {
- if (!$this->context) {
- throw new \LogicException(sprintf('Cannot add complex type "%s", no context is set for this composite strategy.', $type));
- }
-
- $strategy = String::endsWith($type, '[]') ? $this->getArrayStrategy() : $this->getTypeStrategy();
-
- return $strategy->addComplexType($type);
- }
-
- private function getArrayStrategy()
- {
- if (!$this->arrayStrategy) {
- $this->arrayStrategy = new ArrayOfTypeSequence();
- $this->arrayStrategy->setContext($this->context);
- }
-
- return $this->arrayStrategy;
- }
-
- private function getTypeStrategy()
- {
- if (!$this->typeStrategy) {
- $this->typeStrategy = new ComplexType($this->loader, $this->definition);
- $this->typeStrategy->setContext($this->context);
- }
-
- return $this->typeStrategy;
- }
-}
\ No newline at end of file
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Header.php b/src/BeSimple/SoapBundle/ServiceDefinition/Header.php
deleted file mode 100644
index 53cc4cf..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Header.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition;
-
-class Header
-{
- private $name;
- private $type;
-
- public function __construct($name = null, Type $type = null)
- {
- $this->setName($name);
- $this->setType($type);
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function setName($name)
- {
- $this->name = $name;
- }
-
- public function getType()
- {
- return $this->type;
- }
-
- public function setType($type)
- {
- $this->type = $type;
- }
-}
\ No newline at end of file
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php
index 2ce9db4..2a5bd12 100644
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php
@@ -1,7 +1,7 @@
* (c) Francis Besset
@@ -14,6 +14,8 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Loader;
use BeSimple\SoapBundle\ServiceDefinition as Definition;
use BeSimple\SoapBundle\ServiceDefinition\Annotation;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
use Doctrine\Common\Annotations\Reader;
@@ -26,19 +28,23 @@ use Symfony\Component\Config\Loader\LoaderResolverInterface;
* Based on \Symfony\Component\Routing\Loader\AnnotationClassLoader
*
* @author Christian Kerl
+ * @author Francis Besset
*/
class AnnotationClassLoader extends Loader
{
protected $reader;
+ protected $typeRepository;
+
/**
* Constructor.
*
* @param \Doctrine\Common\Annotations\Reader $reader
*/
- public function __construct(Reader $reader)
+ public function __construct(Reader $reader, TypeRepository $typeRepository)
{
$this->reader = $reader;
+ $this->typeRepository = $typeRepository;
}
/**
@@ -58,39 +64,26 @@ class AnnotationClassLoader extends Loader
}
$class = new \ReflectionClass($class);
- $definition = new Definition\ServiceDefinition();
+ $definition = new Definition\Definition($this->typeRepository);
- $serviceMethodHeaders = array();
+ $sharedHeaders = array();
foreach ($this->reader->getClassAnnotations($class) as $annotation) {
if ($annotation instanceof Annotation\Header) {
- $serviceMethodHeaders[$annotation->getValue()] = $annotation;
+ $sharedHeaders[$annotation->getValue()] = $this->loadType($annotation->getPhpType());
}
}
foreach ($class->getMethods() as $method) {
- $serviceArguments =
- $serviceHeaders = array();
+ $serviceHeaders = $sharedHeaders;
+ $serviceArguments = array();
$serviceMethod =
$serviceReturn = null;
- foreach ($serviceMethodHeaders as $annotation) {
- $serviceHeaders[$annotation->getValue()] = new Definition\Header(
- $annotation->getValue(),
- $this->getArgumentType($method, $annotation)
- );
- }
-
foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
if ($annotation instanceof Annotation\Header) {
- $serviceHeaders[$annotation->getValue()] = new Definition\Header(
- $annotation->getValue(),
- $this->getArgumentType($method, $annotation)
- );
+ $serviceHeaders[$annotation->getValue()] = $this->loadType($annotation->getPhpType());
} elseif ($annotation instanceof Annotation\Param) {
- $serviceArguments[] = new Definition\Argument(
- $annotation->getValue(),
- $this->getArgumentType($method, $annotation)
- );
+ $serviceArguments[$annotation->getValue()] = $this->loadType($annotation->getPhpType());
} elseif ($annotation instanceof Annotation\Method) {
if ($serviceMethod) {
throw new \LogicException(sprintf('@Soap\Method defined twice for "%s".', $method->getName()));
@@ -98,6 +91,7 @@ class AnnotationClassLoader extends Loader
$serviceMethod = new Definition\Method(
$annotation->getValue(),
+ $this->typeRepository,
$this->getController($class, $method, $annotation)
);
} elseif ($annotation instanceof Annotation\Result) {
@@ -105,7 +99,7 @@ class AnnotationClassLoader extends Loader
throw new \LogicException(sprintf('@Soap\Result defined twice for "%s".', $method->getName()));
}
- $serviceReturn = new Definition\Type($annotation->getPhpType(), $annotation->getXmlType());
+ $serviceReturn = $annotation->getPhpType();
}
}
@@ -114,16 +108,21 @@ class AnnotationClassLoader extends Loader
}
if ($serviceMethod) {
- $serviceMethod->setArguments($serviceArguments);
- $serviceMethod->setHeaders($serviceHeaders);
+ foreach ($serviceHeaders as $name => $type) {
+ $serviceMethod->addHeader($name, $type);
+ }
+
+ foreach ($serviceArguments as $name => $type) {
+ $serviceMethod->addInput($name, $type);
+ }
if (!$serviceReturn) {
throw new \LogicException(sprintf('@Soap\Result non-existent for "%s".', $method->getName()));
}
- $serviceMethod->setReturn($serviceReturn);
+ $serviceMethod->setOutput($this->loadType($serviceReturn));
- $definition->getMethods()->add($serviceMethod);
+ $definition->addMethod($serviceMethod);
}
}
@@ -169,6 +168,30 @@ class AnnotationClassLoader extends Loader
return new Definition\Type($phpType, $xmlType);
}
+ private function loadType($phpType)
+ {
+ if (false !== $arrayOf = $this->typeRepository->getArrayOf($phpType)) {
+ $this->loadType($arrayOf);
+ }
+
+ if (!$this->typeRepository->hasType($phpType)) {
+ $complexTypeResolver = $this->resolve($phpType, 'annotation_complextype');
+ if (!$complexTypeResolver) {
+ throw new Exception();
+ }
+
+ $loaded = $complexTypeResolver->load($phpType);
+ $complexType = new ComplexType($phpType, $loaded['alias']);
+ foreach ($loaded['properties'] as $name => $property) {
+ $complexType->add($name, $this->loadType($property->getValue()), $property->isNillable());
+ }
+
+ $this->typeRepository->addComplexType($complexType);
+ }
+
+ return $phpType;
+ }
+
/**
* Returns true if this class supports the given resource.
*
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php
index 987cf5d..1d3e095 100644
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php
@@ -1,7 +1,7 @@
* (c) Francis Besset
@@ -65,4 +65,17 @@ class AnnotationComplexTypeLoader extends AnnotationClassLoader
return $annotations;
}
+
+ /**
+ * Returns true if this class supports the given resource.
+ *
+ * @param mixed $resource A resource
+ * @param string $type The resource type
+ *
+ * @return Boolean True if this class supports the given resource, false otherwise
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && class_exists($resource) && 'annotation_complextype' === $type;
+ }
}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationFileLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationFileLoader.php
index a7841fa..8e362c3 100644
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationFileLoader.php
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationFileLoader.php
@@ -1,7 +1,7 @@
* (c) Francis Besset
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/XmlFileLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/XmlFileLoader.php
deleted file mode 100644
index 2039002..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/XmlFileLoader.php
+++ /dev/null
@@ -1,145 +0,0 @@
-
- * (c) Francis Besset
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Loader;
-
-use BeSimple\SoapBundle\ServiceDefinition\Argument;
-use BeSimple\SoapBundle\ServiceDefinition\Header;
-use BeSimple\SoapBundle\ServiceDefinition\Method;
-use BeSimple\SoapBundle\ServiceDefinition\Type;
-use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
-
-use Symfony\Component\Config\Loader\FileLoader;
-
-class XmlFileLoader extends FileLoader
-{
- public function supports($resource, $type = null)
- {
- return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
- }
-
- public function load($file, $type = null)
- {
- $path = $this->locator->locate($file);
- $xml = $this->parseFile($path);
-
- $definition = new ServiceDefinition();
- $definition->setName((string) $xml['name']);
- $definition->setNamespace((string) $xml['namespace']);
-
- foreach($xml->header as $header) {
- $definition->getHeaders()->add($this->parseHeader($header));
- }
-
- foreach($xml->method as $method) {
- $definition->getMethods()->add($this->parseMethod($method));
- }
-
- return $definition;
- }
-
- /**
- * @param \SimpleXMLElement $node
- *
- * @return \BeSimple\SoapBundle\ServiceDefinition\Header
- */
- protected function parseHeader(\SimpleXMLElement $node)
- {
- return new Header((string)$node['name'], $this->parseType($node->type));
- }
-
- /**
- * @param \SimpleXMLElement $node
- *
- * @return \BeSimple\SoapBundle\ServiceDefinition\Method
- */
- protected function parseMethod(\SimpleXMLElement $node)
- {
- $method = new Method((string)$node['name'], (string)$node['controller']);
-
- foreach($node->argument as $argument) {
- $method->getArguments()->add($this->parseArgument($argument));
- }
-
- $method->setReturn($this->parseType($node->return->type));
-
- return $method;
- }
-
- /**
- * @param \SimpleXMLElement $node
- *
- * @return \BeSimple\SoapBundle\ServiceDefinition\Argument
- */
- protected function parseArgument(\SimpleXMLElement $node)
- {
- $argument = new Argument((string)$node['name'], $this->parseType($node->type));
-
- return $argument;
- }
-
- /**
- * @param \SimpleXMLElement $node
- *
- * @return \BeSimple\SoapBundle\ServiceDefinition\Type
- */
- protected function parseType(\SimpleXMLElement $node)
- {
- $namespaces = $node->getDocNamespaces(true);
- $qname = explode(':', $node['xml-type'], 2);
- $xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]);
-
- return new Type((string)$node['php-type'], $xmlType, (string)$node['converter']);
- }
-
- /**
- * @param string $file
- *
- * @return \SimpleXMLElement
- */
- protected function parseFile($file)
- {
- $dom = new \DOMDocument();
- libxml_use_internal_errors(true);
- if (!$dom->load($file, LIBXML_COMPACT)) {
- throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors()));
- }
- if (!$dom->schemaValidate(__DIR__.'/schema/servicedefinition-1.0.xsd')) {
- throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors()));
- }
- $dom->validateOnParse = true;
- $dom->normalizeDocument();
- libxml_use_internal_errors(false);
-
- return simplexml_import_dom($dom);
- }
-
- protected function getXmlErrors()
- {
- $errors = array();
- foreach (libxml_get_errors() as $error) {
- $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
- LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
- $error->code,
- trim($error->message),
- $error->file ? $error->file : 'n/a',
- $error->line,
- $error->column
- );
- }
-
- libxml_clear_errors();
- libxml_use_internal_errors(false);
-
- return $errors;
- }
-}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Method.php b/src/BeSimple/SoapBundle/ServiceDefinition/Method.php
index a03053f..9d3f593 100644
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Method.php
+++ b/src/BeSimple/SoapBundle/ServiceDefinition/Method.php
@@ -1,8 +1,10 @@
+ * (c) Francis Besset
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
@@ -10,36 +12,22 @@
namespace BeSimple\SoapBundle\ServiceDefinition;
-use BeSimple\SoapBundle\Util\Collection;
+use BeSimple\SoapCommon\Definition\Method as BaseMethod;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
-class Method
+/**
+ * @author Christian Kerl
+ * @author Francis Besset
+ */
+class Method extends BaseMethod
{
- private $name;
private $controller;
- private $arguments;
- private $headers;
- private $return;
- public function __construct($name = null, $controller = null, array $headers = array(), array $arguments = array(), Type $return = null)
+ public function __construct($name, TypeRepository $typeRepository, $controller)
{
- $this->setName($name);
- $this->setController($controller);
- $this->setHeaders($headers);
- $this->setArguments($arguments);
+ parent::__construct($name, $typeRepository);
- if ($return) {
- $this->setReturn($return);
- }
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function setName($name)
- {
- $this->name = $name;
+ $this->controller = $controller;
}
public function getController()
@@ -47,40 +35,8 @@ class Method
return $this->controller;
}
- public function setController($controller)
+ public function getVersions()
{
- $this->controller = $controller;
+ return array(\SOAP_1_1);
}
-
- public function getHeaders()
- {
- return $this->headers;
- }
-
- public function setHeaders(array $headers)
- {
- $this->headers = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Header');
- $this->headers->addAll($headers);
- }
-
- public function getArguments()
- {
- return $this->arguments;
- }
-
- public function setArguments(array $arguments)
- {
- $this->arguments = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Argument');
- $this->arguments->addAll($arguments);
- }
-
- public function getReturn()
- {
- return $this->return;
- }
-
- public function setReturn(Type $return)
- {
- $this->return = $return;
- }
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php b/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php
deleted file mode 100644
index 8cfe302..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php
+++ /dev/null
@@ -1,151 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition;
-
-use BeSimple\SoapBundle\Util\Collection;
-use BeSimple\SoapCommon\Classmap;
-
-class ServiceDefinition
-{
- /**
- * @var string
- */
- private $name;
-
- /**
- * @var string
- */
- private $namespace;
-
- /**
- * @var \BeSimple\SoapBundle\Util\Collection
- */
- private $methods;
-
- /**
- * @var \BeSimple\SoapCommon\Classmap
- */
- private $classmap;
-
- private $complexTypes = array();
-
- public function __construct($name = null, $namespace = null, array $methods = array(), Classmap $classmap = null)
- {
- $this->setName($name);
- $this->setNamespace($namespace);
-
- $this->methods = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Method');
- $this->setMethods($methods);
-
- $this->classmap = $classmap;
- }
-
- /**
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
-
- /**
- * @return string
- */
- public function getNamespace()
- {
- return $this->namespace;
- }
-
- /**
- * @param string $namespace
- */
- public function setNamespace($namespace)
- {
- $this->namespace = $namespace;
- }
-
- /**
- * @return \BeSimple\SoapBundle\Util\Collection
- */
- public function getMethods()
- {
- return $this->methods;
- }
-
- /**
- * @param array $methods
- */
- public function setMethods(array $methods)
- {
- $this->methods->addAll($methods);
- }
-
- /**
- * @return array
- */
- public function getAllTypes()
- {
- $types = array();
-
- foreach ($this->methods as $method) {
- foreach ($method->getArguments() as $argument) {
- $types[] = $argument->getType();
- }
-
- foreach ($method->getHeaders() as $header) {
- $types[] = $header->getType();
- }
-
- $types[] = $method->getReturn();
- }
-
- return $types;
- }
-
- public function getClassmap()
- {
- return $this->classmap ?: array();
- }
-
- public function setClassmap(Classmap $classmap)
- {
- $this->classmap = $classmap;
- }
-
- public function hasDefinitionComplexType($type)
- {
- return isset($this->complexTypes[$type]);
- }
-
- public function addDefinitionComplexType($type, array $definition)
- {
- if ($this->hasDefinitionComplexType($type)) {
- return false;
- }
-
- $this->complexTypes[$type] = $definition;
-
- return true;
- }
-
- public function getDefinitionComplexTypes()
- {
- return $this->complexTypes;
- }
-}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php
deleted file mode 100644
index d38d871..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php
+++ /dev/null
@@ -1,89 +0,0 @@
-
- * (c) Francis Besset
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition\Strategy;
-
-use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader;
-use Zend\Soap\Wsdl;
-use Zend\Soap\Wsdl\ComplexTypeStrategy\AbstractComplexTypeStrategy;
-
-/**
- * @author Francis Besset
- */
-class ComplexType extends AbstractComplexTypeStrategy
-{
- private $loader;
- private $definition;
-
- public function __construct(AnnotationComplexTypeLoader $loader, $definition)
- {
- $this->loader = $loader;
- $this->definition = $definition;
- }
-
- /**
- * Add a complex type by recursivly using all the class properties fetched via Reflection.
- *
- * @param string $type Name of the class to be specified
- * @return string XSD Type for the given PHP type
- */
- public function addComplexType($classname)
- {
- $classmap = $this->definition->getClassmap();
- if ($classmap->hasByClassname($classname)) {
- return 'tns:'.$classmap->getByClassname($classname);
- }
-
- if (!$this->loader->supports($classname)) {
- throw new \InvalidArgumentException(sprintf('Cannot add ComplexType "%s" because it is not an object or the class could not be found.', $classname));
- }
-
- $definitionComplexType = $this->loader->load($classname);
- $classnameAlias = isset($definitionComplexType['alias']) ? $definitionComplexType['alias'] : $classname;
-
- $type = $this->getContext()->translateType($classnameAlias);
- $xmlType = 'tns:'.$type;
-
- // Register type here to avoid recursion
- $classmap->add($type, $classname);
- $this->addXmlDefinition($definitionComplexType, $classname, $type);
-
- return $xmlType;
- }
-
- private function addXmlDefinition(array $definitionComplexType, $classname, $type)
- {
- $dom = $this->getContext()->toDomDocument();
- $complexType = $dom->createElement('xsd:complexType');
- $complexType->setAttribute('name', $type);
-
- $all = $dom->createElement('xsd:all');
-
- $elements = array();
- foreach ($definitionComplexType['properties'] as $property) {
- $element = $dom->createElement('xsd:element');
- $element->setAttribute('name', $property->getName());
- $element->setAttribute('type', $this->getContext()->getType($property->getValue()));
-
- if ($property->isNillable()) {
- $element->setAttribute('nillable', 'true');
- }
-
- $all->appendChild($element);
- }
-
- $complexType->appendChild($all);
- $this->getContext()->getSchema()->appendChild($complexType);
-
- $this->definition->addDefinitionComplexType($classname, $definitionComplexType);
- }
-}
diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Type.php b/src/BeSimple/SoapBundle/ServiceDefinition/Type.php
deleted file mode 100644
index 2855689..0000000
--- a/src/BeSimple/SoapBundle/ServiceDefinition/Type.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
-
-namespace BeSimple\SoapBundle\ServiceDefinition;
-
-class Type
-{
- private $phpType;
- private $xmlType;
- private $converter;
-
- public function __construct($phpType = null, $xmlType = null, $converter = null)
- {
- $this->setPhpType($phpType);
- $this->setXmlType($xmlType);
- $this->setConverter($converter);
- }
-
- public function getPhpType()
- {
- return $this->phpType;
- }
-
- public function setPhpType($phpType)
- {
- $phpType = $phpType;
- if ($phpType[0] == '\\') {
- $phpType = substr($phpType, 1);
- }
-
- $this->phpType = $phpType;
- }
-
- public function getXmlType()
- {
- return $this->xmlType;
- }
-
- public function setXmlType($xmlType)
- {
- $this->xmlType = $xmlType;
- }
-
- public function getConverter()
- {
- return $this->converter;
- }
-
- public function setConverter($converter)
- {
- $this->converter = $converter;
- }
-}
\ No newline at end of file
diff --git a/src/BeSimple/SoapBundle/WebServiceContext.php b/src/BeSimple/SoapBundle/WebServiceContext.php
index 6e3249a..694cfc5 100644
--- a/src/BeSimple/SoapBundle/WebServiceContext.php
+++ b/src/BeSimple/SoapBundle/WebServiceContext.php
@@ -3,6 +3,7 @@
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl
+ * (c) Francis Besset
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
@@ -10,13 +11,12 @@
namespace BeSimple\SoapBundle;
-use BeSimple\SoapBundle\Converter\TypeRepository;
use BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface;
use BeSimple\SoapBundle\ServiceBinding\ServiceBinder;
use BeSimple\SoapBundle\ServiceDefinition\Dumper\DumperInterface;
-use BeSimple\SoapCommon\Classmap;
use BeSimple\SoapCommon\Converter\TypeConverterCollection;
+use BeSimple\SoapWsdl\Dumper\Dumper;
use BeSimple\SoapServer\SoapServerBuilder;
use Symfony\Component\Config\ConfigCache;
@@ -26,43 +26,31 @@ use Symfony\Component\Config\Loader\LoaderInterface;
* WebServiceContext.
*
* @author Christian Kerl
+ * @author Francis Besset
*/
class WebServiceContext
{
- private $classmap;
-
- private $typeRepository;
private $converterRepository;
- private $wsdlFileDumper;
-
private $options;
private $serviceDefinition;
private $serviceBinder;
private $serverBuilder;
- public function __construct(LoaderInterface $loader, DumperInterface $dumper, Classmap $classmap, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options)
+ public function __construct(LoaderInterface $loader, TypeConverterCollection $converters, array $options)
{
- $this->loader = $loader;
- $this->wsdlFileDumper = $dumper;
-
- $this->classmap = $classmap;
-
- $this->typeRepository = $typeRepository;
- $this->converters = $converters;
-
- // Issue #6: keep the debug because the cache is invalid
- $options['debug'] = true;
- $this->options = $options;
+ $this->loader = $loader;
+ $this->converters = $converters;
+ $this->options = $options;
}
public function getServiceDefinition()
{
if (null === $this->serviceDefinition) {
- $cacheDefinition = new ConfigCache(sprintf('%s/%s.definition.php', $this->options['cache_dir'], $this->options['name']), $this->options['debug']);
- if ($cacheDefinition->isFresh()) {
- $this->serviceDefinition = include (string) $cacheDefinition;
+ $cache = new ConfigCache(sprintf('%s/%s.definition.php', $this->options['cache_dir'], $this->options['name']), $this->options['debug']);
+ if ($cache->isFresh()) {
+ $this->serviceDefinition = include (string) $cache;
} else {
if (!$this->loader->supports($this->options['resource'], $this->options['resource_type'])) {
throw new \LogicException(sprintf('Cannot load "%s" (%s)', $this->options['resource'], $this->options['resource_type']));
@@ -72,10 +60,7 @@ class WebServiceContext
$this->serviceDefinition->setName($this->options['name']);
$this->serviceDefinition->setNamespace($this->options['namespace']);
- $this->serviceDefinition->setClassmap($this->classmap);
- $this->classmap = null;
-
- $this->typeRepository->fixTypeInformation($this->serviceDefinition);
+ $cache->write('serviceDefinition), true).');');
}
}
@@ -89,19 +74,21 @@ class WebServiceContext
public function getWsdlFile($endpoint = null)
{
- $file = sprintf('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint));
- $cacheWsdl = new ConfigCache($file, $this->options['debug']);
+ $file = sprintf ('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint));
+ $cache = new ConfigCache($file, $this->options['debug']);
- if(!$cacheWsdl->isFresh()) {
- $serviceDefinition = $this->getServiceDefinition();
+ if(!$cache->isFresh()) {
+ $definition = $this->getServiceDefinition();
- $cacheWsdl->write($this->wsdlFileDumper->dumpServiceDefinition($serviceDefinition, $endpoint));
+ if ($endpoint) {
+ $definition->setOption('location', $endpoint);
+ }
- $cacheDefinition = new ConfigCache(sprintf('%s/%s.definition.php', $this->options['cache_dir'], $this->options['name']), $this->options['debug']);
- $cacheDefinition->write('write($dumper->dump());
}
- return (string) $cacheWsdl;
+ return (string) $cache;
}
public function getServiceBinder()
@@ -123,7 +110,7 @@ class WebServiceContext
if (null === $this->serverBuilder) {
$this->serverBuilder = SoapServerBuilder::createWithDefaults()
->withWsdl($this->getWsdlFile())
- ->withClassmap($this->getServiceDefinition()->getClassmap())
+ ->withClassmap($this->getServiceDefinition()->getTypeRepository()->getClassmap())
->withTypeConverters($this->converters)
;
diff --git a/src/BeSimple/SoapCommon/Definition/Definition.php b/src/BeSimple/SoapCommon/Definition/Definition.php
new file mode 100644
index 0000000..7d9f742
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Definition.php
@@ -0,0 +1,148 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition;
+
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+
+/**
+ * @author Francis Besset
+ */
+class Definition
+{
+ protected $name;
+ protected $namespace;
+
+ protected $typeRepository;
+
+ protected $options;
+ protected $methods;
+
+ public function __construct($name, $namespace, TypeRepository $typeRepository, array $options = array())
+ {
+ $this->name = $name;
+ $this->namespace = $namespace;
+ $this->methods = array();
+
+ $this->typeRepository = $typeRepository;
+
+ $this->setOptions($options);
+ }
+
+ public function setOptions(array $options)
+ {
+ $this->options = array(
+ 'version' => \SOAP_1_1,
+ 'style' => \SOAP_RPC,
+ 'use' => \SOAP_LITERAL,
+ 'location' => null,
+ );
+
+ $invalid = array();
+ foreach ($options as $key => $value) {
+ if (array_key_exists($key, $this->options)) {
+ $this->options[$key] = $value;
+ } else {
+ $invalid[] = $key;
+ }
+ }
+
+ if ($invalid) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the following options: "%s"', implode('", "', $invalid)));
+ }
+
+ return $this;
+ }
+
+ public function setOption($key, $value)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the "%s" option.', $key));
+ }
+
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ public function getOption($key)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the "%s" option.', $key));
+ }
+
+ return $this->options[$key];
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getNamespace()
+ {
+ return $this->namespace;
+ }
+
+ public function getType($phpType)
+ {
+ return $this->types[$phpType];
+ }
+
+ public function addType($phpType, $xmlType)
+ {
+ if (isset($$this->types[$phpType])) {
+ throw new \Exception();
+ }
+
+ $this->types[$phpType] = $xmlType;
+ }
+
+ public function getMessages()
+ {
+ $messages = array();
+ foreach ($this->methods as $method) {
+ $messages[] = $method->getHeaders();
+ $messages[] = $method->getInput();
+ $messages[] = $method->getOutput();
+ }
+
+ return $messages;
+ }
+
+ public function getMethod($name, $default = null)
+ {
+ return isset($this->methods[$name]) ? $this->methods[$name] : $default;
+ }
+
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ public function addMethod(Method $method)
+ {
+ $name = $method->getName();
+ if (isset($this->methods[$name])) {
+ throw new \Exception(sprintf('The method "%s" already exists', $name));
+ }
+
+ $this->methods[$name] = $method;
+
+ return $method;
+ }
+
+ public function getTypeRepository()
+ {
+ return $this->typeRepository;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Message.php b/src/BeSimple/SoapCommon/Definition/Message.php
new file mode 100644
index 0000000..caa78fe
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Message.php
@@ -0,0 +1,61 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition;
+
+use BeSimple\SoapCommon\Definition\Type\TypeInterface;
+
+/**
+ * @author Francis Besset
+ */
+class Message
+{
+ protected $name;
+ protected $parts;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ $this->parts = array();
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function all()
+ {
+ return $this->parts;
+ }
+
+ public function get($name, $default = null)
+ {
+ return isset($this->parts[$name]) ? $this->parts[$name] : $default;
+ }
+
+ public function isEmpty()
+ {
+ return 0 === count($this->parts) ? true : false;
+ }
+
+ public function add($name, $phpType, $nillable = false)
+ {
+ if ($phpType instanceof TypeInterface) {
+ $phpType = $phpType->getPhpType();
+ }
+
+ $this->parts[$name] = new Part($name, $phpType, $nillable);
+
+ return $this;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Method.php b/src/BeSimple/SoapCommon/Definition/Method.php
new file mode 100644
index 0000000..a592e6a
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Method.php
@@ -0,0 +1,98 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition;
+
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+
+/**
+ * @author Francis Besset
+ */
+class Method
+{
+ private $name;
+
+ private $headers;
+ private $input;
+ private $output;
+ private $fault;
+
+ public function __construct($name, TypeRepository $typeRepository)
+ {
+ $this->name = $name;
+
+ $this->headers = new Message($name.'Header', $typeRepository);
+ $this->input = new Message($name.'Request', $typeRepository);
+ $this->output = new Message($name.'Response', $typeRepository);
+ $this->fault = new Message($name.'Fault', $typeRepository);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ public function getVersions()
+ {
+ return array(\SOAP_1_1, \SOAP_1_2);
+ }
+
+ public function getUse()
+ {
+ return \SOAP_LITERAL;
+ }
+
+ public function addHeader($name, $type)
+ {
+ $this->headers->add($name, $type);
+ }
+
+ public function addInput($name, $type)
+ {
+ $this->input->add($name, $type);
+ }
+
+ public function setOutput($type)
+ {
+ $this->output->add('return', $type);
+ }
+
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ public function getHeader($name, $default = null)
+ {
+ return $this->headers->get($name, $default);
+ }
+
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ public function getFault()
+ {
+ return $this->fault;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Part.php b/src/BeSimple/SoapCommon/Definition/Part.php
new file mode 100644
index 0000000..317f046
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Part.php
@@ -0,0 +1,55 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition;
+
+/**
+ * @author Francis Besset
+ */
+class Part
+{
+ protected $name;
+ protected $type;
+ protected $nillable;
+
+ public function __construct($name, $type, $nillable = false)
+ {
+ $this->name = $name;
+ $this->type = $type;
+ $this->setNillable($nillable);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function setType($type)
+ {
+ $this->type = $type;
+ }
+
+ public function isNillable()
+ {
+ return $this->nillable;
+ }
+
+ public function setNillable($nillable)
+ {
+ $this->nillable = (boolean) $nillable;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Type/ArrayOfType.php b/src/BeSimple/SoapCommon/Definition/Type/ArrayOfType.php
new file mode 100644
index 0000000..6f05215
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Type/ArrayOfType.php
@@ -0,0 +1,30 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition\Type;
+
+/**
+ * @author Francis Besset
+ */
+class ArrayOfType extends ComplexType
+{
+ public function __construct($phpType, $arrayOf, $xmlTypeOf)
+ {
+ if ($arrayOf instanceof TypeInterface) {
+ $arrayOf = $arrayOf->getPhpType();
+ }
+
+ parent::__construct($phpType, 'ArrayOf'.ucfirst($xmlTypeOf ?: $arrayOf));
+
+ $this->add('item', $arrayOf);
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Type/ComplexType.php b/src/BeSimple/SoapCommon/Definition/Type/ComplexType.php
new file mode 100644
index 0000000..99d6d3e
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Type/ComplexType.php
@@ -0,0 +1,39 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition\Type;
+
+use BeSimple\SoapCommon\Definition\Message;
+
+/**
+ * @author Francis Besset
+ */
+class ComplexType extends Message implements TypeInterface
+{
+ public function __construct($phpType, $xmlType)
+ {
+ parent::__construct($xmlType);
+
+ $this->phpType = $phpType;
+ $this->xmlType = $xmlType;
+ }
+
+ public function getPhpType()
+ {
+ return $this->phpType;
+ }
+
+ public function getXmlType()
+ {
+ return $this->xmlType;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Type/Type.php b/src/BeSimple/SoapCommon/Definition/Type/Type.php
new file mode 100644
index 0000000..7911c5a
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Type/Type.php
@@ -0,0 +1,38 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition\Type;
+
+/**
+ * @author Francis Besset
+ */
+class Type implements TypeInterface
+{
+ protected $phpType;
+ protected $xmlType;
+
+ public function __construct($phpType, $xmlType)
+ {
+ $this->phpType = $phpType;
+ $this->xmlType = $xmlType;
+ }
+
+ public function getPhpType()
+ {
+ return $this->phpType;
+ }
+
+ public function getXmlType()
+ {
+ return $this->xmlType;
+ }
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Type/TypeInterface.php b/src/BeSimple/SoapCommon/Definition/Type/TypeInterface.php
new file mode 100644
index 0000000..7263353
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Type/TypeInterface.php
@@ -0,0 +1,23 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition\Type;
+
+/**
+ * @author Francis Besset
+ */
+interface TypeInterface
+{
+ public function getPhpType();
+
+ public function getXmlType();
+}
diff --git a/src/BeSimple/SoapCommon/Definition/Type/TypeRepository.php b/src/BeSimple/SoapCommon/Definition/Type/TypeRepository.php
new file mode 100644
index 0000000..38d0f30
--- /dev/null
+++ b/src/BeSimple/SoapCommon/Definition/Type/TypeRepository.php
@@ -0,0 +1,135 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon\Definition\Type;
+
+use BeSimple\SoapCommon\Classmap;
+
+/**
+ * @author Christian Kerl
+ * @author Francis Besset
+ */
+class TypeRepository
+{
+ const ARRAY_SUFFIX = '[]';
+
+ protected $xmlNamespaces = array();
+ protected $types = array();
+
+ protected $classmap;
+
+ public function __construct(Classmap $classmap = null)
+ {
+ $this->classmap = $classmap;
+ }
+
+ public function getXmlNamespaces()
+ {
+ return $this->xmlNamespaces;
+ }
+ public function getXmlNamespace($prefix)
+ {
+ return $this->xmlNamespaces[$prefix];
+ }
+
+ public function addXmlNamespace($prefix, $url)
+ {
+ $this->xmlNamespaces[$prefix] = $url;
+ }
+
+ public function getComplexTypes()
+ {
+ $types = array();
+ foreach ($this->types as $type) {
+ if ($type instanceof ComplexType) {
+ $types[] = $type;
+ }
+ }
+
+ return $types;
+ }
+
+ public function getType($phpType)
+ {
+ if (!$this->hasType($phpType)) {
+ throw new \Exception();
+ }
+
+ return $this->types[$phpType];
+ }
+
+ public function addType($phpType, $xmlType)
+ {
+ return $this->types[$phpType] = $xmlType;
+ }
+
+ public function addComplexType(ComplexType $type)
+ {
+ $phpType = $type->getPhpType();
+
+ $this->types[$phpType] = $type;
+ $this->addClassmap($type->getXmlType(), $phpType);
+ }
+
+ public function hasType($type)
+ {
+ if ($type instanceof TypeInterface) {
+ $phpType = $type->getPhpType();
+
+ return !(!$this->hasType($phpType) || $type !== $this->getType($phpType));
+ }
+
+ if (isset($this->types[$type])) {
+ return true;
+ }
+
+ if (false !== $arrayOf = $this->getArrayOf($type)) {
+ if ($this->hasType($arrayOf)) {
+ $xmlTypeOf = null;
+ $arrayOfType = $this->getType($arrayOf);
+ if ($arrayOfType instanceof ComplexType) {
+ $xmlTypeOf = $arrayOfType->getXmlType();
+ }
+
+ $arrayType = new ArrayOfType($type, $arrayOf, $xmlTypeOf);
+ $this->addType($type, $arrayType);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function getArrayOf($arrayType)
+ {
+ if (!preg_match('#(.*)'.preg_quote(static::ARRAY_SUFFIX, '#').'$#', $arrayType, $match)) {
+ return false;
+ }
+
+ return $match[1];
+ }
+
+ public function getClassmap()
+ {
+ return $this->classmap;
+ }
+
+ protected function addClassmap($xmlType, $phpType)
+ {
+ if (!$this->classmap) {
+ return;
+ }
+
+ $this->classmap->add($xmlType, $phpType);
+ }
+}
diff --git a/src/BeSimple/SoapServer/SoapRequest.php b/src/BeSimple/SoapServer/SoapRequest.php
index 8a03d7a..0964771 100644
--- a/src/BeSimple/SoapServer/SoapRequest.php
+++ b/src/BeSimple/SoapServer/SoapRequest.php
@@ -34,7 +34,7 @@ class SoapRequest extends CommonSoapRequest
{
$content = is_null($content) ? file_get_contents("php://input") : $content;
$location = self::getCurrentUrl();
- $action = $_SERVER[SoapMessage::SOAP_ACTION_HEADER];
+ $action = isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null;
$contentType = $_SERVER[SoapMessage::CONTENT_TYPE_HEADER];
$request = new SoapRequest();
@@ -68,4 +68,4 @@ class SoapRequest extends CommonSoapRequest
$url .= isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
return $url;
}
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapServer/SoapServer.php b/src/BeSimple/SoapServer/SoapServer.php
index ced2ad0..045dcd6 100644
--- a/src/BeSimple/SoapServer/SoapServer.php
+++ b/src/BeSimple/SoapServer/SoapServer.php
@@ -158,4 +158,4 @@ class SoapServer extends \SoapServer
);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/BeSimple/SoapWsdl/Dumper/AbstractVersion.php b/src/BeSimple/SoapWsdl/Dumper/AbstractVersion.php
new file mode 100644
index 0000000..c67c035
--- /dev/null
+++ b/src/BeSimple/SoapWsdl/Dumper/AbstractVersion.php
@@ -0,0 +1,150 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapWsdl\Dumper;
+
+use BeSimple\SoapCommon\Definition\Method;
+
+/**
+ * @author Francis Besset
+ */
+abstract class AbstractVersion implements VersionInterface
+{
+ protected $soapNs;
+
+ protected $typeNs;
+
+ protected $name;
+
+ protected $namespace;
+
+ protected $portTypeName;
+
+ protected $location;
+
+ protected $style;
+
+ protected $transport;
+
+ protected $document;
+
+ protected $bindingNode;
+
+ protected $servicePortNode;
+
+ public function __construct($soapNs, $typeNs, $name, $namespace, $portTypeName, $location, $style = \SOAP_RPC, $transport = 'http://schemas.xmlsoap.org/soap/http')
+ {
+ $this->soapNs = $soapNs;
+ $this->typeNs = $typeNs;
+
+ $this->name = $name;
+ $this->namespace = $namespace;
+ $this->portTypeName = $portTypeName;
+
+ $this->location = $location;
+ $this->style = $style;
+ $this->transport = $transport;
+
+ $this->document = new \DOMDocument('1.0', 'utf-8');
+ }
+
+ public function getBindingNode()
+ {
+ if (!$this->bindingNode) {
+ $this->bindingNode = $this->document->createElement('binding');
+ $this->bindingNode->setAttribute('name', $this->name.'Binding');
+ $this->bindingNode->setAttribute('type', $this->portTypeName);
+
+ $this->addSoapBinding();
+ }
+
+ return $this->bindingNode;
+ }
+
+ public function getServicePortNode()
+ {
+ if (!$this->servicePortNode) {
+ $this->servicePortNode = $this->document->createElement('port');
+ $this->servicePortNode->setAttribute('name', $this->name.'Port');
+ $this->servicePortNode->setAttribute('binding', $this->typeNs.':'.$this->name.'Binding');
+
+ $this->addSoapAddress();
+ }
+
+ return $this->servicePortNode;
+ }
+
+ public function addOperation(Method $method)
+ {
+ $operation = $this->document->createElement('operation');
+ $operation->setAttribute('name', $method->getName());
+
+ $soapOperation = $this->document->createElement($this->soapNs.':operation');
+ $soapOperation->setAttribute('soapAction', $this->namespace.$method->getName());
+ $operation->appendChild($soapOperation);
+
+ $this->getBindingNode()->appendChild($operation);
+
+ $use = \SOAP_LITERAL === $method->getUse() ? 'literal' : 'encoded';
+
+ $input = $this->document->createElement('input');
+ $operation->appendChild($input);
+
+ $soapBody = $this->document->createElement($this->soapNs.':body');
+ $soapBody->setAttribute('use', $use);
+ $soapBody->setAttribute('namespace', $this->namespace);
+ $soapBody->setAttribute('encodingStyle', $this->getEncodingStyle());
+ $input->appendChild($soapBody);
+
+ $headers = $method->getHeaders();
+ if (!$headers->isEmpty()) {
+ foreach ($headers->all() as $part) {
+ $soapHeader = $this->document->createElement($this->soapNs.':header');
+ $soapHeader->setAttribute('part', $part->getName());
+ $soapHeader->setAttribute('message', $this->typeNs.':'.$headers->getName());
+ $soapHeader->setAttribute('use', $use);
+ $soapHeader->setAttribute('namespace', $this->namespace);
+ $soapHeader->setAttribute('encodingStyle', $this->getEncodingStyle());
+ $input->appendChild($soapHeader);
+ }
+ }
+
+ $output = $this->document->createElement('output');
+ $soapBody = $this->document->createElement($this->soapNs.':body');
+ $soapBody->setAttribute('use', $use);
+ $soapBody->setAttribute('namespace', $this->namespace);
+ $soapBody->setAttribute('encodingStyle', $this->getEncodingStyle());
+ $output->appendChild($soapBody);
+ $operation->appendChild($output);
+ }
+
+ protected function addSoapBinding()
+ {
+ $soapBinding = $this->document->createElement($this->soapNs.':binding');
+ $soapBinding->setAttribute('transport', $this->transport);
+ $soapBinding->setAttribute('style', \SOAP_RPC === $this->style ? 'rpc' : 'document');
+
+ $this->bindingNode->appendChild($soapBinding);
+
+ return $soapBinding;
+ }
+
+ protected function addSoapAddress()
+ {
+ $soapAddress = $this->document->createElement($this->soapNs.':address');
+ $soapAddress->setAttribute('location', $this->location);
+
+ $this->servicePortNode->appendChild($soapAddress);
+
+ return $soapAddress;
+ }
+}
diff --git a/src/BeSimple/SoapWsdl/Dumper/Dumper.php b/src/BeSimple/SoapWsdl/Dumper/Dumper.php
new file mode 100644
index 0000000..da5d586
--- /dev/null
+++ b/src/BeSimple/SoapWsdl/Dumper/Dumper.php
@@ -0,0 +1,345 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapWsdl\Dumper;
+
+use BeSimple\SoapCommon\Definition\Definition;
+use BeSimple\SoapCommon\Definition\Method;
+use BeSimple\SoapCommon\Definition\Part;
+use BeSimple\SoapCommon\Definition\Type\ArrayOfType;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+
+/**
+ * @author Francis Besset
+ */
+class Dumper
+{
+ 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_NS = 'soap';
+ const SOAP_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap/';
+
+ const SOAP12_NS = 'soap12';
+ const SOAP12_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';
+
+ protected $definition;
+ protected $options;
+
+ protected $version11;
+ protected $version12;
+
+ protected $document;
+ protected $domDefinitions;
+ protected $domSchema;
+ protected $domService;
+ protected $domPortType;
+
+ public function __construct(Definition $definition, array $options = array())
+ {
+ $this->definition = $definition;
+ $this->document = new \DOMDocument('1.0', 'utf-8');
+
+ $this->setOptions($options);
+ }
+
+ public function setOptions(array $options)
+ {
+ $this->options = array(
+ 'version11_class' => 'BeSimple\\SoapWsdl\\Dumper\\Version11',
+ 'version12_class' => 'BeSimple\\SoapWsdl\\Dumper\\Version12',
+ 'version11_name' => $this->definition->getName(),
+ 'version12_name' => $this->definition->getName().'12',
+ );
+
+ $invalid = array();
+ foreach ($options as $key => $value) {
+ if (array_key_exists($key, $this->options)) {
+ $this->options[$key] = $value;
+ } else {
+ $invalid[] = $key;
+ }
+ }
+
+ if ($invalid) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the following options: "%s"', implode('", "', $invalid)));
+ }
+
+ return $this;
+ }
+
+ public function setOption($key, $value)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the "%s" option.', $key));
+ }
+
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ public function getOption($key)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Definition does not support the "%s" option.', $key));
+ }
+
+ return $this->options[$key];
+ }
+
+ public function dump()
+ {
+ $this->addDefinitions();
+ $this->addMethods();
+ $this->addService();
+
+ foreach (array($this->version11, $this->version12) as $version) {
+ if (!$version) {
+ continue;
+ }
+
+ $this->appendVersion($version);
+ }
+
+ $this->document->formatOutput = true;
+
+ return $this->document->saveXML();
+ }
+
+ protected function appendVersion(VersionInterface $version)
+ {
+ $binding = $version->getBindingNode();
+ $binding = $this->document->importNode($binding, true);
+ $this->domDefinitions->appendChild($binding);
+
+ $servicePort = $version->getServicePortNode();
+ $servicePort = $this->document->importNode($servicePort, true);
+ $this->domService->appendChild($servicePort);
+ }
+
+ protected function addService()
+ {
+ $this->domService = $this->document->createElement('service');
+ $this->domService->setAttribute('name', $this->definition->getName().'Service');
+
+ $this->domDefinitions->appendChild($this->domService);
+
+ return $this->domService;
+ }
+
+ protected function addDefinitions()
+ {
+ $this->domDefinitions = $this->document->createElement('definitions');
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS, static::WSDL_NS_URI);
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::TYPES_NS, $this->definition->getNamespace());
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::SOAP_NS, static::SOAP_NS_URI);
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::SOAP12_NS, static::SOAP12_NS_URI);
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::XSD_NS, static::XSD_NS_URI);
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::SOAP_ENC_NS, static::SOAP_ENC_URI);
+ $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::WSDL_NS, static::WSDL_NS_URI);
+
+ foreach ($this->definition->getTypeRepository()->getXmlNamespaces() as $prefix => $uri) {
+ $this->domDefinitions->setAttributeNs(static::XML_NS_URI, static::XML_NS.':'.$prefix, $uri);
+ }
+
+ $this->domDefinitions->setAttribute('name', $this->definition->getName());
+ $this->domDefinitions->setAttribute('targetNamespace', $this->definition->getNamespace());
+
+ $this->document->appendChild($this->domDefinitions);
+ }
+
+ protected function addMethods()
+ {
+ $this->addPortType();
+ $this->addComplexTypes();
+ $this->addMessages($this->definition->getMessages());
+
+ foreach ($this->definition->getMethods() as $method) {
+ $this->addPortOperation($method);
+
+ foreach ($method->getVersions() as $version) {
+ $this->getVersion($version)->addOperation($method);
+ }
+ }
+ }
+
+ protected function addMessages(array $messages)
+ {
+ foreach ($messages as $message) {
+ if ($message->isEmpty()) {
+ continue;
+ }
+
+ $messageElement = $this->document->createElement('message');
+ $messageElement->setAttribute('name', $message->getName());
+
+ foreach ($message->all() as $part) {
+ $type = $this->definition->getTypeRepository()->getType($part->getType());
+
+ $partElement = $this->document->createElement('part');
+ $partElement->setAttribute('name', $part->getName());
+
+ if ($type instanceof ComplexType) {
+ $partElement->setAttribute('type', static::TYPES_NS.':'.$type->getXmlType());
+ } else {
+ $partElement->setAttribute('type', $type);
+ }
+
+ $messageElement->appendChild($partElement);
+ }
+
+ $this->domDefinitions->appendChild($messageElement);
+ }
+ }
+
+ protected function addComplexTypes()
+ {
+ $types = $this->document->createElement('types');
+ $this->domDefinitions->appendChild($types);
+
+ $this->domSchema = $this->document->createElement(static::XSD_NS.':schema');
+ $this->domSchema->setAttribute('targetNamespace', $this->definition->getNamespace());
+ $types->appendChild($this->domSchema);
+
+ foreach ($this->definition->getTypeRepository()->getComplexTypes() as $type) {
+ $this->addComplexType($type);
+ }
+
+ return $types;
+ }
+
+ protected function addComplexType(ComplexType $type)
+ {
+ $complexType = $this->document->createElement(static::XSD_NS.':complexType');
+ $complexType->setAttribute('name', $type->getXmlType());
+
+ $all = $this->document->createElement(static::XSD_NS.':'.($type instanceof ArrayOfType ? 'sequence' : 'all'));
+ $complexType->appendChild($all);
+
+ foreach ($type->all() as $child) {
+ $childType = $this->definition->getTypeRepository()->getType($child->getType());
+
+ $element = $this->document->createElement(static::XSD_NS.':element');
+ $element->setAttribute('name', $child->getName());
+
+ if ($childType instanceof ComplexType) {
+ $name = $child->getName();
+ if ($childType instanceof ArrayOfType) {
+ $name = $childType->getName();
+ } elseif ($type instanceof ArrayOfType && $childType instanceof ComplexType) {
+ $name = $childType->getXmlType();
+ }
+
+ $element->setAttribute('type', static::TYPES_NS.':'.$name);
+ } else {
+ $element->setAttribute('type', $childType);
+ }
+
+ if ($child->isNillable()) {
+ $element->setAttribute('nillable', 'true');
+ }
+
+ if ($type instanceof ArrayOfType) {
+ $element->setAttribute('minOccurs', 0);
+ $element->setAttribute('maxOccurs', 'unbounded');
+ }
+
+ $all->appendChild($element);
+ }
+
+ $this->domSchema->appendChild($complexType);
+ }
+
+ protected function addPortType()
+ {
+ $this->domPortType = $this->document->createElement('portType');
+ $this->domPortType->setAttribute('name', $this->definition->getName().'PortType');
+
+ $this->domDefinitions->appendChild($this->domPortType);
+ }
+
+ protected function addPortOperation(Method $method)
+ {
+ $operation = $this->document->createElement('operation');
+ $operation->setAttribute('name', $method->getName());
+
+ foreach (array('input' => $method->getInput(), 'output' => $method->getOutput(), 'fault' => $method->getFault()) as $type => $message) {
+ if ($message->isEmpty()) {
+ continue;
+ }
+
+ $node = $this->document->createElement($type);
+ $node->setAttribute('message', static::TYPES_NS.':'.$message->getName());
+
+ $operation->appendChild($node);
+ }
+
+ $this->domPortType->appendChild($operation);
+
+ return $operation;
+ }
+
+ protected function getVersion($version)
+ {
+ if (\SOAP_1_2 === $version) {
+ return $this->getVersion12();
+ }
+
+ return $this->getVersion11();
+ }
+
+ protected function getVersion11()
+ {
+ if (!$this->version11) {
+ $this->version11 = new $this->options['version11_class'](
+ static::SOAP_NS,
+ static::TYPES_NS,
+ $this->options['version11_name'],
+ $this->definition->getNamespace(),
+ static::TYPES_NS.':'.$this->definition->getName().'PortType',
+ $this->definition->getOption('location'),
+ $this->definition->getOption('style')
+ );
+ }
+
+ return $this->version11;
+ }
+
+ protected function getVersion12()
+ {
+ if (!$this->version12) {
+ $this->version12 = new $this->options['version12_class'](
+ static::SOAP12_NS,
+ static::TYPES_NS,
+ $this->options['version12_name'],
+ $this->definition->getNamespace(),
+ static::TYPES_NS.':'.$this->definition->getName().'PortType',
+ $this->definition->getOption('location'),
+ $this->definition->getOption('style')
+ );
+ }
+
+ return $this->version12;
+ }
+}
diff --git a/src/BeSimple/SoapWsdl/Dumper/Version11.php b/src/BeSimple/SoapWsdl/Dumper/Version11.php
new file mode 100644
index 0000000..be6d0c8
--- /dev/null
+++ b/src/BeSimple/SoapWsdl/Dumper/Version11.php
@@ -0,0 +1,24 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapWsdl\Dumper;
+
+/**
+ * @author Francis Besset
+ */
+class Version11 extends AbstractVersion
+{
+ public function getEncodingStyle()
+ {
+ return 'http://schemas.xmlsoap.org/soap/encoding/';
+ }
+}
diff --git a/src/BeSimple/SoapWsdl/Dumper/Version12.php b/src/BeSimple/SoapWsdl/Dumper/Version12.php
new file mode 100644
index 0000000..ce65158
--- /dev/null
+++ b/src/BeSimple/SoapWsdl/Dumper/Version12.php
@@ -0,0 +1,24 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapWsdl\Dumper;
+
+/**
+ * @author Francis Besset
+ */
+class Version12 extends AbstractVersion
+{
+ public function getEncodingStyle()
+ {
+ return 'http://www.w3.org/2001/12/soap-encoding';
+ }
+}
diff --git a/src/BeSimple/SoapWsdl/Dumper/VersionInterface.php b/src/BeSimple/SoapWsdl/Dumper/VersionInterface.php
new file mode 100644
index 0000000..fa6b6b8
--- /dev/null
+++ b/src/BeSimple/SoapWsdl/Dumper/VersionInterface.php
@@ -0,0 +1,29 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapWsdl\Dumper;
+
+use BeSimple\SoapCommon\Definition\Method;
+
+/**
+ * @author Francis Besset
+ */
+interface VersionInterface
+{
+ public function getBindingNode();
+
+ public function getServicePortNode();
+
+ public function addOperation(Method $method);
+
+ public function getEncodingStyle();
+}