Skip to content

support WSDL style="document" use="literal-wrapped" (solution: patch) #54

@MichalM1

Description

@MichalM1

Excuse me, that I choose this way throw "Issues" and not "fork & apply my patch". I don't have experience with it, but I do better in future.

It's not pretty, but is functional.
_- repaired configuration parameter: _binding**
- added wrapped parameters nillable support
- added name support for returned value

_SoapBundle_

diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php
index a0b8c51..f0f4e8d 100644
--- a/DependencyInjection/BeSimpleSoapExtension.php
+++ b/DependencyInjection/BeSimpleSoapExtension.php
@@ -22,6 +22,9 @@ use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
 use Symfony\Component\HttpKernel\DependencyInjection\Extension;

+if (!defined('SOAP_LITERAL_WRAPPED')) {
+    define('SOAP_LITERAL_WRAPPED', 3);
+}
 /**
  * BeSimpleSoapExtension.
  *
@@ -35,6 +38,15 @@ class BeSimpleSoapExtension extends Extension
         'rpc-literal'      => 'rpcliteral',
         'document-wrapped' => 'documentwrapped',
     );
+    private $styleMap = [
+        'rpc'      => \SOAP_RPC,
+        'document' => \SOAP_DOCUMENT,
+    ];
+    private $useMap = [
+        'encoded' => \SOAP_ENCODED,
+        'literal' => \SOAP_LITERAL,
+        'wrapped' => \SOAP_LITERAL_WRAPPED,
+    ];

     public function load(array $configs, ContainerBuilder $container)
     {
@@ -152,7 +164,10 @@ class BeSimpleSoapExtension extends Extension

     private function createWebServiceContext(array $config, ContainerBuilder $container)
     {
-        $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']];
+        $bindingSuffix     = $this->bindingConfigToServiceSuffixMap[$config['binding']];
+        list($style, $use) = explode('-', $config['binding']);
+        $config['style']   = $this->styleMap[$style];
+        $config['use']     = $this->useMap[$use];
         unset($config['binding']);

         $contextId  = 'besimple.soap.context.'.$config['name'];
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 9374bff..6cfccd4 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -135,8 +135,15 @@ class Configuration
                             ->scalarNode('binding')
                                 ->defaultValue('document-wrapped')
                                 ->validate()
-                                    ->ifNotInArray(array('rpc-literal', 'document-wrapped'))
-                                    ->thenInvalid("Service binding style has to be either 'rpc-literal' or 'document-wrapped'")
+                                    ->ifNotInArray([ 'rpc-literal', 'document-wrapped' /*, 'rpc-encoded', , 'document-literal'*/ ])
+                                    ->thenInvalid("Service binding style has to be either 'rpc-literal' or 'document-wrapped'!"/*  or 'rpc-encoded' or 'document-literal' */)
+                                ->end()
+                            ->end()
+                            ->scalarNode('version')
+                                ->defaultValue(2)
+                                ->validate()
+                                    ->ifNotInArray([ 1, 2 ])
+                                    ->thenInvalid("Service protocol version has to be either 1 or 2")
                                 ->end()
                             ->end()
                             ->scalarNode('cache_type')
diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml
index 343885c..3f44aa2 100644
--- a/Resources/config/webservice.xml
+++ b/Resources/config/webservice.xml
@@ -69,9 +69,21 @@
         <service id="besimple.soap.type.repository" class="%besimple.soap.type.repository.class%">
             <argument type="service" id="besimple.soap.server.classmap" />
             <call method="addXmlNamespace">
+                <argument>xsi</argument>
+                <argument>http://www.w3.org/2001/XMLSchema-instance</argument>
+            </call>
+            <!--<call method="addXmlNamespace">
                 <argument>xsd</argument>
                 <argument>http://www.w3.org/2001/XMLSchema</argument>
             </call>
+            <call method="addXmlNamespace">
+                <argument>tm</argument>
+                <argument>http://microsoft.com/wsdl/mime/textMatching/</argument>
+            </call>
+            <call method="addXmlNamespace">
+                <argument>mime</argument>
+                <argument>http://schemas.xmlsoap.org/wsdl/mime/</argument>
+            </call>-->
             <call method="addType">
                 <argument>string</argument>
                 <argument>xsd:string</argument>
diff --git a/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.php
new file mode 100644
index 0000000..639c97d
--- /dev/null
+++ b/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace BeSimple\SoapBundle\ServiceBinding;
+
+use BeSimple\SoapBundle\ServiceDefinition\Method;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+/**
+ * Description of DocumentLiteralWrappedRequestHeaderBinder
+ *
+ * @author Michal Mičko <michal.micko@mediaaction.cz>
+ */
+class DocumentLiteralWrappedRequestHeaderMessageBinder extends DocumentLiteralWrappedRequestMessageBinder
+{
+    private $header;
+
+    public function setHeader($header)
+    {
+        $this->header = $header;
+    }
+
+    public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
+    {
+        $this->typeRepository = $typeRepository;
+        $headerDefinition = $messageDefinition->getHeaders()->get($this->header);
+
+        return $this->processType($headerDefinition->getType(), $message);
+    }
+}
diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php
index 5d779b0..e734183 100644
--- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php
+++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php
@@ -11,14 +11,22 @@
 namespace BeSimple\SoapBundle\ServiceBinding;

 use BeSimple\SoapBundle\ServiceDefinition\Method;
+use BeSimple\SoapCommon\Definition\Type\ArrayOfType;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+use BeSimple\SoapCommon\Util\MessageBinder;

 /**
  * @author Christian Kerl <christian-kerl@web.de>
  */
 class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface
 {
-    public function processMessage(Method $messageDefinition, $message)
+    protected $typeRepository;
+
+    public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
     {
+        $this->typeRepository = $typeRepository;
+
         if(count($message) > 1) {
             throw new \InvalidArgumentException();
         }
@@ -26,10 +34,85 @@ class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterfa
         $result  = array();
         $message = $message[0];

-        foreach($messageDefinition->getArguments() as $argument) {
-            $result[$argument->getName()] = $message->{$argument->getName()};
+        foreach($messageDefinition->getInput()->all() as $argument) {
+            $result[$argument->getName()] = $this->processType($argument->getType(), $message->{$argument->getName()});
         }

         return $result;
     }
+
+    protected function processType($phpType, $message)
+    {
+        $isArray = false;
+
+        $type = $this->typeRepository->getType($phpType);
+        if ($type instanceof ArrayOfType) {
+            $isArray = true;
+            $array = array();
+
+            $type = $this->typeRepository->getType($type->get('item')->getType());
+        }
+
+        // @TODO Fix array reference
+        if ($type instanceof ComplexType) {
+            $phpType = $type->getPhpType();
+
+            if ($isArray) {
+                if (isset($message->item)) {
+                    foreach ($message->item as $complexType) {
+                        $array[] = $this->checkComplexType($phpType, $complexType);
+                    }
+
+                    // See https://github.com/BeSimple/BeSimpleSoapBundle/issues/29
+                    if (in_array('BeSimple\SoapCommon\Type\AbstractKeyValue', class_parents($phpType))) {
+                        $assocArray = array();
+                        foreach ($array as $keyValue) {
+                            $assocArray[$keyValue->getKey()] = $keyValue->getValue();
+                        }
+
+                        $array = $assocArray;
+                    }
+                }
+
+                $message = $array;
+            } else {
+                $message = $this->checkComplexType($phpType, $message);
+            }
+        } elseif ($isArray) {
+            if (isset($message->item)) {
+                $message = $message->item;
+            } else {
+                $message = $array;
+            }
+        }
+
+        return $message;
+    }
+
+    protected function checkComplexType($phpType, $message)
+    {
+        $hash = spl_object_hash($message);
+        if (isset($this->messageRefs[$hash])) {
+            return $this->messageRefs[$hash];
+        }
+
+        $this->messageRefs[$hash] = $message;
+
+        $messageBinder = new MessageBinder($message);
+        foreach ($this->typeRepository->getType($phpType)->all() as $type) {
+            $property = $type->getName();
+            $value = $messageBinder->readProperty($property);
+
+            if (null !== $value) {
+                $value = $this->processType($type->getType(), $value);
+
+                $messageBinder->writeProperty($property, $value);
+            } elseif (!$type->isNillable()) {
+                // @TODO use xmlType instead of phpType
+                throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst($phpType), $type->getName()));
+            }
+        }
+
+        return $message;
+    }
 }
\ No newline at end of file
diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php
index 21c72e0..d22c02c 100644
--- a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php
+++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php
@@ -11,17 +11,100 @@
 namespace BeSimple\SoapBundle\ServiceBinding;

 use BeSimple\SoapBundle\ServiceDefinition\Method;
+use BeSimple\SoapCommon\Definition\Type\ArrayOfType;
+use BeSimple\SoapCommon\Definition\Type\ComplexType;
+use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+use BeSimple\SoapCommon\Util\MessageBinder;

 /**
  * @author Christian Kerl <christian-kerl@web.de>
  */
 class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface
 {
-    public function processMessage(Method $messageDefinition, $message)
+    public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
     {
+        $this->typeRepository = $typeRepository;
+
         $result = new \stdClass();
-        $result->{$messageDefinition->getName().'Result'} = $message;
+        //$result->{$messageDefinition->getName().'Result'} = $message;
+        foreach ($messageDefinition->getOutput()->all() as $name => $part) {
+            //$result->{$name} = $message;
+            $result->{$name} = $this->processType($part->getType(), $message);
+            break; // only one iteration
+        }

         return $result;
     }
+
+    private function processType($phpType, $message)
+    {
+        $isArray = false;
+
+        $type = $this->typeRepository->getType($phpType);
+        if ($type instanceof ArrayOfType) {
+            $isArray = true;
+
+            $type = $this->typeRepository->getType($type->get('item')->getType());
+        }
+
+        if ($type instanceof ComplexType) {
+            $phpType = $type->getPhpType();
+
+            if ($isArray) {
+                $array = array();
+
+                // See https://github.com/BeSimple/BeSimpleSoapBundle/issues/29
+                if (is_array($message) && in_array('BeSimple\SoapCommon\Type\AbstractKeyValue', class_parents($phpType))) {
+                    $keyValue = array();
+                    foreach ($message as $key => $value) {
+                        $keyValue[] = new $phpType($key, $value);
+                    }
+
+                    $message = $keyValue;
+                }
+
+                foreach ($message as $complexType) {
+                    $array[] = $this->checkComplexType($phpType, $complexType);
+                }
+
+                $message = $array;
+            } else {
+                $message = $this->checkComplexType($phpType, $message);
+            }
+        }
+
+        return $message;
+    }
+
+    private function checkComplexType($phpType, $message)
+    {
+        $hash = spl_object_hash($message);
+        if (isset($this->messageRefs[$hash])) {
+            return $this->messageRefs[$hash];
+        }
+
+        $this->messageRefs[$hash] = $message;
+
+        if (!$message instanceof $phpType) {
+            throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', $phpType, get_class($message)));
+        }
+
+        $messageBinder = new MessageBinder($message);
+        foreach ($this->typeRepository->getType($phpType)->all() as $type) {
+            $property = $type->getName();
+            $value = $messageBinder->readProperty($property);
+
+            if (null !== $value) {
+                $value = $this->processType($type->getType(), $value);
+
+                $messageBinder->writeProperty($property, $value);
+            }
+
+            if (!$type->isNillable() && null === $value) {
+                throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $phpType, $type->getName()));
+            }
+        }
+
+        return $message;
+    }
 }
\ No newline at end of file
diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php
index b6b4361..82d0924 100644
--- a/ServiceBinding/RpcLiteralResponseMessageBinder.php
+++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php
@@ -32,7 +32,8 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface
     {
         $this->typeRepository = $typeRepository;

-        return $this->processType($messageDefinition->getOutput()->get('return')->getType(), $message);
+        //return $this->processType($messageDefinition->getOutput()->get('return')->getType(), $message);
+        return $this->processType(current($messageDefinition->getOutput()->all())->getType(), $message);
     }

     private function processType($phpType, $message)
diff --git a/ServiceDefinition/Annotation/Param.php b/ServiceDefinition/Annotation/Param.php
index 330569b..257b7b3 100644
--- a/ServiceDefinition/Annotation/Param.php
+++ b/ServiceDefinition/Annotation/Param.php
@@ -18,6 +18,7 @@ class Param extends Configuration implements TypedElementInterface
     private $value;
     private $phpType;
     private $xmlType;
+    private $isNillable = false;

     public function getValue()
     {
@@ -34,6 +35,11 @@ class Param extends Configuration implements TypedElementInterface
         return $this->xmlType;
     }

+    public function isNillable()
+    {
+        return $this->isNillable;
+    }
+
     public function setValue($value)
     {
         $this->value = $value;
@@ -49,6 +55,11 @@ class Param extends Configuration implements TypedElementInterface
         $this->xmlType = $xmlType;
     }

+    public function setNillable($isNillable)
+    {
+        $this->isNillable = (bool) $isNillable;
+    }
+
     public function getAliasName()
     {
         return 'param';
diff --git a/ServiceDefinition/Annotation/Result.php b/ServiceDefinition/Annotation/Result.php
index 0d86f8c..52ee7e5 100644
--- a/ServiceDefinition/Annotation/Result.php
+++ b/ServiceDefinition/Annotation/Result.php
@@ -15,9 +15,15 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Annotation;
  */
 class Result extends Configuration implements TypedElementInterface
 {
+    private $value = 'return';
     private $phpType;
     private $xmlType;

+    public function getValue()
+    {
+        return $this->value;
+    }
+
     public function getPhpType()
     {
         return $this->phpType;
@@ -28,6 +34,11 @@ class Result extends Configuration implements TypedElementInterface
         return $this->xmlType;
     }

+    public function setValue($value)
+    {
+        $this->value = $value;
+    }
+
     public function setPhpType($phpType)
     {
         $this->phpType = $phpType;
diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php
index dcd1500..5fedee1 100644
--- a/ServiceDefinition/Loader/AnnotationClassLoader.php
+++ b/ServiceDefinition/Loader/AnnotationClassLoader.php
@@ -73,14 +73,17 @@ class AnnotationClassLoader extends Loader
         foreach ($class->getMethods() as $method) {
             $serviceHeaders   = $sharedHeaders;
             $serviceArguments = array();
-            $serviceMethod    =
-            $serviceReturn    = null;
+            $serviceMethod    = null;
+            $serviceReturn    = [];

             foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
                 if ($annotation instanceof Annotation\Header) {
                     $serviceHeaders[$annotation->getValue()] = $this->loadType($annotation->getPhpType());
                 } elseif ($annotation instanceof Annotation\Param) {
-                    $serviceArguments[$annotation->getValue()] = $this->loadType($annotation->getPhpType());
+                    $serviceArguments[$annotation->getValue()] = [
+                        'type'     => $this->loadType($annotation->getPhpType()),
+                        'nillable' => $annotation->isNillable()
+                    ];
                 } elseif ($annotation instanceof Annotation\Method) {
                     if ($serviceMethod) {
                         throw new \LogicException(sprintf('@Soap\Method defined twice for "%s".', $method->getName()));
@@ -95,7 +98,7 @@ class AnnotationClassLoader extends Loader
                         throw new \LogicException(sprintf('@Soap\Result defined twice for "%s".', $method->getName()));
                     }

-                    $serviceReturn = $annotation->getPhpType();
+                    $serviceReturn[$annotation->getValue()] = $annotation->getPhpType();
                 }
             }

@@ -108,15 +111,17 @@ class AnnotationClassLoader extends Loader
                     $serviceMethod->addHeader($name, $type);
                 }

-                foreach ($serviceArguments as $name => $type) {
-                    $serviceMethod->addInput($name, $type);
+                /*foreach ($serviceArguments as $name => $type) {
+                    $serviceMethod->addInput($name, $type);*/
+                foreach ($serviceArguments as $name => $argument) {
+                    $serviceMethod->addInput($name, $argument['type'], $argument['nillable']);
                 }

                 if (!$serviceReturn) {
                     throw new \LogicException(sprintf('@Soap\Result non-existent for "%s".', $method->getName()));
                 }

-                $serviceMethod->setOutput($this->loadType($serviceReturn));
+                $serviceMethod->setOutput(key($serviceReturn), $this->loadType(current($serviceReturn)));

                 $definition->addMethod($serviceMethod);
             }
diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php
index a93953c..245c7d7 100644
--- a/ServiceDefinition/Method.php
+++ b/ServiceDefinition/Method.php
@@ -13,7 +13,7 @@
 namespace BeSimple\SoapBundle\ServiceDefinition;

 use BeSimple\SoapCommon\Definition\Method as BaseMethod;
-use BeSimple\SoapCommon\Definition\Type\TypeRepository;
+//use BeSimple\SoapCommon\Definition\Type\TypeRepository;

 /**
  * @author Christian Kerl <christian-kerl@web.de>
diff --git a/WebServiceContext.php b/WebServiceContext.php
index dce81a7..32724b9 100644
--- a/WebServiceContext.php
+++ b/WebServiceContext.php
@@ -53,6 +53,11 @@ class WebServiceContext
                 $this->serviceDefinition = $this->loader->load($this->options['resource'], $this->options['resource_type']);
                 $this->serviceDefinition->setName($this->options['name']);
                 $this->serviceDefinition->setNamespace($this->options['namespace']);
+                $this->serviceDefinition->setOptions([
+                    'style'   => $this->options['style'],
+                    'use'     => $this->options['use'],
+                    'version' => $this->options['version'],
+                ]);

                 $cache->write('<?php return unserialize('.var_export(serialize($this->serviceDefinition), true).');');
             }

_SoapCommon_

diff --git a/Definition/Method.php b/Definition/Method.php
index e79e9d2..6a19d46 100644
--- a/Definition/Method.php
+++ b/Definition/Method.php
@@ -61,14 +61,15 @@ class Method
         $this->headers->add($name, $type);
     }

-    public function addInput($name, $type)
+    public function addInput($name, $type, $nillable = false)
     {
-        $this->input->add($name, $type);
+        $this->input->add($name, $type, $nillable);
     }

-    public function setOutput($type)
+    public function setOutput($name, $type)
     {
-        $this->output->add('return', $type);
+        //$this->output->add('return', $type);
+        $this->output->add($name, $type);
     }

     public function getHeaders()

_SoapWsdl_

diff --git a/Dumper/AbstractVersion.php b/Dumper/AbstractVersion.php
index c67c035..da33be5 100644
--- a/Dumper/AbstractVersion.php
+++ b/Dumper/AbstractVersion.php
@@ -89,7 +89,7 @@ abstract class AbstractVersion implements VersionInterface
         $operation->setAttribute('name', $method->getName());

         $soapOperation = $this->document->createElement($this->soapNs.':operation');
-        $soapOperation->setAttribute('soapAction', $this->namespace.$method->getName());
+        $soapOperation->setAttribute('soapAction', $this->namespace.'/#'.$method->getName());
         $operation->appendChild($soapOperation);

         $this->getBindingNode()->appendChild($operation);
@@ -109,8 +109,8 @@ abstract class AbstractVersion implements VersionInterface
         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('part', \SOAP_RPC === $this->style ? $part->getName() : 'parameters');
                 $soapHeader->setAttribute('use', $use);
                 $soapHeader->setAttribute('namespace', $this->namespace);
                 $soapHeader->setAttribute('encodingStyle', $this->getEncodingStyle());
diff --git a/Dumper/Dumper.php b/Dumper/Dumper.php
index ef55520..786be81 100644
--- a/Dumper/Dumper.php
+++ b/Dumper/Dumper.php
@@ -34,13 +34,14 @@ class Dumper
     const SOAP12_NS = 'soap12';
     const SOAP12_NS_URI = 'http://schemas.xmlsoap.org/wsdl/soap12/';

-    const SOAP_ENC_NS = 'soap-enc';
+    const SOAP_ENC_NS = 'soapenc';
     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';
+    const TARGET_NS = 'tns';
+    const TYPES_NS = 'ns';

     protected $definition;
     protected $options;
@@ -153,28 +154,30 @@ class Dumper
     protected function addDefinitions()
     {
         $this->domDefinitions = $this->document->createElement('definitions');
+
+        $this->domDefinitions->setAttribute('name', $this->definition->getName());
+        $this->domDefinitions->setAttribute('targetNamespace', $this->definition->getNamespace());
+
         $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::TARGET_NS, $this->definition->getNamespace());
+        $this->domDefinitions->setAttributeNS(static::XML_NS_URI, static::XML_NS.':'.static::TYPES_NS, $this->definition->getNamespace().'/types');
         $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::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);
+        //$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->addPortType();
         $this->addMessages($this->definition->getMessages());

         foreach ($this->definition->getMethods() as $method) {
@@ -196,19 +199,43 @@ class Dumper
             $messageElement = $this->document->createElement('message');
             $messageElement->setAttribute('name', $message->getName());

-            foreach ($message->all() as $part) {
-                $type = $this->definition->getTypeRepository()->getType($part->getType());
+            if ($this->definition->getOption('style') === \SOAP_RPC) {

-                $partElement = $this->document->createElement('part');
-                $partElement->setAttribute('name', $part->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);
+                    if ($type instanceof ComplexType) {
+                        $partElement->setAttribute('type', static::TYPES_NS.':'.$type->getXmlType());
+                    } else {
+                        $partElement->setAttribute('type', $type);
+                    }
+
+                    $messageElement->appendChild($partElement);
                 }

+            } else { // \SOAP_DOCUMENT (literal-wrapped)
+
+                $partElement = $this->document->createElement('part');
+                $partElement->setAttribute('name', 'parameters');
+                $partElement->setAttribute('element', static::TYPES_NS.':'.$message->getName());
+
                 $messageElement->appendChild($partElement);
+
+                $paramsComplexType = new ComplexType('array', $message->getName());
+                foreach ($message->all() as $part) {
+                    $paramsComplexType->add($part->getName(), $part->getType(), $part->isNillable());
+                }
+
+                $this->addComplexType($paramsComplexType);
+
+                $paramsElement = $this->document->createElement(static::XSD_NS.':element');
+                $paramsElement->setAttribute('name', $paramsComplexType->getXmlType());
+                $paramsElement->setAttribute('type', static::TYPES_NS.':'.$paramsComplexType->getXmlType());
+
+                $this->domSchema->appendChild($paramsElement);
             }

             $this->domDefinitions->appendChild($messageElement);
@@ -220,8 +247,10 @@ class Dumper
         $types = $this->document->createElement('types');
         $this->domDefinitions->appendChild($types);

+        $nsTypes         = $this->definition->getNamespace() . '/types';
         $this->domSchema = $this->document->createElement(static::XSD_NS.':schema');
-        $this->domSchema->setAttribute('targetNamespace', $this->definition->getNamespace());
+        $this->domSchema->setAttribute('targetNamespace', $nsTypes);
+        $this->domSchema->setAttribute(static::XML_NS, $nsTypes);
         $types->appendChild($this->domSchema);

         foreach ($this->definition->getTypeRepository()->getComplexTypes() as $type) {
@@ -251,6 +280,7 @@ class Dumper
                     $name = $childType->getName();
                 }

+                //$element->setAttribute('element', static::TYPES_NS.':'.$name);
                 $element->setAttribute('type', static::TYPES_NS.':'.$name);
             } else {
                 $element->setAttribute('type', $childType);
@@ -290,7 +320,8 @@ class Dumper
             }

             $node = $this->document->createElement($type);
-            $node->setAttribute('message', static::TYPES_NS.':'.$message->getName());
+            $node->setAttribute('message', static::TARGET_NS.':'.$message->getName());
+            //$node->setAttribute('name', $message->getName());

             $operation->appendChild($node);
         }
@@ -311,11 +342,11 @@ class Dumper

     protected function getVersion($version)
     {
-        if (\SOAP_1_2 === $version) {
+        /*if (\SOAP_1_2 === $version) {
             return $this->getVersion12();
-        }
+        }*/

-        return $this->getVersion11();
+        return (\SOAP_1_2 === $version)? $this->getVersion12() : $this->getVersion11();
     }

     protected function getVersion11()
@@ -323,10 +354,10 @@ class Dumper
         if (!$this->version11) {
             $this->version11 = new $this->options['version11_class'](
                 static::SOAP_NS,
-                static::TYPES_NS,
+                static::TARGET_NS,
                 $this->options['version11_name'],
                 $this->definition->getNamespace(),
-                static::TYPES_NS.':'.$this->definition->getName().'PortType',
+                static::TARGET_NS.':'.$this->definition->getName().'PortType',
                 $this->definition->getOption('location'),
                 $this->definition->getOption('style')
             );
@@ -340,10 +371,10 @@ class Dumper
         if (!$this->version12) {
             $this->version12 = new $this->options['version12_class'](
                 static::SOAP12_NS,
-                static::TYPES_NS,
+                static::TARGET_NS,
                 $this->options['version12_name'],
                 $this->definition->getNamespace(),
-                static::TYPES_NS.':'.$this->definition->getName().'PortType',
+                static::TARGET_NS.':'.$this->definition->getName().'PortType',
                 $this->definition->getOption('location'),
                 $this->definition->getOption('style')
             );

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions