diff --git a/src/BeSimple/SoapBundle/Resources/config/webservice.xml b/src/BeSimple/SoapBundle/Resources/config/webservice.xml index 122cd86..cd1a689 100644 --- a/src/BeSimple/SoapBundle/Resources/config/webservice.xml +++ b/src/BeSimple/SoapBundle/Resources/config/webservice.xml @@ -15,7 +15,7 @@ BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper BeSimple\SoapBundle\Converter\TypeRepository - BeSimple\SoapCommon\Classmap + BeSimple\SoapServer\Classmap diff --git a/src/BeSimple/SoapBundle/Resources/doc/soapserver/tutorial/complex_type.rst b/src/BeSimple/SoapBundle/Resources/doc/soapserver/tutorial/complex_type.rst index 034d762..0c8b84a 100644 --- a/src/BeSimple/SoapBundle/Resources/doc/soapserver/tutorial/complex_type.rst +++ b/src/BeSimple/SoapBundle/Resources/doc/soapserver/tutorial/complex_type.rst @@ -51,8 +51,16 @@ You can expose only the properties (public, protected or private) of a complex t use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + /** + * @Soap\Alias("User") + */ class User { + /** + * @Soap\ComplexType("int", nillable=true) + */ + private $id; + /** * @Soap\ComplexType("string") */ @@ -63,11 +71,6 @@ You can expose only the properties (public, protected or private) of a complex t */ public $lastname; - /** - * @Soap\ComplexType("int", nillable=true) - */ - private $id; - /** * @Soap\ComplexType("string") */ @@ -135,3 +138,9 @@ ComplexType `ComplexType` accepts the following options: * nillable: To specify that the value can be null + +Alias +----- + +If you can Alias annotation, the name of your entity will be renamed in the WSDL generated. +With alias the name in WSDL will `User` instead of `Acme.DemoBundle.Entity.User` (name without Alias annotation). diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Alias.php b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Alias.php new file mode 100644 index 0000000..f88f5d4 --- /dev/null +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Alias.php @@ -0,0 +1,36 @@ + + * (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\Annotation; + +/** + * @Annotation + */ +class Alias extends Configuration +{ + private $value; + + public function getValue() + { + return $this->value; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function getAliasName() + { + return 'alias'; + } +} diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Configuration.php b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Configuration.php index f7c4d0a..2334809 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Configuration.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/Configuration.php @@ -21,10 +21,10 @@ abstract class Configuration implements ConfigurationInterface { foreach ($values as $k => $v) { if (!method_exists($this, $name = 'set'.$k)) { - throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, get_class($this))); + throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, __CLASS__)); } $this->$name($v); } } -} \ No newline at end of file +} diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php index 0cc7579..053aa0e 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php @@ -22,6 +22,7 @@ use BeSimple\SoapBundle\Util\Collection; */ class AnnotationComplexTypeLoader extends AnnotationClassLoader { + private $aliasClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\Alias'; private $complexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\ComplexType'; /** @@ -40,9 +41,14 @@ class AnnotationComplexTypeLoader extends AnnotationClassLoader throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } - $class = new \ReflectionClass($class); - $collection = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\ComplexType'); + $annotations = array(); + $class = new \ReflectionClass($class); + if ($alias = $this->reader->getClassAnnotation($class, $this->aliasClass)) { + $annotations['alias'] = $alias->getValue(); + } + + $annotations['properties'] = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\ComplexType'); foreach ($class->getProperties() as $property) { $complexType = $this->reader->getPropertyAnnotation($property, $this->complexTypeClass); @@ -51,10 +57,10 @@ class AnnotationComplexTypeLoader extends AnnotationClassLoader $propertyComplexType->setValue($complexType->getValue()); $propertyComplexType->setNillable($complexType->isNillable()); $propertyComplexType->setName($property->getName()); - $collection->add($propertyComplexType); + $annotations['properties']->add($propertyComplexType); } } - return $collection; + return $annotations; } -} \ No newline at end of file +} diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php b/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php index 458f23d..8cfe302 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/ServiceDefinition.php @@ -128,13 +128,24 @@ class ServiceDefinition $this->classmap = $classmap; } - public function addDefinitionComplexType($type, Collection $complexType) + public function hasDefinitionComplexType($type) { - $this->complexTypes[$type] = $complexType; + 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; } -} \ No newline at end of file +} diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php index c8df45f..ab824ad 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Strategy/ComplexType.php @@ -36,44 +36,45 @@ class ComplexType extends AbstractComplexTypeStrategy * @param string $type Name of the class to be specified * @return string XSD Type for the given PHP type */ - public function addComplexType($type) + public function addComplexType($classname) { $classmap = $this->definition->getClassmap(); - - if (null !== $soapType = $this->scanRegisteredTypes($type)) { - return $soapType; + if ($classmap->hasByClassname($classname)) { + return 'tns:'.$classmap->getByClassname($classname); } - if (!$this->loader->supports($type)) { - throw new \InvalidArgumentException(sprintf('Cannot add a complex type "%s" that is not an object or where class could not be found in "ComplexType" strategy.', $type)); + 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)); } - $dom = $this->getContext()->toDomDocument(); + $definitionComplexType = $this->loader->load($classname); + $classnameAlias = isset($definitionComplexType['alias']) ? $definitionComplexType['alias'] : $classname; - $soapTypeName = $this->getContext()->translateType($type); - $soapType = 'tns:'.$soapTypeName; - - if (!$classmap->has($soapTypeName)) { - $classmap->add($soapTypeName, $type); - } + $type = $this->getContext()->translateType($classnameAlias); + $xmlType = 'tns:'.$type; // Register type here to avoid recursion - $this->getContext()->addType($type, $soapType); + $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', $soapTypeName); + $complexType->setAttribute('name', $type); $all = $dom->createElement('xsd:all'); - $definitionComplexType = $this->loader->load($type); - $this->definition->addDefinitionComplexType($type, $definitionComplexType); - - foreach ($definitionComplexType as $annotationComplexType) { + $elements = array(); + foreach ($definitionComplexType['properties'] as $property) { $element = $dom->createElement('xsd:element'); - $element->setAttribute('name', $propertyName = $annotationComplexType->getName()); - $element->setAttribute('type', $this->getContext()->getType(trim($annotationComplexType->getValue()))); + $element->setAttribute('name', $property->getName()); + $element->setAttribute('type', $this->getContext()->getType($property->getValue())); - if ($annotationComplexType->isNillable()) { + if ($property->isNillable()) { $element->setAttribute('nillable', 'true'); } @@ -83,6 +84,6 @@ class ComplexType extends AbstractComplexTypeStrategy $complexType->appendChild($all); $this->getContext()->getSchema()->appendChild($complexType); - return $soapType; + $this->definition->addDefinitionComplexType($type, $definitionComplexType); } } diff --git a/src/BeSimple/SoapServer/Classmap.php b/src/BeSimple/SoapServer/Classmap.php new file mode 100644 index 0000000..aa1e3e9 --- /dev/null +++ b/src/BeSimple/SoapServer/Classmap.php @@ -0,0 +1,47 @@ + + * (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\SoapServer; + +use BeSimple\SoapCommon\Classmap as BaseClassmap; + +/** + * @author Francis Besset + */ +class Classmap extends BaseClassmap +{ + protected $classmapInversed = array(); + + /** + * {@inheritdoc} + */ + public function add($type, $classname) + { + parent::add($type, $classname); + + $this->classmapInversed[$classname] = $type; + } + + public function getByClassname($classname) + { + if (!$this->hasByClassname($classname)) { + throw new \InvalidArgumentException(sprintf('The classname "%s" was not found in %s', $classname, __CLASS__)); + } + + return $this->classmapInversed[$classname]; + } + + public function hasByClassname($classname) + { + return isset($this->classmapInversed[$classname]); + } +}