diff --git a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php index e37cd2b..b7232c2 100644 --- a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php +++ b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php @@ -35,7 +35,7 @@ class SoapWebServiceController implements ContainerAwareInterface /** * @var ContainerInterface */ - private $container; + protected $container; /** * @var \SoapServer diff --git a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php index 13abf08..b743a51 100644 --- a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -55,7 +55,8 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $isArray = true; $array = array(); - $type = $this->typeRepository->getType($type->get('item')->getType()); + $phpType = substr($type->getPhpType(), 0, strlen($type->getPhpType()) - 2); + $type = $this->typeRepository->getType($phpType); } // @TODO Fix array reference @@ -78,6 +79,21 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $array = $assocArray; } } + if (is_array($message)) { + foreach ($message 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 { diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php index 85072d4..47f9019 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php @@ -18,6 +18,7 @@ class ComplexType extends Configuration private $name; private $value; private $isNillable = false; + private $isAttribute = false; public function getName() { @@ -49,6 +50,26 @@ class ComplexType extends Configuration $this->isNillable = (bool) $isNillable; } + /** + * @return bool + */ + public function isAttribute() + { + return $this->isAttribute; + } + + /** + * @param bool $isAttribute + * + * @return $this + */ + public function setIsAttribute($isAttribute) + { + $this->isAttribute = $isAttribute; + + return $this; + } + public function getAliasName() { return 'complextype'; diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php index d0ae464..7dca7f2 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/ComplexType.php @@ -20,6 +20,7 @@ class ComplexType private $name; private $value; private $isNillable = false; + private $isAttribute = false; public function getName() { @@ -46,6 +47,26 @@ class ComplexType $this->value = $value; } + /** + * @return bool + */ + public function isAttribute() + { + return $this->isAttribute; + } + + /** + * @param bool $isAttribute + * + * @return $this + */ + public function setIsAttribute($isAttribute) + { + $this->isAttribute = $isAttribute; + + return $this; + } + public function setNillable($isNillable) { $this->isNillable = (bool) $isNillable; diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php index dcd1500..99440c6 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -155,7 +155,7 @@ class AnnotationClassLoader extends Loader $loaded = $complexTypeResolver->load($phpType); $complexType = new ComplexType($phpType, isset($loaded['alias']) ? $loaded['alias'] : $phpType); foreach ($loaded['properties'] as $name => $property) { - $complexType->add($name, $this->loadType($property->getValue()), $property->isNillable()); + $complexType->add($name, $this->loadType($property->getValue()), $property->isNillable(), $property->isAttribute()); } $this->typeRepository->addComplexType($complexType); diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php index 1d3e095..44089b6 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php @@ -58,6 +58,7 @@ class AnnotationComplexTypeLoader extends AnnotationClassLoader $propertyComplexType = new ComplexType(); $propertyComplexType->setValue($complexType->getValue()); $propertyComplexType->setNillable($complexType->isNillable()); + $propertyComplexType->setIsAttribute($complexType->isAttribute()); $propertyComplexType->setName($property->getName()); $annotations['properties']->add($propertyComplexType); } diff --git a/src/BeSimple/SoapBundle/WebServiceContext.php b/src/BeSimple/SoapBundle/WebServiceContext.php index 875659e..7947278 100644 --- a/src/BeSimple/SoapBundle/WebServiceContext.php +++ b/src/BeSimple/SoapBundle/WebServiceContext.php @@ -79,7 +79,10 @@ class WebServiceContext } $dumper = new Dumper($definition, array('stylesheet' => $this->options['wsdl_stylesheet'])); - $cache->write($dumper->dump()); + + $wsdl = $dumper->dump(); + + $cache->write($wsdl); } return $cache->getPath(); diff --git a/src/BeSimple/SoapCommon/Definition/Message.php b/src/BeSimple/SoapCommon/Definition/Message.php index caa78fe..506c56d 100644 --- a/src/BeSimple/SoapCommon/Definition/Message.php +++ b/src/BeSimple/SoapCommon/Definition/Message.php @@ -48,13 +48,13 @@ class Message return 0 === count($this->parts) ? true : false; } - public function add($name, $phpType, $nillable = false) + public function add($name, $phpType, $nillable = false, $attribute = false) { if ($phpType instanceof TypeInterface) { $phpType = $phpType->getPhpType(); } - $this->parts[$name] = new Part($name, $phpType, $nillable); + $this->parts[$name] = new Part($name, $phpType, $nillable, $attribute); return $this; } diff --git a/src/BeSimple/SoapCommon/Definition/Part.php b/src/BeSimple/SoapCommon/Definition/Part.php index 317f046..925d293 100644 --- a/src/BeSimple/SoapCommon/Definition/Part.php +++ b/src/BeSimple/SoapCommon/Definition/Part.php @@ -20,12 +20,14 @@ class Part protected $name; protected $type; protected $nillable; + protected $attribute; - public function __construct($name, $type, $nillable = false) + public function __construct($name, $type, $nillable = false, $attribute = false) { $this->name = $name; $this->type = $type; $this->setNillable($nillable); + $this->setAttribute($attribute); } public function getName() @@ -33,6 +35,26 @@ class Part return $this->name; } + /** + * @return bool + */ + public function isAttribute() + { + return $this->attribute; + } + + /** + * @param bool $attribute + * + * @return $this + */ + public function setAttribute($attribute) + { + $this->attribute = $attribute; + + return $this; + } + public function getType() { return $this->type; diff --git a/src/BeSimple/SoapWsdl/Dumper/Dumper.php b/src/BeSimple/SoapWsdl/Dumper/Dumper.php index ef55520..ff66351 100644 --- a/src/BeSimple/SoapWsdl/Dumper/Dumper.php +++ b/src/BeSimple/SoapWsdl/Dumper/Dumper.php @@ -217,11 +217,13 @@ class Dumper protected function addComplexTypes() { - $types = $this->document->createElement('types'); + $types = $this->document->createElement(static::WSDL_NS . ':types'); $this->domDefinitions->appendChild($types); $this->domSchema = $this->document->createElement(static::XSD_NS.':schema'); $this->domSchema->setAttribute('targetNamespace', $this->definition->getNamespace()); + $this->domSchema->setAttribute('elementFormDefault', 'unqualified'); + $this->domSchema->setAttribute(static::XML_NS.':'.static::XSD_NS, static::XSD_NS_URI); $types->appendChild($this->domSchema); foreach ($this->definition->getTypeRepository()->getComplexTypes() as $type) { @@ -236,13 +238,18 @@ class Dumper $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')); + $all = $this->document->createElement(static::XSD_NS.':'.'sequence'); $complexType->appendChild($all); foreach ($type->all() as $child) { + $isArray = false; $childType = $this->definition->getTypeRepository()->getType($child->getType()); - $element = $this->document->createElement(static::XSD_NS.':element'); + if ($child->isAttribute()) { + $element = $this->document->createElement(static::XSD_NS.':attribute'); + } else { + $element = $this->document->createElement(static::XSD_NS.':element'); + } $element->setAttribute('name', $child->getName()); if ($childType instanceof ComplexType) { @@ -251,6 +258,11 @@ class Dumper $name = $childType->getName(); } + if (0 === strpos($name, 'ArrayOf')) { + $isArray = true; + $name = lcfirst(substr($name, 7)); + } + $element->setAttribute('type', static::TYPES_NS.':'.$name); } else { $element->setAttribute('type', $childType); @@ -260,12 +272,16 @@ class Dumper $element->setAttribute('nillable', 'true'); } - if ($type instanceof ArrayOfType) { + if ($type instanceof ArrayOfType || $isArray) { $element->setAttribute('minOccurs', 0); $element->setAttribute('maxOccurs', 'unbounded'); } - $all->appendChild($element); + if ($child->isAttribute()) { + $complexType->appendChild($element); + } else { + $all->appendChild($element); + } } $this->domSchema->appendChild($complexType);