diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 9fe758b..310860f 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -20,29 +20,25 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; */ class RpcLiteralRequestMessageBinder implements MessageBinderInterface { - private $definitionComplexTypes; + private $messageRefs = array(); public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) { - $this->definitionComplexTypes = $definitionComplexTypes; - $result = array(); $i = 0; foreach($messageDefinition->getArguments() as $argument) { if (isset($message[$i])) { - $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i]); + $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i], $definitionComplexTypes); } $i++; } - $this->definitionComplexTypes = array(); - return $result; } - private function processType($phpType, $message) + private function processType($phpType, $message, array $definitionComplexTypes) { if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; @@ -52,17 +48,17 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $type = $phpType; } - if (isset($this->definitionComplexTypes[$type])) { + if (isset($definitionComplexTypes[$type])) { if ($isArray) { $array = array(); foreach ($message->item as $complexType) { - $array[] = $this->getInstanceOfType($type, $complexType); + $array[] = $this->getInstanceOfType($type, $complexType, $definitionComplexTypes); } $message = $array; } else { - $message = $this->getInstanceOfType($type, $message); + $message = $this->getInstanceOfType($type, $message, $definitionComplexTypes); } } elseif ($isArray) { $message = $message->item; @@ -71,12 +67,18 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface return $message; } - private function getInstanceOfType($phpType, $message) + private function getInstanceOfType($phpType, $message, array $definitionComplexTypes) { - $instanceType = new $phpType(); + $hash = spl_object_hash($message); + if (isset($this->messageRefs[$hash])) { + return $this->messageRefs[$hash]; + } - foreach ($this->definitionComplexTypes[$phpType] as $type) { - $value = $this->processType($type->getValue(), $message->{$type->getName()}); + $this->messageRefs[$hash] = + $instanceType = new $phpType(); + + foreach ($definitionComplexTypes[$phpType] as $type) { + $value = $this->processType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); if ($type instanceof PropertyComplexType) { $instanceType->{$type->getOriginalName()} = $value; diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index 3c8a380..a9b1ee0 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -38,18 +38,17 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase public function testProcessMessageWithComplexType() { - $definitionComplexTypes = $this->getDefinitionComplexTypes(); - $attributes = new \stdClass(); $attributes->foo = 'bar'; $attributes->bar = 10; + $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_argument', null, array( new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), )), array($attributes), - $definitionComplexTypes + $this->getDefinitionComplexTypes() ); $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes']); @@ -62,15 +61,17 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $attributes2 = new \stdClass(); $attributes2->foo = 'barfoo'; $attributes2->bar = 12; + $message = new \stdClass(); $message->item = array($attributes1, $attributes2); + $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_argument', null, array( new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), )), array($message), - $definitionComplexTypes + $this->getDefinitionComplexTypes() ); $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes'][0]); @@ -83,18 +84,17 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase public function testProcessMessageWithComplexTypeIntoComplexType() { - $definitionComplexTypes = $this->getDefinitionComplexTypes(); - $methods = new \stdClass(); $methods->foo = 'bar'; $methods->bar = 23; + $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_methods', null, array( new Argument('setters', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), )), array($methods), - $definitionComplexTypes + $this->getDefinitionComplexTypes() ); $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters', $result['setters']); @@ -104,22 +104,22 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase public function testProcessMessageWithComplexTypeMethods() { - $definitionComplexTypes = $this->getDefinitionComplexTypes(); - $complexType = new \stdClass(); $foo = $complexType->foo = new \stdClass(); $foo->foo = 'hello'; $foo->bar = 24; + $bar = $complexType->bar = new \stdClass(); $bar->foo = 'bonjour'; $bar->bar = 1012; + $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_complextype', null, array( new Argument('complex_type', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), )), array($complexType), - $definitionComplexTypes + $this->getDefinitionComplexTypes() ); $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType', $result['complex_type']); @@ -133,6 +133,40 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame(1012, $result['complex_type']->bar->getBar()); } + public function testProcessMessageWithComplexTypeReferences() + { + $complexType1 = new \stdClass(); + $foo = $complexType1->foo = new \stdClass(); + $foo->foo = 'hello'; + $foo->bar = 24; + + $bar = $complexType1->bar = new \stdClass(); + $bar->foo = 'bonjour'; + $bar->bar = 1012; + + $complexType2 = new \stdClass(); + $complexType2->foo = $foo; + $complexType2->bar = $bar; + + $complexTypes = new \stdClass(); + $complexTypes->item = array($complexType1, $complexType2); + + $messageBinder = new RpcLiteralRequestMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextypes_references', null, array( + new Argument('complex_types', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType[]')), + )), + array($complexTypes), + $this->getDefinitionComplexTypes() + ); + + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType', $result['complex_types'][0]); + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType', $result['complex_types'][1]); + + $this->assertSame($result['complex_types'][0]->getFoo(), $result['complex_types'][1]->getFoo()); + $this->assertSame($result['complex_types'][0]->bar, $result['complex_types'][1]->bar); + } + public function messageProvider() { $messages = array();