From 4edda0256d32cc2ab825955fd99cb8f16b539510 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sun, 3 Oct 2010 17:26:14 +0200 Subject: [PATCH 001/195] added LICENSE and README files --- LICENSE | 7 +++++++ README.markdown | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 LICENSE create mode 100644 README.markdown diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f6307bc --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2010 Christian Kerl + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..0f2c87d --- /dev/null +++ b/README.markdown @@ -0,0 +1,7 @@ +WebServiceBundle +================ + +The WebServiceBundle is a Symfony2 bundle to build WSDL and SOAP based web services. +It is based on the [ckWebServicePlugin] [1] for symfony. + +[1]: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file From 843814ccdfd9025beb50cdb27b3a6ab755ddae27 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Mon, 4 Oct 2010 20:27:00 +0200 Subject: [PATCH 002/195] created bundle and core classes --- DependencyInjection/WebServiceExtension.php | 25 +++++++++++++++++++++ Resources/config/services.xml | 6 +++++ SoapKernel.php | 10 +++++++++ SoapRequest.php | 14 ++++++++++++ WebServiceBundle.php | 20 +++++++++++++++++ 5 files changed, 75 insertions(+) create mode 100644 DependencyInjection/WebServiceExtension.php create mode 100644 Resources/config/services.xml create mode 100644 SoapKernel.php create mode 100644 SoapRequest.php create mode 100644 WebServiceBundle.php diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php new file mode 100644 index 0000000..6c0e1c2 --- /dev/null +++ b/DependencyInjection/WebServiceExtension.php @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/SoapKernel.php b/SoapKernel.php new file mode 100644 index 0000000..8af1562 --- /dev/null +++ b/SoapKernel.php @@ -0,0 +1,10 @@ + Date: Mon, 4 Oct 2010 20:39:04 +0200 Subject: [PATCH 003/195] changed request service class --- DependencyInjection/WebServiceExtension.php | 4 ++++ WebServiceBundle.php | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 6c0e1c2..ae21f02 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -7,6 +7,10 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; class WebServiceExtension extends Extension { + public function configLoad(array $config, ContainerBuilder $configuration) + { + $configuration->getDefinition("request")->setClass("Bundle\\WebServiceBundle\\SoapRequest"); + } public function getXsdValidationBasePath() { diff --git a/WebServiceBundle.php b/WebServiceBundle.php index 8d386d2..a34e543 100644 --- a/WebServiceBundle.php +++ b/WebServiceBundle.php @@ -13,8 +13,4 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; */ class WebServiceBundle extends Bundle { - public function registerExtensions(ContainerBuilder $container) - { - parent::registerExtensions($container); - } } \ No newline at end of file From 1a5ff45a39454bdc7df13b265ab48dfac142c461 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Mon, 4 Oct 2010 21:13:45 +0200 Subject: [PATCH 004/195] added DependencyInjection configuration for SoapKernel --- DependencyInjection/WebServiceExtension.php | 7 ++++++- Resources/config/services.xml | 15 +++++++++++++++ SoapKernel.php | 17 +++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index ae21f02..96043fb 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -2,6 +2,8 @@ namespace Bundle\WebServiceBundle\DependencyInjection; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -9,7 +11,10 @@ class WebServiceExtension extends Extension { public function configLoad(array $config, ContainerBuilder $configuration) { - $configuration->getDefinition("request")->setClass("Bundle\\WebServiceBundle\\SoapRequest"); + $loader = new XmlFileLoader($configuration, __DIR__ . "/../Resources/config"); + $loader->load("services.xml"); + + $configuration->setAlias("http_kernel", "webservice_http_kernel"); } public function getXsdValidationBasePath() diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 44a1a1f..be00ff3 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -3,4 +3,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd"> + + Bundle\WebServiceBundle\SoapRequest + + + + + + + + + + + + + \ No newline at end of file diff --git a/SoapKernel.php b/SoapKernel.php index 8af1562..28644c5 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -2,9 +2,22 @@ namespace Bundle\WebServiceBundle; -use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpFoundation\Request; -class SoapKernel extends HttpKernel +use Symfony\Component\DependencyInjection\ContainerAware; + +use Symfony\Component\HttpKernel\HttpKernelInterface; + + +class SoapKernel extends ContainerAware implements HttpKernelInterface { + public function getRequest() + { + return null; + } + public function handle(Request:: $request = null, $type = self::MASTER_REQUEST, $raw = false) + { + $this->container->getSymfonyHttpKernelService()->handle($request, $type, $raw); + } } \ No newline at end of file From 54a76a4ef8be33694dfd4f18b87550d3d914bb98 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Mon, 4 Oct 2010 21:19:18 +0200 Subject: [PATCH 005/195] added DependencyInjection configuration for SoapKernel --- SoapKernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoapKernel.php b/SoapKernel.php index 28644c5..3298b1f 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -16,7 +16,7 @@ class SoapKernel extends ContainerAware implements HttpKernelInterface return null; } - public function handle(Request:: $request = null, $type = self::MASTER_REQUEST, $raw = false) + public function handle(Request $request = null, $type = self::MASTER_REQUEST, $raw = false) { $this->container->getSymfonyHttpKernelService()->handle($request, $type, $raw); } From b0681e5fcfce6bffa99518e16357db9504df91d7 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Tue, 5 Oct 2010 21:44:30 +0200 Subject: [PATCH 006/195] implemented basic SoapKernel to transform a SoapRequest to a SoapResponse --- DependencyInjection/WebServiceExtension.php | 27 +++- Resources/config/services.xml | 14 +- Soap/SoapRequest.php | 68 ++++++++++ Soap/SoapResponse.php | 48 +++++++ SoapKernel.php | 140 +++++++++++++++++++- SoapRequest.php | 14 -- Tests/SoapKernelTest.php | 40 ++++++ Util/OutputBuffer.php | 33 +++++ Util/String.php | 51 +++++++ WebServiceBundle.php | 10 +- 10 files changed, 414 insertions(+), 31 deletions(-) create mode 100644 Soap/SoapRequest.php create mode 100644 Soap/SoapResponse.php delete mode 100644 SoapRequest.php create mode 100644 Tests/SoapKernelTest.php create mode 100644 Util/OutputBuffer.php create mode 100644 Util/String.php diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 96043fb..0fa0ea2 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -1,20 +1,35 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\DependencyInjection; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -use Symfony\Component\DependencyInjection\Extension\Extension; -use Symfony\Component\DependencyInjection\ContainerBuilder; - +/** + * WebServiceExtension. + * + * @author Christian Kerl + */ class WebServiceExtension extends Extension { public function configLoad(array $config, ContainerBuilder $configuration) { - $loader = new XmlFileLoader($configuration, __DIR__ . "/../Resources/config"); - $loader->load("services.xml"); + if(!$configuration->hasDefinition('webservice_http_kernel')) + { + $loader = new XmlFileLoader($configuration, __DIR__ . "/../Resources/config"); + $loader->load("services.xml"); - $configuration->setAlias("http_kernel", "webservice_http_kernel"); + $configuration->setAlias("http_kernel", "webservice_http_kernel"); + } } public function getXsdValidationBasePath() diff --git a/Resources/config/services.xml b/Resources/config/services.xml index be00ff3..64da6a4 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -8,14 +8,18 @@ - - - - - + + + + + + + + + \ No newline at end of file diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php new file mode 100644 index 0000000..7c6b29e --- /dev/null +++ b/Soap/SoapRequest.php @@ -0,0 +1,68 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Soap; + +use Symfony\Component\HttpFoundation\Request; + +/** + * SoapRequest. + * + * @author Christian Kerl + */ +class SoapRequest extends Request +{ + /** + * @var string + */ + protected $rawContent; + + /** + * @var string + */ + protected $soapAction; + + /** + * @var unknown + */ + protected $soapHeader; + + /** + * @var unknown + */ + protected $soapArguments; + + public function __construct($rawContent = null, array $query = null, array $attributes = null, array $cookies = null, array $server = null) + { + parent::__construct($query, null, $attributes, $cookies, null, $server); + + $this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent(); + } + + /** + * Gets the SOAP XML content. + * + * @return string + */ + public function getRawContent() + { + return $this->rawContent; + } + + /** + * Loads the plain HTTP POST data. + * + * @return string + */ + protected function loadRawContent() + { + return isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents('php://input'); + } +} \ No newline at end of file diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php new file mode 100644 index 0000000..3ef872d --- /dev/null +++ b/Soap/SoapResponse.php @@ -0,0 +1,48 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Soap; + +use Symfony\Component\HttpFoundation\Response; + +/** + * SoapResponse. + * + * @author Christian Kerl + */ +class SoapResponse extends Response +{ + protected $soapHeaders; + + protected $soapReturnValue; + + public function __construct($returnValue) + { + parent::__construct(); + + $this->soapHeaders = array(); + $this->soapReturnValue = $returnValue; + } + + public function addSoapHeader(\SoapHeader $header) + { + $this->soapHeaders[] = $header; + } + + public function getSoapHeaders() + { + return $this->soapHeaders; + } + + public function getReturnValue() + { + return $this->soapReturnValue; + } +} \ No newline at end of file diff --git a/SoapKernel.php b/SoapKernel.php index 3298b1f..08f88a9 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -1,23 +1,153 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle; use Symfony\Component\HttpFoundation\Request; - -use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Bundle\WebServiceBundle\Soap\SoapRequest; +use Bundle\WebServiceBundle\Soap\SoapResponse; -class SoapKernel extends ContainerAware implements HttpKernelInterface +use Bundle\WebServiceBundle\Util\OutputBuffer; +use Bundle\WebServiceBundle\Util\String; + +/** + * SoapKernel converts a SoapRequest to a SoapResponse. It uses PHP's SoapServer for SOAP message + * handling. The logic for every service method is implemented in a Symfony controller. The controller + * to use for a specific service method is defined in the ServiceDefinition. The controller is invoked + * by Symfony's HttpKernel implementation. + * + * @author Christian Kerl + */ +class SoapKernel implements HttpKernelInterface { + /** + * @var \SoapServer + */ + protected $soapServer; + + /** + * @var \Bundle\WebServiceBundle\Soap\SoapRequest + */ + protected $soapRequest; + + /** + * @var \Bundle\WebServiceBundle\Soap\SoapResponse + */ + protected $soapResponse; + + /** + * @var \Symfony\Component\HttpKernel\HttpKernelInterface + */ + protected $kernel; + + public function __construct(\SoapServer $server, HttpKernelInterface $kernel) + { + $this->soapServer = $server; + $this->soapServer->setObject($this); + + $this->kernel = $kernel; + } + public function getRequest() { - return null; + return $this->soapRequest; } public function handle(Request $request = null, $type = self::MASTER_REQUEST, $raw = false) { - $this->container->getSymfonyHttpKernelService()->handle($request, $type, $raw); + $this->soapRequest = $this->checkRequest($request); + + $this->soapResponse->setContent(OutputBuffer::get( + function() use($this) + { + $this->soapServer->handle($this->soapRequest->getRawContent()); + } + )); + + return $this->soapResponse; + } + + public function __call($method, $arguments) + { + if($this->isSoapHeaderCallback($method)) + { + // $this->soapRequest->addSoapHeader(null); + } + else + { + // TODO: set _controller attribute of request + $this->soapRequest->attributes->set('_controller', $method); + + $response = $this->kernel->handle($this->soapRequest, self::MASTER_REQUEST, true); + + $this->soapResponse = $this->checkResponse($response); + + foreach($this->soapResponse->getSoapHeaders() as $header) + { + $this->soapServer->addSoapHeader($header); + } + + return $this->soapResponse->getReturnValue(); + } + } + + /** + * Checks the given Request, that it is a SoapRequest. If the request is null a new + * SoapRequest is created. + * + * @param Request $request A request to check + * + * @return SoapRequest A valid SoapRequest + * + * @throws InvalidArgumentException if the given Request is not a SoapRequest + */ + protected function checkRequest(Request $request) + { + if($request == null) + { + $request = new SoapRequest(); + } + + if(!is_a($request, __NAMESPACE__ . '\\Soap\\SoapRequest')) + { + throw new InvalidArgumentException(); + } + + return $request; + } + + /** + * Checks the given Response, that it is a SoapResponse. + * + * @param Response $response A response to check + * + * @return SoapResponse A valid SoapResponse + * + * @throws InvalidArgumentException if the given Response is null or not a SoapResponse + */ + protected function checkResponse(Response $response) + { + if($response == null || !is_a($request, __NAMESPACE__ . '\\Soap\\SoapResponse')) + { + throw new InvalidArgumentException(); + } + + return $response; + } + + protected function isSoapHeaderCallback($method) + { + return false; //String::endsWith($method, 'Header'); } } \ No newline at end of file diff --git a/SoapRequest.php b/SoapRequest.php deleted file mode 100644 index 5424cd8..0000000 --- a/SoapRequest.php +++ /dev/null @@ -1,14 +0,0 @@ - + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Tests; + +use Symfony\Component\HttpFoundation\Request; + +use Bundle\WebServiceBundle\SoapKernel; + +/** + * UnitTest for \Bundle\WebServiceBundle\SoapKernel. + * + * @author Christian Kerl + */ +class SoapKernelTest extends \PHPUnit_Framework_TestCase +{ + private $soapKernel; + + public function setUp() + { + $soapServer = new \SoapServer(); + + $this->soapKernel = new SoapKernel($soapServer, null); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidRequest() + { + $this->soapKernel->handle(new Request()); + } +} \ No newline at end of file diff --git a/Util/OutputBuffer.php b/Util/OutputBuffer.php new file mode 100644 index 0000000..d40ccc6 --- /dev/null +++ b/Util/OutputBuffer.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Util; + +/** + * OutputBuffer provides utility methods to work with PHP's output buffer. + * + * @author Christian Kerl + */ +class OutputBuffer +{ + /** + * Gets the output created by the given callable. + * + * @param callable $callback A callable to execute + * + * @return string The output + */ + static public function get($callback) + { + ob_start(); + $callback(); + return ob_get_clean(); + } +} \ No newline at end of file diff --git a/Util/String.php b/Util/String.php new file mode 100644 index 0000000..1c641d5 --- /dev/null +++ b/Util/String.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Util; + +/** + * String provides utility methods for strings. + * + * @author Christian Kerl + */ +class String +{ + /** + * Checks if a string starts with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str starts with substr + */ + public static function startsWith($str, $substr) + { + if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) + { + return $substr == substr($str, 0, strlen($substr)); + } + } + + /** + * Checks if a string ends with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str ends with substr + */ + public static function endsWith($str, $substr) + { + if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) + { + return $substr == substr($str, strlen($str) - strlen($substr)); + } + } +} \ No newline at end of file diff --git a/WebServiceBundle.php b/WebServiceBundle.php index a34e543..2ea3bb6 100644 --- a/WebServiceBundle.php +++ b/WebServiceBundle.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle; @@ -9,7 +17,7 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; /** * WebServiceBundle. * - * @author Christian Kerl + * @author Christian Kerl */ class WebServiceBundle extends Bundle { From 27da3dcb4aac8ca520835559515d0398abdae842 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Tue, 5 Oct 2010 22:42:47 +0200 Subject: [PATCH 007/195] fixed compilation/runtime errors; added test fixture; --- SoapKernel.php | 18 +++-- Tests/SoapKernelTest.php | 24 ++++++- Tests/fixtures/api.wsdl | 145 +++++++++++++++++++++++++++++++++++++++ Util/OutputBuffer.php | 33 --------- 4 files changed, 174 insertions(+), 46 deletions(-) create mode 100644 Tests/fixtures/api.wsdl delete mode 100644 Util/OutputBuffer.php diff --git a/SoapKernel.php b/SoapKernel.php index 08f88a9..4441d31 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -18,7 +18,6 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; -use Bundle\WebServiceBundle\Util\OutputBuffer; use Bundle\WebServiceBundle\Util\String; /** @@ -68,12 +67,11 @@ class SoapKernel implements HttpKernelInterface { $this->soapRequest = $this->checkRequest($request); - $this->soapResponse->setContent(OutputBuffer::get( - function() use($this) - { - $this->soapServer->handle($this->soapRequest->getRawContent()); - } - )); + ob_start(); + $this->soapServer->handle($this->soapRequest->getRawContent()); + + $soapResponseContent = ob_get_clean(); + $this->soapResponse->setContent($soapResponseContent); return $this->soapResponse; } @@ -121,7 +119,7 @@ class SoapKernel implements HttpKernelInterface if(!is_a($request, __NAMESPACE__ . '\\Soap\\SoapRequest')) { - throw new InvalidArgumentException(); + throw new \InvalidArgumentException(); } return $request; @@ -138,9 +136,9 @@ class SoapKernel implements HttpKernelInterface */ protected function checkResponse(Response $response) { - if($response == null || !is_a($request, __NAMESPACE__ . '\\Soap\\SoapResponse')) + if($response == null || !is_a($response, __NAMESPACE__ . '\\Soap\\SoapResponse')) { - throw new InvalidArgumentException(); + throw new \InvalidArgumentException(); } return $response; diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index b1b6098..47aa0e9 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -10,9 +10,12 @@ namespace Bundle\WebServiceBundle\Tests; + use Symfony\Component\HttpFoundation\Request; use Bundle\WebServiceBundle\SoapKernel; +use Bundle\WebServiceBundle\Soap\SoapRequest; +use Bundle\WebServiceBundle\Soap\SoapResponse; /** * UnitTest for \Bundle\WebServiceBundle\SoapKernel. @@ -21,19 +24,34 @@ use Bundle\WebServiceBundle\SoapKernel; */ class SoapKernelTest extends \PHPUnit_Framework_TestCase { + private static $soapRequestContent = '1020'; + private static $soapResponseContent = '200'; + private $soapKernel; public function setUp() { - $soapServer = new \SoapServer(); + $soapServer = new \SoapServer(__DIR__ . '/fixtures/api.wsdl'); + $httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); + $httpKernel->expects($this->any()) + ->method('handle') + ->will($this->returnValue(new SoapResponse(200))); - $this->soapKernel = new SoapKernel($soapServer, null); + $this->soapKernel = new SoapKernel($soapServer, $httpKernel); + } + + public function testHandle() + { + $response = $this->soapKernel->handle(new SoapRequest(self::$soapRequestContent)); + + $this->assertEquals(200, $response->getReturnValue()); + $this->assertEquals(self::$soapResponseContent, $response->getContent()); } /** * @expectedException InvalidArgumentException */ - public function testInvalidRequest() + public function testHandleWithInvalidRequest() { $this->soapKernel->handle(new Request()); } diff --git a/Tests/fixtures/api.wsdl b/Tests/fixtures/api.wsdl new file mode 100644 index 0000000..c20abed --- /dev/null +++ b/Tests/fixtures/api.wsdl @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Util/OutputBuffer.php b/Util/OutputBuffer.php deleted file mode 100644 index d40ccc6..0000000 --- a/Util/OutputBuffer.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\Util; - -/** - * OutputBuffer provides utility methods to work with PHP's output buffer. - * - * @author Christian Kerl - */ -class OutputBuffer -{ - /** - * Gets the output created by the given callable. - * - * @param callable $callback A callable to execute - * - * @return string The output - */ - static public function get($callback) - { - ob_start(); - $callback(); - return ob_get_clean(); - } -} \ No newline at end of file From b083a4f512b682c9252f52af39c8c4f446e40743 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Tue, 5 Oct 2010 23:22:12 +0200 Subject: [PATCH 008/195] fixed test assertion --- Tests/SoapKernelTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index 47aa0e9..79887b0 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -25,7 +25,7 @@ use Bundle\WebServiceBundle\Soap\SoapResponse; class SoapKernelTest extends \PHPUnit_Framework_TestCase { private static $soapRequestContent = '1020'; - private static $soapResponseContent = '200'; + private static $soapResponseContent = '200'; private $soapKernel; @@ -45,7 +45,7 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase $response = $this->soapKernel->handle(new SoapRequest(self::$soapRequestContent)); $this->assertEquals(200, $response->getReturnValue()); - $this->assertEquals(self::$soapResponseContent, $response->getContent()); + $this->assertXmlStringEqualsXmlString(self::$soapResponseContent, $response->getContent()); } /** From 783ced3b7b5e3ffef7979301a1efbabb1c1acd7f Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 6 Oct 2010 00:00:15 +0200 Subject: [PATCH 009/195] fixed di container configuration --- DependencyInjection/WebServiceExtension.php | 8 +++++--- Resources/config/services.xml | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 0fa0ea2..872e3b2 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -25,11 +25,13 @@ class WebServiceExtension extends Extension { if(!$configuration->hasDefinition('webservice_http_kernel')) { - $loader = new XmlFileLoader($configuration, __DIR__ . "/../Resources/config"); - $loader->load("services.xml"); + $loader = new XmlFileLoader($configuration, __DIR__ . '/../Resources/config'); + $loader->load('services.xml'); - $configuration->setAlias("http_kernel", "webservice_http_kernel"); + $configuration->setAlias('http_kernel', 'webservice_http_kernel'); } + + $configuration->setParameter('webservice.config.wsdl', $config['wsdl']); } public function getXsdValidationBasePath() diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 64da6a4..6845e72 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd"> - Bundle\WebServiceBundle\SoapRequest + Bundle\WebServiceBundle\Soap\SoapRequest @@ -14,8 +14,8 @@ - - + + %webservice.config.wsdl% From 31d40380a6fca9e704f630ecd236f543e598d5c7 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Oct 2010 15:16:56 +0200 Subject: [PATCH 010/195] added initial support for service definition --- DependencyInjection/WebServiceExtension.php | 20 ++- Resources/config/services.xml | 23 +++- ServiceDefinition/Dumper/DumperInterface.php | 10 ++ ServiceDefinition/Loader/FileLoader.php | 21 ++++ ServiceDefinition/Loader/LoaderInterface.php | 15 +++ ServiceDefinition/Loader/XmlFileLoader.php | 116 ++++++++++++++++++ .../Loader/schema/servicedefinition-1.0.xsd | 81 ++++++++++++ ServiceDefinition/ServiceDefinition.php | 80 ++++++++++++ ServiceDefinition/ServiceHeader.php | 35 ++++++ ServiceDefinition/ServiceMethod.php | 35 ++++++ ServiceDefinition/ServiceType.php | 47 +++++++ Soap/SoapHeader.php | 37 ++++++ Soap/SoapRequest.php | 13 +- Soap/SoapResponse.php | 21 ++-- SoapKernel.php | 66 ++++++++-- Tests/SoapKernelTest.php | 18 ++- Tests/StaticFileDumper.php | 21 ++++ Util/Collection.php | 52 ++++++++ 18 files changed, 677 insertions(+), 34 deletions(-) create mode 100644 ServiceDefinition/Dumper/DumperInterface.php create mode 100644 ServiceDefinition/Loader/FileLoader.php create mode 100644 ServiceDefinition/Loader/LoaderInterface.php create mode 100644 ServiceDefinition/Loader/XmlFileLoader.php create mode 100644 ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd create mode 100644 ServiceDefinition/ServiceDefinition.php create mode 100644 ServiceDefinition/ServiceHeader.php create mode 100644 ServiceDefinition/ServiceMethod.php create mode 100644 ServiceDefinition/ServiceType.php create mode 100644 Soap/SoapHeader.php create mode 100644 Tests/StaticFileDumper.php create mode 100644 Util/Collection.php diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 872e3b2..015591c 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -28,10 +28,26 @@ class WebServiceExtension extends Extension $loader = new XmlFileLoader($configuration, __DIR__ . '/../Resources/config'); $loader->load('services.xml'); - $configuration->setAlias('http_kernel', 'webservice_http_kernel'); + $configuration->setAlias('http_kernel', 'webservice.kernel'); } - $configuration->setParameter('webservice.config.wsdl', $config['wsdl']); + if(!isset($config['definition'])) + { + throw new \InvalidArgumentException(); + } + + $this->registerServiceDefinitionConfig($config['definition'], $configuration); + } + + protected function registerServiceDefinitionConfig(array $config, ContainerBuilder $configuration) + { + if(!isset($config['name'])) + { + throw new \InvalidArgumentException(); + } + + $configuration->setParameter('webservice.definition.name', $config['name']); + $configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null); } public function getXsdValidationBasePath() diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 6845e72..896ec68 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -5,6 +5,10 @@ Bundle\WebServiceBundle\Soap\SoapRequest + + Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition + Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader + Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralFileDumper @@ -14,12 +18,21 @@ - - %webservice.config.wsdl% - - - + + + + + + + %webservice.definition.name% + + + %webservice.definition.resource% + + + + \ No newline at end of file diff --git a/ServiceDefinition/Dumper/DumperInterface.php b/ServiceDefinition/Dumper/DumperInterface.php new file mode 100644 index 0000000..9cb12ee --- /dev/null +++ b/ServiceDefinition/Dumper/DumperInterface.php @@ -0,0 +1,10 @@ +file = $file; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Loader/LoaderInterface.php b/ServiceDefinition/Loader/LoaderInterface.php new file mode 100644 index 0000000..d3e2a2e --- /dev/null +++ b/ServiceDefinition/Loader/LoaderInterface.php @@ -0,0 +1,15 @@ +parseFile($this->file); + + if($definition->getName() != $xml['name']) + { + throw new \InvalidArgumentException(); + } + + foreach($xml->header as $header) + { + $definition->getHeaders()->add($this->parseHeader($header)); + } + + foreach($xml->method as $method) + { + $definition->getMethods()->add($this->parseMethod($method)); + } + } + + /** + * @param \SimpleXMLElement $node + * + * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader + */ + protected function parseHeader(\SimpleXMLElement $node) + { + $header = new ServiceHeader((string)$node['name'], $this->parseType($node->type)); + + return $header; + } + + /** + * @param \SimpleXMLElement $node + * + * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod + */ + protected function parseMethod(\SimpleXMLElement $node) + { + $method = new ServiceMethod((string)$node['name'], (string)$node['controller']); + + return $method; + } + + /** + * @param \SimpleXMLElement $node + * + * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceType + */ + protected function parseType(\SimpleXMLElement $node) + { + $namespaces = $node->getDocNamespaces(true); + $qname = explode(':', $node['xml-type'], 2); + $xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]); + + $type = new ServiceType((string)$node['php-type'], $xmlType, (string)$node['converter']); + + return $type; + } + + /** + * @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; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd new file mode 100644 index 0000000..ed2d68f --- /dev/null +++ b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php new file mode 100644 index 0000000..1446275 --- /dev/null +++ b/ServiceDefinition/ServiceDefinition.php @@ -0,0 +1,80 @@ +setName($name); + $this->setMethods($methods); + $this->setHeaders($headers); + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return \Bundle\WebServiceBundle\Util\Collection + */ + public function getMethods() + { + return $this->methods; + } + + /** + * @param array $methods + */ + public function setMethods($methods) + { + $this->methods = new Collection('getName'); + $this->methods->addAll($methods); + } + + /** + * @return \Bundle\WebServiceBundle\Util\Collection + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * @param array $headers + */ + public function setHeaders($headers) + { + $this->headers = new Collection('getName'); + $this->headers->addAll($headers); + } +} \ No newline at end of file diff --git a/ServiceDefinition/ServiceHeader.php b/ServiceDefinition/ServiceHeader.php new file mode 100644 index 0000000..8df73fb --- /dev/null +++ b/ServiceDefinition/ServiceHeader.php @@ -0,0 +1,35 @@ +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/ServiceDefinition/ServiceMethod.php b/ServiceDefinition/ServiceMethod.php new file mode 100644 index 0000000..d78ead6 --- /dev/null +++ b/ServiceDefinition/ServiceMethod.php @@ -0,0 +1,35 @@ +setName($name); + $this->setController($controller); + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getController() + { + return $this->controller; + } + + public function setController($controller) + { + $this->controller = $controller; + } +} \ No newline at end of file diff --git a/ServiceDefinition/ServiceType.php b/ServiceDefinition/ServiceType.php new file mode 100644 index 0000000..bcf0699 --- /dev/null +++ b/ServiceDefinition/ServiceType.php @@ -0,0 +1,47 @@ +setPhpType($phpType); + $this->setXmlType($xmlType); + $this->setConverter($converter); + } + + public function getPhpType() + { + return $this->phpType; + } + + public function setPhpType($value) + { + $this->phpType = $value; + } + + public function getXmlType() + { + return $this->xmlType; + } + + public function setXmlType($value) + { + $this->xmlType = $value; + } + + public function getConverter() + { + return $this->converter; + } + + public function setConverter($value) + { + $this->converter = $value; + } +} \ No newline at end of file diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php new file mode 100644 index 0000000..5cf895b --- /dev/null +++ b/Soap/SoapHeader.php @@ -0,0 +1,37 @@ +namespace = $namespace; + $this->name = $name; + $this->data = $data; + } + + public function getNamespace() + { + return $this->namespace; + } + + public function getName() + { + return $this->name; + } + + public function getData() + { + return $this->data; + } + + public function toNativeSoapHeader() + { + return new \SoapHeader($this->namespace, $this->name, $this->data); + } +} \ No newline at end of file diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 7c6b29e..da0d99b 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\Soap; +use Bundle\WebServiceBundle\Util\Collection; + use Symfony\Component\HttpFoundation\Request; /** @@ -30,9 +32,9 @@ class SoapRequest extends Request protected $soapAction; /** - * @var unknown + * @var \Bundle\WebServiceBundle\Util\Collection */ - protected $soapHeader; + protected $soapHeaders; /** * @var unknown @@ -44,6 +46,8 @@ class SoapRequest extends Request parent::__construct($query, null, $attributes, $cookies, null, $server); $this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent(); + + $this->soapHeaders = new Collection('getName'); } /** @@ -56,6 +60,11 @@ class SoapRequest extends Request return $this->rawContent; } + public function getSoapHeaders() + { + return $this->soapHeaders; + } + /** * Loads the plain HTTP POST data. * diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 3ef872d..4d7cc34 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\Soap; +use Bundle\WebServiceBundle\Util\Collection; + use Symfony\Component\HttpFoundation\Response; /** @@ -19,21 +21,19 @@ use Symfony\Component\HttpFoundation\Response; */ class SoapResponse extends Response { + /** + * @var \Bundle\WebServiceBundle\Util\Collection + */ protected $soapHeaders; protected $soapReturnValue; - public function __construct($returnValue) + public function __construct($returnValue = null) { parent::__construct(); - $this->soapHeaders = array(); - $this->soapReturnValue = $returnValue; - } - - public function addSoapHeader(\SoapHeader $header) - { - $this->soapHeaders[] = $header; + $this->soapHeaders = new Collection('getName'); + $this->setReturnValue($returnValue); } public function getSoapHeaders() @@ -41,6 +41,11 @@ class SoapResponse extends Response return $this->soapHeaders; } + public function setReturnValue($value) + { + $this->soapReturnValue = $value; + } + public function getReturnValue() { return $this->soapReturnValue; diff --git a/SoapKernel.php b/SoapKernel.php index 4441d31..36b1514 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -10,6 +10,12 @@ namespace Bundle\WebServiceBundle; +use Bundle\WebServiceBundle\Soap\SoapHeader; + +use Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader; + +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -18,6 +24,9 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\ServiceDefinition\Loader\LoaderInterface; + use Bundle\WebServiceBundle\Util\String; /** @@ -45,14 +54,25 @@ class SoapKernel implements HttpKernelInterface */ protected $soapResponse; + /** + * @var \Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition + */ + protected $serviceDefinition; + /** * @var \Symfony\Component\HttpKernel\HttpKernelInterface */ protected $kernel; - public function __construct(\SoapServer $server, HttpKernelInterface $kernel) + public function __construct(ServiceDefinition $definition, LoaderInterface $loader, DumperInterface $dumper, HttpKernelInterface $kernel) { - $this->soapServer = $server; + $this->serviceDefinition = $definition; + $loader->loadServiceDefinition($this->serviceDefinition); + + // assume $dumper creates WSDL 1.1 file + $wsdl = $dumper->dumpServiceDefinition($this->serviceDefinition); + + $this->soapServer = new \SoapServer($wsdl); $this->soapServer->setObject($this); $this->kernel = $kernel; @@ -76,26 +96,43 @@ class SoapKernel implements HttpKernelInterface return $this->soapResponse; } + /** + * This method gets called once for every SOAP header the \SoapServer received + * and afterwards once for the called SOAP operation. + * + * @param string $method The SOAP header or SOAP operation name + * @param array $arguments + * + * @return mixed + */ public function __call($method, $arguments) { - if($this->isSoapHeaderCallback($method)) + if($this->serviceDefinition->getHeaders()->has($method)) { - // $this->soapRequest->addSoapHeader(null); - } - else - { - // TODO: set _controller attribute of request - $this->soapRequest->attributes->set('_controller', $method); + // collect request soap headers + $headerDefinition = $this->serviceDefinition->getHeaders()->get($method); + $this->soapRequest->getSoapHeaders()->add($this->createSoapHeader($headerDefinition, $arguments[0])); + return; + } + + if($this->serviceDefinition->getMethods()->has($method)) + { + $methodDefinition = $this->serviceDefinition->getMethods()->get($method); + $this->soapRequest->attributes->set('_controller', $methodDefinition->getController()); + + // delegate to standard http kernel $response = $this->kernel->handle($this->soapRequest, self::MASTER_REQUEST, true); $this->soapResponse = $this->checkResponse($response); + // add response soap headers to soap server foreach($this->soapResponse->getSoapHeaders() as $header) { - $this->soapServer->addSoapHeader($header); + $this->soapServer->addSoapHeader($header->toNativeSoapHeader()); } + // return operation return value to soap server return $this->soapResponse->getReturnValue(); } } @@ -144,8 +181,13 @@ class SoapKernel implements HttpKernelInterface return $response; } - protected function isSoapHeaderCallback($method) + protected function createSoapHeader(ServiceHeader $headerDefinition, $data) { - return false; //String::endsWith($method, 'Header'); + if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches)) + { + throw new \InvalidArgumentException(); + } + + return new SoapHeader($matches[1], $matches[2], $data); } } \ No newline at end of file diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index 79887b0..890259f 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -11,6 +11,10 @@ namespace Bundle\WebServiceBundle\Tests; +use Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod; + +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; + use Symfony\Component\HttpFoundation\Request; use Bundle\WebServiceBundle\SoapKernel; @@ -31,13 +35,18 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase public function setUp() { - $soapServer = new \SoapServer(__DIR__ . '/fixtures/api.wsdl'); + $serviceDefinition = new ServiceDefinition('api'); + $serviceDefinition->getMethods()->add(new ServiceMethod('math_multiply', 'MathController::multiply')); + + $serviceDefinitionLoader = null; + $serviceDefinitionDumper = new StaticFileDumper(__DIR__ . '/fixtures/api.wsdl'); + $httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); $httpKernel->expects($this->any()) ->method('handle') ->will($this->returnValue(new SoapResponse(200))); - $this->soapKernel = new SoapKernel($soapServer, $httpKernel); + $this->soapKernel = new SoapKernel($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $httpKernel); } public function testHandle() @@ -48,11 +57,10 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase $this->assertXmlStringEqualsXmlString(self::$soapResponseContent, $response->getContent()); } - /** - * @expectedException InvalidArgumentException - */ public function testHandleWithInvalidRequest() { + $this->setExpectedException('InvalidArgumentException'); + $this->soapKernel->handle(new Request()); } } \ No newline at end of file diff --git a/Tests/StaticFileDumper.php b/Tests/StaticFileDumper.php new file mode 100644 index 0000000..dd28739 --- /dev/null +++ b/Tests/StaticFileDumper.php @@ -0,0 +1,21 @@ +file = $file; + } + + public function dumpServiceDefinition(ServiceDefinition $definition) + { + return $this->file; + } +} \ No newline at end of file diff --git a/Util/Collection.php b/Util/Collection.php new file mode 100644 index 0000000..2ed42cb --- /dev/null +++ b/Util/Collection.php @@ -0,0 +1,52 @@ +keyPropertyGetter = $keyPropertyGetter; + } + + public function add($element) + { + $this->elements[call_user_func(array($element, $this->keyPropertyGetter))] = $element; + } + + public function addAll($elements) + { + foreach ($elements as $element) + { + $this->add($element); + } + } + + public function has($key) + { + return isset($this->elements[$key]); + } + + public function get($key) + { + return $this->has($key) ? $this->elements[$key] : null; + } + + public function clear() + { + $this->elements = array(); + } + + public function count() + { + return count($this->elements); + } + + public function getIterator () + { + return new \ArrayIterator($this->elements); + } +} \ No newline at end of file From 8d3743d92872e3892062a3e628e665296558af78 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Oct 2010 14:24:42 +0200 Subject: [PATCH 011/195] added initial support for service binding --- DependencyInjection/WebServiceExtension.php | 35 +++++- Resources/config/services.xml | 23 +++- ...mentLiteralWrappedRequestMessageBinder.php | 26 +++++ ...entLiteralWrappedResponseMessageBinder.php | 16 +++ ServiceBinding/MessageBinderInterface.php | 18 ++++ .../RpcLiteralRequestMessageBinder.php | 22 ++++ .../RpcLiteralResponseMessageBinder.php | 13 +++ ServiceBinding/ServiceBinder.php | 101 ++++++++++++++++++ .../{ServiceHeader.php => Argument.php} | 4 +- ServiceDefinition/Header.php | 35 ++++++ ServiceDefinition/Loader/XmlFileLoader.php | 39 ++++--- .../{ServiceMethod.php => Method.php} | 19 +++- .../{ServiceType.php => Type.php} | 2 +- Soap/SoapRequest.php | 1 - Soap/SoapResponse.php | 3 + SoapKernel.php | 53 ++++----- Tests/SoapKernelTest.php | 23 ++-- Tests/fixtures/api-servicedefinition.xml | 14 +++ 18 files changed, 379 insertions(+), 68 deletions(-) create mode 100644 ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php create mode 100644 ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php create mode 100644 ServiceBinding/MessageBinderInterface.php create mode 100644 ServiceBinding/RpcLiteralRequestMessageBinder.php create mode 100644 ServiceBinding/RpcLiteralResponseMessageBinder.php create mode 100644 ServiceBinding/ServiceBinder.php rename ServiceDefinition/{ServiceHeader.php => Argument.php} (83%) create mode 100644 ServiceDefinition/Header.php rename ServiceDefinition/{ServiceMethod.php => Method.php} (59%) rename ServiceDefinition/{ServiceType.php => Type.php} (97%) create mode 100644 Tests/fixtures/api-servicedefinition.xml diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 015591c..e4b4d9e 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -31,12 +31,19 @@ class WebServiceExtension extends Extension $configuration->setAlias('http_kernel', 'webservice.kernel'); } - if(!isset($config['definition'])) + if(isset($config['definition'])) + { + $this->registerServiceDefinitionConfig($config['definition'], $configuration); + } + else { throw new \InvalidArgumentException(); } - $this->registerServiceDefinitionConfig($config['definition'], $configuration); + if(isset($config['binding'])) + { + $this->registerServiceBindingConfig($config['binding'], $configuration); + } } protected function registerServiceDefinitionConfig(array $config, ContainerBuilder $configuration) @@ -50,6 +57,30 @@ class WebServiceExtension extends Extension $configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null); } + protected function registerServiceBindingConfig(array $config, ContainerBuilder $configuration) + { + $style = isset($config['style']) ? $config['style'] : 'document-literal-wrapped'; + + if(!in_array($style, array('document-literal-wrapped', 'rpc-literal'))) + { + throw new \InvalidArgumentException(); + } + + $binderNamespace = 'Bundle\\WebServiceBundle\\ServiceBinding\\'; + + switch ($style) + { + case 'document-literal-wrapped': + $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'DocumentLiteralWrappedRequestMessageBinder'); + $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'DocumentLiteralWrappedResponseMessageBinder'); + break; + case 'rpc-literal': + $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'RpcLiteralRequestMessageBinder'); + $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'RpcLiteralResponseMessageBinder'); + break; + } + } + public function getXsdValidationBasePath() { return null; diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 896ec68..accd3c7 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -6,9 +6,12 @@ Bundle\WebServiceBundle\Soap\SoapRequest + Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder + Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder + Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader - Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralFileDumper + Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralWrappedFileDumper @@ -19,12 +22,22 @@ - - - - + + + + + + + + + + + + + + %webservice.definition.name% diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php new file mode 100644 index 0000000..6401d19 --- /dev/null +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -0,0 +1,26 @@ + 1) + { + throw new \InvalidArgumentException(); + } + + $result = array(); + $message = $message[0]; + + foreach($messageDefinition->getArguments() as $argument) + { + $result[$argument->getName()] = $message->{$argument->getName()}; + } + + return $result; + } +} \ No newline at end of file diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php new file mode 100644 index 0000000..7ff4910 --- /dev/null +++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -0,0 +1,16 @@ +{$messageDefinition->getName() . 'Result'} = $message; + + return $result; + } +} \ No newline at end of file diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php new file mode 100644 index 0000000..867c781 --- /dev/null +++ b/ServiceBinding/MessageBinderInterface.php @@ -0,0 +1,18 @@ +getArguments() as $argument) + { + $result[$argument->getName()] = $message[$i]; + $i++; + } + + return $result; + } +} \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php new file mode 100644 index 0000000..b04c14f --- /dev/null +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -0,0 +1,13 @@ +loadServiceDefinition($definition); + + $this->definition = $definition; + $this->definitionDumper = $dumper; + + $this->requestMessageBinder = $requestMessageBinder; + $this->responseMessageBinder = $responseMessageBinder; + } + + public function getSerializedServiceDefinition() + { + // TODO: add caching + return $this->definitionDumper->dumpServiceDefinition($this->definition); + } + + public function isServiceHeader($name) + { + return $this->definition->getHeaders()->has($name); + } + + public function isServiceMethod($name) + { + return $this->definition->getMethods()->has($name); + } + + public function processServiceHeader($name, $data) + { + $headerDefinition = $this->definition->getHeaders()->get($name); + + return $this->createSoapHeader($headerDefinition, $data); + } + + public function processServiceMethodArguments($name, $arguments) + { + $methodDefinition = $this->definition->getMethods()->get($name); + + $result = array(); + $result['_controller'] = $methodDefinition->getController(); + $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments)); + + return $result; + } + + public function processServiceMethodReturnValue($name, $return) + { + $methodDefinition = $this->definition->getMethods()->get($name); + + return $this->responseMessageBinder->processMessage($methodDefinition, $return); + } + + protected function createSoapHeader(Header $headerDefinition, $data) + { + if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches)) + { + throw new \InvalidArgumentException(); + } + + return new SoapHeader($matches[1], $matches[2], $data); + } +} \ No newline at end of file diff --git a/ServiceDefinition/ServiceHeader.php b/ServiceDefinition/Argument.php similarity index 83% rename from ServiceDefinition/ServiceHeader.php rename to ServiceDefinition/Argument.php index 8df73fb..4f812ec 100644 --- a/ServiceDefinition/ServiceHeader.php +++ b/ServiceDefinition/Argument.php @@ -2,12 +2,12 @@ namespace Bundle\WebServiceBundle\ServiceDefinition; -class ServiceHeader +class Argument { private $name; private $type; - public function __construct($name = null, ServiceType $type = null) + public function __construct($name = null, Type $type = null) { $this->setName($name); $this->setType($type); diff --git a/ServiceDefinition/Header.php b/ServiceDefinition/Header.php new file mode 100644 index 0000000..42ef3e2 --- /dev/null +++ b/ServiceDefinition/Header.php @@ -0,0 +1,35 @@ +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/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index af3cdfd..b35a265 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -2,13 +2,11 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceType; - use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader; +use Bundle\WebServiceBundle\ServiceDefinition\Header; +use Bundle\WebServiceBundle\ServiceDefinition\Method; +use Bundle\WebServiceBundle\ServiceDefinition\Argument; +use Bundle\WebServiceBundle\ServiceDefinition\Type; class XmlFileLoader extends FileLoader { @@ -35,11 +33,11 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader + * @return \Bundle\WebServiceBundle\ServiceDefinition\Header */ protected function parseHeader(\SimpleXMLElement $node) { - $header = new ServiceHeader((string)$node['name'], $this->parseType($node->type)); + $header = new Header((string)$node['name'], $this->parseType($node->type)); return $header; } @@ -47,11 +45,16 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod + * @return \Bundle\WebServiceBundle\ServiceDefinition\Method */ protected function parseMethod(\SimpleXMLElement $node) { - $method = new ServiceMethod((string)$node['name'], (string)$node['controller']); + $method = new Method((string)$node['name'], (string)$node['controller']); + + foreach($node->argument as $argument) + { + $method->getArguments()->add($this->parseArgument($argument)); + } return $method; } @@ -59,7 +62,19 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceType + * @return \Bundle\WebServiceBundle\ServiceDefinition\Argument + */ + protected function parseArgument(\SimpleXMLElement $node) + { + $argument = new Argument((string)$node['name'], $this->parseType($node->type)); + + return $argument; + } + + /** + * @param \SimpleXMLElement $node + * + * @return \Bundle\WebServiceBundle\ServiceDefinition\Type */ protected function parseType(\SimpleXMLElement $node) { @@ -67,7 +82,7 @@ class XmlFileLoader extends FileLoader $qname = explode(':', $node['xml-type'], 2); $xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]); - $type = new ServiceType((string)$node['php-type'], $xmlType, (string)$node['converter']); + $type = new Type((string)$node['php-type'], $xmlType, (string)$node['converter']); return $type; } diff --git a/ServiceDefinition/ServiceMethod.php b/ServiceDefinition/Method.php similarity index 59% rename from ServiceDefinition/ServiceMethod.php rename to ServiceDefinition/Method.php index d78ead6..1a157fe 100644 --- a/ServiceDefinition/ServiceMethod.php +++ b/ServiceDefinition/Method.php @@ -2,15 +2,19 @@ namespace Bundle\WebServiceBundle\ServiceDefinition; -class ServiceMethod +use Bundle\WebServiceBundle\Util\Collection; + +class Method { private $name; private $controller; + private $arguments; - public function __construct($name = null, $controller = null) + public function __construct($name = null, $controller = null, array $arguments = array()) { $this->setName($name); $this->setController($controller); + $this->setArguments($arguments); } public function getName() @@ -32,4 +36,15 @@ class ServiceMethod { $this->controller = $controller; } + + public function getArguments() + { + return $this->arguments; + } + + public function setArguments($arguments) + { + $this->arguments = new Collection('getName'); + $this->arguments->addAll($arguments); + } } \ No newline at end of file diff --git a/ServiceDefinition/ServiceType.php b/ServiceDefinition/Type.php similarity index 97% rename from ServiceDefinition/ServiceType.php rename to ServiceDefinition/Type.php index bcf0699..f4e33de 100644 --- a/ServiceDefinition/ServiceType.php +++ b/ServiceDefinition/Type.php @@ -2,7 +2,7 @@ namespace Bundle\WebServiceBundle\ServiceDefinition; -class ServiceType +class Type { private $phpType; private $xmlType; diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index da0d99b..cbc8b89 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -46,7 +46,6 @@ class SoapRequest extends Request parent::__construct($query, null, $attributes, $cookies, null, $server); $this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent(); - $this->soapHeaders = new Collection('getName'); } diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 4d7cc34..46042cc 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -26,6 +26,9 @@ class SoapResponse extends Response */ protected $soapHeaders; + /** + * @var mixed + */ protected $soapReturnValue; public function __construct($returnValue = null) diff --git a/SoapKernel.php b/SoapKernel.php index 36b1514..ba80ca4 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -10,12 +10,6 @@ namespace Bundle\WebServiceBundle; -use Bundle\WebServiceBundle\Soap\SoapHeader; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader; - -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; - use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -23,9 +17,9 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; +use Bundle\WebServiceBundle\Soap\SoapHeader; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\ServiceDefinition\Loader\LoaderInterface; +use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; use Bundle\WebServiceBundle\Util\String; @@ -55,24 +49,20 @@ class SoapKernel implements HttpKernelInterface protected $soapResponse; /** - * @var \Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition + * @var \Bundle\WebServiceBundle\ServiceBinding\ServiceBinder */ - protected $serviceDefinition; + protected $serviceBinder; /** * @var \Symfony\Component\HttpKernel\HttpKernelInterface */ protected $kernel; - public function __construct(ServiceDefinition $definition, LoaderInterface $loader, DumperInterface $dumper, HttpKernelInterface $kernel) + public function __construct(ServiceBinder $serviceBinder, HttpKernelInterface $kernel) { - $this->serviceDefinition = $definition; - $loader->loadServiceDefinition($this->serviceDefinition); + $this->serviceBinder = $serviceBinder; - // assume $dumper creates WSDL 1.1 file - $wsdl = $dumper->dumpServiceDefinition($this->serviceDefinition); - - $this->soapServer = new \SoapServer($wsdl); + $this->soapServer = new \SoapServer($this->serviceBinder->getSerializedServiceDefinition()); $this->soapServer->setObject($this); $this->kernel = $kernel; @@ -107,19 +97,21 @@ class SoapKernel implements HttpKernelInterface */ public function __call($method, $arguments) { - if($this->serviceDefinition->getHeaders()->has($method)) + if($this->serviceBinder->isServiceHeader($method)) { // collect request soap headers - $headerDefinition = $this->serviceDefinition->getHeaders()->get($method); - $this->soapRequest->getSoapHeaders()->add($this->createSoapHeader($headerDefinition, $arguments[0])); + $this->soapRequest->getSoapHeaders()->add( + $this->serviceBinder->processServiceHeader($method, $arguments[0]) + ); return; } - if($this->serviceDefinition->getMethods()->has($method)) + if($this->serviceBinder->isServiceMethod($method)) { - $methodDefinition = $this->serviceDefinition->getMethods()->get($method); - $this->soapRequest->attributes->set('_controller', $methodDefinition->getController()); + $this->soapRequest->attributes->add( + $this->serviceBinder->processServiceMethodArguments($method, $arguments) + ); // delegate to standard http kernel $response = $this->kernel->handle($this->soapRequest, self::MASTER_REQUEST, true); @@ -133,7 +125,10 @@ class SoapKernel implements HttpKernelInterface } // return operation return value to soap server - return $this->soapResponse->getReturnValue(); + return $this->serviceBinder->processServiceMethodReturnValue( + $method, + $this->soapResponse->getReturnValue() + ); } } @@ -180,14 +175,4 @@ class SoapKernel implements HttpKernelInterface return $response; } - - protected function createSoapHeader(ServiceHeader $headerDefinition, $data) - { - if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches)) - { - throw new \InvalidArgumentException(); - } - - return new SoapHeader($matches[1], $matches[2], $data); - } } \ No newline at end of file diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index 890259f..49e8727 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -10,17 +10,20 @@ namespace Bundle\WebServiceBundle\Tests; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; - use Symfony\Component\HttpFoundation\Request; use Bundle\WebServiceBundle\SoapKernel; use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; +use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; +use Bundle\WebServiceBundle\ServiceBinding\RpcLiteralResponseMessageBinder; +use Bundle\WebServiceBundle\ServiceBinding\RpcLiteralRequestMessageBinder; + +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\ServiceDefinition\Method; +use Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader; + /** * UnitTest for \Bundle\WebServiceBundle\SoapKernel. * @@ -36,17 +39,19 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase public function setUp() { $serviceDefinition = new ServiceDefinition('api'); - $serviceDefinition->getMethods()->add(new ServiceMethod('math_multiply', 'MathController::multiply')); - - $serviceDefinitionLoader = null; + $serviceDefinitionLoader = new XmlFileLoader(__DIR__ . '/fixtures/api-servicedefinition.xml'); $serviceDefinitionDumper = new StaticFileDumper(__DIR__ . '/fixtures/api.wsdl'); + $requestMessageBinder = new RpcLiteralRequestMessageBinder(); + $responseMessageBinder = new RpcLiteralResponseMessageBinder(); + + $serviceBinder = new ServiceBinder($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $requestMessageBinder, $responseMessageBinder); $httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); $httpKernel->expects($this->any()) ->method('handle') ->will($this->returnValue(new SoapResponse(200))); - $this->soapKernel = new SoapKernel($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $httpKernel); + $this->soapKernel = new SoapKernel($serviceBinder, $httpKernel); } public function testHandle() diff --git a/Tests/fixtures/api-servicedefinition.xml b/Tests/fixtures/api-servicedefinition.xml new file mode 100644 index 0000000..30fd286 --- /dev/null +++ b/Tests/fixtures/api-servicedefinition.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file From 4ed8d6813ad021a83839a99f9e0384b55dd62b9d Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Oct 2010 16:58:14 +0200 Subject: [PATCH 012/195] added initial support for incoming mtom/xop message handling --- Soap/SoapAttachment.php | 32 +++++++++++ Soap/SoapRequest.php | 121 +++++++++++++++++++++++++++++++++++++++- SoapKernel.php | 2 +- 3 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 Soap/SoapAttachment.php diff --git a/Soap/SoapAttachment.php b/Soap/SoapAttachment.php new file mode 100644 index 0000000..4103652 --- /dev/null +++ b/Soap/SoapAttachment.php @@ -0,0 +1,32 @@ +id = $id; + $this->type = $type; + $this->content = $content; + } + + public function getId() + { + return $this->id; + } + + public function getType() + { + return $this->type; + } + + public function getContent() + { + return $this->content; + } +} \ No newline at end of file diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index cbc8b89..5be7a4b 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -14,6 +14,9 @@ use Bundle\WebServiceBundle\Util\Collection; use Symfony\Component\HttpFoundation\Request; +use Zend\Mime\Mime; +use Zend\Mime\Message; + /** * SoapRequest. * @@ -26,6 +29,11 @@ class SoapRequest extends Request */ protected $rawContent; + /** + * @var string + */ + protected $soapMessage; + /** * @var string */ @@ -37,20 +45,22 @@ class SoapRequest extends Request protected $soapHeaders; /** - * @var unknown + * @var \Bundle\WebServiceBundle\Util\Collection */ - protected $soapArguments; + protected $soapAttachments; public function __construct($rawContent = null, array $query = null, array $attributes = null, array $cookies = null, array $server = null) { parent::__construct($query, null, $attributes, $cookies, null, $server); $this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent(); + $this->soapMessage = null; $this->soapHeaders = new Collection('getName'); + $this->soapAttachments = new Collection('getId'); } /** - * Gets the SOAP XML content. + * Gets raw data send to the server. * * @return string */ @@ -59,11 +69,31 @@ class SoapRequest extends Request return $this->rawContent; } + /** + * Gets the XML string of the SOAP message. + * + * @return string + */ + public function getSoapMessage() + { + if($this->soapMessage === null) + { + $this->soapMessage = $this->initializeSoapMessage(); + } + + return $this->soapMessage; + } + public function getSoapHeaders() { return $this->soapHeaders; } + public function getSoapAttachments() + { + return $this->soapAttachments; + } + /** * Loads the plain HTTP POST data. * @@ -73,4 +103,89 @@ class SoapRequest extends Request { return isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents('php://input'); } + + protected function initializeSoapMessage() + { + if($this->server->has('CONTENT_TYPE')) + { + $type = $this->splitContentTypeHeader($this->server->get('CONTENT_TYPE')); + + switch($type['_type']) + { + case 'multipart/related': + if($type['type'] == 'application/xop+xml') + { + return $this->initializeMtomSoapMessage($type, $this->rawContent); + } + else + { + //log error + } + break; + case 'application/soap+xml': + // goto fallback + break; + default: + // log error + break; + } + } + + // fallback + return $this->rawContent; + } + + protected function initializeMtomSoapMessage(array $contentTypeHeader, $content) + { + if(!isset($contentTypeHeader['start']) || !isset($contentTypeHeader['boundary'])) + { + throw new \InvalidArgumentException(); + } + + $mimeMessage = Message::createFromMessage($content, $contentTypeHeader['boundary']); + $mimeParts = $mimeMessage->getParts(); + + $soapMimePartId = $contentTypeHeader['start']; + $soapMimePartType = $this->splitContentTypeHeader($contentTypeHeader['start-info']); + + $rootPart = array_shift($mimeParts); + $rootPartType = $this->splitContentTypeHeader($rootPart->type); + + // TODO: add more checks to achieve full compatibility to MTOM spec + // http://www.w3.org/TR/soap12-mtom/ + if($rootPart->id != $soapMimePartId || $rootPartType['_type'] != 'application/xop+xml' || $rootPartType['type'] != $soapMimePartType['type']) + { + throw new \InvalidArgumentException(); + } + + foreach($mimeParts as $mimePart) + { + $this->soapAttachments->add(new SoapAttachment( + trim($mimePart->id, '<>'), + $mimePart->type, + // handle content decoding / prevent encoding + $mimePart->getContent() + )); + } + + // handle content decoding / prevent encoding + return $rootPart->getContent(); + } + + protected function splitContentTypeHeader($header) + { + $result = array(); + $parts = explode(';', strtolower($header)); + + $result['_type'] = array_shift($parts); + + foreach($parts as $part) + { + list($key, $value) = explode('=', trim($part), 2); + + $result[$key] = trim($value, '"'); + } + + return $result; + } } \ No newline at end of file diff --git a/SoapKernel.php b/SoapKernel.php index ba80ca4..6e67b1f 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -78,7 +78,7 @@ class SoapKernel implements HttpKernelInterface $this->soapRequest = $this->checkRequest($request); ob_start(); - $this->soapServer->handle($this->soapRequest->getRawContent()); + $this->soapServer->handle($this->soapRequest->getSoapMessage()); $soapResponseContent = ob_get_clean(); $this->soapResponse->setContent($soapResponseContent); From c7f173456b2997ef4f2f4ba23865305e78792d30 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Oct 2010 17:01:27 +0200 Subject: [PATCH 013/195] added header comment --- .../DocumentLiteralWrappedRequestMessageBinder.php | 8 ++++++++ .../DocumentLiteralWrappedResponseMessageBinder.php | 8 ++++++++ ServiceBinding/MessageBinderInterface.php | 8 ++++++++ ServiceBinding/RpcLiteralRequestMessageBinder.php | 8 ++++++++ ServiceBinding/RpcLiteralResponseMessageBinder.php | 8 ++++++++ ServiceBinding/ServiceBinder.php | 8 ++++++++ ServiceDefinition/Argument.php | 8 ++++++++ ServiceDefinition/Dumper/DumperInterface.php | 8 ++++++++ ServiceDefinition/Header.php | 8 ++++++++ ServiceDefinition/Loader/FileLoader.php | 8 ++++++++ ServiceDefinition/Loader/LoaderInterface.php | 8 ++++++++ ServiceDefinition/Loader/XmlFileLoader.php | 8 ++++++++ ServiceDefinition/Method.php | 8 ++++++++ ServiceDefinition/ServiceDefinition.php | 8 ++++++++ ServiceDefinition/Type.php | 8 ++++++++ Soap/SoapAttachment.php | 8 ++++++++ Soap/SoapHeader.php | 8 ++++++++ Tests/StaticFileDumper.php | 8 ++++++++ Util/Collection.php | 8 ++++++++ 19 files changed, 152 insertions(+) diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index 6401d19..59409eb 100644 --- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php index 7ff4910..9138fe2 100644 --- a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php index 867c781..876fb99 100644 --- a/ServiceBinding/MessageBinderInterface.php +++ b/ServiceBinding/MessageBinderInterface.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 3ab5016..50590f7 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index b04c14f..970d587 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 8bd5e8e..207cecf 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceBinding; diff --git a/ServiceDefinition/Argument.php b/ServiceDefinition/Argument.php index 4f812ec..5a715d2 100644 --- a/ServiceDefinition/Argument.php +++ b/ServiceDefinition/Argument.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition; diff --git a/ServiceDefinition/Dumper/DumperInterface.php b/ServiceDefinition/Dumper/DumperInterface.php index 9cb12ee..4ae8701 100644 --- a/ServiceDefinition/Dumper/DumperInterface.php +++ b/ServiceDefinition/Dumper/DumperInterface.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; diff --git a/ServiceDefinition/Header.php b/ServiceDefinition/Header.php index 42ef3e2..ef450a2 100644 --- a/ServiceDefinition/Header.php +++ b/ServiceDefinition/Header.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition; diff --git a/ServiceDefinition/Loader/FileLoader.php b/ServiceDefinition/Loader/FileLoader.php index 0c2564d..9a54e2c 100644 --- a/ServiceDefinition/Loader/FileLoader.php +++ b/ServiceDefinition/Loader/FileLoader.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; diff --git a/ServiceDefinition/Loader/LoaderInterface.php b/ServiceDefinition/Loader/LoaderInterface.php index d3e2a2e..c7f25c3 100644 --- a/ServiceDefinition/Loader/LoaderInterface.php +++ b/ServiceDefinition/Loader/LoaderInterface.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index b35a265..0c9d354 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php index 1a157fe..9f2fb9a 100644 --- a/ServiceDefinition/Method.php +++ b/ServiceDefinition/Method.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition; diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index 1446275..e116372 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition; diff --git a/ServiceDefinition/Type.php b/ServiceDefinition/Type.php index f4e33de..176f748 100644 --- a/ServiceDefinition/Type.php +++ b/ServiceDefinition/Type.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\ServiceDefinition; diff --git a/Soap/SoapAttachment.php b/Soap/SoapAttachment.php index 4103652..d9d07db 100644 --- a/Soap/SoapAttachment.php +++ b/Soap/SoapAttachment.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\Soap; diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php index 5cf895b..9c926ec 100644 --- a/Soap/SoapHeader.php +++ b/Soap/SoapHeader.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\Soap; diff --git a/Tests/StaticFileDumper.php b/Tests/StaticFileDumper.php index dd28739..82675ed 100644 --- a/Tests/StaticFileDumper.php +++ b/Tests/StaticFileDumper.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\Tests; diff --git a/Util/Collection.php b/Util/Collection.php index 2ed42cb..5afe7d9 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -1,4 +1,12 @@ + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ namespace Bundle\WebServiceBundle\Util; From 6ff34b8db9ead5ec26ea977c01033bc5cca0583b Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Oct 2010 17:27:46 +0200 Subject: [PATCH 014/195] added unit test for SoapRequest's mtom handling; fixed bugs; --- Soap/SoapRequest.php | 8 +++--- Tests/SoapRequestTest.php | 45 ++++++++++++++++++++++++++++++++++ Tests/fixtures/mtom/simple.txt | 16 ++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 Tests/SoapRequestTest.php create mode 100644 Tests/fixtures/mtom/simple.txt diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 5be7a4b..bd316fb 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -145,15 +145,15 @@ class SoapRequest extends Request $mimeMessage = Message::createFromMessage($content, $contentTypeHeader['boundary']); $mimeParts = $mimeMessage->getParts(); - $soapMimePartId = $contentTypeHeader['start']; - $soapMimePartType = $this->splitContentTypeHeader($contentTypeHeader['start-info']); + $soapMimePartId = trim($contentTypeHeader['start'], '<>'); + $soapMimePartType = $contentTypeHeader['start-info']; $rootPart = array_shift($mimeParts); $rootPartType = $this->splitContentTypeHeader($rootPart->type); // TODO: add more checks to achieve full compatibility to MTOM spec // http://www.w3.org/TR/soap12-mtom/ - if($rootPart->id != $soapMimePartId || $rootPartType['_type'] != 'application/xop+xml' || $rootPartType['type'] != $soapMimePartType['type']) + if($rootPart->id != $soapMimePartId || $rootPartType['_type'] != 'application/xop+xml' || $rootPartType['type'] != $soapMimePartType) { throw new \InvalidArgumentException(); } @@ -161,7 +161,7 @@ class SoapRequest extends Request foreach($mimeParts as $mimePart) { $this->soapAttachments->add(new SoapAttachment( - trim($mimePart->id, '<>'), + $mimePart->id, $mimePart->type, // handle content decoding / prevent encoding $mimePart->getContent() diff --git a/Tests/SoapRequestTest.php b/Tests/SoapRequestTest.php new file mode 100644 index 0000000..4f041a7 --- /dev/null +++ b/Tests/SoapRequestTest.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Tests; + +use Bundle\WebServiceBundle\Soap\SoapRequest; + +/** + * UnitTest for \Bundle\WebServiceBundle\Soap\SoapRequest. + * + * @author Christian Kerl + */ +class SoapRequestTest extends \PHPUnit_Framework_TestCase +{ + public function testMtomMessage() + { + $content = $this->loadRequestContentFixture('mtom/simple.txt'); + + $request = new SoapRequest($content); + $request->server->set('CONTENT_TYPE', 'multipart/related; type="application/xop+xml";start="";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=7";start-info="application/soap+xml"'); + + $message = $request->getSoapMessage(); + + $this->assertEquals(735, strlen(trim($message))); + $this->assertEquals(1, count($request->getSoapAttachments())); + + $attachment = $request->getSoapAttachments()->get('http://tempuri.org/1/632618206527087310'); + + $this->assertNotNull($attachment); + $this->assertEquals('application/octet-stream', $attachment->getType()); + $this->assertEquals(767, strlen(trim($attachment->getContent()))); + } + + private function loadRequestContentFixture($name) + { + return file_get_contents(__DIR__ . '/fixtures/' . $name); + } +} diff --git a/Tests/fixtures/mtom/simple.txt b/Tests/fixtures/mtom/simple.txt new file mode 100644 index 0000000..a1bf2b1 --- /dev/null +++ b/Tests/fixtures/mtom/simple.txt @@ -0,0 +1,16 @@ + +--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=7 +Content-ID: +Content-Transfer-Encoding: 8bit +Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml" + +http://xmlsoap.org/echoBinaryAsStringurn:uuid:1bf061d6-d532-4b0c-930b-8b8202c38b8ahttp://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymoushttp://131.107.72.15/Mtom/svc/service.svc/Soap12MtomUTF8 + +--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=7 +Content-ID: +Content-Transfer-Encoding: binary +Content-Type: application/octet-stream + +H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! H e l l o W o r l d ! + +--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=7-- \ No newline at end of file From 370147653cc0773e156df40cef789ba7e132da30 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Oct 2010 17:42:42 +0200 Subject: [PATCH 015/195] updated README --- README.markdown | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.markdown b/README.markdown index 0f2c87d..5bf024f 100644 --- a/README.markdown +++ b/README.markdown @@ -4,4 +4,25 @@ WebServiceBundle The WebServiceBundle is a Symfony2 bundle to build WSDL and SOAP based web services. It is based on the [ckWebServicePlugin] [1] for symfony. +Installation +------------ + +Put WebServiceBundle in your `src/Bundle` dir. Enable PHP's `SOAP` extension. + +Create a new front controller script (like `index.php`) for your web service endpoint, e.g. `webservice.php`. +Change the environment passed to the kernel constructor, e.g. to `soap`, in this new front controller script. + +Configure the WebServiceBundle in the configuration file for this new environment (e.g. `config_soap.yml`): + + webservice.config: + definition: + name: MyWebService + binding: + style: rpc-literal + +Test +---- + + phpunit -c myapp src/Bundle/WebServiceBundle + [1]: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file From 4cc5950a66a5612db154fcfb232e2f97a94db153 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 30 Dec 2010 02:13:56 +0100 Subject: [PATCH 016/195] updated mtom message validity checks --- Soap/SoapRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index bd316fb..3074e12 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -137,7 +137,7 @@ class SoapRequest extends Request protected function initializeMtomSoapMessage(array $contentTypeHeader, $content) { - if(!isset($contentTypeHeader['start']) || !isset($contentTypeHeader['boundary'])) + if(!isset($contentTypeHeader['start']) || !isset($contentTypeHeader['start-info']) || !isset($contentTypeHeader['boundary'])) { throw new \InvalidArgumentException(); } From 60795fbcbb47f754b4254222cafedbc7f5825cda Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 30 Dec 2010 02:18:10 +0100 Subject: [PATCH 017/195] added support for 'typemap' and 'classmap' SoapServer option --- Converter/ConverterRepository.php | 62 +++++++++++++++++++++ Converter/TypeConverterInterface.php | 30 ++++++++++ Converter/XopIncludeTypeConverter.php | 59 ++++++++++++++++++++ DependencyInjection/WebServiceExtension.php | 3 +- Resources/config/services.xml | 11 +++- ServiceBinding/ServiceBinder.php | 46 ++++++++++++++- SoapKernel.php | 21 ++++++- Tests/SoapKernelTest.php | 6 +- 8 files changed, 229 insertions(+), 9 deletions(-) create mode 100644 Converter/ConverterRepository.php create mode 100644 Converter/TypeConverterInterface.php create mode 100644 Converter/XopIncludeTypeConverter.php diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php new file mode 100644 index 0000000..b0b85a5 --- /dev/null +++ b/Converter/ConverterRepository.php @@ -0,0 +1,62 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Converter; + +/** + * + * @author Christian Kerl + */ +use Bundle\WebServiceBundle\SoapKernel; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +class ConverterRepository +{ + private $typeConverters = array(); + + public function __construct() + { + } + + public function addTypeConverter(TypeConverterInterface $converter) + { + $this->typeConverters[] = $converter; + } + + public function toSoapServerTypemap(SoapKernel $kernel) + { + $result = array(); + + foreach($this->typeConverters as $typeConverter) + { + $result[] = array( + 'type_name' => $typeConverter->getTypeName(), + 'type_ns' => $typeConverter->getTypeNamespace(), + 'from_xml' => function($input) use ($kernel, $typeConverter) { + return $typeConverter->convertXmlToPhp($kernel->getRequest(), $input); + }, + 'to_xml' => function($input) use ($kernel, $typeConverter) { + return $typeConverter->convertPhpToXml($kernel->getResponse(), $input); + } + ); + } + + return $result; + } + + public function registerTypeConverterServices(ContainerInterface $container) + { + foreach($container->findTaggedServiceIds('webservice.converter') as $id => $attributes) + { + $this->addTypeConverter($container->get($id)); + } + } +} diff --git a/Converter/TypeConverterInterface.php b/Converter/TypeConverterInterface.php new file mode 100644 index 0000000..d9453b9 --- /dev/null +++ b/Converter/TypeConverterInterface.php @@ -0,0 +1,30 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Converter; + +use Bundle\WebServiceBundle\Soap\SoapRequest; + +use Bundle\WebServiceBundle\Soap\SoapResponse; + +/** + * + * @author Christian Kerl + */ +interface TypeConverterInterface +{ + function getTypeNamespace(); + + function getTypeName(); + + function convertXmlToPhp(SoapRequest $request, $data); + + function convertPhpToXml(SoapResponse $response, $data); +} diff --git a/Converter/XopIncludeTypeConverter.php b/Converter/XopIncludeTypeConverter.php new file mode 100644 index 0000000..385a8ad --- /dev/null +++ b/Converter/XopIncludeTypeConverter.php @@ -0,0 +1,59 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Converter; + +use Bundle\WebServiceBundle\Soap\SoapRequest; + +use Bundle\WebServiceBundle\Soap\SoapResponse; + +use Bundle\WebServiceBundle\Util\String; + +/** + * + * @author Christian Kerl + */ +class XopIncludeTypeConverter implements TypeConverterInterface +{ + public function getTypeNamespace() + { + return 'http://www.w3.org/2001/XMLSchema'; + } + + public function getTypeName() + { + return 'base64Binary'; + } + + public function convertXmlToPhp(SoapRequest $request, $data) + { + $doc = new \DOMDocument(); + $doc->loadXML($data); + + $includes = $doc->getElementsByTagNameNS('http://www.w3.org/2004/08/xop/include', 'Include'); + $include = $includes->item(0); + + $ref = $include->getAttribute('href'); + + if(String::startsWith($ref, 'cid:')) + { + $cid = urldecode(substr($ref, 4)); + + return $request->getSoapAttachments()->get($cid)->getContent(); + } + + return $data; + } + + public function convertPhpToXml(SoapResponse $response, $data) + { + return $data; + } +} diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index e4b4d9e..17fb3ca 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -23,7 +23,7 @@ class WebServiceExtension extends Extension { public function configLoad(array $config, ContainerBuilder $configuration) { - if(!$configuration->hasDefinition('webservice_http_kernel')) + if(!$configuration->hasDefinition('webservice.kernel')) { $loader = new XmlFileLoader($configuration, __DIR__ . '/../Resources/config'); $loader->load('services.xml'); @@ -55,6 +55,7 @@ class WebServiceExtension extends Extension $configuration->setParameter('webservice.definition.name', $config['name']); $configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null); + $configuration->setParameter('webservice.definition.wsdl', isset($config['wsdl']) ? $config['wsdl'] : null); } protected function registerServiceBindingConfig(array $config, ContainerBuilder $configuration) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index accd3c7..e0eb394 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -11,7 +11,7 @@ Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader - Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralWrappedFileDumper + Bundle\WebServiceBundle\Tests\StaticFileDumper @@ -23,6 +23,7 @@ + @@ -38,6 +39,12 @@ + + + + + + %webservice.definition.name% @@ -45,7 +52,7 @@ %webservice.definition.resource% - + %webservice.definition.wsdl% \ No newline at end of file diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 207cecf..375e2f5 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\ServiceBinding; +use Bundle\WebServiceBundle\ServiceDefinition\Type; + use Bundle\WebServiceBundle\Soap\SoapHeader; use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; @@ -62,6 +64,39 @@ class ServiceBinder return $this->definitionDumper->dumpServiceDefinition($this->definition); } + public function getSoapServerClassmap() + { + $result = array(); + + foreach($this->definition->getHeaders() as $header) + { + $this->addSoapServerClassmapEntry($result, $header->getType()); + } + + foreach($this->definition->getMethods() as $method) + { + foreach($method->getArguments() as $arg) + { + $this->addSoapServerClassmapEntry($result, $arg->getType()); + } + } + + return $result; + } + + private function addSoapServerClassmapEntry(&$classmap, Type $type) + { + list($namespace, $xmlType) = $this->parsePackedQName($type->getXmlType()); + $phpType = $type->getPhpType(); + + if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) + { + // log warning + } + + $classmap[$xmlType] = $phpType; + } + public function isServiceHeader($name) { return $this->definition->getHeaders()->has($name); @@ -99,11 +134,18 @@ class ServiceBinder protected function createSoapHeader(Header $headerDefinition, $data) { - if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches)) + list($namespace, $name) = $this->parsePackedQName($headerDefinition->getType()->getXmlType()); + + return new SoapHeader($namespace, $name, $data); + } + + private function parsePackedQName($qname) + { + if(!preg_match('/^\{(.+)\}(.+)$/', $qname, $matches)) { throw new \InvalidArgumentException(); } - return new SoapHeader($matches[1], $matches[2], $data); + return array($matches[1], $matches[2]); } } \ No newline at end of file diff --git a/SoapKernel.php b/SoapKernel.php index 6e67b1f..e939583 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -10,6 +10,7 @@ namespace Bundle\WebServiceBundle; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -21,6 +22,8 @@ use Bundle\WebServiceBundle\Soap\SoapHeader; use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; +use Bundle\WebServiceBundle\Converter\ConverterRepository; + use Bundle\WebServiceBundle\Util\String; /** @@ -58,11 +61,18 @@ class SoapKernel implements HttpKernelInterface */ protected $kernel; - public function __construct(ServiceBinder $serviceBinder, HttpKernelInterface $kernel) + public function __construct(ServiceBinder $serviceBinder, ConverterRepository $converterRepository, HttpKernelInterface $kernel) { $this->serviceBinder = $serviceBinder; - $this->soapServer = new \SoapServer($this->serviceBinder->getSerializedServiceDefinition()); + $this->soapServer = new \SoapServer( + $this->serviceBinder->getSerializedServiceDefinition(), + array( + 'classmap' => $this->serviceBinder->getSoapServerClassmap(), + 'typemap' => $converterRepository->toSoapServerTypemap($this), + 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, + ) + ); $this->soapServer->setObject($this); $this->kernel = $kernel; @@ -73,7 +83,12 @@ class SoapKernel implements HttpKernelInterface return $this->soapRequest; } - public function handle(Request $request = null, $type = self::MASTER_REQUEST, $raw = false) + public function getResponse() + { + return $this->soapResponse; + } + + public function handle(Request $request = null, $type = self::MASTER_REQUEST, $catch = true) { $this->soapRequest = $this->checkRequest($request); diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index 49e8727..21d4490 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\Tests; +use Bundle\WebServiceBundle\Converter\ConverterRepository; + use Symfony\Component\HttpFoundation\Request; use Bundle\WebServiceBundle\SoapKernel; @@ -46,12 +48,14 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase $serviceBinder = new ServiceBinder($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $requestMessageBinder, $responseMessageBinder); + $converterRepository = new ConverterRepository(); + $httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); $httpKernel->expects($this->any()) ->method('handle') ->will($this->returnValue(new SoapResponse(200))); - $this->soapKernel = new SoapKernel($serviceBinder, $httpKernel); + $this->soapKernel = new SoapKernel($serviceBinder, $converterRepository, $httpKernel); } public function testHandle() From 1f8773a43301d4c1218dae40f04e427dcc20130b Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 22:57:40 +0100 Subject: [PATCH 018/195] fixed indention --- Converter/ConverterRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php index b0b85a5..b1691f1 100644 --- a/Converter/ConverterRepository.php +++ b/Converter/ConverterRepository.php @@ -38,7 +38,7 @@ class ConverterRepository foreach($this->typeConverters as $typeConverter) { $result[] = array( - 'type_name' => $typeConverter->getTypeName(), + 'type_name' => $typeConverter->getTypeName(), 'type_ns' => $typeConverter->getTypeNamespace(), 'from_xml' => function($input) use ($kernel, $typeConverter) { return $typeConverter->convertXmlToPhp($kernel->getRequest(), $input); From 928dc80b5e21570a3c32b9ce209d702950c8bf11 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 23:00:17 +0100 Subject: [PATCH 019/195] added return type to Method class --- ServiceDefinition/Loader/XmlFileLoader.php | 2 ++ ServiceDefinition/Method.php | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index 0c9d354..1fab1aa 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -64,6 +64,8 @@ class XmlFileLoader extends FileLoader $method->getArguments()->add($this->parseArgument($argument)); } + $method->setReturn($this->parseType($node->return->type)); + return $method; } diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php index 9f2fb9a..136f9a4 100644 --- a/ServiceDefinition/Method.php +++ b/ServiceDefinition/Method.php @@ -17,12 +17,14 @@ class Method private $name; private $controller; private $arguments; + private $return; - public function __construct($name = null, $controller = null, array $arguments = array()) + public function __construct($name = null, $controller = null, array $arguments = array(), $return = null) { $this->setName($name); $this->setController($controller); $this->setArguments($arguments); + $this->setReturn($return); } public function getName() @@ -55,4 +57,14 @@ class Method $this->arguments = new Collection('getName'); $this->arguments->addAll($arguments); } + + public function getReturn() + { + return $this->return; + } + + public function setReturn($return) + { + $this->return = $return; + } } \ No newline at end of file From 4d8fae2fbe640a89cd612fe50ea86a901b8ec833 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 23:01:34 +0100 Subject: [PATCH 020/195] added Assert class to simplify method parameter validation --- Util/Assert.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Util/Assert.php diff --git a/Util/Assert.php b/Util/Assert.php new file mode 100644 index 0000000..93daab8 --- /dev/null +++ b/Util/Assert.php @@ -0,0 +1,34 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Util; + +/** + * + * @author Christian Kerl + */ +class Assert +{ + const ARGUMENT_INVALID = "Argument '%s' is invalid!"; + const ARGUMENT_NULL = "Argument '%s' can't be null!"; + + public static function thatArgument($name, $condition, $message = self::ARGUMENT_INVALID) + { + if(!$condition) + { + throw new \InvalidArgumentException(sprintf($message, $name)); + } + } + + public static function thatArgumentNotNull($name, $value) + { + self::thatArgument($name, $value != null, self::ARGUMENT_NULL); + } +} From 4e54616d1e9afaaae60ae85e6619f7f68e7f4ff7 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 23:02:04 +0100 Subject: [PATCH 021/195] refactored FileLoader class to use new Assert class --- ServiceDefinition/Loader/FileLoader.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ServiceDefinition/Loader/FileLoader.php b/ServiceDefinition/Loader/FileLoader.php index 9a54e2c..a7e86bf 100644 --- a/ServiceDefinition/Loader/FileLoader.php +++ b/ServiceDefinition/Loader/FileLoader.php @@ -10,19 +10,16 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; +use Bundle\WebServiceBundle\Util\Assert; + abstract class FileLoader implements LoaderInterface { protected $file; public function __construct($file) { - if (!file_exists($file)) { - throw new \InvalidArgumentException(sprintf('The service definition file %s does not exist', $file)); - } - - if (!is_readable($file)) { - throw new \InvalidArgumentException(sprintf('The service definition file %s is not readable', $file)); - } + Assert::thatArgument('file', file_exists($file), 'The service definition file %s does not exist'); + Assert::thatArgument('file', is_readable($file), 'The service definition file %s is not readable'); $this->file = $file; } From 2a2552b14763092dbd14a9d560dae7364c59aa20 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 23:03:03 +0100 Subject: [PATCH 022/195] added initial implementation of WsdlFileDumper based on Zend Wsdl class --- ServiceDefinition/Dumper/FileDumper.php | 30 +++++ ServiceDefinition/Dumper/WsdlFileDumper.php | 117 ++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 ServiceDefinition/Dumper/FileDumper.php create mode 100644 ServiceDefinition/Dumper/WsdlFileDumper.php diff --git a/ServiceDefinition/Dumper/FileDumper.php b/ServiceDefinition/Dumper/FileDumper.php new file mode 100644 index 0000000..577e8c6 --- /dev/null +++ b/ServiceDefinition/Dumper/FileDumper.php @@ -0,0 +1,30 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; + +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; +use Bundle\WebServiceBundle\Util\Assert; + +/** + * + * @author Christian Kerl + */ +abstract class FileDumper implements DumperInterface +{ + protected $file; + + public function __construct($file) + { + Assert::thatArgumentNotNull('file', $file); + + $this->file = $file; + } +} diff --git a/ServiceDefinition/Dumper/WsdlFileDumper.php b/ServiceDefinition/Dumper/WsdlFileDumper.php new file mode 100644 index 0000000..e691cbd --- /dev/null +++ b/ServiceDefinition/Dumper/WsdlFileDumper.php @@ -0,0 +1,117 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; + +use Bundle\WebServiceBundle\ServiceDefinition\Method; +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; + +use Bundle\WebServiceBundle\Util\Assert; + +use Zend\Soap\Wsdl; + + +/** + * + * @author Christian Kerl + */ +class WsdlFileDumper extends FileDumper +{ + private $namespace; + + public function __construct($file, $namespace) + { + parent::__construct($file); + + Assert::thatArgumentNotNull('namespace', $namespace); + + $this->namespace = $namespace; + } + + public function dumpServiceDefinition(ServiceDefinition $definition) + { + Assert::thatArgumentNotNull('definition', $definition); + + $wsdl = new Wsdl($definition->getName(), $this->namespace); + + $port = $wsdl->addPortType($this->getPortTypeName($definition)); + $binding = $wsdl->addBinding($this->getBindingName($definition), $this->getPortTypeName($definition)); + + $wsdl->addSoapBinding($binding, 'document'); + $wsdl->addService($this->getServiceName($definition), $this->getPortTypeName($definition), $this->getBindingName($definition), 'http://localhost/service/'); + + foreach($definition->getMethods() as $method) + { + $requestParts = array(); + $responseParts = array(); + + foreach($method->getArguments() as $argument) + { + $requestParts[$argument->getName()] = $wsdl->getType($argument->getType()->getPhpType()); + } + + $responseParts['return'] = $wsdl->getType($method->getReturn()->getPhpType()); + + $wsdl->addMessage($this->getRequestMessageName($method), $requestParts); + $wsdl->addMessage($this->getResponseMessageName($method), $responseParts); + + $portOperation = $wsdl->addPortOperation($port, $method->getName(), $this->getRequestMessageName($method), $this->getResponseMessageName($method)); + $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); + + $bindingInput = array( + 'parts' => implode(' ', array_keys($requestParts)), + 'use' => 'literal', + 'namespace' => $this->namespace, + 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', + ); + $bindingOutput = array( + 'parts' => implode(' ', array_keys($responseParts)), + 'use' => 'literal', + 'namespace' => $this->namespace, + 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', + ); + + $bindingOperation = $wsdl->addBindingOperation($binding, $method->getName(), $bindingInput, $bindingOutput); + $wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method)); + } + + $wsdl->dump($this->file); + } + + protected function getPortTypeName(ServiceDefinition $definition) + { + return $definition->getName() . 'PortType'; + } + + protected function getBindingName(ServiceDefinition $definition) + { + return $definition->getName() . 'Binding'; + } + + protected function getServiceName(ServiceDefinition $definition) + { + return $definition->getName() . 'Service'; + } + + 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->namespace . $method->getName(); + } +} From 79da80bdb93df8c91fdbb89955a7cf0e02450a97 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 7 Jan 2011 23:03:37 +0100 Subject: [PATCH 023/195] fixed path to xsd schema --- Tests/fixtures/api-servicedefinition.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/fixtures/api-servicedefinition.xml b/Tests/fixtures/api-servicedefinition.xml index 30fd286..952f1a3 100644 --- a/Tests/fixtures/api-servicedefinition.xml +++ b/Tests/fixtures/api-servicedefinition.xml @@ -1,5 +1,5 @@ - + From e53b83616b6329529979ab2aa3aee7ef1fd8c793 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 3 Feb 2011 01:04:12 +0100 Subject: [PATCH 024/195] added namespace to service definition; --- DependencyInjection/WebServiceExtension.php | 9 +++-- ServiceDefinition/Dumper/WsdlFileDumper.php | 43 ++++++++++----------- ServiceDefinition/ServiceDefinition.php | 24 +++++++++++- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 17fb3ca..95dcb33 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\DependencyInjection; +use Bundle\WebServiceBundle\Util\Assert; + use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -48,12 +50,11 @@ class WebServiceExtension extends Extension protected function registerServiceDefinitionConfig(array $config, ContainerBuilder $configuration) { - if(!isset($config['name'])) - { - throw new \InvalidArgumentException(); - } + Assert::thatArgument('config.name', isset($config['name'])); + Assert::thatArgument('config.namespace', isset($config['namespace'])); $configuration->setParameter('webservice.definition.name', $config['name']); + $configuration->setParameter('webservice.definition.namespace', $config['namespace']); $configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null); $configuration->setParameter('webservice.definition.wsdl', isset($config['wsdl']) ? $config['wsdl'] : null); } diff --git a/ServiceDefinition/Dumper/WsdlFileDumper.php b/ServiceDefinition/Dumper/WsdlFileDumper.php index e691cbd..45746bf 100644 --- a/ServiceDefinition/Dumper/WsdlFileDumper.php +++ b/ServiceDefinition/Dumper/WsdlFileDumper.php @@ -24,28 +24,21 @@ use Zend\Soap\Wsdl; */ class WsdlFileDumper extends FileDumper { - private $namespace; - - public function __construct($file, $namespace) - { - parent::__construct($file); - - Assert::thatArgumentNotNull('namespace', $namespace); - - $this->namespace = $namespace; - } + private $definition; public function dumpServiceDefinition(ServiceDefinition $definition) { Assert::thatArgumentNotNull('definition', $definition); - $wsdl = new Wsdl($definition->getName(), $this->namespace); + $this->definition = $definition; - $port = $wsdl->addPortType($this->getPortTypeName($definition)); - $binding = $wsdl->addBinding($this->getBindingName($definition), $this->getPortTypeName($definition)); + $wsdl = new Wsdl($definition->getName(), $definition->getNamespace()); + + $port = $wsdl->addPortType($this->getPortTypeName()); + $binding = $wsdl->addBinding($this->getBindingName(), $this->getPortTypeName()); $wsdl->addSoapBinding($binding, 'document'); - $wsdl->addService($this->getServiceName($definition), $this->getPortTypeName($definition), $this->getBindingName($definition), 'http://localhost/service/'); + $wsdl->addService($this->getServiceName(), $this->getPortTypeName(), $this->getBindingName(), ''); foreach($definition->getMethods() as $method) { @@ -68,13 +61,13 @@ class WsdlFileDumper extends FileDumper $bindingInput = array( 'parts' => implode(' ', array_keys($requestParts)), 'use' => 'literal', - 'namespace' => $this->namespace, + 'namespace' => $definition->getNamespace(), 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); $bindingOutput = array( 'parts' => implode(' ', array_keys($responseParts)), 'use' => 'literal', - 'namespace' => $this->namespace, + 'namespace' => $definition->getNamespace(), 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); @@ -83,21 +76,25 @@ class WsdlFileDumper extends FileDumper } $wsdl->dump($this->file); + + $this->definition = null; + + return $this->file; } - protected function getPortTypeName(ServiceDefinition $definition) + protected function getPortTypeName() { - return $definition->getName() . 'PortType'; + return $this->definition->getName() . 'PortType'; } - protected function getBindingName(ServiceDefinition $definition) + protected function getBindingName() { - return $definition->getName() . 'Binding'; + return $this->definition->getName() . 'Binding'; } - protected function getServiceName(ServiceDefinition $definition) + protected function getServiceName() { - return $definition->getName() . 'Service'; + return $this->definition->getName() . 'Service'; } protected function getRequestMessageName(Method $method) @@ -112,6 +109,6 @@ class WsdlFileDumper extends FileDumper protected function getSoapOperationName(Method $method) { - return $this->namespace . $method->getName(); + return $this->definition->getNamespace() . $method->getName(); } } diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index e116372..b587b9e 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -19,6 +19,11 @@ class ServiceDefinition */ private $name; + /** + * @var string + */ + private $namespace; + /** * @var \Bundle\WebServiceBundle\Util\Collection */ @@ -29,9 +34,10 @@ class ServiceDefinition */ private $headers; - public function __construct($name = null, array $methods = array(), array $headers = array()) + public function __construct($name = null, $namespace = null, array $methods = array(), array $headers = array()) { $this->setName($name); + $this->setNamespace($namespace); $this->setMethods($methods); $this->setHeaders($headers); } @@ -52,6 +58,22 @@ class ServiceDefinition $this->name = $name; } + /** + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * @param string $namespace + */ + public function setNamespace($namespace) + { + $this->namespace = $namespace; + } + /** * @return \Bundle\WebServiceBundle\Util\Collection */ From 047db378c7082253f66bdb7cdad95437d8936b97 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 3 Feb 2011 01:07:08 +0100 Subject: [PATCH 025/195] refactored code to better separate responsibilities --- Converter/ConverterRepository.php | 20 +----- Resources/config/services.xml | 14 ++-- ServiceBinding/ServiceBinder.php | 60 ++-------------- Soap/SoapServerFactory.php | 111 ++++++++++++++++++++++++++++++ SoapKernel.php | 16 ++--- Tests/SoapKernelTest.php | 10 +-- Tests/StaticFileDumper.php | 11 +-- Util/QName.php | 49 +++++++++++++ 8 files changed, 190 insertions(+), 101 deletions(-) create mode 100644 Soap/SoapServerFactory.php create mode 100644 Util/QName.php diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php index b1691f1..2a31a95 100644 --- a/Converter/ConverterRepository.php +++ b/Converter/ConverterRepository.php @@ -31,25 +31,9 @@ class ConverterRepository $this->typeConverters[] = $converter; } - public function toSoapServerTypemap(SoapKernel $kernel) + public function getTypeConverters() { - $result = array(); - - foreach($this->typeConverters as $typeConverter) - { - $result[] = array( - 'type_name' => $typeConverter->getTypeName(), - 'type_ns' => $typeConverter->getTypeNamespace(), - 'from_xml' => function($input) use ($kernel, $typeConverter) { - return $typeConverter->convertXmlToPhp($kernel->getRequest(), $input); - }, - 'to_xml' => function($input) use ($kernel, $typeConverter) { - return $typeConverter->convertPhpToXml($kernel->getResponse(), $input); - } - ); - } - - return $result; + return $this->typeConverters; } public function registerTypeConverterServices(ContainerInterface $container) diff --git a/Resources/config/services.xml b/Resources/config/services.xml index e0eb394..4cb4bf6 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -11,7 +11,7 @@ Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader - Bundle\WebServiceBundle\Tests\StaticFileDumper + Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlFileDumper @@ -23,14 +23,12 @@ - + - - @@ -39,6 +37,12 @@ + + + + + + @@ -47,6 +51,8 @@ %webservice.definition.name% + %webservice.definition.namespace% + %webservice.definition.resource% diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 375e2f5..abf0430 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\ServiceBinding; +use Bundle\WebServiceBundle\Util\QName; + use Bundle\WebServiceBundle\ServiceDefinition\Type; use Bundle\WebServiceBundle\Soap\SoapHeader; @@ -43,60 +45,16 @@ class ServiceBinder public function __construct( ServiceDefinition $definition, - LoaderInterface $loader, - DumperInterface $dumper, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder ) { - $loader->loadServiceDefinition($definition); - $this->definition = $definition; - $this->definitionDumper = $dumper; $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; } - public function getSerializedServiceDefinition() - { - // TODO: add caching - return $this->definitionDumper->dumpServiceDefinition($this->definition); - } - - public function getSoapServerClassmap() - { - $result = array(); - - foreach($this->definition->getHeaders() as $header) - { - $this->addSoapServerClassmapEntry($result, $header->getType()); - } - - foreach($this->definition->getMethods() as $method) - { - foreach($method->getArguments() as $arg) - { - $this->addSoapServerClassmapEntry($result, $arg->getType()); - } - } - - return $result; - } - - private function addSoapServerClassmapEntry(&$classmap, Type $type) - { - list($namespace, $xmlType) = $this->parsePackedQName($type->getXmlType()); - $phpType = $type->getPhpType(); - - if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) - { - // log warning - } - - $classmap[$xmlType] = $phpType; - } - public function isServiceHeader($name) { return $this->definition->getHeaders()->has($name); @@ -134,18 +92,8 @@ class ServiceBinder protected function createSoapHeader(Header $headerDefinition, $data) { - list($namespace, $name) = $this->parsePackedQName($headerDefinition->getType()->getXmlType()); + $qname = QName::fromPackedQName($headerDefinition->getType()->getXmlType()); - return new SoapHeader($namespace, $name, $data); - } - - private function parsePackedQName($qname) - { - if(!preg_match('/^\{(.+)\}(.+)$/', $qname, $matches)) - { - throw new \InvalidArgumentException(); - } - - return array($matches[1], $matches[2]); + return new SoapHeader($qname->getNamespace(), $qname->getName(), $data); } } \ No newline at end of file diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php new file mode 100644 index 0000000..983a07c --- /dev/null +++ b/Soap/SoapServerFactory.php @@ -0,0 +1,111 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Soap; + +/** + * + * @author Christian Kerl + */ +use Bundle\WebServiceBundle\ServiceDefinition\Type; + +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\FileDumper; + +use Bundle\WebServiceBundle\Converter\ConverterRepository; + +use Bundle\WebServiceBundle\SoapKernel; + +use Bundle\WebServiceBundle\Util\QName; + +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; + +class SoapServerFactory +{ + private $definition; + private $converters; + private $dumper; + + public function __construct(ServiceDefinition $definition, ConverterRepository $converters, FileDumper $dumper) + { + $this->definition = $definition; + $this->converters = $converters; + $this->dumper = $dumper; + } + + public function create(&$request, &$response) + { + $file = $this->dumper->dumpServiceDefinition($this->definition); + + $server = new \SoapServer( + $file, + array( + 'classmap' => $this->createSoapServerClassmap(), + 'typemap' => $this->createSoapServerTypemap($request, $response), + 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, + ) + ); + + return $server; + } + + private function createSoapServerTypemap(&$request, &$response) + { + $result = array(); + + foreach($this->converters->getTypeConverters() as $typeConverter) + { + $result[] = array( + 'type_name' => $typeConverter->getTypeName(), + 'type_ns' => $typeConverter->getTypeNamespace(), + 'from_xml' => function($input) use (&$request, $typeConverter) { + return $typeConverter->convertXmlToPhp($request, $input); + }, + 'to_xml' => function($input) use (&$response, $typeConverter) { + return $typeConverter->convertPhpToXml($response, $input); + } + ); + } + + return $result; + } + + private function createSoapServerClassmap() + { + $result = array(); + + foreach($this->definition->getHeaders() as $header) + { + $this->addSoapServerClassmapEntry($result, $header->getType()); + } + + foreach($this->definition->getMethods() as $method) + { + foreach($method->getArguments() as $arg) + { + $this->addSoapServerClassmapEntry($result, $arg->getType()); + } + } + + return $result; + } + + private function addSoapServerClassmapEntry(&$classmap, Type $type) + { + $xmlType = QName::fromPackedQName($type->getXmlType())->getName(); + $phpType = $type->getPhpType(); + + if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) + { + // log warning + } + + $classmap[$xmlType] = $phpType; + } +} diff --git a/SoapKernel.php b/SoapKernel.php index e939583..aedd9bd 100644 --- a/SoapKernel.php +++ b/SoapKernel.php @@ -11,6 +11,8 @@ namespace Bundle\WebServiceBundle; +use Bundle\WebServiceBundle\Soap\SoapServerFactory; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -61,21 +63,13 @@ class SoapKernel implements HttpKernelInterface */ protected $kernel; - public function __construct(ServiceBinder $serviceBinder, ConverterRepository $converterRepository, HttpKernelInterface $kernel) + public function __construct(ServiceBinder $serviceBinder, SoapServerFactory $soapServerFactory, HttpKernelInterface $kernel) { $this->serviceBinder = $serviceBinder; - - $this->soapServer = new \SoapServer( - $this->serviceBinder->getSerializedServiceDefinition(), - array( - 'classmap' => $this->serviceBinder->getSoapServerClassmap(), - 'typemap' => $converterRepository->toSoapServerTypemap($this), - 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, - ) - ); + $this->soapServer = $soapServerFactory->create($this->soapRequest, $this->soapResponse); $this->soapServer->setObject($this); - $this->kernel = $kernel; + } public function getRequest() diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php index 21d4490..bb6dc5c 100644 --- a/Tests/SoapKernelTest.php +++ b/Tests/SoapKernelTest.php @@ -10,6 +10,8 @@ namespace Bundle\WebServiceBundle\Tests; +use Bundle\WebServiceBundle\Soap\SoapServerFactory; + use Bundle\WebServiceBundle\Converter\ConverterRepository; use Symfony\Component\HttpFoundation\Request; @@ -42,20 +44,20 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase { $serviceDefinition = new ServiceDefinition('api'); $serviceDefinitionLoader = new XmlFileLoader(__DIR__ . '/fixtures/api-servicedefinition.xml'); + $serviceDefinitionLoader->loadServiceDefinition($serviceDefinition); $serviceDefinitionDumper = new StaticFileDumper(__DIR__ . '/fixtures/api.wsdl'); $requestMessageBinder = new RpcLiteralRequestMessageBinder(); $responseMessageBinder = new RpcLiteralResponseMessageBinder(); - $serviceBinder = new ServiceBinder($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $requestMessageBinder, $responseMessageBinder); - + $serviceBinder = new ServiceBinder($serviceDefinition, $requestMessageBinder, $responseMessageBinder); $converterRepository = new ConverterRepository(); - + $soapServerFactory = new SoapServerFactory($serviceDefinition, $converterRepository, $serviceDefinitionDumper); $httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface'); $httpKernel->expects($this->any()) ->method('handle') ->will($this->returnValue(new SoapResponse(200))); - $this->soapKernel = new SoapKernel($serviceBinder, $converterRepository, $httpKernel); + $this->soapKernel = new SoapKernel($serviceBinder, $soapServerFactory, $httpKernel); } public function testHandle() diff --git a/Tests/StaticFileDumper.php b/Tests/StaticFileDumper.php index 82675ed..3d91744 100644 --- a/Tests/StaticFileDumper.php +++ b/Tests/StaticFileDumper.php @@ -10,18 +10,13 @@ namespace Bundle\WebServiceBundle\Tests; +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\FileDumper; + use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; -class StaticFileDumper implements DumperInterface +class StaticFileDumper extends FileDumper { - private $file; - - public function __construct($file) - { - $this->file = $file; - } - public function dumpServiceDefinition(ServiceDefinition $definition) { return $this->file; diff --git a/Util/QName.php b/Util/QName.php new file mode 100644 index 0000000..d2bf3f2 --- /dev/null +++ b/Util/QName.php @@ -0,0 +1,49 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Util; + +/** + * + * @author Christian Kerl + */ +class QName +{ + public static function fromPackedQName($qname) + { + Assert::thatArgument('qname', preg_match('/^\{(.+)\}(.+)$/', $qname, $matches)); + + return new self($matches[1], $matches[2]); + } + + private $namespace; + private $name; + + public function __construct($namespace, $name) + { + $this->namespace = $namespace; + $this->name = $name; + } + + public function getNamespace() + { + return $this->namespace; + } + + public function getName() + { + return $this->name; + } + + public function __toString() + { + return sprintf('{%s}%s', $this->getNamespace(), $this->getName()); + } +} From 52642f3ec6e5b8cb24758d67f9110b0903f0c7fb Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 25 Mar 2011 20:09:23 +0100 Subject: [PATCH 026/195] started refactoring SoapKernel to SoapWebServiceController, so Symfony2 kernel is no longer overridden and no special front controller scripts or environments are required --- .../SoapWebServiceController.php | 88 +++++++++---------- Soap/SoapRequest.php | 41 +++------ 2 files changed, 55 insertions(+), 74 deletions(-) rename SoapKernel.php => Controller/SoapWebServiceController.php (68%) diff --git a/SoapKernel.php b/Controller/SoapWebServiceController.php similarity index 68% rename from SoapKernel.php rename to Controller/SoapWebServiceController.php index aedd9bd..eb13e58 100644 --- a/SoapKernel.php +++ b/Controller/SoapWebServiceController.php @@ -29,14 +29,11 @@ use Bundle\WebServiceBundle\Converter\ConverterRepository; use Bundle\WebServiceBundle\Util\String; /** - * SoapKernel converts a SoapRequest to a SoapResponse. It uses PHP's SoapServer for SOAP message - * handling. The logic for every service method is implemented in a Symfony controller. The controller - * to use for a specific service method is defined in the ServiceDefinition. The controller is invoked - * by Symfony's HttpKernel implementation. + * * * @author Christian Kerl */ -class SoapKernel implements HttpKernelInterface +class SoapWebServiceController extends ContainerAware { /** * @var \SoapServer @@ -53,6 +50,11 @@ class SoapKernel implements HttpKernelInterface */ protected $soapResponse; + /** + * @var \Bundle\WebServiceBundle\ServiceConfigurationFactory + */ + protected $serviceConfigurationFactory; + /** * @var \Bundle\WebServiceBundle\ServiceBinding\ServiceBinder */ @@ -63,13 +65,10 @@ class SoapKernel implements HttpKernelInterface */ protected $kernel; - public function __construct(ServiceBinder $serviceBinder, SoapServerFactory $soapServerFactory, HttpKernelInterface $kernel) + public function __construct(ServiceConfigurationFactory $serviceConfigurationFactory, HttpKernelInterface $kernel) { - $this->serviceBinder = $serviceBinder; - $this->soapServer = $soapServerFactory->create($this->soapRequest, $this->soapResponse); - $this->soapServer->setObject($this); + $this->serviceConfigurationFactory = $serviceConfigurationFactory; $this->kernel = $kernel; - } public function getRequest() @@ -82,19 +81,45 @@ class SoapKernel implements HttpKernelInterface return $this->soapResponse; } - public function handle(Request $request = null, $type = self::MASTER_REQUEST, $catch = true) + public function handle($webservice) { - $this->soapRequest = $this->checkRequest($request); + $serviceConfiguration = $this->serviceConfigurationFactory->create($webservice); + + $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); + + $this->serviceBinder = $serviceConfiguration->createServiceBinder(); + + $this->soapServer = $serviceConfiguration->createServer($this->soapRequest, $this->soapResponse); + $this->soapServer->setObject($this); ob_start(); - $this->soapServer->handle($this->soapRequest->getSoapMessage()); - + { + $this->soapServer->handle($this->soapRequest->getSoapMessage()); + } $soapResponseContent = ob_get_clean(); + $this->soapResponse->setContent($soapResponseContent); return $this->soapResponse; } + public function definition($webservice) + { + $serviceConfiguration = $this->serviceConfigurationFactory->create($webservice); + $request = $this->container->get('request'); + + if($request->query->has('WSDL')) + { + // dump wsdl file + // return + } + else + { + // dump pretty definition + // return $this->container->get('templating')->renderView(''); + } + } + /** * This method gets called once for every SOAP header the \SoapServer received * and afterwards once for the called SOAP operation. @@ -122,8 +147,8 @@ class SoapKernel implements HttpKernelInterface $this->serviceBinder->processServiceMethodArguments($method, $arguments) ); - // delegate to standard http kernel - $response = $this->kernel->handle($this->soapRequest, self::MASTER_REQUEST, true); + // forward to controller + $response = $this->kernel->handle($this->soapRequest, self::SUB_REQUEST, false); $this->soapResponse = $this->checkResponse($response); @@ -142,32 +167,7 @@ class SoapKernel implements HttpKernelInterface } /** - * Checks the given Request, that it is a SoapRequest. If the request is null a new - * SoapRequest is created. - * - * @param Request $request A request to check - * - * @return SoapRequest A valid SoapRequest - * - * @throws InvalidArgumentException if the given Request is not a SoapRequest - */ - protected function checkRequest(Request $request) - { - if($request == null) - { - $request = new SoapRequest(); - } - - if(!is_a($request, __NAMESPACE__ . '\\Soap\\SoapRequest')) - { - throw new \InvalidArgumentException(); - } - - return $request; - } - - /** - * Checks the given Response, that it is a SoapResponse. + * Checks that the given Response is a SoapResponse. * * @param Response $response A response to check * @@ -177,11 +177,11 @@ class SoapKernel implements HttpKernelInterface */ protected function checkResponse(Response $response) { - if($response == null || !is_a($response, __NAMESPACE__ . '\\Soap\\SoapResponse')) + if($response == null || $response instanceof SoapResponse) { throw new \InvalidArgumentException(); } return $response; } -} \ No newline at end of file +} diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 3074e12..3f4b325 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -24,11 +24,11 @@ use Zend\Mime\Message; */ class SoapRequest extends Request { - /** - * @var string - */ - protected $rawContent; - + public static function createFromHttpRequest(Request $request) + { + return new static($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->content); + } + /** * @var string */ @@ -49,24 +49,15 @@ class SoapRequest extends Request */ protected $soapAttachments; - public function __construct($rawContent = null, array $query = null, array $attributes = null, array $cookies = null, array $server = null) + public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { - parent::__construct($query, null, $attributes, $cookies, null, $server); + parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content); - $this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent(); $this->soapMessage = null; $this->soapHeaders = new Collection('getName'); $this->soapAttachments = new Collection('getId'); - } - /** - * Gets raw data send to the server. - * - * @return string - */ - public function getRawContent() - { - return $this->rawContent; + $this->setRequestFormat('soap'); } /** @@ -94,16 +85,6 @@ class SoapRequest extends Request return $this->soapAttachments; } - /** - * Loads the plain HTTP POST data. - * - * @return string - */ - protected function loadRawContent() - { - return isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents('php://input'); - } - protected function initializeSoapMessage() { if($this->server->has('CONTENT_TYPE')) @@ -115,7 +96,7 @@ class SoapRequest extends Request case 'multipart/related': if($type['type'] == 'application/xop+xml') { - return $this->initializeMtomSoapMessage($type, $this->rawContent); + return $this->initializeMtomSoapMessage($type, $this->getContent()); } else { @@ -132,7 +113,7 @@ class SoapRequest extends Request } // fallback - return $this->rawContent; + return $this->getContent(); } protected function initializeMtomSoapMessage(array $contentTypeHeader, $content) @@ -188,4 +169,4 @@ class SoapRequest extends Request return $result; } -} \ No newline at end of file +} From 74005058c07ab585f0a3cf82e4de044e99a352e9 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 25 Mar 2011 20:14:48 +0100 Subject: [PATCH 027/195] added default routing configuration for SoapWebServiceController --- Resources/config/routing.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Resources/config/routing.xml diff --git a/Resources/config/routing.xml b/Resources/config/routing.xml new file mode 100644 index 0000000..9120e74 --- /dev/null +++ b/Resources/config/routing.xml @@ -0,0 +1,15 @@ + + + + + + webservice_controller:handle + POST + + + webservice_controller:definition + GET + + From 0996cf80d98ed66aae02bf914949de736b0850fd Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sat, 26 Mar 2011 16:22:56 +0100 Subject: [PATCH 028/195] removed ServiceConfigurationFactory --- Controller/SoapWebServiceController.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index eb13e58..3090872 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -50,11 +50,6 @@ class SoapWebServiceController extends ContainerAware */ protected $soapResponse; - /** - * @var \Bundle\WebServiceBundle\ServiceConfigurationFactory - */ - protected $serviceConfigurationFactory; - /** * @var \Bundle\WebServiceBundle\ServiceBinding\ServiceBinder */ @@ -65,9 +60,9 @@ class SoapWebServiceController extends ContainerAware */ protected $kernel; - public function __construct(ServiceConfigurationFactory $serviceConfigurationFactory, HttpKernelInterface $kernel) + public function __construct(ContainerInterface $container, HttpKernelInterface $kernel) { - $this->serviceConfigurationFactory = $serviceConfigurationFactory; + $this->setContainer($container); $this->kernel = $kernel; } From d4c3e15f6f4cf99fa4ef4a992d1eb28443d65e59 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sat, 26 Mar 2011 16:23:44 +0100 Subject: [PATCH 029/195] updated service configuration --- Resources/config/routing.xml | 4 ++-- Resources/config/services.xml | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Resources/config/routing.xml b/Resources/config/routing.xml index 9120e74..52a27f8 100644 --- a/Resources/config/routing.xml +++ b/Resources/config/routing.xml @@ -5,11 +5,11 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - webservice_controller:handle + webservice.controller:handle POST - webservice_controller:definition + webservice.controller:definition GET diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 4cb4bf6..ba52356 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -14,17 +14,11 @@ Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlFileDumper - - - - - - - - + + - + @@ -61,4 +55,4 @@ %webservice.definition.wsdl% - \ No newline at end of file + From 0f29e64f74dc193b00e35d994128db0320d047cd Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sat, 26 Mar 2011 16:43:41 +0100 Subject: [PATCH 030/195] added empty configuration definition --- DependencyInjection/Configuration.php | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 DependencyInjection/Configuration.php diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php new file mode 100644 index 0000000..43667cb --- /dev/null +++ b/DependencyInjection/Configuration.php @@ -0,0 +1,40 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +/** + * WebServiceExtension configuration structure. + * + * @author Christian Kerl + */ +class Configuration +{ + /** + * Generates the configuration tree. + * + * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + */ + public function getConfigTree() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('webservice'); + + $rootNode + ->children() + ->end() + ; + + return $treeBuilder->buildTree(); + } +} From 71914f34d2a0de173a4a2a9114b05dc411cf78f5 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 18:38:38 +0200 Subject: [PATCH 031/195] moved LICENSE to Resources/meta/ --- LICENSE => Resources/meta/LICENSE | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE => Resources/meta/LICENSE (100%) diff --git a/LICENSE b/Resources/meta/LICENSE similarity index 100% rename from LICENSE rename to Resources/meta/LICENSE From 8a0e84aaead320eb7c474b422355b6cbf7ec4e7c Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 18:39:41 +0200 Subject: [PATCH 032/195] added default routing configuration --- Resources/config/routing/webservicecontroller.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Resources/config/routing/webservicecontroller.xml diff --git a/Resources/config/routing/webservicecontroller.xml b/Resources/config/routing/webservicecontroller.xml new file mode 100644 index 0000000..52a27f8 --- /dev/null +++ b/Resources/config/routing/webservicecontroller.xml @@ -0,0 +1,15 @@ + + + + + + webservice.controller:handle + POST + + + webservice.controller:definition + GET + + From cf5665a5028f0601ac4616481fe9505be0296d75 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 19:47:14 +0200 Subject: [PATCH 033/195] renamed service definition file; removed old routing.xml; --- Resources/config/routing.xml | 15 --------------- Resources/config/{services.xml => webservice.xml} | 0 2 files changed, 15 deletions(-) delete mode 100644 Resources/config/routing.xml rename Resources/config/{services.xml => webservice.xml} (100%) diff --git a/Resources/config/routing.xml b/Resources/config/routing.xml deleted file mode 100644 index 52a27f8..0000000 --- a/Resources/config/routing.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - webservice.controller:handle - POST - - - webservice.controller:definition - GET - - diff --git a/Resources/config/services.xml b/Resources/config/webservice.xml similarity index 100% rename from Resources/config/services.xml rename to Resources/config/webservice.xml From ff6eca48ee4a36d29d0bf9ccae8d93c830b115cb Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 21:49:01 +0200 Subject: [PATCH 034/195] reimplemented DI extension classes and DI container config; --- DependencyInjection/Configuration.php | 26 ++++++- DependencyInjection/WebServiceExtension.php | 79 ++++++--------------- Resources/config/webservice.xml | 72 +++++++++---------- 3 files changed, 81 insertions(+), 96 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 43667cb..3939b3e 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -28,10 +28,34 @@ class Configuration public function getConfigTree() { $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('webservice'); + $rootNode = $treeBuilder->root('web_service'); $rootNode ->children() + ->arrayNode('services') + ->prototype('array') + ->children() + ->scalarNode('name') + ->isRequired() + ->end() + ->scalarNode('namespace') + ->isRequired() + ->end() + ->scalarNode('resource') + ->defaultValue('*') + ->end() + ->scalarNode('resource_type') + ->defaultValue('annotation') + ->end() + ->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'") + ->end() + ->end() + ->end() + ->end() ->end() ; diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 95dcb33..82e82c5 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -12,10 +12,14 @@ namespace Bundle\WebServiceBundle\DependencyInjection; use Bundle\WebServiceBundle\Util\Assert; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Definition\Processor; + use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + /** * WebServiceExtension. * @@ -23,78 +27,35 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; */ class WebServiceExtension extends Extension { - public function configLoad(array $config, ContainerBuilder $configuration) + public function load(array $configs, ContainerBuilder $container) { - if(!$configuration->hasDefinition('webservice.kernel')) - { - $loader = new XmlFileLoader($configuration, __DIR__ . '/../Resources/config'); - $loader->load('services.xml'); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $configuration->setAlias('http_kernel', 'webservice.kernel'); - } + $loader->load('webservice.xml'); + + $processor = new Processor(); + $configuration = new Configuration(); - if(isset($config['definition'])) + $config = $processor->process($configuration->getConfigTree(), $configs); + + foreach($config['services'] as $serviceContextConfig) { - $this->registerServiceDefinitionConfig($config['definition'], $configuration); - } - else - { - throw new \InvalidArgumentException(); - } - - if(isset($config['binding'])) - { - $this->registerServiceBindingConfig($config['binding'], $configuration); + $this->createWebServiceContext($serviceContextConfig, $container); } } - protected function registerServiceDefinitionConfig(array $config, ContainerBuilder $configuration) + private function createWebServiceContext(array $config, ContainerBuilder $container) { - Assert::thatArgument('config.name', isset($config['name'])); - Assert::thatArgument('config.namespace', isset($config['namespace'])); - - $configuration->setParameter('webservice.definition.name', $config['name']); - $configuration->setParameter('webservice.definition.namespace', $config['namespace']); - $configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null); - $configuration->setParameter('webservice.definition.wsdl', isset($config['wsdl']) ? $config['wsdl'] : null); + } - - protected function registerServiceBindingConfig(array $config, ContainerBuilder $configuration) + + public function getNamespace() { - $style = isset($config['style']) ? $config['style'] : 'document-literal-wrapped'; - - if(!in_array($style, array('document-literal-wrapped', 'rpc-literal'))) - { - throw new \InvalidArgumentException(); - } - - $binderNamespace = 'Bundle\\WebServiceBundle\\ServiceBinding\\'; - - switch ($style) - { - case 'document-literal-wrapped': - $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'DocumentLiteralWrappedRequestMessageBinder'); - $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'DocumentLiteralWrappedResponseMessageBinder'); - break; - case 'rpc-literal': - $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'RpcLiteralRequestMessageBinder'); - $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'RpcLiteralResponseMessageBinder'); - break; - } + return null; } public function getXsdValidationBasePath() { return null; } - - public function getNamespace() - { - return null; - } - - public function getAlias() - { - return 'webservice'; - } } \ No newline at end of file diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index ba52356..b847f09 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -1,58 +1,58 @@ - + xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Bundle\WebServiceBundle\Soap\SoapRequest - - Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder - Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder - - Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition - Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader - Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlFileDumper + %kernel.cache_dir%/webservice - - - + + - - - - - + + + + + + + + + %webservice.cache_dir% + - - - - - - - - + + + + - - - %webservice.definition.name% - %webservice.definition.namespace% - + + + + From aa1dfdf0f8aaccf7dfd32fb0de4b4fbd123dceac Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 21:49:59 +0200 Subject: [PATCH 035/195] refactored service definition dumper classes --- ServiceDefinition/Dumper/DumperInterface.php | 2 +- ServiceDefinition/Dumper/FileDumper.php | 30 ------------------- .../{WsdlFileDumper.php => WsdlDumper.php} | 12 ++++---- 3 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 ServiceDefinition/Dumper/FileDumper.php rename ServiceDefinition/Dumper/{WsdlFileDumper.php => WsdlDumper.php} (96%) diff --git a/ServiceDefinition/Dumper/DumperInterface.php b/ServiceDefinition/Dumper/DumperInterface.php index 4ae8701..f957435 100644 --- a/ServiceDefinition/Dumper/DumperInterface.php +++ b/ServiceDefinition/Dumper/DumperInterface.php @@ -14,5 +14,5 @@ use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; interface DumperInterface { - function dumpServiceDefinition(ServiceDefinition $definition); + function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()); } \ No newline at end of file diff --git a/ServiceDefinition/Dumper/FileDumper.php b/ServiceDefinition/Dumper/FileDumper.php deleted file mode 100644 index 577e8c6..0000000 --- a/ServiceDefinition/Dumper/FileDumper.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; - -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; -use Bundle\WebServiceBundle\Util\Assert; - -/** - * - * @author Christian Kerl - */ -abstract class FileDumper implements DumperInterface -{ - protected $file; - - public function __construct($file) - { - Assert::thatArgumentNotNull('file', $file); - - $this->file = $file; - } -} diff --git a/ServiceDefinition/Dumper/WsdlFileDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php similarity index 96% rename from ServiceDefinition/Dumper/WsdlFileDumper.php rename to ServiceDefinition/Dumper/WsdlDumper.php index 45746bf..3bccef6 100644 --- a/ServiceDefinition/Dumper/WsdlFileDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -22,11 +22,11 @@ use Zend\Soap\Wsdl; * * @author Christian Kerl */ -class WsdlFileDumper extends FileDumper +class WsdlDumper implements DumperInterface { private $definition; - - public function dumpServiceDefinition(ServiceDefinition $definition) + + public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) { Assert::thatArgumentNotNull('definition', $definition); @@ -75,13 +75,11 @@ class WsdlFileDumper extends FileDumper $wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method)); } - $wsdl->dump($this->file); - $this->definition = null; - return $this->file; + return $wsdl->toXml(); } - + protected function getPortTypeName() { return $this->definition->getName() . 'PortType'; From b40a1b1efd9ae277f2851e070bf4a858d1a55adf Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 21:52:59 +0200 Subject: [PATCH 036/195] SoapServerFactory no longer depends on dumper interface --- Soap/SoapServerFactory.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 983a07c..27cc588 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -30,21 +30,19 @@ class SoapServerFactory { private $definition; private $converters; - private $dumper; + private $wsdlFile; - public function __construct(ServiceDefinition $definition, ConverterRepository $converters, FileDumper $dumper) + public function __construct(ServiceDefinition $definition, $wsdlFile, ConverterRepository $converters) { $this->definition = $definition; + $this->wsdlFile = $wsdlFile; $this->converters = $converters; - $this->dumper = $dumper; } public function create(&$request, &$response) { - $file = $this->dumper->dumpServiceDefinition($this->definition); - $server = new \SoapServer( - $file, + $this->wsdlFile, array( 'classmap' => $this->createSoapServerClassmap(), 'typemap' => $this->createSoapServerTypemap($request, $response), From 70da526fd49389438fc142f4dfb35e6e1c1cb24f Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Thu, 7 Apr 2011 21:54:53 +0200 Subject: [PATCH 037/195] added WebServiceContext class; SoapWebServiceController now uses WebServiceContext to acquire all objects needed to handle a request for a certain service; --- Controller/SoapWebServiceController.php | 25 ++++--- WebServiceContext.php | 89 +++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 WebServiceContext.php diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 3090872..99d89ed 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -8,19 +8,20 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle; - - -use Bundle\WebServiceBundle\Soap\SoapServerFactory; +namespace Bundle\WebServiceBundle\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerAware; + use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; use Bundle\WebServiceBundle\Soap\SoapHeader; +use Bundle\WebServiceBundle\Soap\SoapServerFactory; use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; @@ -78,13 +79,13 @@ class SoapWebServiceController extends ContainerAware public function handle($webservice) { - $serviceConfiguration = $this->serviceConfigurationFactory->create($webservice); + $webServiceContext = $this->container->get('webservice.context.' . $webservice); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); - $this->serviceBinder = $serviceConfiguration->createServiceBinder(); + $this->serviceBinder = $webServiceContext->getServiceBinder(); - $this->soapServer = $serviceConfiguration->createServer($this->soapRequest, $this->soapResponse); + $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); $this->soapServer->setObject($this); ob_start(); @@ -99,14 +100,16 @@ class SoapWebServiceController extends ContainerAware } public function definition($webservice) - { - $serviceConfiguration = $this->serviceConfigurationFactory->create($webservice); + { + $webServiceContext = $this->container->get('webservice.context.' . $webservice); $request = $this->container->get('request'); if($request->query->has('WSDL')) { - // dump wsdl file - // return + $response = new Response(file_get_contents($webServiceContext->getWsdlFile())); + $response->headers->set('Content-Type', 'application/wsdl+xml'); + + return $response; } else { diff --git a/WebServiceContext.php b/WebServiceContext.php new file mode 100644 index 0000000..0f34b0d --- /dev/null +++ b/WebServiceContext.php @@ -0,0 +1,89 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle; + +/** + * WebServiceContext. + * + * @author Christian Kerl + */ +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; + +use Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface; + +use Bundle\WebServiceBundle\Converter\ConverterRepository; + +use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; + +use Bundle\WebServiceBundle\Soap\SoapServerFactory; + +class WebServiceContext +{ + private $converterRepository; + private $requestMessageBinder; + private $responseMessageBinder; + + private $serviceDefinitionLoader; + private $wsdlFileDumper; + + private $options; + + private $serviceDefinition; + private $serviceBinder; + private $serverFactory; + + public function __construct(LoaderInterface $loader, DumperInterface $dumper, ConverterRepository $converterRepository, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, array $options) + { + $this->serviceDefinitionLoader = $loader; + $this->wsdlFileDumper = $dumper; + + $this->converterRepository = $converterRepository; + $this->requestMessageBinder = $requestMessageBinder; + $this->responseMessageBinder = $responseMessageBinder; + + $this->options = $options; + } + + public function getServiceDefinition() + { + if($this->serviceDefinition === null) + { + + } + + ; + } + + public function getWsdlFile() + { + ; + } + + public function getServiceBinder() + { + if($this->serviceBinder === null) + { + $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestMessageBinder, $this->responseMessageBinder); + } + + return $this->serviceBinder; + } + + public function getServerFactory() + { + if($this->serverFactory === null) + { + $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository); + } + + return $this->serverFactory; + } +} \ No newline at end of file From 8895a69d047711a2fc33f7c3dd2d1ab171d597a1 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Fri, 8 Apr 2011 00:41:16 +0200 Subject: [PATCH 038/195] replaced old LoaderInterface with Symfony Config Component's LoaderInterface; added annotation based loader implementations; --- Resources/config/annotations.xml | 30 +++++ Resources/config/webservice.xml | 32 ++++- .../Loader/AnnotationClassLoader.php | 127 ++++++++++++++++++ .../Loader/AnnotationFileLoader.php | 122 +++++++++++++++++ ServiceDefinition/Loader/FileLoader.php | 26 ---- ServiceDefinition/Loader/LoaderInterface.php | 23 ---- ServiceDefinition/Loader/XmlFileLoader.php | 22 ++- 7 files changed, 321 insertions(+), 61 deletions(-) create mode 100644 Resources/config/annotations.xml create mode 100644 ServiceDefinition/Loader/AnnotationClassLoader.php create mode 100644 ServiceDefinition/Loader/AnnotationFileLoader.php delete mode 100644 ServiceDefinition/Loader/FileLoader.php delete mode 100644 ServiceDefinition/Loader/LoaderInterface.php diff --git a/Resources/config/annotations.xml b/Resources/config/annotations.xml new file mode 100644 index 0000000..1bb69de --- /dev/null +++ b/Resources/config/annotations.xml @@ -0,0 +1,30 @@ + + + + + + Doctrine\Common\Annotations\AnnotationReader + Doctrine\Common\Annotations\Parser + + + + + true + + Bundle\WebServiceBundle\ServiceDefinition\Annotation\ + ws + + + + + + + + + + + + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index b847f09..0c1a07e 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -4,6 +4,8 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + Symfony\Component\HttpKernel\Config\FileLocator + %kernel.cache_dir%/webservice @@ -14,11 +16,13 @@ + + %webservice.cache_dir% + @@ -41,12 +46,27 @@ - - + + + + + + + + + + + + + + + + + + + + + %webservice.cache_dir% - - - - - + + + + - - - - - - - + + + + + + + - - + + - + @@ -65,14 +56,9 @@ - - - - - - + + \ No newline at end of file diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index 59409eb..df3e118 100644 --- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -16,16 +16,14 @@ class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterfa { public function processMessage(Method $messageDefinition, $message) { - if(count($message) > 1) - { + if(count($message) > 1) { throw new \InvalidArgumentException(); } $result = array(); $message = $message[0]; - foreach($messageDefinition->getArguments() as $argument) - { + foreach($messageDefinition->getArguments() as $argument) { $result[$argument->getName()] = $message->{$argument->getName()}; } diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php index 876fb99..6dc9bf5 100644 --- a/ServiceBinding/MessageBinderInterface.php +++ b/ServiceBinding/MessageBinderInterface.php @@ -15,8 +15,6 @@ use Bundle\WebServiceBundle\ServiceDefinition\Method; interface MessageBinderInterface { /** - * - * * @param Method $messageDefinition * @param mixed $message * diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 50590f7..d845ed6 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -19,9 +19,9 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $result = array(); $i = 0; - foreach($messageDefinition->getArguments() as $argument) - { + foreach($messageDefinition->getArguments() as $argument) { $result[$argument->getName()] = $message[$i]; + $i++; } diff --git a/ServiceDefinition/Annotation/Method.php b/ServiceDefinition/Annotation/Method.php index f91abd0..2c0b53e 100644 --- a/ServiceDefinition/Annotation/Method.php +++ b/ServiceDefinition/Annotation/Method.php @@ -14,18 +14,18 @@ class Method { private $name; private $service; - + public function __construct($values) { $this->name = isset($values['value']) ? $values['value'] : null; $this->service = isset($values['service']) ? $values['service'] : null; } - + public function getName($default = null) { return $this->name !== null ? $this->name : $default; } - + public function getService() { return $this->service; diff --git a/ServiceDefinition/Annotation/Param.php b/ServiceDefinition/Annotation/Param.php index 6bc3d55..6bb4f0d 100644 --- a/ServiceDefinition/Annotation/Param.php +++ b/ServiceDefinition/Annotation/Param.php @@ -13,14 +13,14 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; class Param extends TypedElement { private $name; - + public function __construct($values) { parent::__construct($values); - + $this->name = $values['value']; } - + public function getName() { return $this->name; diff --git a/ServiceDefinition/Annotation/Result.php b/ServiceDefinition/Annotation/Result.php index 429c50b..596c5d2 100644 --- a/ServiceDefinition/Annotation/Result.php +++ b/ServiceDefinition/Annotation/Result.php @@ -11,7 +11,7 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; class Result extends TypedElement -{ +{ public function __construct($values) { parent::__construct($values); diff --git a/ServiceDefinition/Annotation/TypedElement.php b/ServiceDefinition/Annotation/TypedElement.php index eb75b66..9d7209c 100644 --- a/ServiceDefinition/Annotation/TypedElement.php +++ b/ServiceDefinition/Annotation/TypedElement.php @@ -14,7 +14,7 @@ abstract class TypedElement { private $phpType; private $xmlType; - + public function __construct($values) { foreach(array('type', 'phpType') as $key) @@ -24,15 +24,15 @@ abstract class TypedElement $this->phpType = $values[$key]; } } - + $this->xmlType = isset($values['xmlType']) ? $values['xmlType'] : null; } - + public function getPhpType() { return $this->phpType; } - + public function getXmlType() { return $this->xmlType; diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 24c31cd..c21556d 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -25,35 +25,32 @@ use Zend\Soap\Wsdl; class WsdlDumper implements DumperInterface { private $definition; - + public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) { Assert::thatArgumentNotNull('definition', $definition); $options = array_merge(array('endpoint' => ''), $options); - + $this->definition = $definition; $wsdl = new Wsdl($definition->getName(), $definition->getNamespace()); $port = $wsdl->addPortType($this->getPortTypeName()); $binding = $wsdl->addBinding($this->getBindingName(), 'tns:' . $this->getPortTypeName()); - + $wsdl->addSoapBinding($binding, 'rpc'); $wsdl->addService($this->getServiceName(), $this->getPortName(), 'tns:' . $this->getBindingName(), $options['endpoint']); - foreach($definition->getMethods() as $method) - { + foreach($definition->getMethods() as $method) { $requestParts = array(); $responseParts = array(); - foreach($method->getArguments() as $argument) - { + foreach($method->getArguments() as $argument) { $requestParts[$argument->getName()] = $wsdl->getType($argument->getType()->getPhpType()); } - if($method->getReturn() !== null) - { + if($method->getReturn() !== null) { $responseParts['return'] = $wsdl->getType($method->getReturn()->getPhpType()); } @@ -83,7 +80,7 @@ class WsdlDumper implements DumperInterface $this->definition = null; $wsdl->toDomDocument()->formatOutput = true; - + return $wsdl->toXml(); } @@ -91,7 +88,7 @@ class WsdlDumper implements DumperInterface { return $this->definition->getName() . 'Port'; } - + protected function getPortTypeName() { return $this->definition->getName() . 'PortType'; @@ -121,4 +118,4 @@ class WsdlDumper implements DumperInterface { return $this->definition->getNamespace() . $method->getName(); } -} +} \ No newline at end of file diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index ee82665..4c97c34 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -35,9 +35,9 @@ class AnnotationClassLoader implements LoaderInterface private $wsMethodAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Method'; private $wsParamAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Param'; private $wsResultAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Result'; - + protected $reader; - + /** * Constructor. * @@ -60,42 +60,37 @@ class AnnotationClassLoader implements LoaderInterface */ public function load($class, $type = null) { - if (!class_exists($class)) - { + if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } $class = new \ReflectionClass($class); $definition = new ServiceDefinition(); - - foreach ($class->getMethods() as $method) - { + + foreach ($class->getMethods() as $method) { $wsMethodAnnot = $this->reader->getMethodAnnotation($method, $this->wsMethodAnnotationClass); - - if($wsMethodAnnot !== null) - { + + if($wsMethodAnnot !== null) { $wsParamAnnots = $this->reader->getMethodAnnotations($method, $this->wsParamAnnotationClass); $wsResultAnnot = $this->reader->getMethodAnnotation($method, $this->wsResultAnnotationClass); - + $serviceMethod = new Method(); $serviceMethod->setName($wsMethodAnnot->getName($method->getName())); $serviceMethod->setController($this->getController($method, $wsMethodAnnot)); - - foreach($wsParamAnnots as $wsParamAnnot) - { + + foreach($wsParamAnnots as $wsParamAnnot) { $serviceArgument = new Argument(); $serviceArgument->setName($wsParamAnnot->getName()); $serviceArgument->setType(new Type($wsParamAnnot->getPhpType(), $wsParamAnnot->getXmlType())); - + $serviceMethod->getArguments()->add($serviceArgument); } - - if($wsResultAnnot !== null) - { + + if($wsResultAnnot !== null) { $serviceMethod->setReturn(new Type($wsResultAnnot->getPhpType(), $wsResultAnnot->getXmlType())); } - + $definition->getMethods()->add($serviceMethod); } } @@ -105,16 +100,13 @@ class AnnotationClassLoader implements LoaderInterface private function getController(\ReflectionMethod $method, MethodAnnotation $annotation) { - if($annotation->getService() !== null) - { + if($annotation->getService() !== null) { return $annotation->getService() . ':' . $method->name; - } - else - { + } else { return $method->class . '::' . $method->name; } } - + /** * Returns true if this class supports the given resource. * @@ -145,4 +137,4 @@ class AnnotationClassLoader implements LoaderInterface public function getResolver() { } -} +} \ No newline at end of file diff --git a/ServiceDefinition/Loader/AnnotationFileLoader.php b/ServiceDefinition/Loader/AnnotationFileLoader.php index 6c13d7d..6d7f405 100644 --- a/ServiceDefinition/Loader/AnnotationFileLoader.php +++ b/ServiceDefinition/Loader/AnnotationFileLoader.php @@ -61,11 +61,11 @@ class AnnotationFileLoader extends FileLoader $path = $this->locator->locate($file); $definition = new ServiceDefinition(); - + if ($class = $this->findClass($path)) { $definition = $this->loader->load($class, $type); } - + return $definition; } @@ -87,7 +87,7 @@ class AnnotationFileLoader extends FileLoader * * @param string $file A PHP file path * - * @return string|false Full class name if found, false otherwise + * @return string|false Full class name if found, false otherwise */ protected function findClass($file) { diff --git a/ServiceDefinition/Loader/AnnotationParser.php b/ServiceDefinition/Loader/AnnotationParser.php index 7b6f523..afd9c1b 100644 --- a/ServiceDefinition/Loader/AnnotationParser.php +++ b/ServiceDefinition/Loader/AnnotationParser.php @@ -15,7 +15,7 @@ use Doctrine\Common\Annotations\Parser; /** * AnnotationParser allows multiple annotations of the same class to be present. - * + * * @author Christian Kerl */ class AnnotationParser extends Parser diff --git a/ServiceDefinition/Loader/AnnotationReader.php b/ServiceDefinition/Loader/AnnotationReader.php index 81e3f03..b65d48d 100644 --- a/ServiceDefinition/Loader/AnnotationReader.php +++ b/ServiceDefinition/Loader/AnnotationReader.php @@ -22,19 +22,18 @@ class AnnotationReader extends BaseAnnotationReader public function getMethodAnnotation(\ReflectionMethod $method, $type) { $annotation = parent::getMethodAnnotation($method, $type); - - if($annotation !== null && count($annotation) > 1) - { + + if($annotation !== null && count($annotation) > 1) { throw new \LogicException(sprintf("There is more than one annotation of type '%s'!", $type)); } - + return $annotation !== null ? $annotation[0] : null; } - + public function getMethodAnnotations(\ReflectionMethod $method, $type = null) { $annotations = parent::getMethodAnnotations($method); - + return $type !== null && isset($annotations[$type]) ? $annotations[$type] : $annotations; } } \ No newline at end of file diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index 3189d7a..feefed5 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -24,27 +24,25 @@ class XmlFileLoader extends FileLoader { 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) - { + foreach($xml->header as $header) { $definition->getHeaders()->add($this->parseHeader($header)); } - foreach($xml->method as $method) - { + foreach($xml->method as $method) { $definition->getMethods()->add($this->parseMethod($method)); } - + return $definition; } @@ -69,8 +67,7 @@ class XmlFileLoader extends FileLoader { $method = new Method((string)$node['name'], (string)$node['controller']); - foreach($node->argument as $argument) - { + foreach($node->argument as $argument) { $method->getArguments()->add($this->parseArgument($argument)); } diff --git a/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd index ed2d68f..4ef903a 100644 --- a/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd +++ b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd @@ -1,81 +1,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 3f4b325..5cfbf6f 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -28,7 +28,7 @@ class SoapRequest extends Request { return new static($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->content); } - + /** * @var string */ @@ -67,8 +67,7 @@ class SoapRequest extends Request */ public function getSoapMessage() { - if($this->soapMessage === null) - { + if($this->soapMessage === null) { $this->soapMessage = $this->initializeSoapMessage(); } @@ -87,19 +86,14 @@ class SoapRequest extends Request protected function initializeSoapMessage() { - if($this->server->has('CONTENT_TYPE')) - { + if($this->server->has('CONTENT_TYPE')) { $type = $this->splitContentTypeHeader($this->server->get('CONTENT_TYPE')); - switch($type['_type']) - { + switch($type['_type']) { case 'multipart/related': - if($type['type'] == 'application/xop+xml') - { + if($type['type'] == 'application/xop+xml') { return $this->initializeMtomSoapMessage($type, $this->getContent()); - } - else - { + } else { //log error } break; @@ -118,8 +112,7 @@ class SoapRequest extends Request protected function initializeMtomSoapMessage(array $contentTypeHeader, $content) { - if(!isset($contentTypeHeader['start']) || !isset($contentTypeHeader['start-info']) || !isset($contentTypeHeader['boundary'])) - { + if(!isset($contentTypeHeader['start']) || !isset($contentTypeHeader['start-info']) || !isset($contentTypeHeader['boundary'])) { throw new \InvalidArgumentException(); } @@ -134,13 +127,11 @@ class SoapRequest extends Request // TODO: add more checks to achieve full compatibility to MTOM spec // http://www.w3.org/TR/soap12-mtom/ - if($rootPart->id != $soapMimePartId || $rootPartType['_type'] != 'application/xop+xml' || $rootPartType['type'] != $soapMimePartType) - { + if($rootPart->id != $soapMimePartId || $rootPartType['_type'] != 'application/xop+xml' || $rootPartType['type'] != $soapMimePartType) { throw new \InvalidArgumentException(); } - foreach($mimeParts as $mimePart) - { + foreach($mimeParts as $mimePart) { $this->soapAttachments->add(new SoapAttachment( $mimePart->id, $mimePart->type, @@ -160,8 +151,7 @@ class SoapRequest extends Request $result['_type'] = array_shift($parts); - foreach($parts as $part) - { + foreach($parts as $part) { list($key, $value) = explode('=', trim($part), 2); $result[$key] = trim($value, '"'); @@ -169,4 +159,4 @@ class SoapRequest extends Request return $result; } -} +} \ No newline at end of file diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 302ab19..6402649 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -57,8 +57,7 @@ class SoapServerFactory { $result = array(); - foreach($this->converters->getTypeConverters() as $typeConverter) - { + foreach($this->converters->getTypeConverters() as $typeConverter) { $result[] = array( 'type_name' => $typeConverter->getTypeName(), 'type_ns' => $typeConverter->getTypeNamespace(), @@ -78,15 +77,12 @@ class SoapServerFactory { $result = array(); - foreach($this->definition->getHeaders() as $header) - { + foreach($this->definition->getHeaders() as $header) { $this->addSoapServerClassmapEntry($result, $header->getType()); } - foreach($this->definition->getMethods() as $method) - { - foreach($method->getArguments() as $arg) - { + foreach($this->definition->getMethods() as $method) { + foreach($method->getArguments() as $arg) { $this->addSoapServerClassmapEntry($result, $arg->getType()); } } @@ -98,15 +94,14 @@ class SoapServerFactory { // TODO: fix this hack if($type->getXmlType() === null) return; - + $xmlType = QName::fromPackedQName($type->getXmlType())->getName(); $phpType = $type->getPhpType(); - if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) - { + if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) { // log warning } $classmap[$xmlType] = $phpType; } -} +} \ No newline at end of file diff --git a/Tests/fixtures/api-servicedefinition.xml b/Tests/fixtures/api-servicedefinition.xml index 952f1a3..3fc5d75 100644 --- a/Tests/fixtures/api-servicedefinition.xml +++ b/Tests/fixtures/api-servicedefinition.xml @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/Tests/fixtures/api.wsdl b/Tests/fixtures/api.wsdl index c20abed..d2f8cef 100644 --- a/Tests/fixtures/api.wsdl +++ b/Tests/fixtures/api.wsdl @@ -1,145 +1,145 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Util/Assert.php b/Util/Assert.php index 93daab8..95563ab 100644 --- a/Util/Assert.php +++ b/Util/Assert.php @@ -21,8 +21,7 @@ class Assert public static function thatArgument($name, $condition, $message = self::ARGUMENT_INVALID) { - if(!$condition) - { + if(!$condition) { throw new \InvalidArgumentException(sprintf($message, $name)); } } diff --git a/Util/Collection.php b/Util/Collection.php index 5afe7d9..8828900 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -27,8 +27,7 @@ class Collection implements \IteratorAggregate, \Countable public function addAll($elements) { - foreach ($elements as $element) - { + foreach ($elements as $element) { $this->add($element); } } diff --git a/Util/String.php b/Util/String.php index 1c641d5..0526453 100644 --- a/Util/String.php +++ b/Util/String.php @@ -17,35 +17,34 @@ namespace Bundle\WebServiceBundle\Util; */ class String { - /** - * Checks if a string starts with a given string. - * - * @param string $str A string - * @param string $substr A string to check against - * - * @return bool True if str starts with substr - */ - public static function startsWith($str, $substr) - { - if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) + /** + * Checks if a string starts with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str starts with substr + */ + public static function startsWith($str, $substr) { - return $substr == substr($str, 0, strlen($substr)); + if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) { + return $substr == substr($str, 0, strlen($substr)); + } } - } - /** - * Checks if a string ends with a given string. - * - * @param string $str A string - * @param string $substr A string to check against - * - * @return bool True if str ends with substr - */ - public static function endsWith($str, $substr) - { - if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) + /** + * Checks if a string ends with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str ends with substr + */ + public static function endsWith($str, $substr) { - return $substr == substr($str, strlen($str) - strlen($substr)); + if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) + { + return $substr == substr($str, strlen($str) - strlen($substr)); + } } - } } \ No newline at end of file diff --git a/WebServiceContext.php b/WebServiceContext.php index ce764bb..8bdd949 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -30,81 +30,76 @@ class WebServiceContext private $converterRepository; private $requestMessageBinder; private $responseMessageBinder; - + private $serviceDefinitionLoader; private $wsdlFileDumper; - + private $options; - + private $serviceDefinition; private $serviceBinder; private $serverFactory; - + public function __construct(LoaderInterface $loader, DumperInterface $dumper, ConverterRepository $converterRepository, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, array $options) { $this->serviceDefinitionLoader = $loader; $this->wsdlFileDumper = $dumper; - + $this->converterRepository = $converterRepository; $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; - + $this->options = $options; } - - public function getServiceDefinition() + + public function getServiceDefinition() { - if($this->serviceDefinition === null) - { - if(!$this->serviceDefinitionLoader->supports($this->options['resource'], $this->options['resource_type'])) - { + if($this->serviceDefinition === null) { + if(!$this->serviceDefinitionLoader->supports($this->options['resource'], $this->options['resource_type'])) { throw new \LogicException(); } - + $this->serviceDefinition = $this->serviceDefinitionLoader->load($this->options['resource'], $this->options['resource_type']); $this->serviceDefinition->setName($this->options['name']); $this->serviceDefinition->setNamespace($this->options['namespace']); } - + return $this->serviceDefinition; } - + public function getWsdlFile($endpoint = null) { $id = $endpoint !== null ? '.' . md5($endpoint) : ''; $file = sprintf('%s/%s.wsdl', $this->options['cache_dir'], $this->options['name'] . $id); $cache = new ConfigCache($file, true); - - if(!$cache->isFresh()) - { + + if(!$cache->isFresh()) { $cache->write($this->wsdlFileDumper->dumpServiceDefinition($this->getServiceDefinition(), array('endpoint' => $endpoint))); } - + return $file; } - + public function getWsdlFileContent($endpoint = null) { return file_get_contents($this->getWsdlFile($endpoint)); } - - public function getServiceBinder() + + public function getServiceBinder() { - if($this->serviceBinder === null) - { + if($this->serviceBinder === null) { $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestMessageBinder, $this->responseMessageBinder); } - + return $this->serviceBinder; } - - public function getServerFactory() + + public function getServerFactory() { - if($this->serverFactory === null) - { + if($this->serverFactory === null) { $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository); } - + return $this->serverFactory; } } \ No newline at end of file From 581ebaf8659b54af7bdeace5d9362ab1cc41ea42 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 14 Jul 2011 18:13:34 +0200 Subject: [PATCH 050/195] Fixed DIC --- DependencyInjection/WebServiceExtension.php | 9 ++++++--- Resources/config/webservice.xml | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 8d6a34e..b67e07a 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -58,13 +58,16 @@ class WebServiceExtension extends Extension $contextPrototype = $container->getDefinition('webservice.context'); $contextPrototypeArguments = $contextPrototype->getArguments(); - $contextId = 'webservice.context.' . $config['name']; + $contextId = 'webservice.context.'.$config['name']; $context = $container->setDefinition($contextId, new DefinitionDecorator('webservice.context')); + $arguments = array(); foreach($bindingDependentArguments as $idx) { - $context->setArgument($idx, new Reference($contextPrototypeArguments[$idx] . $bindingSuffix)); + $arguments[] = new Reference($contextPrototypeArguments[$idx].$bindingSuffix); } - $context->setArgument(5, array_merge($contextPrototypeArguments[5], $config)); + $arguments[5] = array_merge($contextPrototypeArguments[5], $config); + + $context->setArguments($arguments); } public function getNamespace() diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 6b93d64..7fcdd2f 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -54,11 +54,14 @@ - + - + - + + + + \ No newline at end of file From 81118f8d472e51fbab1538b4ed54671f73dbb3de Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 14 Jul 2011 18:39:47 +0200 Subject: [PATCH 051/195] Deleted "name" element in the configuration of services --- DependencyInjection/Configuration.php | 4 +--- DependencyInjection/WebServiceExtension.php | 8 ++++---- README.markdown | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 1dadea7..2f83de3 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -33,11 +33,9 @@ class Configuration $rootNode ->children() ->arrayNode('services') + ->useAttributeAsKey('name') ->prototype('array') ->children() - ->scalarNode('name') - ->isRequired() - ->end() ->scalarNode('namespace') ->isRequired() ->end() diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index b67e07a..c87aaa7 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -44,12 +44,12 @@ class WebServiceExtension extends Extension $config = $processor->process($configuration->getConfigTree(), $configs); - foreach($config['services'] as $serviceContextConfig) { - $this->createWebServiceContext($serviceContextConfig, $container); + foreach($config['services'] as $name => $serviceConfig) { + $this->createWebServiceContext($name, $serviceConfig, $container); } } - private function createWebServiceContext(array $config, ContainerBuilder $container) + private function createWebServiceContext($name, array $config, ContainerBuilder $container) { $bindingDependentArguments = array(1, 3, 4); $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; @@ -58,7 +58,7 @@ class WebServiceExtension extends Extension $contextPrototype = $container->getDefinition('webservice.context'); $contextPrototypeArguments = $contextPrototype->getArguments(); - $contextId = 'webservice.context.'.$config['name']; + $contextId = 'webservice.context.'.$name; $context = $container->setDefinition($contextId, new DefinitionDecorator('webservice.context')); $arguments = array(); diff --git a/README.markdown b/README.markdown index ee2f472..93d6f52 100644 --- a/README.markdown +++ b/README.markdown @@ -26,8 +26,7 @@ QuickStart web_service: services: - demoapi: - name: DemoApi + DemoApi: namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ binding: rpc-literal resource: "@AcmeDemoBundle/Controller/DemoController.php" From 1c608ccf200b22c847f5ce01274d7683561e9a99 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 17 Jul 2011 10:46:54 +0200 Subject: [PATCH 052/195] The bundle is back! The definition of service has changed, read the README. --- Controller/SoapWebServiceController.php | 95 ++++++++----------- Converter/ConverterRepository.php | 13 +-- Converter/TypeConverterInterface.php | 2 - Converter/XopIncludeTypeConverter.php | 5 +- .../Compiler/WebServiceResolverPass.php | 36 +++++++ DependencyInjection/Configuration.php | 1 - DependencyInjection/WebServiceExtension.php | 55 +++++------ EventListener/ControllerListener.php | 64 +++++++++++++ README.markdown | 66 ++++++++++--- Resources/config/annotations.xml | 30 ------ Resources/config/loaders.xml | 40 ++++++++ .../config/routing/webservicecontroller.xml | 6 +- Resources/config/webservice.xml | 60 ++++-------- ...mentLiteralWrappedRequestMessageBinder.php | 2 +- ...entLiteralWrappedResponseMessageBinder.php | 2 +- .../RpcLiteralRequestMessageBinder.php | 6 +- ServiceBinding/ServiceBinder.php | 23 ++--- .../Annotation/Configuration.php | 30 ++++++ .../Annotation/ConfigurationInterface.php | 26 +++++ ServiceDefinition/Annotation/Method.php | 32 +++++-- ServiceDefinition/Annotation/Param.php | 44 +++++++-- ServiceDefinition/Annotation/Result.php | 32 ++++++- ServiceDefinition/Annotation/TypedElement.php | 40 -------- .../Annotation/TypedElementInterface.php | 19 ++++ ServiceDefinition/Dumper/WsdlDumper.php | 43 ++++----- .../Loader/AnnotationClassLoader.php | 75 +++++++++------ .../Loader/AnnotationFileLoader.php | 15 ++- ServiceDefinition/Loader/AnnotationParser.php | 52 ---------- ServiceDefinition/Loader/AnnotationReader.php | 39 -------- ServiceDefinition/Loader/XmlFileLoader.php | 23 ++--- ServiceDefinition/Method.php | 13 ++- ServiceDefinition/ServiceDefinition.php | 10 +- Soap/SoapAttachment.php | 4 +- Soap/SoapHeader.php | 4 +- Soap/SoapRequest.php | 8 +- Soap/SoapResponse.php | 2 +- Soap/SoapServerFactory.php | 36 +++---- Tests/Soap/SoapRequestTest.php | 2 +- .../{ => Soap}/api-servicedefinition.xml | 0 Tests/fixtures/{ => Soap}/api.wsdl | 0 Tests/fixtures/{ => Soap}/mtom/simple.txt | 0 Util/Assert.php | 6 +- Util/Collection.php | 17 +++- Util/QName.php | 7 +- Util/String.php | 33 ++++--- WebServiceBundle.php | 9 +- WebServiceContext.php | 36 ++++--- vendors.php | 13 ++- 48 files changed, 641 insertions(+), 535 deletions(-) create mode 100644 DependencyInjection/Compiler/WebServiceResolverPass.php create mode 100644 EventListener/ControllerListener.php delete mode 100644 Resources/config/annotations.xml create mode 100644 Resources/config/loaders.xml create mode 100644 ServiceDefinition/Annotation/Configuration.php create mode 100644 ServiceDefinition/Annotation/ConfigurationInterface.php delete mode 100644 ServiceDefinition/Annotation/TypedElement.php create mode 100644 ServiceDefinition/Annotation/TypedElementInterface.php delete mode 100644 ServiceDefinition/Loader/AnnotationParser.php delete mode 100644 ServiceDefinition/Loader/AnnotationReader.php rename Tests/fixtures/{ => Soap}/api-servicedefinition.xml (100%) rename Tests/fixtures/{ => Soap}/api.wsdl (100%) rename Tests/fixtures/{ => Soap}/mtom/simple.txt (100%) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 5c6b6b3..0970a18 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -10,28 +10,14 @@ namespace Bundle\WebServiceBundle\Controller; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -use Symfony\Component\HttpKernel\HttpKernelInterface; - -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\ContainerAware; - use Bundle\WebServiceBundle\Soap\SoapRequest; use Bundle\WebServiceBundle\Soap\SoapResponse; -use Bundle\WebServiceBundle\Soap\SoapHeader; -use Bundle\WebServiceBundle\Soap\SoapServerFactory; -use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; - -use Bundle\WebServiceBundle\Converter\ConverterRepository; - -use Bundle\WebServiceBundle\Util\String; +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; /** - * - * * @author Christian Kerl */ class SoapWebServiceController extends ContainerAware @@ -57,54 +43,33 @@ class SoapWebServiceController extends ContainerAware protected $serviceBinder; /** - * @var \Symfony\Component\HttpKernel\HttpKernelInterface + * @return \Bundle\WebServiceBundle\Soap\SoapResponse */ - protected $kernel; - - public function __construct(ContainerInterface $container, HttpKernelInterface $kernel) + public function callAction($webservice) { - $this->setContainer($container); - $this->kernel = $kernel; - } - - public function getRequest() - { - return $this->soapRequest; - } - - public function getResponse() - { - return $this->soapResponse; - } - - public function call($webservice) - { - $webServiceContext = $this->container->get('webservice.context.' . $webservice); - - $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); - + $webServiceContext = $this->container->get('webservice.context.'.$webservice); $this->serviceBinder = $webServiceContext->getServiceBinder(); - $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); + $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); + $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); $this->soapServer->setObject($this); ob_start(); - { - $this->soapServer->handle($this->soapRequest->getSoapMessage()); - } - $soapResponseContent = ob_get_clean(); - - $this->soapResponse->setContent($soapResponseContent); + $this->soapServer->handle($this->soapRequest->getSoapMessage()); + $this->soapResponse->setContent(ob_get_clean()); return $this->soapResponse; } - public function definition($webservice) + /** + * @return Symfony\Component\HttpFoundation\Response + */ + public function definitionAction($webservice) { - $webServiceContext = $this->container->get('webservice.context.' . $webservice); - $request = $this->container->get('request'); + $webServiceContext = $this->container->get('webservice.context.'.$webservice); + $request = $this->container->get('request'); - if($request->query->has('WSDL')) { + if ($request->query->has('wsdl') || $request->query->has('WSDL')) { $endpoint = $this->container->get('router')->generate('_webservice_call', array('webservice' => $webservice), true); $response = new Response($webServiceContext->getWsdlFileContent($endpoint)); @@ -129,7 +94,7 @@ class SoapWebServiceController extends ContainerAware */ public function __call($method, $arguments) { - if($this->serviceBinder->isServiceHeader($method)) { + if ($this->serviceBinder->isServiceHeader($method)) { // collect request soap headers $this->soapRequest->getSoapHeaders()->add( $this->serviceBinder->processServiceHeader($method, $arguments[0]) @@ -138,18 +103,18 @@ class SoapWebServiceController extends ContainerAware return; } - if($this->serviceBinder->isServiceMethod($method)) { + if ($this->serviceBinder->isServiceMethod($method)) { $this->soapRequest->attributes->add( $this->serviceBinder->processServiceMethodArguments($method, $arguments) ); // forward to controller - $response = $this->kernel->handle($this->soapRequest, HttpKernelInterface::SUB_REQUEST, false); + $response = $this->container->get('http_kernel')->handle($this->soapRequest, HttpKernelInterface::SUB_REQUEST, false); $this->soapResponse = $this->checkResponse($response); // add response soap headers to soap server - foreach($this->soapResponse->getSoapHeaders() as $header) { + foreach ($this->soapResponse->getSoapHeaders() as $header) { $this->soapServer->addSoapHeader($header->toNativeSoapHeader()); } @@ -172,10 +137,26 @@ class SoapWebServiceController extends ContainerAware */ protected function checkResponse(Response $response) { - if($response == null || !$response instanceof SoapResponse) { + if (null === $response || !$response instanceof SoapResponse) { throw new \InvalidArgumentException(); } return $response; } + + /** + * @return \Bundle\WebServiceBundle\Soap\SoapRequest + */ + public function getRequest() + { + return $this->soapRequest; + } + + /** + * @return \Bundle\WebServiceBundle\Soap\SoapResponse + */ + public function getResponse() + { + return $this->soapResponse; + } } \ No newline at end of file diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php index 8882a4d..536a654 100644 --- a/Converter/ConverterRepository.php +++ b/Converter/ConverterRepository.php @@ -10,22 +10,15 @@ namespace Bundle\WebServiceBundle\Converter; -/** - * - * @author Christian Kerl - */ -use Bundle\WebServiceBundle\SoapKernel; - use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * @author Christian Kerl + */ class ConverterRepository { private $typeConverters = array(); - public function __construct() - { - } - public function addTypeConverter(TypeConverterInterface $converter) { $this->typeConverters[] = $converter; diff --git a/Converter/TypeConverterInterface.php b/Converter/TypeConverterInterface.php index 096cb0b..4945f8e 100644 --- a/Converter/TypeConverterInterface.php +++ b/Converter/TypeConverterInterface.php @@ -11,11 +11,9 @@ namespace Bundle\WebServiceBundle\Converter; use Bundle\WebServiceBundle\Soap\SoapRequest; - use Bundle\WebServiceBundle\Soap\SoapResponse; /** - * * @author Christian Kerl */ interface TypeConverterInterface diff --git a/Converter/XopIncludeTypeConverter.php b/Converter/XopIncludeTypeConverter.php index 7f1037c..39d6e2f 100644 --- a/Converter/XopIncludeTypeConverter.php +++ b/Converter/XopIncludeTypeConverter.php @@ -11,13 +11,10 @@ namespace Bundle\WebServiceBundle\Converter; use Bundle\WebServiceBundle\Soap\SoapRequest; - use Bundle\WebServiceBundle\Soap\SoapResponse; - use Bundle\WebServiceBundle\Util\String; /** - * * @author Christian Kerl */ class XopIncludeTypeConverter implements TypeConverterInterface @@ -42,7 +39,7 @@ class XopIncludeTypeConverter implements TypeConverterInterface $ref = $include->getAttribute('href'); - if(String::startsWith($ref, 'cid:')) { + if (String::startsWith($ref, 'cid:')) { $cid = urldecode(substr($ref, 4)); return $request->getSoapAttachments()->get($cid)->getContent(); diff --git a/DependencyInjection/Compiler/WebServiceResolverPass.php b/DependencyInjection/Compiler/WebServiceResolverPass.php new file mode 100644 index 0000000..0969848 --- /dev/null +++ b/DependencyInjection/Compiler/WebServiceResolverPass.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged webservice.definition.loader services to ebservice.definition.resolver service + * + * @author Francis Besset + */ +class WebServiceResolverPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('webservice.definition.loader.resolver')) { + return; + } + + $definition = $container->getDefinition('webservice.definition.loader.resolver'); + + foreach ($container->findTaggedServiceIds('webservice.definition.loader') as $id => $attributes) { + $definition->addMethodCall('addLoader', array(new Reference($id))); + } + } +} diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 2f83de3..cb280c6 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -10,7 +10,6 @@ namespace Bundle\WebServiceBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; /** diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index c87aaa7..12e3d63 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -10,16 +10,12 @@ namespace Bundle\WebServiceBundle\DependencyInjection; -use Bundle\WebServiceBundle\Util\Assert; - -use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Definition\Processor; - +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; - use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -29,6 +25,8 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; */ class WebServiceExtension extends Extension { + private $contextArguments; + // maps config options to service suffix' private $bindingConfigToServiceSuffixMap = array('rpc-literal' => '.rpcliteral', 'document-wrapped' => '.documentwrapped'); @@ -36,47 +34,46 @@ class WebServiceExtension extends Extension { $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('annotations.xml'); + $loader->load('loaders.xml'); $loader->load('webservice.xml'); - $processor = new Processor(); + $processor = new Processor(); $configuration = new Configuration(); $config = $processor->process($configuration->getConfigTree(), $configs); foreach($config['services'] as $name => $serviceConfig) { - $this->createWebServiceContext($name, $serviceConfig, $container); + $serviceConfig['name'] = $name; + $this->createWebServiceContext($serviceConfig, $container); } } - private function createWebServiceContext($name, array $config, ContainerBuilder $container) + private function createWebServiceContext(array $config, ContainerBuilder $container) { - $bindingDependentArguments = array(1, 3, 4); $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; unset($config['binding']); - $contextPrototype = $container->getDefinition('webservice.context'); - $contextPrototypeArguments = $contextPrototype->getArguments(); + if (null === $this->contextArguments) { + $this->contextArguments = $container + ->getDefinition('webservice.context') + ->getArguments() + ; + } - $contextId = 'webservice.context.'.$name; - $context = $container->setDefinition($contextId, new DefinitionDecorator('webservice.context')); + $contextId = 'webservice.context.'.$config['name']; + $context = $container->setDefinition($contextId, $definition = new DefinitionDecorator('webservice.context')); $arguments = array(); - foreach($bindingDependentArguments as $idx) { - $arguments[] = new Reference($contextPrototypeArguments[$idx].$bindingSuffix); + foreach($this->contextArguments as $i => $argument) { + if (in_array($i, array(1, 3, 4))) { + $argument = new Reference($argument->__toString().$bindingSuffix); + } elseif (5 === $i) { + $argument = array_merge($argument, $config); + } else { + $argument = new Reference($argument->__toString()); + } + + $definition->replaceArgument($i, $argument); } - $arguments[5] = array_merge($contextPrototypeArguments[5], $config); - - $context->setArguments($arguments); - } - - public function getNamespace() - { - return null; - } - - public function getXsdValidationBasePath() - { - return null; } } \ No newline at end of file diff --git a/EventListener/ControllerListener.php b/EventListener/ControllerListener.php new file mode 100644 index 0000000..5612372 --- /dev/null +++ b/EventListener/ControllerListener.php @@ -0,0 +1,64 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\EventListener; + +use Bundle\WebServiceBundle\ServiceDefinition\Annotation\ConfigurationInterface; + +use Doctrine\Common\Annotations\Reader; + +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; + +/** + * Based on \Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener + * + * @author Francis Besset + */ +class ControllerListener +{ + /** + * @var \Doctrine\Common\Annotations\Reader + */ + protected $reader; + + /** + * Constructor. + * + * @param Reader $reader An Reader instance + */ + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + /** + * Modifies the Request object to apply configuration information found in + * controllers annotations like the template to render or HTTP caching + * configuration. + * + * @param FilterControllerEvent $event A FilterControllerEvent instance + */ + public function onKernelController(FilterControllerEvent $event) + { + if (!is_array($controller = $event->getController())) { + return; + } + + $object = new \ReflectionObject($controller[0]); + $method = $object->getMethod($controller[1]); + + $request = $event->getRequest(); + foreach ($this->reader->getMethodAnnotations($method) as $configuration) { + if ($configuration instanceof ConfigurationInterface) { + $request->attributes->set('_'.$configuration->getAliasName(), $configuration); + } + } + } +} \ No newline at end of file diff --git a/README.markdown b/README.markdown index 93d6f52..6d8f6d8 100644 --- a/README.markdown +++ b/README.markdown @@ -8,14 +8,46 @@ Requirements ------------ * Install and enable PHP's `SOAP` extension - * Download and add `Zend\Soap` library to `app/autoload.php` + * Download `Zend\Soap` + + git submodule add http://github.com/zendframework/zf2.git vendor/zend-framework + + * Add `Zend\Soap` library to `app/autoload.php` + + // app/autoload.php + $loader->registerNamespaces(array( + 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', + // your other namespaces + )); QuickStart ---------- - * Put WebServiceBundle in your `src/Bundle` dir + * Put WebServiceBundle in your `vendor/bundles/Bundle` dir + + git submodule add https://github.com/BeSimple/BeSimpleSoapBundle.git vendor/bundles/WebServiceBundle + * Enable WebServiceBundle in your `app/AppKernel.php` + // app/AppKernel.php + public function registerBundles() + { + return array( + // ... + new new Bundle\WebServiceBundle\WebServiceBundle(), + // ... + ); + } + + * Register the Bundle namespace + + // app/autoload.php + $loader->registerNamespaces(array( + 'Bundle' => __DIR__.'/../vendor/bundles', + 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', + // your other namespaces + )); + * Include the WebServiceBundle's routing configuration in `app/config/routing.yml` (you can choose the prefix arbitrarily) _ws: @@ -27,32 +59,40 @@ QuickStart web_service: services: DemoApi: - namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ + namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ binding: rpc-literal resource: "@AcmeDemoBundle/Controller/DemoController.php" resource_type: annotation * Annotate your controller methods - + // src/Acme/DemoBundle/Controller/DemoController.php - /** - * @ws:Method("Hello") - * @ws:Param("name", type = "string") - * @ws:Result(type = "string") - */ - public function helloAction($name) + use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Method; + use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Param; + use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Result; + use Bundle\WebServiceBundle\Soap\SoapResponse; + + class DemoController extends Controller { - return new SoapResponse(sprintf('Hello %s!', $name)); + /** + * @Method("Hello") + * @Param("name", phpType = "string") + * @Result(phpType = "string") + */ + public function helloAction($name) + { + return new SoapResponse(sprintf('Hello %s!', $name)); + } } * Open your web service endpoint * `http://localhost/app_dev.php/ws/DemoApi` - HTML documentation - * `http://localhost/app_dev.php/ws/DemoApi?WSDL` - WSDL file + * `http://localhost/app_dev.php/ws/DemoApi?wsdl` - WSDL file Test ---- - phpunit -c myapp src/Bundle/WebServiceBundle + phpunit -c phpunit.xml.dist [1]: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file diff --git a/Resources/config/annotations.xml b/Resources/config/annotations.xml deleted file mode 100644 index 9b10ecf..0000000 --- a/Resources/config/annotations.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationReader - Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationParser - - - - - true - - Bundle\WebServiceBundle\ServiceDefinition\Annotation\ - ws - - - - - - - - - - - - - diff --git a/Resources/config/loaders.xml b/Resources/config/loaders.xml new file mode 100644 index 0000000..888d1ad --- /dev/null +++ b/Resources/config/loaders.xml @@ -0,0 +1,40 @@ + + + + + + Bundle\WebServiceBundle\EventListener\ControllerListener + Symfony\Component\Config\Loader\LoaderResolver + Symfony\Component\Config\Loader\DelegatingLoader + Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader + Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationFileLoader + Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationClassLoader + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Resources/config/routing/webservicecontroller.xml b/Resources/config/routing/webservicecontroller.xml index ae2c83b..a3e3df9 100644 --- a/Resources/config/routing/webservicecontroller.xml +++ b/Resources/config/routing/webservicecontroller.xml @@ -5,12 +5,14 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - webservice.controller:call + WebServiceBundle:SoapWebService:Call + xml POST - webservice.controller:definition + WebServiceBundle:SoapWebService:Definition + xml GET diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 7fcdd2f..ebd14d4 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -4,64 +4,44 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Component\HttpKernel\Config\FileLocator - + Bundle\WebServiceBundle\Controller\SoapWebServiceController + Bundle\WebServiceBundle\WebServiceContext %kernel.cache_dir%/webservice + Bundle\WebServiceBundle\ServiceBinding\RpcLiteralRequestMessageBinder + Bundle\WebServiceBundle\ServiceBinding\RpcLiteralResponseMessageBinder + Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder + Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder + Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlDumper + Bundle\WebServiceBundle\Converter\ConverterRepository - - - - - - + - %webservice.cache_dir% - - - - + - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index df3e118..66b07a7 100644 --- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -20,7 +20,7 @@ class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterfa throw new \InvalidArgumentException(); } - $result = array(); + $result = array(); $message = $message[0]; foreach($messageDefinition->getArguments() as $argument) { diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php index 9138fe2..5806852 100644 --- a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -17,7 +17,7 @@ class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterf public function processMessage(Method $messageDefinition, $message) { $result = new \stdClass(); - $result->{$messageDefinition->getName() . 'Result'} = $message; + $result->{$messageDefinition->getName().'Result'} = $message; return $result; } diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index d845ed6..2269afc 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -17,10 +17,12 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface public function processMessage(Method $messageDefinition, $message) { $result = array(); - $i = 0; + $i = 0; foreach($messageDefinition->getArguments() as $argument) { - $result[$argument->getName()] = $message[$i]; + if (isset($message[$i])) { + $result[$argument->getName()] = $message[$i]; + } $i++; } diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index abf0430..c2f860b 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -10,16 +10,10 @@ namespace Bundle\WebServiceBundle\ServiceBinding; -use Bundle\WebServiceBundle\Util\QName; - -use Bundle\WebServiceBundle\ServiceDefinition\Type; - -use Bundle\WebServiceBundle\Soap\SoapHeader; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; use Bundle\WebServiceBundle\ServiceDefinition\Header; -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; -use Bundle\WebServiceBundle\ServiceDefinition\Loader\LoaderInterface; +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\Soap\SoapHeader; +use Bundle\WebServiceBundle\Util\QName; class ServiceBinder { @@ -28,11 +22,6 @@ class ServiceBinder */ private $definition; - /** - * @var \Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface - */ - private $definitionDumper; - /** * @var \Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface */ @@ -51,7 +40,7 @@ class ServiceBinder { $this->definition = $definition; - $this->requestMessageBinder = $requestMessageBinder; + $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; } @@ -76,9 +65,9 @@ class ServiceBinder { $methodDefinition = $this->definition->getMethods()->get($name); - $result = array(); + $result = array(); $result['_controller'] = $methodDefinition->getController(); - $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments)); + $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments)); return $result; } diff --git a/ServiceDefinition/Annotation/Configuration.php b/ServiceDefinition/Annotation/Configuration.php new file mode 100644 index 0000000..2df78b2 --- /dev/null +++ b/ServiceDefinition/Annotation/Configuration.php @@ -0,0 +1,30 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; + +/** + * Based on \Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation + * + * @author Francis Besset + */ +abstract class Configuration implements ConfigurationInterface +{ + public function __construct(array $values) + { + 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))); + } + + $this->$name($v); + } + } +} \ No newline at end of file diff --git a/ServiceDefinition/Annotation/ConfigurationInterface.php b/ServiceDefinition/Annotation/ConfigurationInterface.php new file mode 100644 index 0000000..3c910bf --- /dev/null +++ b/ServiceDefinition/Annotation/ConfigurationInterface.php @@ -0,0 +1,26 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; + +/** + * Based on \Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface + * + * @author Francis Besset + */ +interface ConfigurationInterface +{ + /** + * Returns the alias name for an annotated configuration. + * + * @return string + */ + function getAliasName(); +} \ No newline at end of file diff --git a/ServiceDefinition/Annotation/Method.php b/ServiceDefinition/Annotation/Method.php index 2c0b53e..faf5ae4 100644 --- a/ServiceDefinition/Annotation/Method.php +++ b/ServiceDefinition/Annotation/Method.php @@ -10,24 +10,36 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; -class Method +/** + * @Annotation + */ +class Method extends Configuration { - private $name; + private $value; private $service; - public function __construct($values) + public function getValue() { - $this->name = isset($values['value']) ? $values['value'] : null; - $this->service = isset($values['service']) ? $values['service'] : null; - } - - public function getName($default = null) - { - return $this->name !== null ? $this->name : $default; + return $this->value; } public function getService() { return $this->service; } + + public function setValue($value) + { + $this->value = $value; + } + + public function setService($service) + { + $this->service = $service; + } + + public function getAliasName() + { + return 'method'; + } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/Param.php b/ServiceDefinition/Annotation/Param.php index 6bb4f0d..932fef3 100644 --- a/ServiceDefinition/Annotation/Param.php +++ b/ServiceDefinition/Annotation/Param.php @@ -10,19 +10,47 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; -class Param extends TypedElement +/** + * @Annotation + */ +class Param extends Configuration implements TypedElementInterface { - private $name; + private $value; + private $phpType; + private $xmlType; - public function __construct($values) + public function getValue() { - parent::__construct($values); - - $this->name = $values['value']; + return $this->value; } - public function getName() + public function getPhpType() { - return $this->name; + return $this->phpType; + } + + public function getXmlType() + { + return $this->xmlType; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function setPhpType($phpType) + { + $this->phpType = $phpType; + } + + public function setXmlType($xmlType) + { + $this->xmlType = $xmlType; + } + + public function getAliasName() + { + return 'param'; } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/Result.php b/ServiceDefinition/Annotation/Result.php index 596c5d2..c56a587 100644 --- a/ServiceDefinition/Annotation/Result.php +++ b/ServiceDefinition/Annotation/Result.php @@ -10,10 +10,36 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; -class Result extends TypedElement +/** + * @Annotation + */ +class Result extends Configuration implements TypedElementInterface { - public function __construct($values) + private $phpType; + private $xmlType; + + public function getPhpType() { - parent::__construct($values); + return $this->phpType; + } + + public function getXmlType() + { + return $this->xmlType; + } + + public function setPhpType($phpType) + { + $this->phpType = $phpType; + } + + public function setXmlType($xmlType) + { + $this->xmlType = $xmlType; + } + + public function getAliasName() + { + return 'result'; } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/TypedElement.php b/ServiceDefinition/Annotation/TypedElement.php deleted file mode 100644 index 9d7209c..0000000 --- a/ServiceDefinition/Annotation/TypedElement.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; - -abstract class TypedElement -{ - private $phpType; - private $xmlType; - - public function __construct($values) - { - foreach(array('type', 'phpType') as $key) - { - if(isset($values[$key])) - { - $this->phpType = $values[$key]; - } - } - - $this->xmlType = isset($values['xmlType']) ? $values['xmlType'] : null; - } - - public function getPhpType() - { - return $this->phpType; - } - - public function getXmlType() - { - return $this->xmlType; - } -} \ No newline at end of file diff --git a/ServiceDefinition/Annotation/TypedElementInterface.php b/ServiceDefinition/Annotation/TypedElementInterface.php new file mode 100644 index 0000000..b6c4fe5 --- /dev/null +++ b/ServiceDefinition/Annotation/TypedElementInterface.php @@ -0,0 +1,19 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; + +interface TypedElementInterface +{ + function getPhpType(); + function getXmlType(); + function setPhpType($phpType); + function setXmlType($xmlType); +} \ No newline at end of file diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index c21556d..405d762 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -12,14 +12,11 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; use Bundle\WebServiceBundle\ServiceDefinition\Method; use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; - use Bundle\WebServiceBundle\Util\Assert; use Zend\Soap\Wsdl; - /** - * * @author Christian Kerl */ class WsdlDumper implements DumperInterface @@ -28,22 +25,20 @@ class WsdlDumper implements DumperInterface public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) { - Assert::thatArgumentNotNull('definition', $definition); - $options = array_merge(array('endpoint' => ''), $options); + Assert::thatArgumentNotNull('definition', $definition); + $this->definition = $definition; - - $wsdl = new Wsdl($definition->getName(), $definition->getNamespace()); - - $port = $wsdl->addPortType($this->getPortTypeName()); - $binding = $wsdl->addBinding($this->getBindingName(), 'tns:' . $this->getPortTypeName()); + $wsdl = new Wsdl($definition->getName(), $definition->getNamespace()); + $port = $wsdl->addPortType($this->getPortTypeName()); + $binding = $wsdl->addBinding($this->getBindingName(), 'tns:' . $this->getPortTypeName()); $wsdl->addSoapBinding($binding, 'rpc'); $wsdl->addService($this->getServiceName(), $this->getPortName(), 'tns:' . $this->getBindingName(), $options['endpoint']); foreach($definition->getMethods() as $method) { - $requestParts = array(); + $requestParts = array(); $responseParts = array(); foreach($method->getArguments() as $argument) { @@ -61,15 +56,15 @@ class WsdlDumper implements DumperInterface $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); $bindingInput = array( - 'parts' => implode(' ', array_keys($requestParts)), - 'use' => 'literal', - 'namespace' => $definition->getNamespace(), + 'parts' => implode(' ', array_keys($requestParts)), + 'use' => 'literal', + 'namespace' => $definition->getNamespace(), 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); $bindingOutput = array( - 'parts' => implode(' ', array_keys($responseParts)), - 'use' => 'literal', - 'namespace' => $definition->getNamespace(), + 'parts' => implode(' ', array_keys($responseParts)), + 'use' => 'literal', + 'namespace' => $definition->getNamespace(), 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); @@ -86,36 +81,36 @@ class WsdlDumper implements DumperInterface protected function getPortName() { - return $this->definition->getName() . 'Port'; + return $this->definition->getName().'Port'; } protected function getPortTypeName() { - return $this->definition->getName() . 'PortType'; + return $this->definition->getName().'PortType'; } protected function getBindingName() { - return $this->definition->getName() . 'Binding'; + return $this->definition->getName().'Binding'; } protected function getServiceName() { - return $this->definition->getName() . 'Service'; + return $this->definition->getName().'Service'; } protected function getRequestMessageName(Method $method) { - return $method->getName() . 'Request'; + return $method->getName().'Request'; } protected function getResponseMessageName(Method $method) { - return $method->getName() . 'Response'; + return $method->getName().'Response'; } protected function getSoapOperationName(Method $method) { - return $this->definition->getNamespace() . $method->getName(); + return $this->definition->getNamespace().$method->getName(); } } \ No newline at end of file diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index 4c97c34..bbbada0 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -8,17 +8,17 @@ * with this source code in the file LICENSE. */ - namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; - - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\ServiceDefinition\Method; use Bundle\WebServiceBundle\ServiceDefinition\Argument; +use Bundle\WebServiceBundle\ServiceDefinition\Method; use Bundle\WebServiceBundle\ServiceDefinition\Type; - +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Method as MethodAnnotation; +use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Param as ParamAnnotation; +use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Result as ResultAnnotation; + +use Doctrine\Common\Annotations\Reader; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderResolver; @@ -32,18 +32,18 @@ use Symfony\Component\Config\Loader\LoaderResolver; */ class AnnotationClassLoader implements LoaderInterface { - private $wsMethodAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Method'; - private $wsParamAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Param'; - private $wsResultAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Result'; + private $methodAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Method'; + private $paramAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Param'; + private $resultAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Result'; protected $reader; /** * Constructor. * - * @param AnnotationReader $reader + * @param \Doctrine\Common\Annotations\Reader $reader */ - public function __construct(AnnotationReader $reader) + public function __construct(Reader $reader) { $this->reader = $reader; } @@ -64,31 +64,46 @@ class AnnotationClassLoader implements LoaderInterface throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } - $class = new \ReflectionClass($class); - + $class = new \ReflectionClass($class); $definition = new ServiceDefinition(); - foreach ($class->getMethods() as $method) { - $wsMethodAnnot = $this->reader->getMethodAnnotation($method, $this->wsMethodAnnotationClass); + $serviceArguments = array(); + $serviceMethod = + $serviceReturn = null; - if($wsMethodAnnot !== null) { - $wsParamAnnots = $this->reader->getMethodAnnotations($method, $this->wsParamAnnotationClass); - $wsResultAnnot = $this->reader->getMethodAnnotation($method, $this->wsResultAnnotationClass); + foreach ($this->reader->getMethodAnnotations($method) as $i => $annotation) { + if ($annotation instanceof ParamAnnotation) { + $serviceArguments[] = new Argument( + $annotation->getValue(), + new Type($annotation->getPhpType(), $annotation->getXmlType()) + ); + } elseif ($annotation instanceof MethodAnnotation) { + if ($serviceMethod) { + throw new \LogicException(sprintf('@Method defined twice for "%s".', $method->getName())); + } - $serviceMethod = new Method(); - $serviceMethod->setName($wsMethodAnnot->getName($method->getName())); - $serviceMethod->setController($this->getController($method, $wsMethodAnnot)); + $serviceMethod = new Method( + $annotation->getValue(), + $this->getController($method, $annotation) + ); + } elseif ($annotation instanceof ResultAnnotation) { + if ($serviceReturn) { + throw new \LogicException(sprintf('@Result defined twice for "%s".', $method->getName())); + } - foreach($wsParamAnnots as $wsParamAnnot) { - $serviceArgument = new Argument(); - $serviceArgument->setName($wsParamAnnot->getName()); - $serviceArgument->setType(new Type($wsParamAnnot->getPhpType(), $wsParamAnnot->getXmlType())); - - $serviceMethod->getArguments()->add($serviceArgument); + $serviceReturn = new Type($annotation->getPhpType(), $annotation->getXmlType()); } + } - if($wsResultAnnot !== null) { - $serviceMethod->setReturn(new Type($wsResultAnnot->getPhpType(), $wsResultAnnot->getXmlType())); + if (!$serviceMethod && (!empty($serviceArguments) || $serviceReturn)) { + throw new \LogicException(sprintf('@Method non-existent for "%s".', $method->getName())); + } + + if ($serviceMethod) { + $serviceMethod->setArguments($serviceArguments); + + if ($serviceReturn) { + $serviceMethod->setReturn($serviceReturn); } $definition->getMethods()->add($serviceMethod); @@ -100,7 +115,7 @@ class AnnotationClassLoader implements LoaderInterface private function getController(\ReflectionMethod $method, MethodAnnotation $annotation) { - if($annotation->getService() !== null) { + if(null !== $annotation->getService()) { return $annotation->getService() . ':' . $method->name; } else { return $method->class . '::' . $method->name; diff --git a/ServiceDefinition/Loader/AnnotationFileLoader.php b/ServiceDefinition/Loader/AnnotationFileLoader.php index 6d7f405..688e406 100644 --- a/ServiceDefinition/Loader/AnnotationFileLoader.php +++ b/ServiceDefinition/Loader/AnnotationFileLoader.php @@ -8,14 +8,13 @@ * with this source code in the file LICENSE. */ - namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\Config\Loader\FileLoader; use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\Resource\FileResource; /** * AnnotationFileLoader loads ServiceDefinition from annotations set @@ -60,13 +59,11 @@ class AnnotationFileLoader extends FileLoader { $path = $this->locator->locate($file); - $definition = new ServiceDefinition(); - if ($class = $this->findClass($path)) { - $definition = $this->loader->load($class, $type); + return $definition = $this->loader->load($class, $type); } - return $definition; + return null; } /** @@ -91,9 +88,9 @@ class AnnotationFileLoader extends FileLoader */ protected function findClass($file) { - $class = false; + $class = false; $namespace = false; - $tokens = token_get_all(file_get_contents($file)); + $tokens = token_get_all(file_get_contents($file)); while ($token = array_shift($tokens)) { if (!is_array($token)) { continue; diff --git a/ServiceDefinition/Loader/AnnotationParser.php b/ServiceDefinition/Loader/AnnotationParser.php deleted file mode 100644 index afd9c1b..0000000 --- a/ServiceDefinition/Loader/AnnotationParser.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; - -use Doctrine\Common\Annotations\Lexer; -use Doctrine\Common\Annotations\Parser; - -/** - * AnnotationParser allows multiple annotations of the same class to be present. - * - * @author Christian Kerl - */ -class AnnotationParser extends Parser -{ - /** - * Annotations ::= Annotation {[ "*" ]* [Annotation]}* - * - * @return array - */ - public function Annotations() - { - $this->isNestedAnnotation = false; - - $annotations = array(); - $annot = $this->Annotation(); - - if ($annot !== false) { - $annotations[get_class($annot)][] = $annot; - $this->getLexer()->skipUntil(Lexer::T_AT); - } - - while ($this->getLexer()->lookahead !== null && $this->getLexer()->isNextToken(Lexer::T_AT)) { - $this->isNestedAnnotation = false; - $annot = $this->Annotation(); - - if ($annot !== false) { - $annotations[get_class($annot)][] = $annot; - $this->getLexer()->skipUntil(Lexer::T_AT); - } - } - - return $annotations; - } -} \ No newline at end of file diff --git a/ServiceDefinition/Loader/AnnotationReader.php b/ServiceDefinition/Loader/AnnotationReader.php deleted file mode 100644 index b65d48d..0000000 --- a/ServiceDefinition/Loader/AnnotationReader.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; - -use Doctrine\Common\Annotations\AnnotationReader as BaseAnnotationReader; - -/** - * AnnotationReader. - * - * @author Christian Kerl - */ -class AnnotationReader extends BaseAnnotationReader -{ - public function getMethodAnnotation(\ReflectionMethod $method, $type) - { - $annotation = parent::getMethodAnnotation($method, $type); - - if($annotation !== null && count($annotation) > 1) { - throw new \LogicException(sprintf("There is more than one annotation of type '%s'!", $type)); - } - - return $annotation !== null ? $annotation[0] : null; - } - - public function getMethodAnnotations(\ReflectionMethod $method, $type = null) - { - $annotations = parent::getMethodAnnotations($method); - - return $type !== null && isset($annotations[$type]) ? $annotations[$type] : $annotations; - } -} \ No newline at end of file diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index feefed5..944980c 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -10,13 +10,13 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; -use Symfony\Component\Config\Loader\FileLoader; - -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\ServiceDefinition\Argument; use Bundle\WebServiceBundle\ServiceDefinition\Header; use Bundle\WebServiceBundle\ServiceDefinition\Method; -use Bundle\WebServiceBundle\ServiceDefinition\Argument; use Bundle\WebServiceBundle\ServiceDefinition\Type; +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; + +use Symfony\Component\Config\Loader\FileLoader; class XmlFileLoader extends FileLoader { @@ -28,8 +28,7 @@ class XmlFileLoader extends FileLoader public function load($file, $type = null) { $path = $this->locator->locate($file); - - $xml = $this->parseFile($path); + $xml = $this->parseFile($path); $definition = new ServiceDefinition(); $definition->setName((string) $xml['name']); @@ -53,9 +52,7 @@ class XmlFileLoader extends FileLoader */ protected function parseHeader(\SimpleXMLElement $node) { - $header = new Header((string)$node['name'], $this->parseType($node->type)); - - return $header; + return new Header((string)$node['name'], $this->parseType($node->type)); } /** @@ -96,12 +93,10 @@ class XmlFileLoader extends FileLoader protected function parseType(\SimpleXMLElement $node) { $namespaces = $node->getDocNamespaces(true); - $qname = explode(':', $node['xml-type'], 2); - $xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]); + $qname = explode(':', $node['xml-type'], 2); + $xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]); - $type = new Type((string)$node['php-type'], $xmlType, (string)$node['converter']); - - return $type; + return new Type((string)$node['php-type'], $xmlType, (string)$node['converter']); } /** diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php index 136f9a4..48bf99b 100644 --- a/ServiceDefinition/Method.php +++ b/ServiceDefinition/Method.php @@ -19,12 +19,15 @@ class Method private $arguments; private $return; - public function __construct($name = null, $controller = null, array $arguments = array(), $return = null) + public function __construct($name = null, $controller = null, array $arguments = array(), Type $return = null) { $this->setName($name); $this->setController($controller); $this->setArguments($arguments); - $this->setReturn($return); + + if ($return) { + $this->setReturn($return); + } } public function getName() @@ -52,9 +55,9 @@ class Method return $this->arguments; } - public function setArguments($arguments) + public function setArguments(array $arguments) { - $this->arguments = new Collection('getName'); + $this->arguments = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Argument'); $this->arguments->addAll($arguments); } @@ -63,7 +66,7 @@ class Method return $this->return; } - public function setReturn($return) + public function setReturn(Type $return) { $this->return = $return; } diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index b587b9e..9be4a9e 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -38,6 +38,10 @@ class ServiceDefinition { $this->setName($name); $this->setNamespace($namespace); + + $this->methods = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Method'); + $this->headers = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Header'); + $this->setMethods($methods); $this->setHeaders($headers); } @@ -85,9 +89,8 @@ class ServiceDefinition /** * @param array $methods */ - public function setMethods($methods) + public function setMethods(array $methods) { - $this->methods = new Collection('getName'); $this->methods->addAll($methods); } @@ -102,9 +105,8 @@ class ServiceDefinition /** * @param array $headers */ - public function setHeaders($headers) + public function setHeaders(array $headers) { - $this->headers = new Collection('getName'); $this->headers->addAll($headers); } } \ No newline at end of file diff --git a/Soap/SoapAttachment.php b/Soap/SoapAttachment.php index d9d07db..d5592ce 100644 --- a/Soap/SoapAttachment.php +++ b/Soap/SoapAttachment.php @@ -18,8 +18,8 @@ class SoapAttachment public function __construct($id, $type, $content) { - $this->id = $id; - $this->type = $type; + $this->id = $id; + $this->type = $type; $this->content = $content; } diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php index 9c926ec..a66439a 100644 --- a/Soap/SoapHeader.php +++ b/Soap/SoapHeader.php @@ -19,8 +19,8 @@ class SoapHeader public function __construct($namespace, $name, $data) { $this->namespace = $namespace; - $this->name = $name; - $this->data = $data; + $this->name = $name; + $this->data = $data; } public function getNamespace() diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 5cfbf6f..dc31d9a 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -53,9 +53,9 @@ class SoapRequest extends Request { parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content); - $this->soapMessage = null; - $this->soapHeaders = new Collection('getName'); - $this->soapAttachments = new Collection('getId'); + $this->soapMessage = null; + $this->soapHeaders = new Collection('getName', 'Bundle\WebServiceBundle\Soap\SoapHeader'); + $this->soapAttachments = new Collection('getId', 'Bundle\WebServiceBundle\Soap\SoapAttachment'); $this->setRequestFormat('soap'); } @@ -67,7 +67,7 @@ class SoapRequest extends Request */ public function getSoapMessage() { - if($this->soapMessage === null) { + if(null === $this->soapMessage) { $this->soapMessage = $this->initializeSoapMessage(); } diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 46042cc..1f666ac 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -35,7 +35,7 @@ class SoapResponse extends Response { parent::__construct(); - $this->soapHeaders = new Collection('getName'); + $this->soapHeaders = new Collection('getName', 'Bundle\WebServiceBundle\Soap\SoapHeader'); $this->setReturnValue($returnValue); } diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 6402649..d81ec7f 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -10,22 +10,14 @@ namespace Bundle\WebServiceBundle\Soap; -/** - * - * @author Christian Kerl - */ -use Bundle\WebServiceBundle\ServiceDefinition\Type; - -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\FileDumper; - use Bundle\WebServiceBundle\Converter\ConverterRepository; - -use Bundle\WebServiceBundle\SoapKernel; - +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\ServiceDefinition\Type; use Bundle\WebServiceBundle\Util\QName; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; - +/** + * @author Christian Kerl + */ class SoapServerFactory { private $definition; @@ -35,17 +27,17 @@ class SoapServerFactory public function __construct(ServiceDefinition $definition, $wsdlFile, ConverterRepository $converters) { $this->definition = $definition; - $this->wsdlFile = $wsdlFile; + $this->wsdlFile = $wsdlFile; $this->converters = $converters; } - public function create(&$request, &$response) + public function create($request, $response) { $server = new \SoapServer( $this->wsdlFile, array( 'classmap' => $this->createSoapServerClassmap(), - 'typemap' => $this->createSoapServerTypemap($request, $response), + 'typemap' => $this->createSoapServerTypemap($request, $response), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, ) ); @@ -53,20 +45,20 @@ class SoapServerFactory return $server; } - private function createSoapServerTypemap(&$request, &$response) + private function createSoapServerTypemap($request, $response) { $result = array(); foreach($this->converters->getTypeConverters() as $typeConverter) { $result[] = array( 'type_name' => $typeConverter->getTypeName(), - 'type_ns' => $typeConverter->getTypeNamespace(), - 'from_xml' => function($input) use (&$request, $typeConverter) { + 'type_ns' => $typeConverter->getTypeNamespace(), + 'from_xml' => function($input) use ($request, $typeConverter) { return $typeConverter->convertXmlToPhp($request, $input); }, - 'to_xml' => function($input) use (&$response, $typeConverter) { + 'to_xml' => function($input) use ($response, $typeConverter) { return $typeConverter->convertPhpToXml($response, $input); - } + }, ); } @@ -93,7 +85,7 @@ class SoapServerFactory private function addSoapServerClassmapEntry(&$classmap, Type $type) { // TODO: fix this hack - if($type->getXmlType() === null) return; + if(null === $type->getXmlType()) return; $xmlType = QName::fromPackedQName($type->getXmlType())->getName(); $phpType = $type->getPhpType(); diff --git a/Tests/Soap/SoapRequestTest.php b/Tests/Soap/SoapRequestTest.php index 1185ee6..81df88b 100644 --- a/Tests/Soap/SoapRequestTest.php +++ b/Tests/Soap/SoapRequestTest.php @@ -40,6 +40,6 @@ class SoapRequestTest extends \PHPUnit_Framework_TestCase private function loadRequestContentFixture($name) { - return file_get_contents(__DIR__ . '/fixtures/' . $name); + return file_get_contents(__DIR__.'/../Fixtures/Soap/'.$name); } } diff --git a/Tests/fixtures/api-servicedefinition.xml b/Tests/fixtures/Soap/api-servicedefinition.xml similarity index 100% rename from Tests/fixtures/api-servicedefinition.xml rename to Tests/fixtures/Soap/api-servicedefinition.xml diff --git a/Tests/fixtures/api.wsdl b/Tests/fixtures/Soap/api.wsdl similarity index 100% rename from Tests/fixtures/api.wsdl rename to Tests/fixtures/Soap/api.wsdl diff --git a/Tests/fixtures/mtom/simple.txt b/Tests/fixtures/Soap/mtom/simple.txt similarity index 100% rename from Tests/fixtures/mtom/simple.txt rename to Tests/fixtures/Soap/mtom/simple.txt diff --git a/Util/Assert.php b/Util/Assert.php index 95563ab..a80985a 100644 --- a/Util/Assert.php +++ b/Util/Assert.php @@ -16,8 +16,8 @@ namespace Bundle\WebServiceBundle\Util; */ class Assert { - const ARGUMENT_INVALID = "Argument '%s' is invalid!"; - const ARGUMENT_NULL = "Argument '%s' can't be null!"; + const ARGUMENT_INVALID = 'Argument "%s" is invalid.'; + const ARGUMENT_NULL = 'Argument "%s" can not be null.'; public static function thatArgument($name, $condition, $message = self::ARGUMENT_INVALID) { @@ -28,6 +28,6 @@ class Assert public static function thatArgumentNotNull($name, $value) { - self::thatArgument($name, $value != null, self::ARGUMENT_NULL); + self::thatArgument($name, null !== $value, self::ARGUMENT_NULL); } } diff --git a/Util/Collection.php b/Util/Collection.php index 8828900..97bbfee 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -13,16 +13,23 @@ namespace Bundle\WebServiceBundle\Util; class Collection implements \IteratorAggregate, \Countable { private $elements = array(); - private $keyPropertyGetter; + private $getter; + private $class; - public function __construct($keyPropertyGetter) + public function __construct($getter, $class = null) { - $this->keyPropertyGetter = $keyPropertyGetter; + $this->getter = $getter; + $this->class = $class; } public function add($element) { - $this->elements[call_user_func(array($element, $this->keyPropertyGetter))] = $element; + if ($this->class && !$element instanceof $this->class) { + throw new \InvalidArgument(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $class)); + } + + $getter = $this->getter; + $this->elements[$element->$getter()] = $element; } public function addAll($elements) @@ -52,7 +59,7 @@ class Collection implements \IteratorAggregate, \Countable return count($this->elements); } - public function getIterator () + public function getIterator() { return new \ArrayIterator($this->elements); } diff --git a/Util/QName.php b/Util/QName.php index d2bf3f2..924138e 100644 --- a/Util/QName.php +++ b/Util/QName.php @@ -11,11 +11,13 @@ namespace Bundle\WebServiceBundle\Util; /** - * * @author Christian Kerl */ class QName { + private $namespace; + private $name; + public static function fromPackedQName($qname) { Assert::thatArgument('qname', preg_match('/^\{(.+)\}(.+)$/', $qname, $matches)); @@ -23,9 +25,6 @@ class QName return new self($matches[1], $matches[2]); } - private $namespace; - private $name; - public function __construct($namespace, $name) { $this->namespace = $namespace; diff --git a/Util/String.php b/Util/String.php index 0526453..d88192b 100644 --- a/Util/String.php +++ b/Util/String.php @@ -17,14 +17,14 @@ namespace Bundle\WebServiceBundle\Util; */ class String { - /** - * Checks if a string starts with a given string. - * - * @param string $str A string - * @param string $substr A string to check against - * - * @return bool True if str starts with substr - */ + /** + * Checks if a string starts with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str starts with substr + */ public static function startsWith($str, $substr) { if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) { @@ -33,17 +33,16 @@ class String } /** - * Checks if a string ends with a given string. - * - * @param string $str A string - * @param string $substr A string to check against - * - * @return bool True if str ends with substr - */ + * Checks if a string ends with a given string. + * + * @param string $str A string + * @param string $substr A string to check against + * + * @return bool True if str ends with substr + */ public static function endsWith($str, $substr) { - if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) - { + if(is_string($str) && is_string($substr) && strlen($str) >= strlen($substr)) { return $substr == substr($str, strlen($str) - strlen($substr)); } } diff --git a/WebServiceBundle.php b/WebServiceBundle.php index 2ea3bb6..31c1a88 100644 --- a/WebServiceBundle.php +++ b/WebServiceBundle.php @@ -10,8 +10,9 @@ namespace Bundle\WebServiceBundle; -use Symfony\Component\DependencyInjection\ContainerBuilder; +use Bundle\WebServiceBundle\DependencyInjection\Compiler\WebServiceResolverPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; /** @@ -21,4 +22,10 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; */ class WebServiceBundle extends Bundle { + public function build(ContainerBuilder $container) + { + parent::build($container); + + $container->addCompilerPass(new WebServiceResolverPass()); + } } \ No newline at end of file diff --git a/WebServiceContext.php b/WebServiceContext.php index 8bdd949..f421595 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -10,16 +10,15 @@ namespace Bundle\WebServiceBundle; +use Bundle\WebServiceBundle\Converter\ConverterRepository; +use Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface; +use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; +use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; +use Bundle\WebServiceBundle\Soap\SoapServerFactory; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Loader\LoaderInterface; -use Bundle\WebServiceBundle\Converter\ConverterRepository; -use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; -use Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface; -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; -use Bundle\WebServiceBundle\Soap\SoapServerFactory; - /** * WebServiceContext. * @@ -31,7 +30,6 @@ class WebServiceContext private $requestMessageBinder; private $responseMessageBinder; - private $serviceDefinitionLoader; private $wsdlFileDumper; private $options; @@ -40,13 +38,13 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, ConverterRepository $converterRepository, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, array $options) + public function __construct(LoaderInterface $loader, DumperInterface $dumper, ConverterRepository $converterRepository, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, array $options = array()) { - $this->serviceDefinitionLoader = $loader; + $this->loader = $loader; $this->wsdlFileDumper = $dumper; - $this->converterRepository = $converterRepository; - $this->requestMessageBinder = $requestMessageBinder; + $this->converterRepository = $converterRepository; + $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; $this->options = $options; @@ -54,12 +52,12 @@ class WebServiceContext public function getServiceDefinition() { - if($this->serviceDefinition === null) { - if(!$this->serviceDefinitionLoader->supports($this->options['resource'], $this->options['resource_type'])) { - throw new \LogicException(); + if (null === $this->serviceDefinition) { + 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'])); } - $this->serviceDefinition = $this->serviceDefinitionLoader->load($this->options['resource'], $this->options['resource_type']); + $this->serviceDefinition = $this->loader->load($this->options['resource'], $this->options['resource_type']); $this->serviceDefinition->setName($this->options['name']); $this->serviceDefinition->setNamespace($this->options['namespace']); } @@ -69,8 +67,8 @@ class WebServiceContext public function getWsdlFile($endpoint = null) { - $id = $endpoint !== null ? '.' . md5($endpoint) : ''; - $file = sprintf('%s/%s.wsdl', $this->options['cache_dir'], $this->options['name'] . $id); + $id = null !== $endpoint ? '.'. md5($endpoint) : ''; + $file = sprintf('%s/%s.wsdl', $this->options['cache_dir'], $this->options['name'].$id); $cache = new ConfigCache($file, true); if(!$cache->isFresh()) { @@ -87,7 +85,7 @@ class WebServiceContext public function getServiceBinder() { - if($this->serviceBinder === null) { + if (null === $this->serviceBinder) { $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestMessageBinder, $this->responseMessageBinder); } @@ -96,7 +94,7 @@ class WebServiceContext public function getServerFactory() { - if($this->serverFactory === null) { + if (null === $this->serverFactory) { $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository); } diff --git a/vendors.php b/vendors.php index 47b53e5..1841c89 100755 --- a/vendors.php +++ b/vendors.php @@ -1,20 +1,19 @@ #!/usr/bin/env php + * (c) Christian Kerl * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. */ /* -CAUTION: This file installs the dependencies needed to run the I18nRoutingBundle test suite. +CAUTION: This file installs the dependencies needed to run the WebServiceBundle test suite. -https://github.com/BeSimple/I18nRoutingBundle +https://github.com/BeSimple/BeSimpleSoapBundle */ From 887169de13a32050e202514c77010cd2060de292 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 17 Jul 2011 12:35:47 +0200 Subject: [PATCH 053/195] Added debug parameter at SoapServerFactory If kernel.debug parameter is true, the cache is disabled. --- Resources/config/webservice.xml | 1 + Soap/SoapServerFactory.php | 29 +++++++++++++++-------------- WebServiceContext.php | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index ebd14d4..d0fdbd1 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -24,6 +24,7 @@ %webservice.cache_dir% + %kernel.debug% diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index d81ec7f..1666a8c 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -23,34 +23,35 @@ class SoapServerFactory private $definition; private $converters; private $wsdlFile; + private $debug; - public function __construct(ServiceDefinition $definition, $wsdlFile, ConverterRepository $converters) + public function __construct(ServiceDefinition $definition, $wsdlFile, ConverterRepository $converters, $debug = false) { $this->definition = $definition; $this->wsdlFile = $wsdlFile; $this->converters = $converters; + $this->debug = $debug; } public function create($request, $response) { - $server = new \SoapServer( + return new \SoapServer( $this->wsdlFile, array( - 'classmap' => $this->createSoapServerClassmap(), - 'typemap' => $this->createSoapServerTypemap($request, $response), - 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, + 'classmap' => $this->createSoapServerClassmap(), + 'typemap' => $this->createSoapServerTypemap($request, $response), + 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, + 'cache_wsdl' => $this->debug ? WSDL_CACHE_NONE : WSDL_CACHE_DISK, ) ); - - return $server; } private function createSoapServerTypemap($request, $response) { - $result = array(); + $typemap = array(); foreach($this->converters->getTypeConverters() as $typeConverter) { - $result[] = array( + $typemap[] = array( 'type_name' => $typeConverter->getTypeName(), 'type_ns' => $typeConverter->getTypeNamespace(), 'from_xml' => function($input) use ($request, $typeConverter) { @@ -62,24 +63,24 @@ class SoapServerFactory ); } - return $result; + return $typemap; } private function createSoapServerClassmap() { - $result = array(); + $classmap = array(); foreach($this->definition->getHeaders() as $header) { - $this->addSoapServerClassmapEntry($result, $header->getType()); + $this->addSoapServerClassmapEntry($classmap, $header->getType()); } foreach($this->definition->getMethods() as $method) { foreach($method->getArguments() as $arg) { - $this->addSoapServerClassmapEntry($result, $arg->getType()); + $this->addSoapServerClassmapEntry($classmap, $arg->getType()); } } - return $result; + return $classmap; } private function addSoapServerClassmapEntry(&$classmap, Type $type) diff --git a/WebServiceContext.php b/WebServiceContext.php index f421595..af14ee7 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -95,7 +95,7 @@ class WebServiceContext public function getServerFactory() { if (null === $this->serverFactory) { - $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository); + $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository, $this->options['debug']); } return $this->serverFactory; From 0126cd422193185f8000e7a8b7c9e61147e01388 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sun, 17 Jul 2011 15:01:42 +0200 Subject: [PATCH 054/195] some cleanup Conflicts: Controller/SoapWebServiceController.php ServiceBinding/ServiceBinder.php --- Controller/SoapWebServiceController.php | 18 ++++++++++++++---- ServiceBinding/ServiceBinder.php | 10 ++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 0970a18..be8c747 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -15,6 +15,7 @@ use Bundle\WebServiceBundle\Soap\SoapResponse; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; /** @@ -47,7 +48,7 @@ class SoapWebServiceController extends ContainerAware */ public function callAction($webservice) { - $webServiceContext = $this->container->get('webservice.context.'.$webservice); + $webServiceContext = $this->getWebServiceContext($webservice); $this->serviceBinder = $webServiceContext->getServiceBinder(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); @@ -66,7 +67,7 @@ class SoapWebServiceController extends ContainerAware */ public function definitionAction($webservice) { - $webServiceContext = $this->container->get('webservice.context.'.$webservice); + $webServiceContext = $this->getWebServiceContext($webservice); $request = $this->container->get('request'); if ($request->query->has('wsdl') || $request->query->has('WSDL')) { @@ -75,7 +76,7 @@ class SoapWebServiceController extends ContainerAware $response = new Response($webServiceContext->getWsdlFileContent($endpoint)); $response->headers->set('Content-Type', 'application/wsdl+xml'); } else { - // TODO: replace with better represantation + // TODO: replace with better representation $response = new Response($webServiceContext->getWsdlFileContent()); $response->headers->set('Content-Type', 'text/xml'); } @@ -159,4 +160,13 @@ class SoapWebServiceController extends ContainerAware { return $this->soapResponse; } -} \ No newline at end of file + + private function getWebServiceContext($webservice) + { + if(!$this->container->has('webservice.context.'.$webservice)) + { + throw new NotFoundHttpException(sprintf('No webservice with name "%s" found.', $webservice)); + } + return $this->container->get('webservice.context.'.$webservice); + } +} diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index c2f860b..88c5377 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -32,14 +32,8 @@ class ServiceBinder */ private $responseMessageBinder; - public function __construct( - ServiceDefinition $definition, - MessageBinderInterface $requestMessageBinder, - MessageBinderInterface $responseMessageBinder - ) - { - $this->definition = $definition; - + public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) { + $this->definition = $definition; $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; } From 62e07ba43c5bb1fc2cfaa63f1e6e8411a21e1012 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sun, 17 Jul 2011 15:03:05 +0200 Subject: [PATCH 055/195] added support to retrieve parameter php type form type hint Conflicts: ServiceDefinition/Loader/AnnotationClassLoader.php --- .../Loader/AnnotationClassLoader.php | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index bbbada0..fc0517d 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -66,6 +66,7 @@ class AnnotationClassLoader implements LoaderInterface $class = new \ReflectionClass($class); $definition = new ServiceDefinition(); + foreach ($class->getMethods() as $method) { $serviceArguments = array(); $serviceMethod = @@ -75,7 +76,7 @@ class AnnotationClassLoader implements LoaderInterface if ($annotation instanceof ParamAnnotation) { $serviceArguments[] = new Argument( $annotation->getValue(), - new Type($annotation->getPhpType(), $annotation->getXmlType()) + $this->getArgumentType($method, $annotation) ); } elseif ($annotation instanceof MethodAnnotation) { if ($serviceMethod) { @@ -122,6 +123,30 @@ class AnnotationClassLoader implements LoaderInterface } } + /** + * @param \ReflectionMethod $method + * @param ParamAnnotation $annotation + * + * @return \Bundle\WebServiceBundle\ServiceDefinition\Type + */ + private function getArgumentType(\ReflectionMethod $method, ParamAnnotation $annotation) + { + $phpType = $annotation->getPhpType(); + $xmlType = $annotation->getXmlType(); + + if (null === $phpType) { + foreach ($method->getParameters() as $param) { + if ($param->name === $annotation->getName()) { + $phpType = $param->getClass()->name; + + break; + } + } + } + + return new Type($phpType, $xmlType); + } + /** * Returns true if this class supports the given resource. * @@ -152,4 +177,4 @@ class AnnotationClassLoader implements LoaderInterface public function getResolver() { } -} \ No newline at end of file +} From 5da442b716b640097288f06fe710b871bd9e477a Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sun, 17 Jul 2011 15:04:33 +0200 Subject: [PATCH 056/195] added Zend\Soap\Wsdl\Strategy implementation supporting array types and complex types (classes) Conflicts: ServiceDefinition/Dumper/WsdlDumper.php --- ServiceDefinition/Dumper/WsdlDumper.php | 57 ++++++++++----- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 69 +++++++++++++++++++ 2 files changed, 107 insertions(+), 19 deletions(-) create mode 100644 ServiceDefinition/Dumper/WsdlTypeStrategy.php diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 405d762..9d334a4 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -11,8 +11,10 @@ namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; use Bundle\WebServiceBundle\ServiceDefinition\Method; +use Bundle\WebServiceBundle\ServiceDefinition\Type; use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; use Bundle\WebServiceBundle\Util\Assert; +use Bundle\WebServiceBundle\Util\QName; use Zend\Soap\Wsdl; @@ -21,38 +23,39 @@ use Zend\Soap\Wsdl; */ class WsdlDumper implements DumperInterface { + private $wsdl; private $definition; public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) { - $options = array_merge(array('endpoint' => ''), $options); - Assert::thatArgumentNotNull('definition', $definition); + $options = array_merge(array('endpoint' => '', 'stylesheet' => null), $options); + $this->definition = $definition; - $wsdl = new Wsdl($definition->getName(), $definition->getNamespace()); - $port = $wsdl->addPortType($this->getPortTypeName()); - $binding = $wsdl->addBinding($this->getBindingName(), 'tns:' . $this->getPortTypeName()); + $this->wsdl = new Wsdl($definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy()); + $port = $this->wsdl->addPortType($this->getPortTypeName()); + $binding = $this->wsdl->addBinding($this->getBindingName(), $this->qualify($this->getPortTypeName())); - $wsdl->addSoapBinding($binding, 'rpc'); - $wsdl->addService($this->getServiceName(), $this->getPortName(), 'tns:' . $this->getBindingName(), $options['endpoint']); + $this->wsdl->addSoapBinding($binding, 'rpc'); + $this->wsdl->addService($this->getServiceName(), $this->getPortName(), $this->qualify($this->getBindingName()), $options['endpoint']); - foreach($definition->getMethods() as $method) { + foreach ($definition->getMethods() as $method) { $requestParts = array(); $responseParts = array(); - foreach($method->getArguments() as $argument) { - $requestParts[$argument->getName()] = $wsdl->getType($argument->getType()->getPhpType()); + foreach ($method->getArguments() as $argument) { + $requestParts[$argument->getName()] = $this->wsdl->getType($argument->getType()->getPhpType()); } - if($method->getReturn() !== null) { - $responseParts['return'] = $wsdl->getType($method->getReturn()->getPhpType()); + if ($method->getReturn() !== null) { + $responseParts['return'] = $this->wsdl->getType($method->getReturn()->getPhpType()); } - $wsdl->addMessage($this->getRequestMessageName($method), $requestParts); - $wsdl->addMessage($this->getResponseMessageName($method), $responseParts); + $this->wsdl->addMessage($this->getRequestMessageName($method), $requestParts); + $this->wsdl->addMessage($this->getResponseMessageName($method), $responseParts); - $portOperation = $wsdl->addPortOperation($port, $method->getName(), 'tns:' . $this->getRequestMessageName($method), 'tns:' . $this->getResponseMessageName($method)); + $portOperation = $this->wsdl->addPortOperation($port, $method->getName(), $this->qualify($this->getRequestMessageName($method)), $this->qualify($this->getResponseMessageName($method))); $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); $bindingInput = array( @@ -68,17 +71,33 @@ class WsdlDumper implements DumperInterface 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); - $bindingOperation = $wsdl->addBindingOperation($binding, $method->getName(), $bindingInput, $bindingOutput); - $wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method)); + $bindingOperation = $this->wsdl->addBindingOperation($binding, $method->getName(), $bindingInput, $bindingOutput); + $this->wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method)); } $this->definition = null; - $wsdl->toDomDocument()->formatOutput = true; + $dom = $this->wsdl->toDomDocument(); + $dom->formatOutput = true; + + if (null !== $options['stylesheet']) { + $stylesheet = $dom->createProcessingInstruction('xml-stylesheet', sprintf('type="text/xsl" href="%s"', $options['stylesheet'])); + + $dom->insertBefore($stylesheet, $dom->documentElement); + } return $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'; @@ -113,4 +132,4 @@ class WsdlDumper implements DumperInterface { return $this->definition->getNamespace().$method->getName(); } -} \ No newline at end of file +} diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php new file mode 100644 index 0000000..98005e6 --- /dev/null +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -0,0 +1,69 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; + +use Bundle\WebServiceBundle\Util\String; + +use Zend\Soap\Exception; +use Zend\Soap\Wsdl; +use Zend\Soap\Wsdl\Strategy; +use Zend\Soap\Wsdl\Strategy\ArrayOfTypeSequence; +use Zend\Soap\Wsdl\Strategy\DefaultComplexType; + +class WsdlTypeStrategy implements Strategy +{ + /** + * Context WSDL file + * + * @var \Zend\Soap\Wsdl|null + */ + private $context; + + private $typeStrategy; + private $arrayStrategy; + + public function __construct() + { + $this->typeStrategy = new DefaultComplexType(); + $this->arrayStrategy = new ArrayOfTypeSequence(); + } + + /** + * Method accepts the current WSDL context file. + * + * @param \Zend\Soap\Wsdl $context + */ + public function setContext(Wsdl $context) + { + $this->context = $context; + + return $this; + } + + /** + * Create a complex type based on a strategy + * + * @throws \Zend\Soap\WsdlException + * @param string $type + * @return string XSD type + */ + 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->arrayStrategy : $this->typeStrategy; + $strategy->setContext($this->context); + + return $strategy->addComplexType($type); + } +} \ No newline at end of file From 76e7f42ccb9a62bf5df15ae81250b4ff87119be6 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Sun, 17 Jul 2011 15:08:46 +0200 Subject: [PATCH 057/195] added TypeRepository managing all mappings from php to xml types; removed classmap generation from SoapServerFactory, this will be done by TypeRepository::createComplexTypeMap(...); Conflicts: Resources/config/webservice.xml Soap/SoapServerFactory.php Util/QName.php WebServiceContext.php --- Converter/TypeRepository.php | 91 +++++++++++++++++++++ DependencyInjection/WebServiceExtension.php | 4 +- Resources/config/webservice.xml | 31 +++++-- ServiceDefinition/ServiceDefinition.php | 18 ++++ Soap/SoapServerFactory.php | 45 ++-------- Util/QName.php | 16 +++- WebServiceContext.php | 22 +++-- 7 files changed, 170 insertions(+), 57 deletions(-) create mode 100644 Converter/TypeRepository.php diff --git a/Converter/TypeRepository.php b/Converter/TypeRepository.php new file mode 100644 index 0000000..6946547 --- /dev/null +++ b/Converter/TypeRepository.php @@ -0,0 +1,91 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Bundle\WebServiceBundle\Converter; + +use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use Bundle\WebServiceBundle\Util\Assert; +use Bundle\WebServiceBundle\Util\QName; +use Bundle\WebServiceBundle\Util\String; + +/** + * @author Christian Kerl + */ +class TypeRepository +{ + const ARRAY_SUFFIX = '[]'; + + private $xmlNamespaces = array(); + private $defaultTypeMap = array(); + + public function addXmlNamespace($prefix, $url) + { + $this->xmlNamespaces[$prefix] = $url; + } + + public function getXmlNamespace($prefix) + { + return $this->xmlNamespaces[$prefix]; + } + + public function addDefaultTypeMapping($phpType, $xmlType) + { + Assert::thatArgumentNotNull('phpType', $phpType); + Assert::thatArgumentNotNull('xmlType', $xmlType); + + $this->defaultTypeMap[$phpType] = $this->getQName($xmlType); + } + + public function fixTypeInformation(ServiceDefinition $definition) + { + $typeMap = $this->defaultTypeMap; + + foreach($definition->getAllTypes() as $type) { + $phpType = $type->getPhpType(); + $xmlType = $type->getXmlType(); + + if (null === $phpType) { + throw new \InvalidArgumentException(); + } + + if (null === $xmlType) { + if (!isset($typeMap[$phpType])) { + $parts = explode('\\', $phpType); + $xmlTypeName = ucfirst(end($parts)); + + if (String::endsWith($phpType, self::ARRAY_SUFFIX)) { + $xmlTypeName = str_replace(self::ARRAY_SUFFIX, 'Array', $xmlTypeName); + } + + $typeMap[$phpType] = new QName($definition->getNamespace(), $xmlTypeName); + } + + $xmlType = $typeMap[$phpType]; + } else { + $xmlType = $this->getQName($xmlType); + } + + $type->setXmlType((string) $xmlType); + } + } + + private function getQName($xmlType) + { + if (QName::isPrefixedQName($xmlType)) { + return QName::fromPrefixedQName($xmlType, array($this, 'getXmlNamespace')); + } else { + return QName::fromPackedQName($xmlType); + } + } + + public function createComplexTypeMap(ServiceDefinition $definition) + { + } +} \ No newline at end of file diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php index 12e3d63..68afc93 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/WebServiceExtension.php @@ -65,9 +65,9 @@ class WebServiceExtension extends Extension $arguments = array(); foreach($this->contextArguments as $i => $argument) { - if (in_array($i, array(1, 3, 4))) { + if (in_array($i, array(1, 2, 3))) { $argument = new Reference($argument->__toString().$bindingSuffix); - } elseif (5 === $i) { + } elseif (6 === $i) { $argument = array_merge($argument, $config); } else { $argument = new Reference($argument->__toString()); diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index d0fdbd1..a2d6950 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -13,15 +13,17 @@ Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlDumper Bundle\WebServiceBundle\Converter\ConverterRepository + Bundle\WebServiceBundle\Converter\TypeRepository - + + %webservice.cache_dir% %kernel.debug% @@ -38,11 +40,30 @@ - - - + + + + + xsd + http://www.w3.org/2001/XMLSchema + + + string + xsd:string + + + int + xsd:int + + + bool + xsd:boolean + + + float + xsd:float - \ No newline at end of file + diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index 9be4a9e..8a24bc0 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -109,4 +109,22 @@ class ServiceDefinition { $this->headers->addAll($headers); } + + /** + * @return array + */ + public function getAllTypes() + { + $types = array(); + + foreach($this->methods as $method) { + foreach($method->getArguments() as $argument) { + $types[] = $argument->getType(); + } + + $types[] = $method->getReturn(); + } + + return $types; + } } \ No newline at end of file diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 1666a8c..9ffa0c6 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -11,24 +11,21 @@ namespace Bundle\WebServiceBundle\Soap; use Bundle\WebServiceBundle\Converter\ConverterRepository; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\ServiceDefinition\Type; -use Bundle\WebServiceBundle\Util\QName; /** * @author Christian Kerl */ class SoapServerFactory { - private $definition; - private $converters; private $wsdlFile; + private $classmap; + private $converters; private $debug; - public function __construct(ServiceDefinition $definition, $wsdlFile, ConverterRepository $converters, $debug = false) + public function __construct($wsdlFile, array $classmap, ConverterRepository $converters, $debug = false) { - $this->definition = $definition; $this->wsdlFile = $wsdlFile; + $this->classmap = $classmap; $this->converters = $converters; $this->debug = $debug; } @@ -38,7 +35,7 @@ class SoapServerFactory return new \SoapServer( $this->wsdlFile, array( - 'classmap' => $this->createSoapServerClassmap(), + 'classmap' => $this->classmap, 'typemap' => $this->createSoapServerTypemap($request, $response), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'cache_wsdl' => $this->debug ? WSDL_CACHE_NONE : WSDL_CACHE_DISK, @@ -65,36 +62,4 @@ class SoapServerFactory return $typemap; } - - private function createSoapServerClassmap() - { - $classmap = array(); - - foreach($this->definition->getHeaders() as $header) { - $this->addSoapServerClassmapEntry($classmap, $header->getType()); - } - - foreach($this->definition->getMethods() as $method) { - foreach($method->getArguments() as $arg) { - $this->addSoapServerClassmapEntry($classmap, $arg->getType()); - } - } - - return $classmap; - } - - private function addSoapServerClassmapEntry(&$classmap, Type $type) - { - // TODO: fix this hack - if(null === $type->getXmlType()) return; - - $xmlType = QName::fromPackedQName($type->getXmlType())->getName(); - $phpType = $type->getPhpType(); - - if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType) { - // log warning - } - - $classmap[$xmlType] = $phpType; - } } \ No newline at end of file diff --git a/Util/QName.php b/Util/QName.php index 924138e..874f52d 100644 --- a/Util/QName.php +++ b/Util/QName.php @@ -18,6 +18,20 @@ class QName private $namespace; private $name; + public static function isPrefixedQName($qname) + { + return false !== strpos($qname, ':') ? true : false; + } + + public static function fromPrefixedQName($qname, $resolveNamespacePrefixCallable) + { + Assert::thatArgument('qname', self::isPrefixedQName($qname)); + + list($prefix, $name) = explode(':', $qname); + + return new self(call_user_func($resolveNamespacePrefixCallable, $prefix), $name); + } + public static function fromPackedQName($qname) { Assert::thatArgument('qname', preg_match('/^\{(.+)\}(.+)$/', $qname, $matches)); @@ -28,7 +42,7 @@ class QName public function __construct($namespace, $name) { $this->namespace = $namespace; - $this->name = $name; + $this->name = $name; } public function getNamespace() diff --git a/WebServiceContext.php b/WebServiceContext.php index af14ee7..90c3879 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -11,6 +11,7 @@ namespace Bundle\WebServiceBundle; use Bundle\WebServiceBundle\Converter\ConverterRepository; +use Bundle\WebServiceBundle\Converter\TypeRepository; use Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface; use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; @@ -26,9 +27,10 @@ use Symfony\Component\Config\Loader\LoaderInterface; */ class WebServiceContext { - private $converterRepository; private $requestMessageBinder; private $responseMessageBinder; + private $typeRepository; + private $converterRepository; private $wsdlFileDumper; @@ -38,15 +40,16 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, ConverterRepository $converterRepository, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, array $options = array()) - { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { $this->loader = $loader; $this->wsdlFileDumper = $dumper; - $this->converterRepository = $converterRepository; $this->requestMessageBinder = $requestMessageBinder; $this->responseMessageBinder = $responseMessageBinder; + $this->typeRepository = $typeRepository; + $this->converterRepository = $converterRepository; + $this->options = $options; } @@ -60,6 +63,8 @@ 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->typeRepository->fixTypeInformation($this->serviceDefinition); } return $this->serviceDefinition; @@ -67,15 +72,14 @@ class WebServiceContext public function getWsdlFile($endpoint = null) { - $id = null !== $endpoint ? '.'. md5($endpoint) : ''; - $file = sprintf('%s/%s.wsdl', $this->options['cache_dir'], $this->options['name'].$id); - $cache = new ConfigCache($file, true); + $file = sprintf('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint)); + $cache = new ConfigCache($file, $this->options['debug']); if(!$cache->isFresh()) { $cache->write($this->wsdlFileDumper->dumpServiceDefinition($this->getServiceDefinition(), array('endpoint' => $endpoint))); } - return $file; + return (string) $cache; } public function getWsdlFileContent($endpoint = null) @@ -95,7 +99,7 @@ class WebServiceContext public function getServerFactory() { if (null === $this->serverFactory) { - $this->serverFactory = new SoapServerFactory($this->getServiceDefinition(), $this->getWsdlFile(), $this->converterRepository, $this->options['debug']); + $this->serverFactory = new SoapServerFactory($this->getWsdlFile(), array(), $this->converterRepository, $this->options['debug']); } return $this->serverFactory; From 234689f4e57f3f5c2b9fa2073a98d6418a783e55 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 17 Jul 2011 19:41:06 +0200 Subject: [PATCH 058/195] Fixed typo --- ServiceDefinition/Dumper/WsdlDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 9d334a4..37e9c40 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -86,7 +86,7 @@ class WsdlDumper implements DumperInterface $dom->insertBefore($stylesheet, $dom->documentElement); } - return $wsdl->toXml(); + return $this->wsdl->toXml(); } protected function qualify($name, $namespace = null) From b4a293940a89f64a766c49dbce4b9daae8a9c97e Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 17 Jul 2011 19:46:43 +0200 Subject: [PATCH 059/195] Added Contributors file --- CONTRIBUTORS.markdown | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CONTRIBUTORS.markdown diff --git a/CONTRIBUTORS.markdown b/CONTRIBUTORS.markdown new file mode 100644 index 0000000..d78d2c3 --- /dev/null +++ b/CONTRIBUTORS.markdown @@ -0,0 +1,2 @@ +* [Christian Kerl](https://github.com/christiankerl) +* [Francis Besset](https://github.com/francisbesset) From 265826f6c66df5c0560b11b0c670e39cfdce895b Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 17 Jul 2011 20:41:18 +0200 Subject: [PATCH 060/195] Deleted useless ControllerListener --- EventListener/ControllerListener.php | 64 ---------------------------- Resources/config/loaders.xml | 8 +--- 2 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 EventListener/ControllerListener.php diff --git a/EventListener/ControllerListener.php b/EventListener/ControllerListener.php deleted file mode 100644 index 5612372..0000000 --- a/EventListener/ControllerListener.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Bundle\WebServiceBundle\EventListener; - -use Bundle\WebServiceBundle\ServiceDefinition\Annotation\ConfigurationInterface; - -use Doctrine\Common\Annotations\Reader; - -use Symfony\Component\HttpKernel\Event\FilterControllerEvent; - -/** - * Based on \Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener - * - * @author Francis Besset - */ -class ControllerListener -{ - /** - * @var \Doctrine\Common\Annotations\Reader - */ - protected $reader; - - /** - * Constructor. - * - * @param Reader $reader An Reader instance - */ - public function __construct(Reader $reader) - { - $this->reader = $reader; - } - - /** - * Modifies the Request object to apply configuration information found in - * controllers annotations like the template to render or HTTP caching - * configuration. - * - * @param FilterControllerEvent $event A FilterControllerEvent instance - */ - public function onKernelController(FilterControllerEvent $event) - { - if (!is_array($controller = $event->getController())) { - return; - } - - $object = new \ReflectionObject($controller[0]); - $method = $object->getMethod($controller[1]); - - $request = $event->getRequest(); - foreach ($this->reader->getMethodAnnotations($method) as $configuration) { - if ($configuration instanceof ConfigurationInterface) { - $request->attributes->set('_'.$configuration->getAliasName(), $configuration); - } - } - } -} \ No newline at end of file diff --git a/Resources/config/loaders.xml b/Resources/config/loaders.xml index 888d1ad..3665b9d 100644 --- a/Resources/config/loaders.xml +++ b/Resources/config/loaders.xml @@ -5,7 +5,6 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Bundle\WebServiceBundle\EventListener\ControllerListener Symfony\Component\Config\Loader\LoaderResolver Symfony\Component\Config\Loader\DelegatingLoader Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader @@ -14,11 +13,6 @@ - - - - - @@ -37,4 +31,4 @@ - \ No newline at end of file + From 055bb8a96c80534c4f4050d425f8e665ad92b9d8 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 18 Jul 2011 22:43:12 +0200 Subject: [PATCH 061/195] Replaced Bundle\WebServiceBundle by BeSimple\SoapBundle --- ...erviceBundle.php => BeSimpleSoapBundle.php | 12 +++--- Controller/SoapWebServiceController.php | 20 +++++----- Converter/ConverterRepository.php | 4 +- Converter/TypeConverterInterface.php | 8 ++-- Converter/TypeRepository.php | 12 +++--- Converter/XopIncludeTypeConverter.php | 10 ++--- ...xtension.php => BeSimpleSoapExtension.php} | 10 ++--- .../Compiler/WebServiceResolverPass.php | 4 +- DependencyInjection/Configuration.php | 4 +- README.markdown | 38 +++++++++---------- Resources/config/loaders.xml | 6 +-- .../config/routing/webservicecontroller.xml | 4 +- Resources/config/webservice.xml | 18 ++++----- ...mentLiteralWrappedRequestMessageBinder.php | 6 +-- ...entLiteralWrappedResponseMessageBinder.php | 6 +-- ServiceBinding/MessageBinderInterface.php | 6 +-- .../RpcLiteralRequestMessageBinder.php | 6 +-- .../RpcLiteralResponseMessageBinder.php | 6 +-- ServiceBinding/ServiceBinder.php | 18 ++++----- .../Annotation/Configuration.php | 4 +- .../Annotation/ConfigurationInterface.php | 4 +- ServiceDefinition/Annotation/Method.php | 4 +- ServiceDefinition/Annotation/Param.php | 4 +- ServiceDefinition/Annotation/Result.php | 4 +- .../Annotation/TypedElementInterface.php | 4 +- ServiceDefinition/Argument.php | 4 +- ServiceDefinition/Dumper/DumperInterface.php | 6 +-- ServiceDefinition/Dumper/WsdlDumper.php | 14 +++---- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 6 +-- ServiceDefinition/Header.php | 4 +- .../Loader/AnnotationClassLoader.php | 26 ++++++------- .../Loader/AnnotationFileLoader.php | 6 +-- ServiceDefinition/Loader/XmlFileLoader.php | 22 +++++------ .../Loader/schema/servicedefinition-1.0.xsd | 4 +- ServiceDefinition/Method.php | 8 ++-- ServiceDefinition/ServiceDefinition.php | 18 ++++----- ServiceDefinition/Type.php | 4 +- Soap/SoapAttachment.php | 4 +- Soap/SoapHeader.php | 4 +- Soap/SoapRequest.php | 14 +++---- Soap/SoapResponse.php | 10 ++--- Soap/SoapServerFactory.php | 6 +-- Tests/Soap/SoapRequestTest.php | 8 ++-- Tests/bootstrap.php | 2 +- Util/Assert.php | 4 +- Util/Collection.php | 4 +- Util/QName.php | 4 +- Util/String.php | 4 +- WebServiceContext.php | 16 ++++---- vendors.php | 4 +- 50 files changed, 214 insertions(+), 214 deletions(-) rename WebServiceBundle.php => BeSimpleSoapBundle.php (70%) rename DependencyInjection/{WebServiceExtension.php => BeSimpleSoapExtension.php} (93%) diff --git a/WebServiceBundle.php b/BeSimpleSoapBundle.php similarity index 70% rename from WebServiceBundle.php rename to BeSimpleSoapBundle.php index 31c1a88..e6c692d 100644 --- a/WebServiceBundle.php +++ b/BeSimpleSoapBundle.php @@ -1,6 +1,6 @@ * @@ -8,19 +8,19 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle; +namespace BeSimple\SoapBundle; -use Bundle\WebServiceBundle\DependencyInjection\Compiler\WebServiceResolverPass; +use BeSimple\SoapBundle\DependencyInjection\Compiler\WebServiceResolverPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; /** - * WebServiceBundle. + * BeSimpleSoapBundle. * * @author Christian Kerl */ -class WebServiceBundle extends Bundle +class BeSimpleSoapBundle extends Bundle { public function build(ContainerBuilder $container) { @@ -28,4 +28,4 @@ class WebServiceBundle extends Bundle $container->addCompilerPass(new WebServiceResolverPass()); } -} \ No newline at end of file +} diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index be8c747..8449470 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -1,6 +1,6 @@ * @@ -8,10 +8,10 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Controller; +namespace BeSimple\SoapBundle\Controller; -use Bundle\WebServiceBundle\Soap\SoapRequest; -use Bundle\WebServiceBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpFoundation\Response; @@ -29,22 +29,22 @@ class SoapWebServiceController extends ContainerAware protected $soapServer; /** - * @var \Bundle\WebServiceBundle\Soap\SoapRequest + * @var \BeSimple\SoapBundle\Soap\SoapRequest */ protected $soapRequest; /** - * @var \Bundle\WebServiceBundle\Soap\SoapResponse + * @var \BeSimple\SoapBundle\Soap\SoapResponse */ protected $soapResponse; /** - * @var \Bundle\WebServiceBundle\ServiceBinding\ServiceBinder + * @var \BeSimple\SoapBundle\ServiceBinding\ServiceBinder */ protected $serviceBinder; /** - * @return \Bundle\WebServiceBundle\Soap\SoapResponse + * @return \BeSimple\SoapBundle\Soap\SoapResponse */ public function callAction($webservice) { @@ -146,7 +146,7 @@ class SoapWebServiceController extends ContainerAware } /** - * @return \Bundle\WebServiceBundle\Soap\SoapRequest + * @return \BeSimple\SoapBundle\Soap\SoapRequest */ public function getRequest() { @@ -154,7 +154,7 @@ class SoapWebServiceController extends ContainerAware } /** - * @return \Bundle\WebServiceBundle\Soap\SoapResponse + * @return \BeSimple\SoapBundle\Soap\SoapResponse */ public function getResponse() { diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php index 536a654..3a3e1f6 100644 --- a/Converter/ConverterRepository.php +++ b/Converter/ConverterRepository.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Converter; +namespace BeSimple\SoapBundle\Converter; use Symfony\Component\DependencyInjection\ContainerInterface; diff --git a/Converter/TypeConverterInterface.php b/Converter/TypeConverterInterface.php index 4945f8e..ae74ed3 100644 --- a/Converter/TypeConverterInterface.php +++ b/Converter/TypeConverterInterface.php @@ -1,6 +1,6 @@ * @@ -8,10 +8,10 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Converter; +namespace BeSimple\SoapBundle\Converter; -use Bundle\WebServiceBundle\Soap\SoapRequest; -use Bundle\WebServiceBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; /** * @author Christian Kerl diff --git a/Converter/TypeRepository.php b/Converter/TypeRepository.php index 6946547..2167a49 100644 --- a/Converter/TypeRepository.php +++ b/Converter/TypeRepository.php @@ -1,6 +1,6 @@ * @@ -8,12 +8,12 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Converter; +namespace BeSimple\SoapBundle\Converter; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\Util\Assert; -use Bundle\WebServiceBundle\Util\QName; -use Bundle\WebServiceBundle\Util\String; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\Util\Assert; +use BeSimple\SoapBundle\Util\QName; +use BeSimple\SoapBundle\Util\String; /** * @author Christian Kerl diff --git a/Converter/XopIncludeTypeConverter.php b/Converter/XopIncludeTypeConverter.php index 39d6e2f..fc5a9da 100644 --- a/Converter/XopIncludeTypeConverter.php +++ b/Converter/XopIncludeTypeConverter.php @@ -1,6 +1,6 @@ * @@ -8,11 +8,11 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Converter; +namespace BeSimple\SoapBundle\Converter; -use Bundle\WebServiceBundle\Soap\SoapRequest; -use Bundle\WebServiceBundle\Soap\SoapResponse; -use Bundle\WebServiceBundle\Util\String; +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Util\String; /** * @author Christian Kerl diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/BeSimpleSoapExtension.php similarity index 93% rename from DependencyInjection/WebServiceExtension.php rename to DependencyInjection/BeSimpleSoapExtension.php index 68afc93..f03810f 100644 --- a/DependencyInjection/WebServiceExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\DependencyInjection; +namespace BeSimple\SoapBundle\DependencyInjection; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Config\FileLocator; @@ -19,11 +19,11 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** - * WebServiceExtension. + * BeSimpleSoapExtension. * * @author Christian Kerl */ -class WebServiceExtension extends Extension +class BeSimpleSoapExtension extends Extension { private $contextArguments; @@ -76,4 +76,4 @@ class WebServiceExtension extends Extension $definition->replaceArgument($i, $argument); } } -} \ No newline at end of file +} diff --git a/DependencyInjection/Compiler/WebServiceResolverPass.php b/DependencyInjection/Compiler/WebServiceResolverPass.php index 0969848..bde6e76 100644 --- a/DependencyInjection/Compiler/WebServiceResolverPass.php +++ b/DependencyInjection/Compiler/WebServiceResolverPass.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\DependencyInjection\Compiler; +namespace BeSimple\SoapBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index cb280c6..ded0ae1 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\DependencyInjection; +namespace BeSimple\SoapBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; diff --git a/README.markdown b/README.markdown index 6d8f6d8..7bdea20 100644 --- a/README.markdown +++ b/README.markdown @@ -1,7 +1,7 @@ -WebServiceBundle -================ +BeSimpleSoapBundle +================== -The WebServiceBundle is a Symfony2 bundle to build WSDL and SOAP based web services. +The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. It is based on the [ckWebServicePlugin] [1] for symfony. Requirements @@ -13,7 +13,7 @@ Requirements git submodule add http://github.com/zendframework/zf2.git vendor/zend-framework * Add `Zend\Soap` library to `app/autoload.php` - + // app/autoload.php $loader->registerNamespaces(array( 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', @@ -23,40 +23,40 @@ Requirements QuickStart ---------- - * Put WebServiceBundle in your `vendor/bundles/Bundle` dir + * Put BeSimplSoapBundle in your `vendor/bundles/BeSimple` dir - git submodule add https://github.com/BeSimple/BeSimpleSoapBundle.git vendor/bundles/WebServiceBundle + git submodule add https://github.com/BeSimple/BeSimpleSoapBundle.git vendor/bundles/BeSimple/SoapBundle - * Enable WebServiceBundle in your `app/AppKernel.php` + * Enable BeSimpleSoapBundle in your `app/AppKernel.php` // app/AppKernel.php public function registerBundles() { return array( // ... - new new Bundle\WebServiceBundle\WebServiceBundle(), + new new BeSimple\SoapBundle\BeSimpleSoapBundle(), // ... ); } - * Register the Bundle namespace + * Register the BeSimple namespace // app/autoload.php $loader->registerNamespaces(array( - 'Bundle' => __DIR__.'/../vendor/bundles', + 'BeSimple' => __DIR__.'/../vendor/bundles', 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', // your other namespaces )); - * Include the WebServiceBundle's routing configuration in `app/config/routing.yml` (you can choose the prefix arbitrarily) + * Include the BeSimpleSoapBundle's routing configuration in `app/config/routing.yml` (you can choose the prefix arbitrarily) - _ws: - resource: "@WebServiceBundle/Resources/config/routing/webservicecontroller.xml" + _besimple_soap: + resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml" prefix: /ws * Configure your first web service in `app/config/config.yml` - web_service: + be_simple_soap: services: DemoApi: namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ @@ -67,10 +67,10 @@ QuickStart * Annotate your controller methods // src/Acme/DemoBundle/Controller/DemoController.php - use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Method; - use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Param; - use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Result; - use Bundle\WebServiceBundle\Soap\SoapResponse; + use BeSimple\SoapBundle\ServiceDefinition\Annotation\Method; + use BeSimple\SoapBundle\ServiceDefinition\Annotation\Param; + use BeSimple\SoapBundle\ServiceDefinition\Annotation\Result; + use BeSimple\SoapBundle\Soap\SoapResponse; class DemoController extends Controller { @@ -95,4 +95,4 @@ Test phpunit -c phpunit.xml.dist -[1]: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file +[1]: http://www.symfony-project.org/plugins/ckWebServicePlugin diff --git a/Resources/config/loaders.xml b/Resources/config/loaders.xml index 3665b9d..ac6c859 100644 --- a/Resources/config/loaders.xml +++ b/Resources/config/loaders.xml @@ -7,9 +7,9 @@ Symfony\Component\Config\Loader\LoaderResolver Symfony\Component\Config\Loader\DelegatingLoader - Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader - Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationFileLoader - Bundle\WebServiceBundle\ServiceDefinition\Loader\AnnotationClassLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationFileLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationClassLoader diff --git a/Resources/config/routing/webservicecontroller.xml b/Resources/config/routing/webservicecontroller.xml index a3e3df9..98e80e4 100644 --- a/Resources/config/routing/webservicecontroller.xml +++ b/Resources/config/routing/webservicecontroller.xml @@ -5,13 +5,13 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - WebServiceBundle:SoapWebService:Call + BeSimpleSoapBundle:SoapWebService:Call xml POST - WebServiceBundle:SoapWebService:Definition + BeSimpleSoapBundle:SoapWebService:Definition xml GET diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index a2d6950..a242499 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -4,16 +4,16 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Bundle\WebServiceBundle\Controller\SoapWebServiceController - Bundle\WebServiceBundle\WebServiceContext + BeSimple\SoapBundle\Controller\SoapWebServiceController + BeSimple\SoapBundle\WebServiceContext %kernel.cache_dir%/webservice - Bundle\WebServiceBundle\ServiceBinding\RpcLiteralRequestMessageBinder - Bundle\WebServiceBundle\ServiceBinding\RpcLiteralResponseMessageBinder - Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder - Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder - Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlDumper - Bundle\WebServiceBundle\Converter\ConverterRepository - Bundle\WebServiceBundle\Converter\TypeRepository + BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder + BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder + BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder + BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder + BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper + BeSimple\SoapBundle\Converter\ConverterRepository + BeSimple\SoapBundle\Converter\TypeRepository diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index 66b07a7..3245448 100644 --- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Method; class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface { diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php index 5806852..d8d7e78 100644 --- a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Method; class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface { diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php index 6dc9bf5..f355f76 100644 --- a/ServiceBinding/MessageBinderInterface.php +++ b/ServiceBinding/MessageBinderInterface.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Method; interface MessageBinderInterface { diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 2269afc..12c8e78 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Method; class RpcLiteralRequestMessageBinder implements MessageBinderInterface { diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 970d587..e4b4aa2 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Method; class RpcLiteralResponseMessageBinder implements MessageBinderInterface { diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 88c5377..aa329f1 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -1,6 +1,6 @@ * @@ -8,27 +8,27 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceBinding; +namespace BeSimple\SoapBundle\ServiceBinding; -use Bundle\WebServiceBundle\ServiceDefinition\Header; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\Soap\SoapHeader; -use Bundle\WebServiceBundle\Util\QName; +use BeSimple\SoapBundle\ServiceDefinition\Header; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\Soap\SoapHeader; +use BeSimple\SoapBundle\Util\QName; class ServiceBinder { /** - * @var \Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition + * @var \BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition */ private $definition; /** - * @var \Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface + * @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface */ private $requestMessageBinder; /** - * @var \Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface + * @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface */ private $responseMessageBinder; diff --git a/ServiceDefinition/Annotation/Configuration.php b/ServiceDefinition/Annotation/Configuration.php index 2df78b2..f7c4d0a 100644 --- a/ServiceDefinition/Annotation/Configuration.php +++ b/ServiceDefinition/Annotation/Configuration.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * Based on \Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation diff --git a/ServiceDefinition/Annotation/ConfigurationInterface.php b/ServiceDefinition/Annotation/ConfigurationInterface.php index 3c910bf..c25656a 100644 --- a/ServiceDefinition/Annotation/ConfigurationInterface.php +++ b/ServiceDefinition/Annotation/ConfigurationInterface.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * Based on \Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface diff --git a/ServiceDefinition/Annotation/Method.php b/ServiceDefinition/Annotation/Method.php index faf5ae4..a7a2395 100644 --- a/ServiceDefinition/Annotation/Method.php +++ b/ServiceDefinition/Annotation/Method.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * @Annotation diff --git a/ServiceDefinition/Annotation/Param.php b/ServiceDefinition/Annotation/Param.php index 932fef3..330569b 100644 --- a/ServiceDefinition/Annotation/Param.php +++ b/ServiceDefinition/Annotation/Param.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * @Annotation diff --git a/ServiceDefinition/Annotation/Result.php b/ServiceDefinition/Annotation/Result.php index c56a587..0d86f8c 100644 --- a/ServiceDefinition/Annotation/Result.php +++ b/ServiceDefinition/Annotation/Result.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * @Annotation diff --git a/ServiceDefinition/Annotation/TypedElementInterface.php b/ServiceDefinition/Annotation/TypedElementInterface.php index b6c4fe5..94eaeb3 100644 --- a/ServiceDefinition/Annotation/TypedElementInterface.php +++ b/ServiceDefinition/Annotation/TypedElementInterface.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Annotation; +namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; interface TypedElementInterface { diff --git a/ServiceDefinition/Argument.php b/ServiceDefinition/Argument.php index 5a715d2..87da04f 100644 --- a/ServiceDefinition/Argument.php +++ b/ServiceDefinition/Argument.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition; +namespace BeSimple\SoapBundle\ServiceDefinition; class Argument { diff --git a/ServiceDefinition/Dumper/DumperInterface.php b/ServiceDefinition/Dumper/DumperInterface.php index f957435..e1dcb11 100644 --- a/ServiceDefinition/Dumper/DumperInterface.php +++ b/ServiceDefinition/Dumper/DumperInterface.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; +namespace BeSimple\SoapBundle\ServiceDefinition\Dumper; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; interface DumperInterface { diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 37e9c40..09548b5 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -1,6 +1,6 @@ * @@ -8,13 +8,13 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; +namespace BeSimple\SoapBundle\ServiceDefinition\Dumper; -use Bundle\WebServiceBundle\ServiceDefinition\Method; -use Bundle\WebServiceBundle\ServiceDefinition\Type; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\Util\Assert; -use Bundle\WebServiceBundle\Util\QName; +use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Type; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\Util\Assert; +use BeSimple\SoapBundle\Util\QName; use Zend\Soap\Wsdl; diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 98005e6..8ca9acb 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Dumper; +namespace BeSimple\SoapBundle\ServiceDefinition\Dumper; -use Bundle\WebServiceBundle\Util\String; +use BeSimple\SoapBundle\Util\String; use Zend\Soap\Exception; use Zend\Soap\Wsdl; diff --git a/ServiceDefinition/Header.php b/ServiceDefinition/Header.php index ef450a2..53cc4cf 100644 --- a/ServiceDefinition/Header.php +++ b/ServiceDefinition/Header.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition; +namespace BeSimple\SoapBundle\ServiceDefinition; class Header { diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index fc0517d..2faccbc 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -1,6 +1,6 @@ * @@ -8,15 +8,15 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; +namespace BeSimple\SoapBundle\ServiceDefinition\Loader; -use Bundle\WebServiceBundle\ServiceDefinition\Argument; -use Bundle\WebServiceBundle\ServiceDefinition\Method; -use Bundle\WebServiceBundle\ServiceDefinition\Type; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; -use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Method as MethodAnnotation; -use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Param as ParamAnnotation; -use Bundle\WebServiceBundle\ServiceDefinition\Annotation\Result as ResultAnnotation; +use BeSimple\SoapBundle\ServiceDefinition\Argument; +use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Type; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\ServiceDefinition\Annotation\Method as MethodAnnotation; +use BeSimple\SoapBundle\ServiceDefinition\Annotation\Param as ParamAnnotation; +use BeSimple\SoapBundle\ServiceDefinition\Annotation\Result as ResultAnnotation; use Doctrine\Common\Annotations\Reader; @@ -32,9 +32,9 @@ use Symfony\Component\Config\Loader\LoaderResolver; */ class AnnotationClassLoader implements LoaderInterface { - private $methodAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Method'; - private $paramAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Param'; - private $resultAnnotationClass = 'Bundle\\WebServiceBundle\\ServiceDefinition\\Annotation\\Result'; + private $methodAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Method'; + private $paramAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Param'; + private $resultAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Result'; protected $reader; @@ -127,7 +127,7 @@ class AnnotationClassLoader implements LoaderInterface * @param \ReflectionMethod $method * @param ParamAnnotation $annotation * - * @return \Bundle\WebServiceBundle\ServiceDefinition\Type + * @return \BeSimple\SoapBundle\ServiceDefinition\Type */ private function getArgumentType(\ReflectionMethod $method, ParamAnnotation $annotation) { diff --git a/ServiceDefinition/Loader/AnnotationFileLoader.php b/ServiceDefinition/Loader/AnnotationFileLoader.php index 688e406..606a45e 100644 --- a/ServiceDefinition/Loader/AnnotationFileLoader.php +++ b/ServiceDefinition/Loader/AnnotationFileLoader.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; +namespace BeSimple\SoapBundle\ServiceDefinition\Loader; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\FileLoader; diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php index 944980c..fee469b 100644 --- a/ServiceDefinition/Loader/XmlFileLoader.php +++ b/ServiceDefinition/Loader/XmlFileLoader.php @@ -1,6 +1,6 @@ * @@ -8,13 +8,13 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition\Loader; +namespace BeSimple\SoapBundle\ServiceDefinition\Loader; -use Bundle\WebServiceBundle\ServiceDefinition\Argument; -use Bundle\WebServiceBundle\ServiceDefinition\Header; -use Bundle\WebServiceBundle\ServiceDefinition\Method; -use Bundle\WebServiceBundle\ServiceDefinition\Type; -use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition; +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; @@ -48,7 +48,7 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\Header + * @return \BeSimple\SoapBundle\ServiceDefinition\Header */ protected function parseHeader(\SimpleXMLElement $node) { @@ -58,7 +58,7 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\Method + * @return \BeSimple\SoapBundle\ServiceDefinition\Method */ protected function parseMethod(\SimpleXMLElement $node) { @@ -76,7 +76,7 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\Argument + * @return \BeSimple\SoapBundle\ServiceDefinition\Argument */ protected function parseArgument(\SimpleXMLElement $node) { @@ -88,7 +88,7 @@ class XmlFileLoader extends FileLoader /** * @param \SimpleXMLElement $node * - * @return \Bundle\WebServiceBundle\ServiceDefinition\Type + * @return \BeSimple\SoapBundle\ServiceDefinition\Type */ protected function parseType(\SimpleXMLElement $node) { diff --git a/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd index 4ef903a..2867eab 100644 --- a/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd +++ b/ServiceDefinition/Loader/schema/servicedefinition-1.0.xsd @@ -1,5 +1,5 @@ - + @@ -78,4 +78,4 @@ - \ No newline at end of file + diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php index 48bf99b..14e1efa 100644 --- a/ServiceDefinition/Method.php +++ b/ServiceDefinition/Method.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition; +namespace BeSimple\SoapBundle\ServiceDefinition; -use Bundle\WebServiceBundle\Util\Collection; +use BeSimple\SoapBundle\Util\Collection; class Method { @@ -57,7 +57,7 @@ class Method public function setArguments(array $arguments) { - $this->arguments = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Argument'); + $this->arguments = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Argument'); $this->arguments->addAll($arguments); } diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index 8a24bc0..d11e285 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition; +namespace BeSimple\SoapBundle\ServiceDefinition; -use Bundle\WebServiceBundle\Util\Collection; +use BeSimple\SoapBundle\Util\Collection; class ServiceDefinition { @@ -25,12 +25,12 @@ class ServiceDefinition private $namespace; /** - * @var \Bundle\WebServiceBundle\Util\Collection + * @var \BeSimple\SoapBundle\Util\Collection */ private $methods; /** - * @var \Bundle\WebServiceBundle\Util\Collection + * @var \BeSimple\SoapBundle\Util\Collection */ private $headers; @@ -39,8 +39,8 @@ class ServiceDefinition $this->setName($name); $this->setNamespace($namespace); - $this->methods = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Method'); - $this->headers = new Collection('getName', 'Bundle\WebServiceBundle\ServiceDefinition\Header'); + $this->methods = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Method'); + $this->headers = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Header'); $this->setMethods($methods); $this->setHeaders($headers); @@ -79,7 +79,7 @@ class ServiceDefinition } /** - * @return \Bundle\WebServiceBundle\Util\Collection + * @return \BeSimple\SoapBundle\Util\Collection */ public function getMethods() { @@ -95,7 +95,7 @@ class ServiceDefinition } /** - * @return \Bundle\WebServiceBundle\Util\Collection + * @return \BeSimple\SoapBundle\Util\Collection */ public function getHeaders() { diff --git a/ServiceDefinition/Type.php b/ServiceDefinition/Type.php index 176f748..dbf69e5 100644 --- a/ServiceDefinition/Type.php +++ b/ServiceDefinition/Type.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\ServiceDefinition; +namespace BeSimple\SoapBundle\ServiceDefinition; class Type { diff --git a/Soap/SoapAttachment.php b/Soap/SoapAttachment.php index d5592ce..15e8a1e 100644 --- a/Soap/SoapAttachment.php +++ b/Soap/SoapAttachment.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Soap; +namespace BeSimple\SoapBundle\Soap; class SoapAttachment { diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php index a66439a..e24d58c 100644 --- a/Soap/SoapHeader.php +++ b/Soap/SoapHeader.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Soap; +namespace BeSimple\SoapBundle\Soap; class SoapHeader { diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index dc31d9a..6cc0f97 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Soap; +namespace BeSimple\SoapBundle\Soap; -use Bundle\WebServiceBundle\Util\Collection; +use BeSimple\SoapBundle\Util\Collection; use Symfony\Component\HttpFoundation\Request; @@ -40,12 +40,12 @@ class SoapRequest extends Request protected $soapAction; /** - * @var \Bundle\WebServiceBundle\Util\Collection + * @var \BeSimple\SoapBundle\Util\Collection */ protected $soapHeaders; /** - * @var \Bundle\WebServiceBundle\Util\Collection + * @var \BeSimple\SoapBundle\Util\Collection */ protected $soapAttachments; @@ -54,8 +54,8 @@ class SoapRequest extends Request parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content); $this->soapMessage = null; - $this->soapHeaders = new Collection('getName', 'Bundle\WebServiceBundle\Soap\SoapHeader'); - $this->soapAttachments = new Collection('getId', 'Bundle\WebServiceBundle\Soap\SoapAttachment'); + $this->soapHeaders = new Collection('getName', 'BeSimple\SoapBundle\Soap\SoapHeader'); + $this->soapAttachments = new Collection('getId', 'BeSimple\SoapBundle\Soap\SoapAttachment'); $this->setRequestFormat('soap'); } diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 1f666ac..cb9c9a3 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Soap; +namespace BeSimple\SoapBundle\Soap; -use Bundle\WebServiceBundle\Util\Collection; +use BeSimple\SoapBundle\Util\Collection; use Symfony\Component\HttpFoundation\Response; @@ -22,7 +22,7 @@ use Symfony\Component\HttpFoundation\Response; class SoapResponse extends Response { /** - * @var \Bundle\WebServiceBundle\Util\Collection + * @var \BeSimple\SoapBundle\Util\Collection */ protected $soapHeaders; @@ -35,7 +35,7 @@ class SoapResponse extends Response { parent::__construct(); - $this->soapHeaders = new Collection('getName', 'Bundle\WebServiceBundle\Soap\SoapHeader'); + $this->soapHeaders = new Collection('getName', 'BeSimple\SoapBundle\Soap\SoapHeader'); $this->setReturnValue($returnValue); } diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 9ffa0c6..1c83499 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -1,6 +1,6 @@ * @@ -8,9 +8,9 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Soap; +namespace BeSimple\SoapBundle\Soap; -use Bundle\WebServiceBundle\Converter\ConverterRepository; +use BeSimple\SoapBundle\Converter\ConverterRepository; /** * @author Christian Kerl diff --git a/Tests/Soap/SoapRequestTest.php b/Tests/Soap/SoapRequestTest.php index 81df88b..53375a2 100644 --- a/Tests/Soap/SoapRequestTest.php +++ b/Tests/Soap/SoapRequestTest.php @@ -1,6 +1,6 @@ * @@ -8,12 +8,12 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Tests\Soap; +namespace BeSimple\SoapBundle\Tests\Soap; -use Bundle\WebServiceBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapRequest; /** - * UnitTest for \Bundle\WebServiceBundle\Soap\SoapRequest. + * UnitTest for \BeSimple\SoapBundle\Soap\SoapRequest. * * @author Christian Kerl */ diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 798095e..8fa8a1e 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -11,7 +11,7 @@ $loader->register(); spl_autoload_register(function($class) { //if (0 === strpos($class, 'BeSimple\\SoapBundle\\')) { - if (0 === strpos($class, 'Bundle\\WebServiceBundle\\')) { + if (0 === strpos($class, 'BeSimple\\SoapBundle\\')) { $path = __DIR__.'/../'.implode('/', array_slice(explode('\\', $class), 2)).'.php'; if (file_exists($path)) { diff --git a/Util/Assert.php b/Util/Assert.php index a80985a..d428a27 100644 --- a/Util/Assert.php +++ b/Util/Assert.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Util; +namespace BeSimple\SoapBundle\Util; /** * diff --git a/Util/Collection.php b/Util/Collection.php index 97bbfee..e13703f 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Util; +namespace BeSimple\SoapBundle\Util; class Collection implements \IteratorAggregate, \Countable { diff --git a/Util/QName.php b/Util/QName.php index 874f52d..c71a686 100644 --- a/Util/QName.php +++ b/Util/QName.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Util; +namespace BeSimple\SoapBundle\Util; /** * @author Christian Kerl diff --git a/Util/String.php b/Util/String.php index d88192b..b95d53e 100644 --- a/Util/String.php +++ b/Util/String.php @@ -1,6 +1,6 @@ * @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle\Util; +namespace BeSimple\SoapBundle\Util; /** * String provides utility methods for strings. diff --git a/WebServiceContext.php b/WebServiceContext.php index 90c3879..0a429ee 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -1,6 +1,6 @@ * @@ -8,14 +8,14 @@ * with this source code in the file LICENSE. */ -namespace Bundle\WebServiceBundle; +namespace BeSimple\SoapBundle; -use Bundle\WebServiceBundle\Converter\ConverterRepository; -use Bundle\WebServiceBundle\Converter\TypeRepository; -use Bundle\WebServiceBundle\ServiceBinding\MessageBinderInterface; -use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder; -use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface; -use Bundle\WebServiceBundle\Soap\SoapServerFactory; +use BeSimple\SoapBundle\Converter\ConverterRepository; +use BeSimple\SoapBundle\Converter\TypeRepository; +use BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface; +use BeSimple\SoapBundle\ServiceBinding\ServiceBinder; +use BeSimple\SoapBundle\ServiceDefinition\Dumper\DumperInterface; +use BeSimple\SoapBundle\Soap\SoapServerFactory; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Loader\LoaderInterface; diff --git a/vendors.php b/vendors.php index 1841c89..3c473b8 100755 --- a/vendors.php +++ b/vendors.php @@ -1,7 +1,7 @@ #!/usr/bin/env php * @@ -11,7 +11,7 @@ /* -CAUTION: This file installs the dependencies needed to run the WebServiceBundle test suite. +CAUTION: This file installs the dependencies needed to run the BeSimpleSoapBundle test suite. https://github.com/BeSimple/BeSimpleSoapBundle From c13a96131baf27693c5d37267238a01577daa099 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 18 Jul 2011 22:59:20 +0200 Subject: [PATCH 062/195] Replaced webservice.* service name by besimple.soap.* --- .gitignore | 1 + Controller/SoapWebServiceController.php | 4 +- DependencyInjection/BeSimpleSoapExtension.php | 8 +-- .../Compiler/WebServiceResolverPass.php | 8 +-- Resources/config/loaders.xml | 26 +++++----- Resources/config/webservice.xml | 49 +++++++++---------- 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 09fafaa..e4cd1e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ phpunit.xml vendor +*.swp diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 8449470..90eede1 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -163,10 +163,10 @@ class SoapWebServiceController extends ContainerAware private function getWebServiceContext($webservice) { - if(!$this->container->has('webservice.context.'.$webservice)) + if(!$this->container->has('besimple.soap.context.'.$webservice)) { throw new NotFoundHttpException(sprintf('No webservice with name "%s" found.', $webservice)); } - return $this->container->get('webservice.context.'.$webservice); + return $this->container->get('besimple.soap.context.'.$webservice); } } diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index f03810f..5f132e4 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -27,7 +27,7 @@ class BeSimpleSoapExtension extends Extension { private $contextArguments; - // maps config options to service suffix' + // maps config options to service suffix private $bindingConfigToServiceSuffixMap = array('rpc-literal' => '.rpcliteral', 'document-wrapped' => '.documentwrapped'); public function load(array $configs, ContainerBuilder $container) @@ -55,13 +55,13 @@ class BeSimpleSoapExtension extends Extension if (null === $this->contextArguments) { $this->contextArguments = $container - ->getDefinition('webservice.context') + ->getDefinition('besimple.soap.context') ->getArguments() ; } - $contextId = 'webservice.context.'.$config['name']; - $context = $container->setDefinition($contextId, $definition = new DefinitionDecorator('webservice.context')); + $contextId = 'besimple.soap.context.'.$config['name']; + $context = $container->setDefinition($contextId, $definition = new DefinitionDecorator('besimple.soap.context')); $arguments = array(); foreach($this->contextArguments as $i => $argument) { diff --git a/DependencyInjection/Compiler/WebServiceResolverPass.php b/DependencyInjection/Compiler/WebServiceResolverPass.php index bde6e76..06bd755 100644 --- a/DependencyInjection/Compiler/WebServiceResolverPass.php +++ b/DependencyInjection/Compiler/WebServiceResolverPass.php @@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; /** - * Adds tagged webservice.definition.loader services to ebservice.definition.resolver service + * Adds tagged besimple.soap.definition.loader services to ebservice.definition.resolver service * * @author Francis Besset */ @@ -23,13 +23,13 @@ class WebServiceResolverPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (false === $container->hasDefinition('webservice.definition.loader.resolver')) { + if (false === $container->hasDefinition('besimple.soap.definition.loader.resolver')) { return; } - $definition = $container->getDefinition('webservice.definition.loader.resolver'); + $definition = $container->getDefinition('besimple.soap.definition.loader.resolver'); - foreach ($container->findTaggedServiceIds('webservice.definition.loader') as $id => $attributes) { + foreach ($container->findTaggedServiceIds('besimple.soap.definition.loader') as $id => $attributes) { $definition->addMethodCall('addLoader', array(new Reference($id))); } } diff --git a/Resources/config/loaders.xml b/Resources/config/loaders.xml index ac6c859..51c4e10 100644 --- a/Resources/config/loaders.xml +++ b/Resources/config/loaders.xml @@ -5,28 +5,28 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Component\Config\Loader\LoaderResolver - Symfony\Component\Config\Loader\DelegatingLoader - BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader - BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationFileLoader - BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationClassLoader + Symfony\Component\Config\Loader\LoaderResolver + Symfony\Component\Config\Loader\DelegatingLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationFileLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationClassLoader - + - - + + - - + + - + - - + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index a242499..514c2b4 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -4,45 +4,44 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - BeSimple\SoapBundle\Controller\SoapWebServiceController - BeSimple\SoapBundle\WebServiceContext - %kernel.cache_dir%/webservice - BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder - BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder - BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder - BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder - BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper - BeSimple\SoapBundle\Converter\ConverterRepository - BeSimple\SoapBundle\Converter\TypeRepository + BeSimple\SoapBundle\WebServiceContext + %kernel.cache_dir%/webservice + BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder + BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder + BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder + BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder + BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper + BeSimple\SoapBundle\Converter\ConverterRepository + BeSimple\SoapBundle\Converter\TypeRepository - - - - - - - + + + + + + + - %webservice.cache_dir% + %besimple.soap.cache_dir% %kernel.debug% - + - + - + - + - + - + - + xsd http://www.w3.org/2001/XMLSchema From 3c5ef798c19a39d6e0736f84bb2371b105d78a16 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 18 Jul 2011 23:31:03 +0200 Subject: [PATCH 063/195] Fixed typo in README --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 7bdea20..8883cbd 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Requirements QuickStart ---------- - * Put BeSimplSoapBundle in your `vendor/bundles/BeSimple` dir + * Put BeSimpleSoapBundle in your `vendor/bundles/BeSimple` dir git submodule add https://github.com/BeSimple/BeSimpleSoapBundle.git vendor/bundles/BeSimple/SoapBundle From 695b7fb663a6008a9ca09c0ca63ba6a01acee13a Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Jul 2011 20:53:49 +0200 Subject: [PATCH 064/195] Simplified exposure functions in README --- README.markdown | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 8883cbd..e8434f7 100644 --- a/README.markdown +++ b/README.markdown @@ -67,17 +67,15 @@ QuickStart * Annotate your controller methods // src/Acme/DemoBundle/Controller/DemoController.php - use BeSimple\SoapBundle\ServiceDefinition\Annotation\Method; - use BeSimple\SoapBundle\ServiceDefinition\Annotation\Param; - use BeSimple\SoapBundle\ServiceDefinition\Annotation\Result; + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapBundle\Soap\SoapResponse; class DemoController extends Controller { /** - * @Method("Hello") - * @Param("name", phpType = "string") - * @Result(phpType = "string") + * @Soap\Method("Hello") + * @Soap\Param("name", phpType = "string") + * @Soap\Result(phpType = "string") */ public function helloAction($name) { From c33005fed2f08fbc142ce7a6247628a15a62a2e5 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Jul 2011 21:03:39 +0200 Subject: [PATCH 065/195] Fixed ServiceDefinition argument and type --- ServiceDefinition/Argument.php | 2 +- ServiceDefinition/Type.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ServiceDefinition/Argument.php b/ServiceDefinition/Argument.php index 87da04f..b1f8849 100644 --- a/ServiceDefinition/Argument.php +++ b/ServiceDefinition/Argument.php @@ -36,7 +36,7 @@ class Argument return $this->type; } - public function setType($type) + public function setType(Type $type) { $this->type = $type; } diff --git a/ServiceDefinition/Type.php b/ServiceDefinition/Type.php index dbf69e5..bf2c1d1 100644 --- a/ServiceDefinition/Type.php +++ b/ServiceDefinition/Type.php @@ -28,9 +28,9 @@ class Type return $this->phpType; } - public function setPhpType($value) + public function setPhpType($phpType) { - $this->phpType = $value; + $this->phpType = $phpType; } public function getXmlType() @@ -38,9 +38,9 @@ class Type return $this->xmlType; } - public function setXmlType($value) + public function setXmlType($xmlType) { - $this->xmlType = $value; + $this->xmlType = $xmlType; } public function getConverter() @@ -48,8 +48,8 @@ class Type return $this->converter; } - public function setConverter($value) + public function setConverter($converter) { - $this->converter = $value; + $this->converter = $converter; } } \ No newline at end of file From 9bd96773257ee06c06551ca5f490f1778a4ee9f1 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Jul 2011 22:55:59 +0200 Subject: [PATCH 066/195] Simplified the creation of WebServiceContext --- DependencyInjection/BeSimpleSoapExtension.php | 34 ++++++------------- Resources/config/webservice.xml | 27 +++++++++++---- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 5f132e4..e6a271f 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -25,10 +25,11 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; */ class BeSimpleSoapExtension extends Extension { - private $contextArguments; - // maps config options to service suffix - private $bindingConfigToServiceSuffixMap = array('rpc-literal' => '.rpcliteral', 'document-wrapped' => '.documentwrapped'); + private $bindingConfigToServiceSuffixMap = array( + 'rpc-literal' => 'rpcliteral', + 'document-wrapped' => 'documentwrapped' + ); public function load(array $configs, ContainerBuilder $container) { @@ -53,27 +54,14 @@ class BeSimpleSoapExtension extends Extension $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; unset($config['binding']); - if (null === $this->contextArguments) { - $this->contextArguments = $container - ->getDefinition('besimple.soap.context') - ->getArguments() - ; - } + $contextId = 'besimple.soap.context.'.$config['name']; + $definition = new DefinitionDecorator('besimple.soap.context.'.$bindingSuffix); + $context = $container->setDefinition($contextId, $definition); - $contextId = 'besimple.soap.context.'.$config['name']; - $context = $container->setDefinition($contextId, $definition = new DefinitionDecorator('besimple.soap.context')); + $options = $container + ->getDefinition('besimple.soap.context.'.$bindingSuffix) + ->getArgument(6); - $arguments = array(); - foreach($this->contextArguments as $i => $argument) { - if (in_array($i, array(1, 2, 3))) { - $argument = new Reference($argument->__toString().$bindingSuffix); - } elseif (6 === $i) { - $argument = array_merge($argument, $config); - } else { - $argument = new Reference($argument->__toString()); - } - - $definition->replaceArgument($i, $argument); - } + $definition->replaceArgument(6, array_merge($options, $config)); } } diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 514c2b4..5dc9f8f 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -16,13 +16,26 @@ - - - - - - - + + + + + + + + + %besimple.soap.cache_dir% + %kernel.debug% + + + + + + + + + + %besimple.soap.cache_dir% %kernel.debug% From 4fa893042f4ac0b81e0b0be73f9619b6ef0c0461 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 23 Jul 2011 20:06:42 +0200 Subject: [PATCH 067/195] New definition of complex type The exposure of complex type properties was done only with public property. Now you can expose properties and public methods. Before: In a complex type: /** * @var string */ public $var; After: In a complex type: use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; /** * @Soap\PropertyComplexType("string", name="var", nillable="true") */ public $username; private $email; /** * @Soap\MethodComplexType("string", name="email", nillable="true", setter="setEmail") */ public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } name, nillable are optionnal. setter is optional and only available for MethodComplexType. --- Controller/SoapWebServiceController.php | 1 + Resources/config/loaders.xml | 5 + Resources/config/webservice.xml | 4 +- ServiceBinding/MessageBinderInterface.php | 2 +- .../RpcLiteralRequestMessageBinder.php | 62 +++++++++++- .../RpcLiteralResponseMessageBinder.php | 55 ++++++++++- ServiceBinding/ServiceBinder.php | 4 +- .../Annotation/MethodComplexType.php | 67 +++++++++++++ .../Annotation/PropertyComplexType.php | 56 +++++++++++ ServiceDefinition/Dumper/WsdlDumper.php | 9 +- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 40 ++++++-- .../Loader/AnnotationClassLoader.php | 4 - .../Loader/AnnotationComplexTypeLoader.php | 94 +++++++++++++++++++ ServiceDefinition/ServiceDefinition.php | 12 +++ .../Strategy/BaseComplexType.php | 62 ++++++++++++ ServiceDefinition/Strategy/ComplexType.php | 81 ++++++++++++++++ .../Strategy/MethodComplexType.php | 29 ++++++ .../Strategy/PropertyComplexType.php | 18 ++++ WebServiceContext.php | 10 +- 19 files changed, 592 insertions(+), 23 deletions(-) create mode 100644 ServiceDefinition/Annotation/MethodComplexType.php create mode 100644 ServiceDefinition/Annotation/PropertyComplexType.php create mode 100644 ServiceDefinition/Loader/AnnotationComplexTypeLoader.php create mode 100644 ServiceDefinition/Strategy/BaseComplexType.php create mode 100644 ServiceDefinition/Strategy/ComplexType.php create mode 100644 ServiceDefinition/Strategy/MethodComplexType.php create mode 100644 ServiceDefinition/Strategy/PropertyComplexType.php diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 90eede1..1816377 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -53,6 +53,7 @@ class SoapWebServiceController extends ContainerAware $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); + $this->soapServer->setObject($this); ob_start(); diff --git a/Resources/config/loaders.xml b/Resources/config/loaders.xml index 51c4e10..4347f94 100644 --- a/Resources/config/loaders.xml +++ b/Resources/config/loaders.xml @@ -10,6 +10,7 @@ BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationDirectoryLoader BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationFileLoader BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationClassLoader + BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader @@ -29,6 +30,10 @@ + + + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 5dc9f8f..3fb9b7e 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -50,7 +50,9 @@ - + + + diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php index f355f76..542112b 100644 --- a/ServiceBinding/MessageBinderInterface.php +++ b/ServiceBinding/MessageBinderInterface.php @@ -20,5 +20,5 @@ interface MessageBinderInterface * * @return mixed */ - function processMessage(Method $messageDefinition, $message); + function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()); } \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 12c8e78..c349b73 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -11,16 +11,42 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; class RpcLiteralRequestMessageBinder implements MessageBinderInterface { - public function processMessage(Method $messageDefinition, $message) + public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) { $result = array(); $i = 0; foreach($messageDefinition->getArguments() as $argument) { if (isset($message[$i])) { + if (preg_match('/^([^\[]+)\[\]$/', $argument->getType()->getPhpType(), $match)) { + $isArray = true; + $type = $match[1]; + } else { + $isArray = false; + $type = $argument->getType()->getPhpType(); + } + + if (isset($definitionComplexTypes[$type])) { + if ($isArray) { + $array = array(); + + foreach ($message[$i]->item as $complexType) { + $array[] = $this->getInstanceOfType($type, $complexType, $definitionComplexTypes); + } + + $message[$i] = $array; + } else { + $message[$i] = $this->getInstanceOfType($type, $message[$i], $definitionComplexTypes); + } + } elseif ($isArray) { + $message[$i] = $message[$i]->item; + } + $result[$argument->getName()] = $message[$i]; } @@ -29,4 +55,38 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface return $result; } + + private function getInstanceOfType($type, $message, array $definitionComplexTypes) + { + $typeClass = $type; + $instanceType = new $typeClass(); + + foreach ($definitionComplexTypes[$type] as $type) { + if ($type instanceof PropertyComplexType) { + if (isset($definitionComplexTypes[$type->getValue()])) { + $value = $this->getInstanceOfType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); + } else { + $value = $message->{$type->getName()}; + } + + $instanceType->{$type->getOriginalName()} = $value; + } elseif ($type instanceof MethodComplexType) { + if (!$type->getSetter()) { + throw new \LogicException(); + } + + if (isset($definitionComplexTypes[$type->getValue()])) { + $value = $this->getInstanceOfType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); + } else { + $value = $message->{$type->getName()}; + } + + $instanceType->{$type->getSetter()}($value); + } else { + throw new \InvalidArgumentException(); + } + } + + return $instanceType; + } } \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index e4b4aa2..29b7d0e 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -11,11 +11,64 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; class RpcLiteralResponseMessageBinder implements MessageBinderInterface { - public function processMessage(Method $messageDefinition, $message) + public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) { + $return = $messageDefinition->getReturn(); + $class = $return->getPhpType(); + + if (preg_match('/^([^\[]+)\[\]$/', $class, $match)) { + $isArray = true; + $type = + $class = $match[1]; + } else { + $isArray = false; + $type = $return->getPhpType(); + } + + if (isset($definitionComplexTypes[$type])) { + if ($class[0] == '\\') { + $class = substr($class, 1); + } + + if ($isArray) { + $array = array(); + + foreach ($message as $complexType) { + $array[] = $this->getInstanceOfStdClass($type, $class, $complexType, $definitionComplexTypes); + } + + $message = $array; + } else { + $message = $this->getInstanceOfStdClass($type, $class, $message, $definitionComplexTypes); + } + } + return $message; } + + private function getInstanceOfStdClass($type, $class, $message, $definitionComplexTypes) + { + if (get_class($message) !== $class) { + throw new \InvalidArgumentException(); + } + + $stdClass = new \stdClass(); + + foreach ($definitionComplexTypes[$type] as $type) { + if ($type instanceof PropertyComplexType) { + $stdClass->{$type->getName()} = $message->{$type->getOriginalName()}; + } elseif ($type instanceof MethodComplexType) { + $stdClass->{$type->getName()} = $message->{$type->getOriginalName()}(); + } else { + throw new \InvalidArgumentException(); + } + } + + return $stdClass; + } } \ No newline at end of file diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index aa329f1..d6d46bc 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -61,7 +61,7 @@ class ServiceBinder $result = array(); $result['_controller'] = $methodDefinition->getController(); - $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments)); + $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getDefinitionComplexTypes())); return $result; } @@ -70,7 +70,7 @@ class ServiceBinder { $methodDefinition = $this->definition->getMethods()->get($name); - return $this->responseMessageBinder->processMessage($methodDefinition, $return); + return $this->responseMessageBinder->processMessage($methodDefinition, $return, $this->definition->getDefinitionComplexTypes()); } protected function createSoapHeader(Header $headerDefinition, $data) diff --git a/ServiceDefinition/Annotation/MethodComplexType.php b/ServiceDefinition/Annotation/MethodComplexType.php new file mode 100644 index 0000000..cf1cdaf --- /dev/null +++ b/ServiceDefinition/Annotation/MethodComplexType.php @@ -0,0 +1,67 @@ + + * + * 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 MethodComplexType extends Configuration +{ + private $name; + private $value; + private $setter; + private $isNillable = false; + + public function getName() + { + return $this->name; + } + + public function getValue() + { + return $this->value; + } + + public function getSetter() + { + return $this->setter; + } + + public function isNillable() + { + return $this->isNillable; + } + + public function setName($name) + { + $this->name = $name; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function setSetter($setter) + { + $this->setter = $setter; + } + + public function setNillable($isNillable) + { + $this->isNillable = (bool) $isNillable; + } + + public function getAliasName() + { + return 'methodcomplextype'; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Annotation/PropertyComplexType.php b/ServiceDefinition/Annotation/PropertyComplexType.php new file mode 100644 index 0000000..6f1f046 --- /dev/null +++ b/ServiceDefinition/Annotation/PropertyComplexType.php @@ -0,0 +1,56 @@ + + * + * 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 PropertyComplexType extends Configuration +{ + private $name; + private $value; + private $isNillable = false; + + public function getName() + { + return $this->name; + } + + public function getValue() + { + return $this->value; + } + + public function isNillable() + { + return $this->isNillable; + } + + public function setName($name) + { + $this->name = $name; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function setNillable($isNillable) + { + $this->isNillable = (bool) $isNillable; + } + + public function getAliasName() + { + return 'propertycomplextype'; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 09548b5..7c07064 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -13,6 +13,7 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Dumper; 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; @@ -23,9 +24,15 @@ use Zend\Soap\Wsdl; */ class WsdlDumper implements DumperInterface { + private $loader; private $wsdl; private $definition; + public function __construct(AnnotationComplexTypeLoader $loader) + { + $this->loader = $loader; + } + public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) { Assert::thatArgumentNotNull('definition', $definition); @@ -33,7 +40,7 @@ class WsdlDumper implements DumperInterface $options = array_merge(array('endpoint' => '', 'stylesheet' => null), $options); $this->definition = $definition; - $this->wsdl = new Wsdl($definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy()); + $this->wsdl = new Wsdl($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())); diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 8ca9acb..77aa131 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -10,13 +10,15 @@ 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; use Zend\Soap\Wsdl\Strategy; use Zend\Soap\Wsdl\Strategy\ArrayOfTypeSequence; -use Zend\Soap\Wsdl\Strategy\DefaultComplexType; class WsdlTypeStrategy implements Strategy { @@ -27,13 +29,16 @@ class WsdlTypeStrategy implements Strategy */ private $context; + private $loader; + private $definition; + private $typeStrategy; private $arrayStrategy; - public function __construct() + public function __construct(AnnotationComplexTypeLoader $loader, ServiceDefinition $definition) { - $this->typeStrategy = new DefaultComplexType(); - $this->arrayStrategy = new ArrayOfTypeSequence(); + $this->loader = $loader; + $this->definition = $definition; } /** @@ -51,9 +56,11 @@ class WsdlTypeStrategy implements Strategy /** * Create a complex type based on a strategy * - * @throws \Zend\Soap\WsdlException * @param string $type + * * @return string XSD type + * + * @throws \Zend\Soap\WsdlException */ public function addComplexType($type) { @@ -61,9 +68,28 @@ class WsdlTypeStrategy implements Strategy throw new \LogicException(sprintf('Cannot add complex type "%s", no context is set for this composite strategy.', $type)); } - $strategy = String::endsWith($type, '[]') ? $this->arrayStrategy : $this->typeStrategy; - $strategy->setContext($this->context); + $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/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index 2faccbc..b71732f 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -32,10 +32,6 @@ use Symfony\Component\Config\Loader\LoaderResolver; */ class AnnotationClassLoader implements LoaderInterface { - private $methodAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Method'; - private $paramAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Param'; - private $resultAnnotationClass = 'BeSimple\\SoapBundle\\ServiceDefinition\\Annotation\\Result'; - protected $reader; /** diff --git a/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php b/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php new file mode 100644 index 0000000..21c9085 --- /dev/null +++ b/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php @@ -0,0 +1,94 @@ + + * + * 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\Annotation\ComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +use BeSimple\SoapBundle\Util\Collection; + +/** + * AnnotationComplexTypeLoader loads ServiceDefinition from a PHP class and its methods. + * + * Based on \Symfony\Component\Routing\Loader\AnnotationClassLoader + * + * @author Francis Besset + */ +class AnnotationComplexTypeLoader extends AnnotationClassLoader +{ + private $propertyComplexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\PropertyComplexType'; + private $methodComplexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\MethodComplexType'; + + /** + * Loads a ServiceDefinition from annotations from a class. + * + * @param string $class A class name + * @param string $type The resource type + * + * @return ServiceDefinition A ServiceDefinition instance + * + * @throws \InvalidArgumentException When route can't be parsed + */ + public function load($class, $type = null) + { + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + $class = new \ReflectionClass($class); + $collection = new Collection('getName'); + + foreach ($class->getProperties() as $property) { + if ($property->isPublic()) { + $complexType = $this->reader->getPropertyAnnotation($property, $this->propertyComplexTypeClass); + + if ($complexType) { + $propertyComplexType = new PropertyComplexType(); + $propertyComplexType->setValue($complexType->getValue()); + $propertyComplexType->setNillable($complexType->isNillable()); + + if (!$complexType->getName()) { + $propertyComplexType->setName($property->getName()); + } else { + $propertyComplexType->setName($complexType->getName()); + $propertyComplexType->setOriginalName($property->getName()); + } + + $collection->add($propertyComplexType); + } + } + } + + foreach ($class->getMethods() as $method) { + if ($method->isPublic()) { + $complexType = $this->reader->getMethodAnnotation($method, $this->methodComplexTypeClass); + + if ($complexType) { + $methodComplexType = new MethodComplexType(); + $methodComplexType->setValue($complexType->getValue()); + $methodComplexType->setSetter($complexType->getSetter()); + $methodComplexType->setNillable($complexType->isNillable()); + + if (!$complexType->getName()) { + $methodComplexType->setName($property->getName()); + } else { + $methodComplexType->setName($complexType->getName()); + $methodComplexType->setOriginalName($method->getName()); + } + + $collection->add($methodComplexType); + } + } + } + + return $collection; + } +} \ No newline at end of file diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index d11e285..683de74 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -34,6 +34,8 @@ class ServiceDefinition */ private $headers; + private $complexTypes = array(); + public function __construct($name = null, $namespace = null, array $methods = array(), array $headers = array()) { $this->setName($name); @@ -127,4 +129,14 @@ class ServiceDefinition return $types; } + + public function addDefinitionComplexType($type, Collection $complexType) + { + $this->complexTypes[$type] = $complexType; + } + + public function getDefinitionComplexTypes() + { + return $this->complexTypes; + } } \ No newline at end of file diff --git a/ServiceDefinition/Strategy/BaseComplexType.php b/ServiceDefinition/Strategy/BaseComplexType.php new file mode 100644 index 0000000..917fb57 --- /dev/null +++ b/ServiceDefinition/Strategy/BaseComplexType.php @@ -0,0 +1,62 @@ + + * + * 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; + +/** + * @author Francis Besset + */ +abstract class BaseComplexType +{ + private $name; + private $originalName; + private $value; + private $isNillable = false; + + public function getName() + { + return $this->name; + } + + public function getOriginalName() + { + return $this->originalName ?: $this->name; + } + + public function getValue() + { + return $this->value; + } + + public function isNillable() + { + return $this->isNillable; + } + + public function setName($name) + { + $this->name = $name; + } + + public function setOriginalName($originalName) + { + $this->originalName = $originalName; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function setNillable($isNillable) + { + $this->isNillable = (bool) $isNillable; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php new file mode 100644 index 0000000..8af3fb1 --- /dev/null +++ b/ServiceDefinition/Strategy/ComplexType.php @@ -0,0 +1,81 @@ + + * + * 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\Strategy\AbstractStrategy; + +/** + * @author Francis Besset + */ +class ComplexType extends AbstractStrategy +{ + 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($type) + { + if (null !== $soapType = $this->scanRegisteredTypes($type)) { + return $soapType; + } + + 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)); + } + + $dom = $this->getContext()->toDomDocument(); + + $soapTypeName = Wsdl::translateType($type); + $soapType = 'tns:'.$soapTypeName; + + // Register type here to avoid recursion + $this->getContext()->addType($type, $soapType); + + $complexType = $dom->createElement('xsd:complexType'); + $complexType->setAttribute('name', $soapTypeName); + + $all = $dom->createElement('xsd:all'); + + $definitionComplexType = $this->loader->load($type); + $this->definition->addDefinitionComplexType($type, $definitionComplexType); + + foreach ($definitionComplexType as $annotationComplexType) { + $element = $dom->createElement('xsd:element'); + $element->setAttribute('name', $propertyName = $annotationComplexType->getName()); + $element->setAttribute('type', $this->getContext()->getType(trim($annotationComplexType->getValue()))); + + if ($annotationComplexType->isNillable()) { + $element->setAttribute('nillable', 'true'); + } + + $all->appendChild($element); + } + + $complexType->appendChild($all); + $this->getContext()->getSchema()->appendChild($complexType); + + return $soapType; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Strategy/MethodComplexType.php b/ServiceDefinition/Strategy/MethodComplexType.php new file mode 100644 index 0000000..7205ab5 --- /dev/null +++ b/ServiceDefinition/Strategy/MethodComplexType.php @@ -0,0 +1,29 @@ + + * + * 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; + +/** + * @author Francis Besset + */ +class MethodComplexType extends BaseComplexType +{ + private $setter; + + public function getSetter() + { + return $this->setter; + } + + public function setSetter($setter) + { + $this->setter = $setter; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Strategy/PropertyComplexType.php b/ServiceDefinition/Strategy/PropertyComplexType.php new file mode 100644 index 0000000..7545f0e --- /dev/null +++ b/ServiceDefinition/Strategy/PropertyComplexType.php @@ -0,0 +1,18 @@ + + * + * 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; + +/** + * @author Francis Besset + */ +class PropertyComplexType extends BaseComplexType +{ +} \ No newline at end of file diff --git a/WebServiceContext.php b/WebServiceContext.php index 0a429ee..f0acaf6 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -70,6 +70,11 @@ class WebServiceContext return $this->serviceDefinition; } + public function getWsdlFileContent($endpoint = null) + { + return file_get_contents($this->getWsdlFile($endpoint)); + } + public function getWsdlFile($endpoint = null) { $file = sprintf('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint)); @@ -82,11 +87,6 @@ class WebServiceContext return (string) $cache; } - public function getWsdlFileContent($endpoint = null) - { - return file_get_contents($this->getWsdlFile($endpoint)); - } - public function getServiceBinder() { if (null === $this->serviceBinder) { From ba0855a2379193309b5caa4a780e20d0c55b7ac4 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 24 Jul 2011 10:56:07 +0200 Subject: [PATCH 068/195] Fixed typo --- .../RpcLiteralRequestMessageBinder.php | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index c349b73..11d7430 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -16,71 +16,71 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; class RpcLiteralRequestMessageBinder implements MessageBinderInterface { + private $definitionComplexTypes; + 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])) { - if (preg_match('/^([^\[]+)\[\]$/', $argument->getType()->getPhpType(), $match)) { - $isArray = true; - $type = $match[1]; - } else { - $isArray = false; - $type = $argument->getType()->getPhpType(); - } - - if (isset($definitionComplexTypes[$type])) { - if ($isArray) { - $array = array(); - - foreach ($message[$i]->item as $complexType) { - $array[] = $this->getInstanceOfType($type, $complexType, $definitionComplexTypes); - } - - $message[$i] = $array; - } else { - $message[$i] = $this->getInstanceOfType($type, $message[$i], $definitionComplexTypes); - } - } elseif ($isArray) { - $message[$i] = $message[$i]->item; - } - - $result[$argument->getName()] = $message[$i]; + $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i]); } $i++; } + $this->definitionComplexTypes = array(); + return $result; } - private function getInstanceOfType($type, $message, array $definitionComplexTypes) + private function processType($phpType, $message) { - $typeClass = $type; - $instanceType = new $typeClass(); + if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { + $isArray = true; + $type = $match[1]; + } else { + $isArray = false; + $type = $phpType; + } - foreach ($definitionComplexTypes[$type] as $type) { - if ($type instanceof PropertyComplexType) { - if (isset($definitionComplexTypes[$type->getValue()])) { - $value = $this->getInstanceOfType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); - } else { - $value = $message->{$type->getName()}; + if (isset($this->definitionComplexTypes[$type])) { + if ($isArray) { + $array = array(); + + foreach ($message->item as $complexType) { + $array[] = $this->getInstanceOfType($type, $complexType); } + $message = $array; + } else { + $message = $this->getInstanceOfType($type, $message); + } + } elseif ($isArray) { + $message = $message->item; + } + + return $message; + } + + private function getInstanceOfType($phpType, $message) + { + $instanceType = new $phpType(); + + foreach ($this->definitionComplexTypes[$phpType] as $type) { + $value = $this->processType($type->getValue(), $message->{$type->getName()}); + + if ($type instanceof PropertyComplexType) { $instanceType->{$type->getOriginalName()} = $value; } elseif ($type instanceof MethodComplexType) { if (!$type->getSetter()) { throw new \LogicException(); } - if (isset($definitionComplexTypes[$type->getValue()])) { - $value = $this->getInstanceOfType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); - } else { - $value = $message->{$type->getName()}; - } - $instanceType->{$type->getSetter()}($value); } else { throw new \InvalidArgumentException(); From fd7fcf215b9a72683f73faa9eff3a461ad8f0278 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 24 Jul 2011 11:31:15 +0200 Subject: [PATCH 069/195] Added authors --- ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php | 3 +++ .../DocumentLiteralWrappedResponseMessageBinder.php | 3 +++ ServiceBinding/MessageBinderInterface.php | 3 +++ ServiceBinding/RpcLiteralRequestMessageBinder.php | 4 ++++ ServiceBinding/RpcLiteralResponseMessageBinder.php | 4 ++++ ServiceBinding/ServiceBinder.php | 3 +++ 6 files changed, 20 insertions(+) diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index 3245448..5d779b0 100644 --- a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -12,6 +12,9 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +/** + * @author Christian Kerl + */ class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface { public function processMessage(Method $messageDefinition, $message) diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php index d8d7e78..21c72e0 100644 --- a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php +++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -12,6 +12,9 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +/** + * @author Christian Kerl + */ class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface { public function processMessage(Method $messageDefinition, $message) diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php index 542112b..85ca02f 100644 --- a/ServiceBinding/MessageBinderInterface.php +++ b/ServiceBinding/MessageBinderInterface.php @@ -12,6 +12,9 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +/** + * @author Christian Kerl + */ interface MessageBinderInterface { /** diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 11d7430..9fe758b 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -14,6 +14,10 @@ use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +/** + * @author Christian Kerl + * @author Francis Besset + */ class RpcLiteralRequestMessageBinder implements MessageBinderInterface { private $definitionComplexTypes; diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 29b7d0e..b97d503 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -14,6 +14,10 @@ use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +/** + * @author Christian Kerl + * @author Francis Besset + */ class RpcLiteralResponseMessageBinder implements MessageBinderInterface { public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index d6d46bc..57065e6 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -15,6 +15,9 @@ use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; use BeSimple\SoapBundle\Soap\SoapHeader; use BeSimple\SoapBundle\Util\QName; +/** + * @author Christian Kerl + */ class ServiceBinder { /** From f6775ef88f9048bb777afed706bc1a786134e702 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 24 Jul 2011 14:40:52 +0200 Subject: [PATCH 070/195] Fixed typo in Util\Collection --- Util/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Util/Collection.php b/Util/Collection.php index e13703f..60b1256 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -25,7 +25,7 @@ class Collection implements \IteratorAggregate, \Countable public function add($element) { if ($this->class && !$element instanceof $this->class) { - throw new \InvalidArgument(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $class)); + throw new \InvalidArgumentException(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $this->class)); } $getter = $this->getter; From 7d4e88c941c539fe586dd23aa918e545de0c7985 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 24 Jul 2011 14:40:52 +0200 Subject: [PATCH 071/195] Fixed typo in Util\Collection --- Util/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Util/Collection.php b/Util/Collection.php index e13703f..60b1256 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -25,7 +25,7 @@ class Collection implements \IteratorAggregate, \Countable public function add($element) { if ($this->class && !$element instanceof $this->class) { - throw new \InvalidArgument(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $class)); + throw new \InvalidArgumentException(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $this->class)); } $getter = $this->getter; From 444107b89aa755bc734e92504f5b744c324fcb96 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 24 Jul 2011 21:30:45 +0200 Subject: [PATCH 072/195] Added unit tests on RpcLiteralRequestMessageBinder --- .../RpcLiteralRequestMessageBinderTest.php | 136 ++++++++++++++++++ Tests/ServiceBinding/fixtures/Foo.php | 13 ++ 2 files changed, 149 insertions(+) create mode 100644 Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php create mode 100644 Tests/ServiceBinding/fixtures/Foo.php diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php new file mode 100644 index 0000000..6b6a90e --- /dev/null +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -0,0 +1,136 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Tests\ServiceBinding; + +use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Argument; +use BeSimple\SoapBundle\ServiceDefinition\Type; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder; +use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo; +use BeSimple\SoapBundle\Util\Collection; + +/** + * UnitTest for \BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder. + * + * @author Francis Besset + */ +class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider messageProvider + */ + public function testProcessMessage(Method $method, $message, $assert) + { + $messageBinder = new RpcLiteralRequestMessageBinder(); + $result = $messageBinder->processMessage($method, $message); + + $this->assertSame($assert, $result); + } + + /** + * @TODO test with complex type into complex type + * @TODO test setter and getter + */ + public function testProcessMessageWithComplexType() + { + $definitionComplexTypes = $this->getDefinitionComplexTypes(); + + $foo = new \stdClass(); + $foo->bar = 'foobar'; + $messageBinder = new RpcLiteralRequestMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_argument', null, array( + new Argument('foo', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo')), + )), + array($foo), + $definitionComplexTypes + ); + + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo']); + $this->assertEquals('foobar', $result['foo']->bar); + + $foobar = new \stdClass(); + $foobar->bar = 'foobar'; + $barfoo = new \stdClass(); + $barfoo->bar = 'barfoo'; + $message = new \stdClass(); + $message->item = array($foobar, $barfoo); + $messageBinder = new RpcLiteralRequestMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_argument', null, array( + new Argument('foo', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo[]')), + )), + array($message), + $definitionComplexTypes + ); + + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo'][0]); + $this->assertEquals('foobar', $result['foo'][0]->bar); + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo'][1]); + $this->assertEquals('barfoo', $result['foo'][1]->bar); + } + + public function messageProvider() + { + $messages = array(); + + $messages[] = array( + new Method('no_argument'), + array(), + array(), + ); + + $messages[] = array( + new Method('string_argument', null, array( + new Argument('foo', new Type('string')), + )), + array('bar'), + array('foo' => 'bar'), + ); + + $messages[] = array( + new Method('string_int_arguments', null, array( + new Argument('foo', new Type('string')), + new Argument('bar', new Type('int')), + )), + array('test', 20), + array('foo' => 'test', 'bar' => 20), + ); + + $strings = new \stdClass(); + $strings->item = array('foo', 'bar', 'barfoo'); + $messages[] = array( + new Method('array_string_arguments', null, array( + new Argument('foo', new Type('string[]')), + new Argument('bar', new Type('int')), + )), + array($strings, 4), + array('foo' => array('foo', 'bar', 'barfoo'), 'bar' => 4), + ); + + return $messages; + } + + public function getDefinitionComplexTypes() + { + $this->definitionComplexTypes = array(); + + $collection = new Collection('getName'); + $property = new PropertyComplexType(); + $property->setName('bar'); + $property->setValue('string'); + $collection->add($property); + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo'] = $collection; + + return $this->definitionComplexTypes; + } +} diff --git a/Tests/ServiceBinding/fixtures/Foo.php b/Tests/ServiceBinding/fixtures/Foo.php new file mode 100644 index 0000000..e3d570b --- /dev/null +++ b/Tests/ServiceBinding/fixtures/Foo.php @@ -0,0 +1,13 @@ +bar = $bar; + } +} \ No newline at end of file From 483e8d1bb24f1978e3a9c0c811e9c57931da8462 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 00:13:24 +0200 Subject: [PATCH 073/195] Added tests on RpcLiteralRequestMessageBinder --- .../RpcLiteralRequestMessageBinderTest.php | 153 ++++++++++++++---- Tests/ServiceBinding/fixtures/Attributes.php | 9 ++ Tests/ServiceBinding/fixtures/ComplexType.php | 20 +++ Tests/ServiceBinding/fixtures/Foo.php | 13 -- Tests/ServiceBinding/fixtures/Setters.php | 29 ++++ 5 files changed, 183 insertions(+), 41 deletions(-) create mode 100644 Tests/ServiceBinding/fixtures/Attributes.php create mode 100644 Tests/ServiceBinding/fixtures/ComplexType.php delete mode 100644 Tests/ServiceBinding/fixtures/Foo.php create mode 100644 Tests/ServiceBinding/fixtures/Setters.php diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index 6b6a90e..3c8a380 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -14,8 +14,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Argument; use BeSimple\SoapBundle\ServiceDefinition\Type; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder; -use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo; use BeSimple\SoapBundle\Util\Collection; /** @@ -36,47 +36,101 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame($assert, $result); } - /** - * @TODO test with complex type into complex type - * @TODO test setter and getter - */ public function testProcessMessageWithComplexType() { $definitionComplexTypes = $this->getDefinitionComplexTypes(); - $foo = new \stdClass(); - $foo->bar = 'foobar'; + $attributes = new \stdClass(); + $attributes->foo = 'bar'; + $attributes->bar = 10; $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_argument', null, array( - new Argument('foo', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo')), + new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), )), - array($foo), + array($attributes), $definitionComplexTypes ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo']); - $this->assertEquals('foobar', $result['foo']->bar); + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes']); + $this->assertSame('bar', $result['attributes']->foo); + $this->assertSame(10, $result['attributes']->bar); - $foobar = new \stdClass(); - $foobar->bar = 'foobar'; - $barfoo = new \stdClass(); - $barfoo->bar = 'barfoo'; + $attributes1 = new \stdClass(); + $attributes1->foo = 'foobar'; + $attributes1->bar = 11; + $attributes2 = new \stdClass(); + $attributes2->foo = 'barfoo'; + $attributes2->bar = 12; $message = new \stdClass(); - $message->item = array($foobar, $barfoo); + $message->item = array($attributes1, $attributes2); $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( new Method('complextype_argument', null, array( - new Argument('foo', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo[]')), + new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), )), array($message), $definitionComplexTypes ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo'][0]); - $this->assertEquals('foobar', $result['foo'][0]->bar); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo', $result['foo'][1]); - $this->assertEquals('barfoo', $result['foo'][1]->bar); + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes'][0]); + $this->assertSame('foobar', $result['attributes'][0]->foo); + $this->assertSame(11, $result['attributes'][0]->bar); + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes'][1]); + $this->assertSame('barfoo', $result['attributes'][1]->foo); + $this->assertSame(12, $result['attributes'][1]->bar); + } + + 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->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters', $result['setters']); + $this->assertSame('bar', $result['setters']->getFoo()); + $this->assertSame(23, $result['setters']->getBar()); + } + + 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->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType', $result['complex_type']); + + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['complex_type']->getFoo()); + $this->assertSame('hello', $result['complex_type']->getFoo()->foo); + $this->assertSame(24, $result['complex_type']->getFoo()->bar); + + $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters', $result['complex_type']->bar); + $this->assertSame('bonjour', $result['complex_type']->bar->getFoo()); + $this->assertSame(1012, $result['complex_type']->bar->getBar()); } public function messageProvider() @@ -120,17 +174,60 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase return $messages; } - public function getDefinitionComplexTypes() + private function getDefinitionComplexTypes() { $this->definitionComplexTypes = array(); - $collection = new Collection('getName'); - $property = new PropertyComplexType(); - $property->setName('bar'); - $property->setValue('string'); - $collection->add($property); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Foo'] = $collection; + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes'] = $this->createPropertiesCollection(array( + array('foo', 'string'), + array('bar', 'int'), + )); + + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'] = $this->createMethodsCollection(array( + array('foo', 'string', 'getFoo', 'setFoo'), + array('bar', 'int', 'getBar', 'setBar'), + )); + + $collection = $this->createMethodsCollection(array( + array('foo', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', 'getFoo', 'setFoo'), + )); + $this->createPropertiesCollection(array( + array('bar', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'), + ), $collection); + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType'] = $collection; return $this->definitionComplexTypes; } + + private function createPropertiesCollection(array $properties, Collection $collection = null) + { + $collection = $collection ?: new Collection('getName'); + + foreach ($properties as $property) { + $collectionProperty = new PropertyComplexType(); + $collectionProperty->setName($property[0]); + $collectionProperty->setValue($property[1]); + + $collection->add($collectionProperty); + } + + return $collection; + } + + private function createMethodsCollection(array $methods, Collection $collection = null) + { + $collection = $collection ?: new Collection('getName'); + + foreach ($methods as $method) { + $collectionMethod = new MethodComplexType(); + $collectionMethod->setName($method[0]); + $collectionMethod->setValue($method[1]); + $collectionMethod->setOriginalName($method[2]); + $collectionMethod->setSetter($method[3]); + + $collection->add($collectionMethod); + } + + return $collection; + } } diff --git a/Tests/ServiceBinding/fixtures/Attributes.php b/Tests/ServiceBinding/fixtures/Attributes.php new file mode 100644 index 0000000..53d4aee --- /dev/null +++ b/Tests/ServiceBinding/fixtures/Attributes.php @@ -0,0 +1,9 @@ +foo; + } + + public function setFoo($foo) + { + $this->foo = $foo; + } +} \ No newline at end of file diff --git a/Tests/ServiceBinding/fixtures/Foo.php b/Tests/ServiceBinding/fixtures/Foo.php deleted file mode 100644 index e3d570b..0000000 --- a/Tests/ServiceBinding/fixtures/Foo.php +++ /dev/null @@ -1,13 +0,0 @@ -bar = $bar; - } -} \ No newline at end of file diff --git a/Tests/ServiceBinding/fixtures/Setters.php b/Tests/ServiceBinding/fixtures/Setters.php new file mode 100644 index 0000000..a8de35a --- /dev/null +++ b/Tests/ServiceBinding/fixtures/Setters.php @@ -0,0 +1,29 @@ +foo; + } + + public function setFoo($foo) + { + $this->foo = $foo; + } + + public function getBar() + { + return $this->bar; + } + + public function setBar($bar) + { + $this->bar = $bar; + } +} \ No newline at end of file From 2994129b8d06491efe88f2cf1d7d4b4165892995 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 00:48:45 +0200 Subject: [PATCH 074/195] Added RpcLiteralResponseMessageBinderTest --- .../RpcLiteralResponseMessageBinderTest.php | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php diff --git a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php new file mode 100644 index 0000000..fe31332 --- /dev/null +++ b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php @@ -0,0 +1,131 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Tests\ServiceBinding; + +use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapBundle\ServiceDefinition\Type; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +use BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder; +use BeSimple\SoapBundle\Util\Collection; +use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes; + +/** + * UnitTest for \BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder. + * + * @author Francis Besset + */ +class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider messageProvider + */ + public function testProcessMessage(Method $method, $message, $assert) + { + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage($method, $message); + + $this->assertSame($assert, $result); + } + + /** + * @TODO test with complex type into complex type + * @TODO test setter and getter + */ + public function testProcessMessageWithComplexType() + { + $definitionComplexTypes = $this->getDefinitionComplexTypes(); + + $attributes = new Attributes(); + $attributes->foo = 'foobar'; + $attributes->bar = 20349; + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), + $attributes, + $definitionComplexTypes + ); + + $this->assertInstanceOf('stdClass', $result); + $this->assertSame('foobar', $result->foo); + $this->assertSame(20349, $result->bar); + + $attributes1 = new Attributes(); + $attributes1->foo = 'bar'; + $attributes1->bar = 2929; + $attributes2 = new Attributes(); + $attributes2->foo = 'foo'; + $attributes2->bar = 123992; + $message = array($attributes1, $attributes2); + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_argument', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), + $message, + $definitionComplexTypes + ); + + $this->assertTrue(is_array($result)); + + $this->assertInstanceOf('stdClass', $result[0]); + $this->assertSame('bar', $result[0]->foo); + $this->assertSame(2929, $result[0]->bar); + + $this->assertInstanceOf('stdClass', $result[1]); + $this->assertSame('foo', $result[1]->foo); + $this->assertSame(123992, $result[1]->bar); + } + + public function messageProvider() + { + $messages = array(); + + $messages[] = array( + new Method('boolean', null, array(), new Type('boolean')), + true, + true, + ); + + $messages[] = array( + new Method('strings', null, array(), new Type('string[]')), + array('hello', 'world'), + array('hello', 'world'), + ); + + return $messages; + } + + private function getDefinitionComplexTypes() + { + $this->definitionComplexTypes = array(); + + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes'] = $this->createPropertiesCollection(array( + array('foo', 'string'), + array('bar', 'int'), + )); + + return $this->definitionComplexTypes; + } + + private function createPropertiesCollection(array $properties, Collection $collection = null) + { + $collection = $collection ?: new Collection('getName'); + + foreach ($properties as $property) { + $collectionProperty = new PropertyComplexType(); + $collectionProperty->setName($property[0]); + $collectionProperty->setValue($property[1]); + + $collection->add($collectionProperty); + } + + return $collection; + } +} From 8cd07acc1183097196196ee048db68c0bc81b6ab Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 22:53:33 +0200 Subject: [PATCH 075/195] Used the object hash in RpcLiteralRequestMessageBinder to return a same instance of an object --- .../RpcLiteralRequestMessageBinder.php | 30 ++++++----- .../RpcLiteralRequestMessageBinderTest.php | 54 +++++++++++++++---- 2 files changed, 60 insertions(+), 24 deletions(-) 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(); From a0a321646963ff1d5763b45fb62e9d82daf44196 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 23:15:47 +0200 Subject: [PATCH 076/195] Used the object hash in RpcLiteralResponseMessageBinder to return a same instance of an object --- .../RpcLiteralResponseMessageBinder.php | 8 ++++++++ .../RpcLiteralResponseMessageBinderTest.php | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index b97d503..37463de 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -20,6 +20,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; */ class RpcLiteralResponseMessageBinder implements MessageBinderInterface { + private $messageRefs = array(); + public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) { $return = $messageDefinition->getReturn(); @@ -61,7 +63,13 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface throw new \InvalidArgumentException(); } + $hash = spl_object_hash($message); + if (isset($this->messageRefs[$hash])) { + return $this->messageRefs[$hash]; + } + $stdClass = new \stdClass(); + $this->messageRefs[$hash] = $stdClass; foreach ($definitionComplexTypes[$type] as $type) { if ($type instanceof PropertyComplexType) { diff --git a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php index fe31332..2ccb4ea 100644 --- a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php @@ -83,6 +83,24 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame(123992, $result[1]->bar); } + public function testProcessMessageWithComplexTypeReferences() + { + $attributes = new Attributes(); + $attributes->foo = 'bar'; + $attributes->bar = 2929; + + $message = array($attributes, $attributes); + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_argument', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), + $message, + $this->getDefinitionComplexTypes() + ); + + $this->assertInstanceOf('stdClass', $result[0]); + $this->assertSame($result[0], $result[1]); + } + public function messageProvider() { $messages = array(); From ff2cf6e730ee5c9599a329e1b3eb5833a8ad4249 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 23:20:01 +0200 Subject: [PATCH 077/195] Fixed typo in webservice definition --- Resources/config/webservice.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 5dc9f8f..f43610b 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -31,7 +31,7 @@ - + From 4e6592a38e2fe9de039b5e94d2bc3e91264dde5c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Jul 2011 23:38:21 +0200 Subject: [PATCH 078/195] Fixed typo --- Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index a9b1ee0..0eb1997 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -82,7 +82,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame(12, $result['attributes'][1]->bar); } - public function testProcessMessageWithComplexTypeIntoComplexType() + public function testProcessMessageWithComplexTypeMethods() { $methods = new \stdClass(); $methods->foo = 'bar'; @@ -102,7 +102,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame(23, $result['setters']->getBar()); } - public function testProcessMessageWithComplexTypeMethods() + public function testProcessMessageWithComplexTypeIntoComplexType() { $complexType = new \stdClass(); $foo = $complexType->foo = new \stdClass(); From 966077aca0327e67672f293a17044ed9cbbe1d06 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 28 Jul 2011 00:39:19 +0200 Subject: [PATCH 079/195] Added recursion of types in RpcLiteralResponseMessageBinder --- .../RpcLiteralRequestMessageBinder.php | 2 +- .../RpcLiteralResponseMessageBinder.php | 46 +++++++++++-------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 310860f..2d3c32d 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -27,7 +27,7 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $result = array(); $i = 0; - foreach($messageDefinition->getArguments() as $argument) { + foreach ($messageDefinition->getArguments() as $argument) { if (isset($message[$i])) { $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i], $definitionComplexTypes); } diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 37463de..fcf5f77 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -27,58 +27,68 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $return = $messageDefinition->getReturn(); $class = $return->getPhpType(); - if (preg_match('/^([^\[]+)\[\]$/', $class, $match)) { + $message = $this->processType($messageDefinition->getReturn()->getPhpType(), $message, $definitionComplexTypes); + + return $message; + } + + private function processType($phpType, $message, array $definitionComplexTypes) + { + if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; - $type = - $class = $match[1]; + $type = $match[1]; } else { $isArray = false; - $type = $return->getPhpType(); + $type = $phpType; } if (isset($definitionComplexTypes[$type])) { - if ($class[0] == '\\') { - $class = substr($class, 1); - } - if ($isArray) { $array = array(); foreach ($message as $complexType) { - $array[] = $this->getInstanceOfStdClass($type, $class, $complexType, $definitionComplexTypes); + $array[] = $this->getInstanceOfStdClass($type, $complexType, $definitionComplexTypes); } $message = $array; } else { - $message = $this->getInstanceOfStdClass($type, $class, $message, $definitionComplexTypes); + $message = $this->getInstanceOfStdClass($type, $message, $definitionComplexTypes); } } return $message; } - private function getInstanceOfStdClass($type, $class, $message, $definitionComplexTypes) + private function getInstanceOfStdClass($phpType, $message, $definitionComplexTypes) { - if (get_class($message) !== $class) { - throw new \InvalidArgumentException(); - } - $hash = spl_object_hash($message); if (isset($this->messageRefs[$hash])) { return $this->messageRefs[$hash]; } + $class = $phpType; + if ($class[0] == '\\') { + $class = substr($class, 1); + } + + if (get_class($message) !== $class) { + throw new \InvalidArgumentException(); + } + $stdClass = new \stdClass(); $this->messageRefs[$hash] = $stdClass; - foreach ($definitionComplexTypes[$type] as $type) { + foreach ($definitionComplexTypes[$phpType] as $type) { + if ($type instanceof PropertyComplexType) { - $stdClass->{$type->getName()} = $message->{$type->getOriginalName()}; + $value = $message->{$type->getOriginalName()}; } elseif ($type instanceof MethodComplexType) { - $stdClass->{$type->getName()} = $message->{$type->getOriginalName()}(); + $value = $message->{$type->getOriginalName()}(); } else { throw new \InvalidArgumentException(); } + + $stdClass->{$type->getName()} = $this->processType($type->getValue(), $value, $definitionComplexTypes); } return $stdClass; From 9c2dd31b681529435caa3f4a8d3540ec986baca1 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 28 Jul 2011 00:39:55 +0200 Subject: [PATCH 080/195] Added unit tests --- .../RpcLiteralResponseMessageBinderTest.php | 86 ++++++++++++++++++- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php index 2ccb4ea..bc6129f 100644 --- a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php @@ -17,6 +17,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder; use BeSimple\SoapBundle\Util\Collection; use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes; +use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType; +use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters; /** * UnitTest for \BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder. @@ -36,10 +38,6 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame($assert, $result); } - /** - * @TODO test with complex type into complex type - * @TODO test setter and getter - */ public function testProcessMessageWithComplexType() { $definitionComplexTypes = $this->getDefinitionComplexTypes(); @@ -83,6 +81,56 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertSame(123992, $result[1]->bar); } + public function testProcessMessageWithComplexTypeMethods() + { + $setters = new Setters(); + $setters->setFoo('foobar'); + $setters->setBar(42); + + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_methods', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), + $setters, + $this->getDefinitionComplexTypes() + ); + + $this->assertInstanceOf('stdClass', $result); + $this->assertSame('foobar', $result->foo); + $this->assertSame(42, $result->bar); + } + + public function testProcessMessageWithComplexTypeIntoComplexType() + { + $complexType = new ComplexType(); + + $foo = new Attributes(); + $foo->foo = 'Hello world!'; + $foo->bar = 4242; + $complexType->setFoo($foo); + + $bar = new Setters(); + $bar->setFoo('bar foo'); + $bar->setBar(2424); + $complexType->bar = $bar; + + $messageBinder = new RpcLiteralResponseMessageBinder(); + $result = $messageBinder->processMessage( + new Method('complextype_complextype', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), + $complexType, + $this->getDefinitionComplexTypes() + ); + + $this->assertInstanceOf('stdClass', $result); + + $this->assertInstanceOf('stdClass', $result->foo); + $this->assertSame('Hello world!', $result->foo->foo); + $this->assertSame(4242, $result->foo->bar); + + $this->assertInstanceOf('stdClass', $result->bar); + $this->assertSame('bar foo', $result->bar->foo); + $this->assertSame(2424, $result->bar->bar); + } + public function testProcessMessageWithComplexTypeReferences() { $attributes = new Attributes(); @@ -129,6 +177,19 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase array('bar', 'int'), )); + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'] = $this->createMethodsCollection(array( + array('foo', 'string', 'getFoo', 'setFoo'), + array('bar', 'int', 'getBar', 'setBar'), + )); + + $collection = $this->createMethodsCollection(array( + array('foo', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', 'getFoo', 'setFoo'), + )); + $this->createPropertiesCollection(array( + array('bar', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'), + ), $collection); + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType'] = $collection; + return $this->definitionComplexTypes; } @@ -146,4 +207,21 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase return $collection; } + + private function createMethodsCollection(array $methods, Collection $collection = null) + { + $collection = $collection ?: new Collection('getName'); + + foreach ($methods as $method) { + $collectionMethod = new MethodComplexType(); + $collectionMethod->setName($method[0]); + $collectionMethod->setValue($method[1]); + $collectionMethod->setOriginalName($method[2]); + $collectionMethod->setSetter($method[3]); + + $collection->add($collectionMethod); + } + + return $collection; + } } From c4217ce816c05813a8f92307e802a8338dfef7ac Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 2 Aug 2011 23:27:56 +0200 Subject: [PATCH 081/195] Added RST documentation --- Resources/doc/_static/.gitkeep | 0 Resources/doc/conf.py | 226 ++++++++++++++++++++++ Resources/doc/index.rst | 27 +++ Resources/doc/reference/configuration.rst | 51 +++++ Resources/doc/reference/installation.rst | 65 +++++++ Resources/doc/tutorial/array.rst | 26 +++ Resources/doc/tutorial/complex_type.rst | 120 ++++++++++++ 7 files changed, 515 insertions(+) create mode 100644 Resources/doc/_static/.gitkeep create mode 100644 Resources/doc/conf.py create mode 100644 Resources/doc/index.rst create mode 100644 Resources/doc/reference/configuration.rst create mode 100644 Resources/doc/reference/installation.rst create mode 100644 Resources/doc/tutorial/array.rst create mode 100644 Resources/doc/tutorial/complex_type.rst diff --git a/Resources/doc/_static/.gitkeep b/Resources/doc/_static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Resources/doc/conf.py b/Resources/doc/conf.py new file mode 100644 index 0000000..fcbd938 --- /dev/null +++ b/Resources/doc/conf.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- +# +# BeSimpleSoapBundle documentation build configuration file, created by +# sphinx-quickstart on Mon Aug 1 22:24:10 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer +lexers['php'] = PhpLexer(startinline=True) + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) +sys.path.append(os.path.abspath('_exts')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'BeSimpleSoapBundle' +copyright = u'2011, Christian Kerl, Francis Besset' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.0.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0-DEV' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'sphinx' +pygments_style = 'perldoc' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'BeSimpleSoapBundledoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'BeSimpleSoapBundle.tex', u'BeSimpleSoapBundle Documentation', + u'Christian Kerl, Francis Besset', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'besimplesoapbundle', u'BeSimpleSoapBundle Documentation', + [u'Christian Kerl, Francis Besset'], 1) +] + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst new file mode 100644 index 0000000..d272f45 --- /dev/null +++ b/Resources/doc/index.rst @@ -0,0 +1,27 @@ +BeSimpleSoapBundle +================== + +The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. +It is based on the `ckWebServicePlugin`_ for symfony. + +Reference Guide +--------------- + +.. toctree:: + :maxdepth: 1 + :numbered: + + reference/installation + reference/configuration + +Tutorial +-------- + +.. toctree:: + :maxdepth: 1 + :numbered: + + tutorial/complex_type + tutorial/array + +.. _`ckWebServicePlugin`: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file diff --git a/Resources/doc/reference/configuration.rst b/Resources/doc/reference/configuration.rst new file mode 100644 index 0000000..4c2d469 --- /dev/null +++ b/Resources/doc/reference/configuration.rst @@ -0,0 +1,51 @@ +Configuration +============= + +Routing +------- + +Include the `BeSimpleSoapBundle`'s routing configuration in your routing file (you can choose the prefix arbitrarily): + +.. code-block:: yaml + + # app/config/routing.yml + _besimple_soap: + resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml" + prefix: /ws + +Config +------ + +Configure your first web service in your config file: + +.. code-block:: yaml + + # app/config/config.yml + be_simple_soap: + services: + DemoApi: + namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ + binding: rpc-literal + resource: "@AcmeDemoBundle/Controller/DemoController.php" + resource_type: annotation + +Annotations for Controllers +--------------------------- + +.. code-block:: php + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use BeSimple\SoapBundle\Soap\SoapResponse; + + class DemoController extends Controller + { + /** + * @Soap\Method("Hello") + * @Soap\Param("name", phpType = "string") + * @Soap\Result(phpType = "string") + */ + public function helloAction($name) + { + return new SoapResponse(sprintf('Hello %s!', $name)); + } + } \ No newline at end of file diff --git a/Resources/doc/reference/installation.rst b/Resources/doc/reference/installation.rst new file mode 100644 index 0000000..69b5d70 --- /dev/null +++ b/Resources/doc/reference/installation.rst @@ -0,0 +1,65 @@ +Installation +============ + +Requirements +------------ + +Install and enable PHP's SOAP extension +Download `Zend\Soap`_ or add in `deps` file + +.. code-block:: ini + + ; deps file + [Zend\Soap] + git=http://github.com/BeSimple/zend-soap.git + target=/zend-framework/library/Zend/Soap + +Add Zend\Soap library in autoload.php + +.. code-block:: php + + // app/autoload.php + $loader->registerNamespaces(array( + 'ZendSoap' => __DIR__.'/../vendor/zend-framework/library', + // your other namespaces + )); + +Installation +------------ + +`Download`_ the bundle or add in `deps` file + +.. code-block:: ini + + ; deps file + [BeSimpleSoapBundle] + git=http://github.com/BeSimple/BeSimpleSoapBundle.git + target=/bundles/BeSimple/SoapBundle + +Add `BeSimple` in autoload.php + +.. code-block:: php + + // app/autoload.php + $loader->registerNamespaces(array( + 'BeSimple' => __DIR__.'/../vendor/bundles', + // your other namespaces + )); + +Add `BeSimpleSoapBundle` in your Kernel class + +.. code-block:: php + + // app/AppKernel.php + public function registerBundles() + { + return array( + // ... + new new BeSimple\SoapBundle\BeSimpleSoapBundle(), + // ... + ); + } + + +.. _`Zend\Soap`: http://github.com/BeSimple/zend-soap +.. _`Download`: http://github.com/BeSimple/BeSimpleSoapBundle \ No newline at end of file diff --git a/Resources/doc/tutorial/array.rst b/Resources/doc/tutorial/array.rst new file mode 100644 index 0000000..32b28ff --- /dev/null +++ b/Resources/doc/tutorial/array.rst @@ -0,0 +1,26 @@ +Array +===== + +Controller +---------- + +.. code-block:: php + + namespace My\App\Controller; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use BeSimple\SoapBundle\Soap\SoapResponse; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware + { + /** + * @Soap\Method("isString") + * @Soap\Param("strings", phpType = "string[]") + * @Soap\Result(phpType = "boolean") + */ + public function helloAction(array $strings) + { + return new SoapResponse(true); + } + } \ No newline at end of file diff --git a/Resources/doc/tutorial/complex_type.rst b/Resources/doc/tutorial/complex_type.rst new file mode 100644 index 0000000..de60eb8 --- /dev/null +++ b/Resources/doc/tutorial/complex_type.rst @@ -0,0 +1,120 @@ +Complex Type +============ + +This tutorial explains how to do to return a complex type. + +If your SOAP function takes a complex type as input, this tutorial is +valid. You'll just have to adapt the input parameters of your method. + + +Controller +---------- + +.. code-block:: php + + namespace My\App\Controller; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use BeSimple\SoapBundle\Soap\SoapResponse; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware + { + /** + * @Soap\Method("getUser") + * @Soap\Param("name", phpType = "string") + * + * Specify \My\App\Entity\User phpType + * Warning: Do not forget the first backslash + * @Soap\Result(phpType = "\My\App\Entity\User") + */ + public function getUserAction($name) + { + $user = $this->container->getDoctrine()->getRepository('MyApp:User')->findOneByName($name); + + if (!$user) { + throw new \SoapFault('USER_NOT_FOUND', sprintf('The user with the name "%s" can not be found', $name)); + } + + return new SoapResponse($user); + } + } + +User class +---------- + +You can expose public property and public method (getter and setter). + +.. code-block:: php + + namespace My\App\Entity; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + + class User + { + /** + * @Soap\PropertyComplexType("string") + */ + public $firstname; + + /** + * @Soap\PropertyComplexType("string") + */ + public $lastname; + + private $id; + private $username; + private $email; + + /** + * @Soap\MethodComplexType("int", name="user_id", nillable=true) + */ + public function getId() + { + return $this->id; + } + + /** + * @Soap\MethodComplexType("string", setter="setUsername") + */ + public function getUsername() + { + return $this->username; + } + + /** + * @Soap\MethodComplexType("string", setter="setEmail") + */ + public function getEmail() + { + return $this->email; + } + + public function setUsername($username) + { + $this->username = $username; + } + + public function setEmail($email) + { + $this->email = $email; + } + } + +PropertyComplexType +------------------- + +`PropertyComplexType` accepts the following options: + + * **name**: To override the original name of the property + * **nillable**: To specify that the value can be null + +MethodComplexType +------------------- + +`MethodComplexType` accepts the following options: + + * **name**: To override the original name of the property + * **nillable**: To specify that the value can be null + * **setter**: The set method name value. *Mandatory if the complex type is passed as a parameter to a function.* \ No newline at end of file From de94580403f5ae11e20ca0857248b2f8c85238db Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 4 Aug 2011 10:57:41 +0300 Subject: [PATCH 082/195] [Doc] Moved array in first tutorial --- Resources/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index d272f45..07ac795 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -21,7 +21,7 @@ Tutorial :maxdepth: 1 :numbered: - tutorial/complex_type tutorial/array + tutorial/complex_type .. _`ckWebServicePlugin`: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file From b843acbec7774bd8d44b413647aa44a1fa6a0551 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 7 Aug 2011 11:33:34 +0200 Subject: [PATCH 083/195] Replaced zf2 by zend-soap and zend-mime of BeSimple Repository --- Tests/bootstrap.php | 2 +- phpunit.xml.dist | 4 ++-- vendors.php | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 8fa8a1e..4d7062a 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -22,4 +22,4 @@ spl_autoload_register(function($class) { return false; } -}); \ No newline at end of file +}); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4024132..c40be1e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -13,7 +13,7 @@ > - + @@ -21,4 +21,4 @@ ./Tests - \ No newline at end of file + diff --git a/vendors.php b/vendors.php index 3c473b8..098bddc 100755 --- a/vendors.php +++ b/vendors.php @@ -23,7 +23,8 @@ if (!is_dir($vendorDir = dirname(__FILE__).'/vendor')) { $deps = array( array('symfony', 'http://github.com/symfony/symfony.git', 'origin/HEAD'), - array('zend', 'http://github.com/zendframework/zf2.git', 'origin/HEAD'), + array('zend-framework/library/Zend/Soap', 'http://github.com/BeSimple/zend-soap.git', 'origin/HEAD'), + array('zend-framework/library/Zend/Mime', 'http://github.com/BeSimple/zend-mime.git', 'origin/HEAD'), ); foreach ($deps as $dep) { From b945632dcf86311eb77cb07a2ff649f1c6600755 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 7 Aug 2011 11:34:00 +0200 Subject: [PATCH 084/195] [Doc] Updated installation --- Resources/doc/reference/installation.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Resources/doc/reference/installation.rst b/Resources/doc/reference/installation.rst index 69b5d70..9711348 100644 --- a/Resources/doc/reference/installation.rst +++ b/Resources/doc/reference/installation.rst @@ -5,7 +5,7 @@ Requirements ------------ Install and enable PHP's SOAP extension -Download `Zend\Soap`_ or add in `deps` file +Download `Zend\\Soap`_ and `Zend\\Mime`_ or add in `deps` file .. code-block:: ini @@ -14,13 +14,17 @@ Download `Zend\Soap`_ or add in `deps` file git=http://github.com/BeSimple/zend-soap.git target=/zend-framework/library/Zend/Soap -Add Zend\Soap library in autoload.php + [Zend\Mime] + git=http://github.com/BeSimple/zend-mime.git + target=/zend-framework/library/Zend/Mime + +Add `Zend` library in autoload.php .. code-block:: php // app/autoload.php $loader->registerNamespaces(array( - 'ZendSoap' => __DIR__.'/../vendor/zend-framework/library', + 'Zend' => __DIR__.'/../vendor/zend-framework/library', // your other namespaces )); @@ -61,5 +65,6 @@ Add `BeSimpleSoapBundle` in your Kernel class } -.. _`Zend\Soap`: http://github.com/BeSimple/zend-soap -.. _`Download`: http://github.com/BeSimple/BeSimpleSoapBundle \ No newline at end of file +.. _`Zend\\Soap`: http://github.com/BeSimple/zend-soap +.. _`Zend\\Mime`: http://github.com/BeSimple/zend-mime +.. _`Download`: http://github.com/BeSimple/BeSimpleSoapBundle From ea003a122439f3e51d24ea2688044073099b529c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 9 Aug 2011 14:48:56 +0300 Subject: [PATCH 085/195] [Doc] Fixed typo --- Resources/doc/reference/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/doc/reference/installation.rst b/Resources/doc/reference/installation.rst index 9711348..495bec3 100644 --- a/Resources/doc/reference/installation.rst +++ b/Resources/doc/reference/installation.rst @@ -59,7 +59,7 @@ Add `BeSimpleSoapBundle` in your Kernel class { return array( // ... - new new BeSimple\SoapBundle\BeSimpleSoapBundle(), + new BeSimple\SoapBundle\BeSimpleSoapBundle(), // ... ); } From b0efd027d5c678d6f695042e3024f55029471dc7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 11 Aug 2011 00:42:14 +0200 Subject: [PATCH 086/195] Fixed issue #3 --- Controller/SoapWebServiceController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 1816377..2a697b8 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -111,7 +111,13 @@ class SoapWebServiceController extends ContainerAware ); // forward to controller - $response = $this->container->get('http_kernel')->handle($this->soapRequest, HttpKernelInterface::SUB_REQUEST, false); + try { + $response = $this->container->get('http_kernel')->handle($this->soapRequest, HttpKernelInterface::SUB_REQUEST, false); + } catch (\SoapFault $e) { + $this->soapResponse = new Response(null, 500); + + throw $e; + } $this->soapResponse = $this->checkResponse($response); @@ -139,7 +145,7 @@ class SoapWebServiceController extends ContainerAware */ protected function checkResponse(Response $response) { - if (null === $response || !$response instanceof SoapResponse) { + if (!$response instanceof SoapResponse) { throw new \InvalidArgumentException(); } From 838e16b1c4fbbdff07874d0cc79ee3bea36ef4a3 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 11 Aug 2011 00:59:40 +0200 Subject: [PATCH 087/195] Fixed issue #4 --- Soap/SoapResponse.php | 11 +++++++++++ Util/Collection.php | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index cb9c9a3..5fba41b 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -39,6 +39,17 @@ class SoapResponse extends Response $this->setReturnValue($returnValue); } + /** + * @param SoapHeader $soapHeader + */ + public function addSoapHeader(SoapHeader $soapHeader) + { + $this->soapHeaders->add($soapHeader); + } + + /** + * @return \BeSimple\SoapBundle\Util\Collection + */ public function getSoapHeaders() { return $this->soapHeaders; diff --git a/Util/Collection.php b/Util/Collection.php index 60b1256..4ea5699 100644 --- a/Util/Collection.php +++ b/Util/Collection.php @@ -28,8 +28,7 @@ class Collection implements \IteratorAggregate, \Countable throw new \InvalidArgumentException(sprintf('Cannot add class "%s" because it is not an instance of "%s"', get_class($element), $this->class)); } - $getter = $this->getter; - $this->elements[$element->$getter()] = $element; + $this->elements[$element->{$this->getter}()] = $element; } public function addAll($elements) From 985ac61625137918ceb5c804049cb57fb34417a9 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 11 Aug 2011 02:13:40 +0300 Subject: [PATCH 088/195] Updated README --- README.markdown | 91 +------------------------------------------------ 1 file changed, 1 insertion(+), 90 deletions(-) diff --git a/README.markdown b/README.markdown index e8434f7..1040d20 100644 --- a/README.markdown +++ b/README.markdown @@ -4,93 +4,4 @@ BeSimpleSoapBundle The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. It is based on the [ckWebServicePlugin] [1] for symfony. -Requirements ------------- - - * Install and enable PHP's `SOAP` extension - * Download `Zend\Soap` - - git submodule add http://github.com/zendframework/zf2.git vendor/zend-framework - - * Add `Zend\Soap` library to `app/autoload.php` - - // app/autoload.php - $loader->registerNamespaces(array( - 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', - // your other namespaces - )); - -QuickStart ----------- - - * Put BeSimpleSoapBundle in your `vendor/bundles/BeSimple` dir - - git submodule add https://github.com/BeSimple/BeSimpleSoapBundle.git vendor/bundles/BeSimple/SoapBundle - - * Enable BeSimpleSoapBundle in your `app/AppKernel.php` - - // app/AppKernel.php - public function registerBundles() - { - return array( - // ... - new new BeSimple\SoapBundle\BeSimpleSoapBundle(), - // ... - ); - } - - * Register the BeSimple namespace - - // app/autoload.php - $loader->registerNamespaces(array( - 'BeSimple' => __DIR__.'/../vendor/bundles', - 'Zend\\Soap' => __DIR__.'/../vendor/zend-frameword/library', - // your other namespaces - )); - - * Include the BeSimpleSoapBundle's routing configuration in `app/config/routing.yml` (you can choose the prefix arbitrarily) - - _besimple_soap: - resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml" - prefix: /ws - - * Configure your first web service in `app/config/config.yml` - - be_simple_soap: - services: - DemoApi: - namespace: http://mysymfonyapp.com/ws/DemoApi/1.0/ - binding: rpc-literal - resource: "@AcmeDemoBundle/Controller/DemoController.php" - resource_type: annotation - - * Annotate your controller methods - - // src/Acme/DemoBundle/Controller/DemoController.php - use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; - use BeSimple\SoapBundle\Soap\SoapResponse; - - class DemoController extends Controller - { - /** - * @Soap\Method("Hello") - * @Soap\Param("name", phpType = "string") - * @Soap\Result(phpType = "string") - */ - public function helloAction($name) - { - return new SoapResponse(sprintf('Hello %s!', $name)); - } - } - - * Open your web service endpoint - - * `http://localhost/app_dev.php/ws/DemoApi` - HTML documentation - * `http://localhost/app_dev.php/ws/DemoApi?wsdl` - WSDL file - -Test ----- - - phpunit -c phpunit.xml.dist - -[1]: http://www.symfony-project.org/plugins/ckWebServicePlugin +Read about it on its [official homepage](http://besim.pl/SoapBundle/). From b4f29373ba756ac275197bcaf39b50e4648b1c22 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 11 Aug 2011 11:22:31 +0300 Subject: [PATCH 089/195] Added link to ckWebServicePlugin in README --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 1040d20..63c8aa0 100644 --- a/README.markdown +++ b/README.markdown @@ -2,6 +2,6 @@ BeSimpleSoapBundle ================== The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. -It is based on the [ckWebServicePlugin] [1] for symfony. +It is based on the [ckWebServicePlugin](http://www.symfony-project.org/plugins/ckWebServicePlugin) for symfony. Read about it on its [official homepage](http://besim.pl/SoapBundle/). From a6f8ccbfd28163e5e830f55c8a2319f7ad15329c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 11 Aug 2011 23:55:46 +0200 Subject: [PATCH 090/195] Cleaned code --- Controller/SoapWebServiceController.php | 6 +----- ServiceBinding/ServiceBinder.php | 9 ++++----- Soap/SoapRequest.php | 15 ++++++++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 2a697b8..e2dbd53 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -101,11 +101,7 @@ class SoapWebServiceController extends ContainerAware $this->soapRequest->getSoapHeaders()->add( $this->serviceBinder->processServiceHeader($method, $arguments[0]) ); - - return; - } - - if ($this->serviceBinder->isServiceMethod($method)) { + } elseif ($this->serviceBinder->isServiceMethod($method)) { $this->soapRequest->attributes->add( $this->serviceBinder->processServiceMethodArguments($method, $arguments) ); diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 57065e6..e359c55 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -62,11 +62,10 @@ class ServiceBinder { $methodDefinition = $this->definition->getMethods()->get($name); - $result = array(); - $result['_controller'] = $methodDefinition->getController(); - $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getDefinitionComplexTypes())); - - return $result; + return array_merge( + array('_controller' => $methodDefinition->getController()), + $this->requestMessageBinder->processMessage($methodDefinition, $arguments, $this->definition->getDefinitionComplexTypes()) + ); } public function processServiceMethodReturnValue($name, $return) diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 6cc0f97..0b20161 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -24,11 +24,6 @@ use Zend\Mime\Message; */ class SoapRequest extends Request { - public static function createFromHttpRequest(Request $request) - { - return new static($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->content); - } - /** * @var string */ @@ -49,6 +44,16 @@ class SoapRequest extends Request */ protected $soapAttachments; + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return SoapRequest + */ + public static function createFromHttpRequest(Request $request) + { + return new static($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->content); + } + public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { parent::initialize($query, $request, $attributes, $cookies, $files, $server, $content); From c5902122bb84eb2932e92a17c049745605d6d812 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 18:00:28 +0200 Subject: [PATCH 091/195] Added headers in request You can add @Soap\Header("foobar", phpType="string") in a method definition --- Controller/SoapWebServiceController.php | 58 ++++++++++-------- DependencyInjection/BeSimpleSoapExtension.php | 6 +- Resources/config/webservice.xml | 4 ++ .../RpcLiteralRequestHeaderMessageBinder.php | 33 ++++++++++ .../RpcLiteralRequestMessageBinder.php | 2 +- ServiceBinding/ServiceBinder.php | 36 +++++++---- ServiceDefinition/Annotation/Header.php | 22 +++++++ ServiceDefinition/Dumper/Wsdl.php | 37 ++++++++++++ ServiceDefinition/Dumper/WsdlDumper.php | 48 ++++++++++----- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 4 +- .../Loader/AnnotationClassLoader.php | 60 +++++++++++-------- ServiceDefinition/Method.php | 15 ++++- ServiceDefinition/ServiceDefinition.php | 33 +++------- WebServiceContext.php | 10 ++-- 14 files changed, 256 insertions(+), 112 deletions(-) create mode 100644 ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php create mode 100644 ServiceDefinition/Annotation/Header.php create mode 100644 ServiceDefinition/Dumper/Wsdl.php diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index e2dbd53..f801cb4 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -43,6 +43,11 @@ class SoapWebServiceController extends ContainerAware */ protected $serviceBinder; + /** + * @var array + */ + private $headers = array(); + /** * @return \BeSimple\SoapBundle\Soap\SoapResponse */ @@ -96,12 +101,14 @@ class SoapWebServiceController extends ContainerAware */ public function __call($method, $arguments) { - if ($this->serviceBinder->isServiceHeader($method)) { - // collect request soap headers - $this->soapRequest->getSoapHeaders()->add( - $this->serviceBinder->processServiceHeader($method, $arguments[0]) - ); - } elseif ($this->serviceBinder->isServiceMethod($method)) { + if ($this->serviceBinder->isServiceMethod($method)) { + foreach ($this->headers as $name => $value) { + if ($this->serviceBinder->isServiceHeader($method, $name)) { + $this->soapRequest->getSoapHeaders()->add($this->serviceBinder->processServiceHeader($method, $name, $value)); + } + } + $this->headers = null; + $this->soapRequest->attributes->add( $this->serviceBinder->processServiceMethodArguments($method, $arguments) ); @@ -127,9 +134,28 @@ class SoapWebServiceController extends ContainerAware $method, $this->soapResponse->getReturnValue() ); + } else { + // collect request soap headers + $this->headers[$method] = $arguments[0]; } } + /** + * @return \BeSimple\SoapBundle\Soap\SoapRequest + */ + public function getRequest() + { + return $this->soapRequest; + } + + /** + * @return \BeSimple\SoapBundle\Soap\SoapResponse + */ + public function getResponse() + { + return $this->soapResponse; + } + /** * Checks that the given Response is a SoapResponse. * @@ -148,28 +174,12 @@ class SoapWebServiceController extends ContainerAware return $response; } - /** - * @return \BeSimple\SoapBundle\Soap\SoapRequest - */ - public function getRequest() - { - return $this->soapRequest; - } - - /** - * @return \BeSimple\SoapBundle\Soap\SoapResponse - */ - public function getResponse() - { - return $this->soapResponse; - } - private function getWebServiceContext($webservice) { - if(!$this->container->has('besimple.soap.context.'.$webservice)) - { + if (!$this->container->has('besimple.soap.context.'.$webservice)) { throw new NotFoundHttpException(sprintf('No webservice with name "%s" found.', $webservice)); } + return $this->container->get('besimple.soap.context.'.$webservice); } } diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index e6a271f..e7ca025 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -28,7 +28,7 @@ class BeSimpleSoapExtension extends Extension // maps config options to service suffix private $bindingConfigToServiceSuffixMap = array( 'rpc-literal' => 'rpcliteral', - 'document-wrapped' => 'documentwrapped' + 'document-wrapped' => 'documentwrapped', ); public function load(array $configs, ContainerBuilder $container) @@ -60,8 +60,8 @@ class BeSimpleSoapExtension extends Extension $options = $container ->getDefinition('besimple.soap.context.'.$bindingSuffix) - ->getArgument(6); + ->getArgument(7); - $definition->replaceArgument(6, array_merge($options, $config)); + $definition->replaceArgument(7, array_merge($options, $config)); } } diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 3dfa981..0722411 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -6,6 +6,7 @@ BeSimple\SoapBundle\WebServiceContext %kernel.cache_dir%/webservice + BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestHeaderMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder @@ -19,6 +20,7 @@ + @@ -32,6 +34,7 @@ + @@ -42,6 +45,7 @@ + diff --git a/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php b/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php new file mode 100644 index 0000000..15fcf0c --- /dev/null +++ b/ServiceBinding/RpcLiteralRequestHeaderMessageBinder.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\ServiceBinding; + +use BeSimple\SoapBundle\ServiceDefinition\Method; + +/** + * @author Francis Besset + */ +class RpcLiteralRequestHeaderMessageBinder extends RpcLiteralRequestMessageBinder +{ + private $header; + + public function setHeader($header) + { + $this->header = $header; + } + + public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) + { + $headerDefinition = $messageDefinition->getHeaders()->get($this->header); + + return $this->processType($headerDefinition->getType()->getPhpType(), $message, $definitionComplexTypes); + } +} \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 2d3c32d..58ac675 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -38,7 +38,7 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface return $result; } - private function processType($phpType, $message, array $definitionComplexTypes) + protected function processType($phpType, $message, array $definitionComplexTypes) { if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index e359c55..01c4ebd 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -25,6 +25,11 @@ class ServiceBinder */ private $definition; + /** + * @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface + */ + private $requestHeaderMessageBinder; + /** * @var \BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface */ @@ -35,32 +40,39 @@ class ServiceBinder */ private $responseMessageBinder; - public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) { - $this->definition = $definition; - $this->requestMessageBinder = $requestMessageBinder; + public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) { + $this->definition = $definition; + + $this->requestHeaderMessageBinder = $requestHeaderMessageBinder; + $this->requestMessageBinder = $requestMessageBinder; + $this->responseMessageBinder = $responseMessageBinder; } - public function isServiceHeader($name) + public function isServiceHeader($method, $header) { - return $this->definition->getHeaders()->has($name); + return $this->definition->getMethods()->get($method)->getHeaders()->has($header); } - public function isServiceMethod($name) + public function isServiceMethod($method) { - return $this->definition->getMethods()->has($name); + return $this->definition->getMethods()->has($method); } - public function processServiceHeader($name, $data) + public function processServiceHeader($method, $header, $data) { - $headerDefinition = $this->definition->getHeaders()->get($name); + $methodDefinition = $this->definition->getMethods()->get($method); + $headerDefinition = $methodDefinition->getHeaders()->get($header); + + $this->requestHeaderMessageBinder->setHeader($header); + $data = $this->requestHeaderMessageBinder->processMessage($methodDefinition, $data, $this->definition->getDefinitionComplexTypes()); return $this->createSoapHeader($headerDefinition, $data); } - public function processServiceMethodArguments($name, $arguments) + public function processServiceMethodArguments($method, $arguments) { - $methodDefinition = $this->definition->getMethods()->get($name); + $methodDefinition = $this->definition->getMethods()->get($method); return array_merge( array('_controller' => $methodDefinition->getController()), @@ -79,6 +91,6 @@ class ServiceBinder { $qname = QName::fromPackedQName($headerDefinition->getType()->getXmlType()); - return new SoapHeader($qname->getNamespace(), $qname->getName(), $data); + return new SoapHeader($qname->getNamespace(), $headerDefinition->getName(), $data); } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/Header.php b/ServiceDefinition/Annotation/Header.php new file mode 100644 index 0000000..f6ed406 --- /dev/null +++ b/ServiceDefinition/Annotation/Header.php @@ -0,0 +1,22 @@ + + * + * 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 Header extends Param +{ + public function getAliasName() + { + return 'header'; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Dumper/Wsdl.php b/ServiceDefinition/Dumper/Wsdl.php new file mode 100644 index 0000000..4410f9a --- /dev/null +++ b/ServiceDefinition/Dumper/Wsdl.php @@ -0,0 +1,37 @@ + + * + * 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 Zend\Soap\Wsdl as BaseWsdl; + +/** + * @author Francis Besset + */ +class Wsdl extends BaseWsdl +{ + 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; + } +} \ No newline at end of file diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 7c07064..8ac4d87 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -17,8 +17,6 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use BeSimple\SoapBundle\Util\Assert; use BeSimple\SoapBundle\Util\QName; -use Zend\Soap\Wsdl; - /** * @author Christian Kerl */ @@ -48,8 +46,13 @@ class WsdlDumper implements DumperInterface $this->wsdl->addService($this->getServiceName(), $this->getPortName(), $this->qualify($this->getBindingName()), $options['endpoint']); foreach ($definition->getMethods() as $method) { - $requestParts = array(); - $responseParts = array(); + $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()); @@ -59,26 +62,38 @@ class WsdlDumper implements DumperInterface $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))); + $portOperation = $this->wsdl->addPortOperation( + $port, + $method->getName(), + $this->qualify($this->getRequestMessageName($method)), + $this->qualify($this->getResponseMessageName($method)) + ); $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); - $bindingInput = array( - 'parts' => implode(' ', array_keys($requestParts)), - 'use' => 'literal', - 'namespace' => $definition->getNamespace(), - 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', - ); - $bindingOutput = array( - 'parts' => implode(' ', array_keys($responseParts)), + $baseBinding = array( 'use' => 'literal', 'namespace' => $definition->getNamespace(), 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/', ); - $bindingOperation = $this->wsdl->addBindingOperation($binding, $method->getName(), $bindingInput, $bindingOutput); + $bindingOperation = $this->wsdl->addBindingOperation( + $binding, + $method->getName(), + array_merge(array('parts' => implode(' ', array_keys($requestParts))), $baseBinding), + array_merge(array('parts' => implode(' ', array_keys($responseParts))), $baseBinding) + ); + $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)); } @@ -125,6 +140,11 @@ class WsdlDumper implements DumperInterface return $this->definition->getName().'Service'; } + protected function getRequestHeaderMessageName(Method $method) + { + return $method->getName().'Header'; + } + protected function getRequestMessageName(Method $method) { return $method->getName().'Request'; diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 77aa131..62610e8 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -16,7 +16,7 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\ComplexType; use BeSimple\SoapBundle\Util\String; use Zend\Soap\Exception; -use Zend\Soap\Wsdl; +use Zend\Soap\Wsdl as BaseWsdl; use Zend\Soap\Wsdl\Strategy; use Zend\Soap\Wsdl\Strategy\ArrayOfTypeSequence; @@ -46,7 +46,7 @@ class WsdlTypeStrategy implements Strategy * * @param \Zend\Soap\Wsdl $context */ - public function setContext(Wsdl $context) + public function setContext(BaseWsdl $context) { $this->context = $context; diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index b71732f..190e362 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -10,13 +10,8 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Loader; -use BeSimple\SoapBundle\ServiceDefinition\Argument; -use BeSimple\SoapBundle\ServiceDefinition\Method; -use BeSimple\SoapBundle\ServiceDefinition\Type; -use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; -use BeSimple\SoapBundle\ServiceDefinition\Annotation\Method as MethodAnnotation; -use BeSimple\SoapBundle\ServiceDefinition\Annotation\Param as ParamAnnotation; -use BeSimple\SoapBundle\ServiceDefinition\Annotation\Result as ResultAnnotation; +use BeSimple\SoapBundle\ServiceDefinition as Definition; +use BeSimple\SoapBundle\ServiceDefinition\Annotation; use Doctrine\Common\Annotations\Reader; @@ -50,7 +45,7 @@ class AnnotationClassLoader implements LoaderInterface * @param string $class A class name * @param string $type The resource type * - * @return ServiceDefinition A ServiceDefinition instance + * @return \BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition A ServiceDefinition instance * * @throws \InvalidArgumentException When route can't be parsed */ @@ -61,48 +56,57 @@ class AnnotationClassLoader implements LoaderInterface } $class = new \ReflectionClass($class); - $definition = new ServiceDefinition(); + $definition = new Definition\ServiceDefinition(); foreach ($class->getMethods() as $method) { - $serviceArguments = array(); + $serviceArguments = + $serviceHeaders = array(); $serviceMethod = $serviceReturn = null; foreach ($this->reader->getMethodAnnotations($method) as $i => $annotation) { - if ($annotation instanceof ParamAnnotation) { - $serviceArguments[] = new Argument( + if ($annotation instanceof Annotation\Header) { + $serviceHeaders[] = new Definition\Header( $annotation->getValue(), $this->getArgumentType($method, $annotation) ); - } elseif ($annotation instanceof MethodAnnotation) { + } elseif ($annotation instanceof Annotation\Param) { + $serviceArguments[] = new Definition\Argument( + $annotation->getValue(), + $this->getArgumentType($method, $annotation) + ); + } elseif ($annotation instanceof Annotation\Method) { if ($serviceMethod) { - throw new \LogicException(sprintf('@Method defined twice for "%s".', $method->getName())); + throw new \LogicException(sprintf('@Soap\Method defined twice for "%s".', $method->getName())); } - $serviceMethod = new Method( + $serviceMethod = new Definition\Method( $annotation->getValue(), $this->getController($method, $annotation) ); - } elseif ($annotation instanceof ResultAnnotation) { + } elseif ($annotation instanceof Annotation\Result) { if ($serviceReturn) { - throw new \LogicException(sprintf('@Result defined twice for "%s".', $method->getName())); + throw new \LogicException(sprintf('@Soap\Result defined twice for "%s".', $method->getName())); } - $serviceReturn = new Type($annotation->getPhpType(), $annotation->getXmlType()); + $serviceReturn = new Definition\Type($annotation->getPhpType(), $annotation->getXmlType()); } } if (!$serviceMethod && (!empty($serviceArguments) || $serviceReturn)) { - throw new \LogicException(sprintf('@Method non-existent for "%s".', $method->getName())); + throw new \LogicException(sprintf('@Soap\Method non-existent for "%s".', $method->getName())); } if ($serviceMethod) { $serviceMethod->setArguments($serviceArguments); + $serviceMethod->setHeaders($serviceHeaders); - if ($serviceReturn) { - $serviceMethod->setReturn($serviceReturn); + if (!$serviceReturn) { + throw new \LogicException(sprintf('@Soap\Result non-existent for "%s".', $method->getName())); } + $serviceMethod->setReturn($serviceReturn); + $definition->getMethods()->add($serviceMethod); } } @@ -110,7 +114,13 @@ class AnnotationClassLoader implements LoaderInterface return $definition; } - private function getController(\ReflectionMethod $method, MethodAnnotation $annotation) + /** + * @param \ReflectionMethod $method + * @param \BeSimple\SoapBundle\ServiceDefinition\Annotation\Method $annotation + * + * @return string + */ + private function getController(\ReflectionMethod $method, Annotation\Method $annotation) { if(null !== $annotation->getService()) { return $annotation->getService() . ':' . $method->name; @@ -121,11 +131,11 @@ class AnnotationClassLoader implements LoaderInterface /** * @param \ReflectionMethod $method - * @param ParamAnnotation $annotation + * @param \BeSimple\SoapBundle\ServiceDefinition\Annotation\Param $annotation * * @return \BeSimple\SoapBundle\ServiceDefinition\Type */ - private function getArgumentType(\ReflectionMethod $method, ParamAnnotation $annotation) + private function getArgumentType(\ReflectionMethod $method, Annotation\Param $annotation) { $phpType = $annotation->getPhpType(); $xmlType = $annotation->getXmlType(); @@ -140,7 +150,7 @@ class AnnotationClassLoader implements LoaderInterface } } - return new Type($phpType, $xmlType); + return new Definition\Type($phpType, $xmlType); } /** diff --git a/ServiceDefinition/Method.php b/ServiceDefinition/Method.php index 14e1efa..a03053f 100644 --- a/ServiceDefinition/Method.php +++ b/ServiceDefinition/Method.php @@ -17,12 +17,14 @@ class Method private $name; private $controller; private $arguments; + private $headers; private $return; - public function __construct($name = null, $controller = null, array $arguments = array(), Type $return = null) + public function __construct($name = null, $controller = null, array $headers = array(), array $arguments = array(), Type $return = null) { $this->setName($name); $this->setController($controller); + $this->setHeaders($headers); $this->setArguments($arguments); if ($return) { @@ -50,6 +52,17 @@ class Method $this->controller = $controller; } + 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; diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index 683de74..adfd50b 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -29,23 +29,16 @@ class ServiceDefinition */ private $methods; - /** - * @var \BeSimple\SoapBundle\Util\Collection - */ - private $headers; - private $complexTypes = array(); - public function __construct($name = null, $namespace = null, array $methods = array(), array $headers = array()) + public function __construct($name = null, $namespace = null, array $methods = array()) { $this->setName($name); $this->setNamespace($namespace); $this->methods = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Method'); - $this->headers = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Header'); $this->setMethods($methods); - $this->setHeaders($headers); } /** @@ -96,22 +89,6 @@ class ServiceDefinition $this->methods->addAll($methods); } - /** - * @return \BeSimple\SoapBundle\Util\Collection - */ - public function getHeaders() - { - return $this->headers; - } - - /** - * @param array $headers - */ - public function setHeaders(array $headers) - { - $this->headers->addAll($headers); - } - /** * @return array */ @@ -119,11 +96,15 @@ class ServiceDefinition { $types = array(); - foreach($this->methods as $method) { - foreach($method->getArguments() as $argument) { + foreach ($this->methods as $method) { + foreach ($method->getArguments() as $argument) { $types[] = $argument->getType(); } + foreach ($method->getHeaders() as $header) { + $types[] = $header->getType(); + } + $types[] = $method->getReturn(); } diff --git a/WebServiceContext.php b/WebServiceContext.php index f0acaf6..c676a45 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -27,6 +27,7 @@ use Symfony\Component\Config\Loader\LoaderInterface; */ class WebServiceContext { + private $requestHeaderMessageBinder; private $requestMessageBinder; private $responseMessageBinder; private $typeRepository; @@ -40,12 +41,13 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { $this->loader = $loader; $this->wsdlFileDumper = $dumper; - $this->requestMessageBinder = $requestMessageBinder; - $this->responseMessageBinder = $responseMessageBinder; + $this->requestHeaderMessageBinder = $requestHeaderMessageBinder; + $this->requestMessageBinder = $requestMessageBinder; + $this->responseMessageBinder = $responseMessageBinder; $this->typeRepository = $typeRepository; $this->converterRepository = $converterRepository; @@ -90,7 +92,7 @@ class WebServiceContext public function getServiceBinder() { if (null === $this->serviceBinder) { - $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestMessageBinder, $this->responseMessageBinder); + $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestHeaderMessageBinder, $this->requestMessageBinder, $this->responseMessageBinder); } return $this->serviceBinder; From d3a8965500d3ccf9ec8c6e6671ab238e871d6b8b Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 18:13:12 +0200 Subject: [PATCH 092/195] [Doc] Updated array tutorial --- Resources/doc/tutorial/array.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/doc/tutorial/array.rst b/Resources/doc/tutorial/array.rst index 32b28ff..7972624 100644 --- a/Resources/doc/tutorial/array.rst +++ b/Resources/doc/tutorial/array.rst @@ -15,12 +15,12 @@ Controller class DemoController extends ContainerAware { /** - * @Soap\Method("isString") - * @Soap\Param("strings", phpType = "string[]") - * @Soap\Result(phpType = "boolean") + * @Soap\Method("hello") + * @Soap\Param("names", phpType = "string[]") + * @Soap\Result(phpType = "string") */ - public function helloAction(array $strings) + public function helloAction(array $names) { - return new SoapResponse(true); + return new SoapResponse("Hello ".implode(', ', $names)); } } \ No newline at end of file From edf2f9f0119f2f1473384b4eeea69aca72603387 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 18:25:32 +0200 Subject: [PATCH 093/195] [Doc] Added header tutorial --- Resources/doc/index.rst | 1 + Resources/doc/tutorial/header.rst | 32 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Resources/doc/tutorial/header.rst diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index 07ac795..f7ca83b 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -23,5 +23,6 @@ Tutorial tutorial/array tutorial/complex_type + tutorial/header .. _`ckWebServicePlugin`: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/tutorial/header.rst new file mode 100644 index 0000000..b71bd89 --- /dev/null +++ b/Resources/doc/tutorial/header.rst @@ -0,0 +1,32 @@ +Header +====== + +Controller +---------- + +.. code-block:: php + + namespace My\App\Controller; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use BeSimple\SoapBundle\Soap\SoapResponse; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware + { + /** + * @Soap\Method("hello") + * @Soap\Header("api_key", phpType = "string") + * @Soap\Param("names", phpType = "string[]") + * @Soap\Result(phpType = "string") + */ + public function helloAction(array $names) + { + $soapHeaders = $this->container->get('request')->getSoapHeaders(); + if (!$soapHeaders->has('api_key') || '1234' !== $soapHeaders->get('api_key')->getData()) { + throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); + } + + return new SoapResponse("Hello ".implode(', ', $names)); + } + } \ No newline at end of file From 33165ce8d21990925fef8cf301ba695af8cc554e Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 21:06:04 +0200 Subject: [PATCH 094/195] Refactored the declaration of services for ServiceBinder --- DependencyInjection/BeSimpleSoapExtension.php | 4 ++-- Resources/config/webservice.xml | 16 ++++------------ WebServiceContext.php | 13 ++++++------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index e6a271f..faeb6bf 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -60,8 +60,8 @@ class BeSimpleSoapExtension extends Extension $options = $container ->getDefinition('besimple.soap.context.'.$bindingSuffix) - ->getArgument(6); + ->getArgument(4); - $definition->replaceArgument(6, array_merge($options, $config)); + $definition->replaceArgument(4, array_merge($options, $config)); } } diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 3dfa981..5b7798f 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -19,37 +19,29 @@ - - %besimple.soap.cache_dir% %kernel.debug% + %besimple.soap.binder.request.rpcliteral.class% + %besimple.soap.binder.response.rpcliteral.class% - - %besimple.soap.cache_dir% %kernel.debug% + %besimple.soap.binder.request.documentwrapped.class% + %besimple.soap.binder.response.documentwrapped.class% - - - - - - - - diff --git a/WebServiceContext.php b/WebServiceContext.php index f0acaf6..7303809 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -27,8 +27,6 @@ use Symfony\Component\Config\Loader\LoaderInterface; */ class WebServiceContext { - private $requestMessageBinder; - private $responseMessageBinder; private $typeRepository; private $converterRepository; @@ -40,13 +38,10 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { $this->loader = $loader; $this->wsdlFileDumper = $dumper; - $this->requestMessageBinder = $requestMessageBinder; - $this->responseMessageBinder = $responseMessageBinder; - $this->typeRepository = $typeRepository; $this->converterRepository = $converterRepository; @@ -90,7 +85,11 @@ class WebServiceContext public function getServiceBinder() { if (null === $this->serviceBinder) { - $this->serviceBinder = new ServiceBinder($this->getServiceDefinition(), $this->requestMessageBinder, $this->responseMessageBinder); + $this->serviceBinder = new ServiceBinder( + $this->getServiceDefinition(), + new $this->options['binder_request_class'](), + new $this->options['binder_response_class']() + ); } return $this->serviceBinder; From 7fd56b657c6b4d630490f8b6977c90949275cde9 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 21:10:21 +0200 Subject: [PATCH 095/195] Fixed tests --- .../RpcLiteralRequestMessageBinderTest.php | 16 ++++++++-------- .../RpcLiteralResponseMessageBinderTest.php | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index 0eb1997..befb786 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -44,7 +44,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array( + new Method('complextype_argument', null, array(), array( new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), )), array($attributes), @@ -67,7 +67,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array( + new Method('complextype_argument', null, array(), array( new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), )), array($message), @@ -90,7 +90,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_methods', null, array( + new Method('complextype_methods', null, array(), array( new Argument('setters', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), )), array($methods), @@ -115,7 +115,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_complextype', null, array( + new Method('complextype_complextype', null, array(), array( new Argument('complex_type', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), )), array($complexType), @@ -153,7 +153,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextypes_references', null, array( + new Method('complextypes_references', null, array(), array( new Argument('complex_types', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType[]')), )), array($complexTypes), @@ -178,7 +178,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase ); $messages[] = array( - new Method('string_argument', null, array( + new Method('string_argument', null, array(), array( new Argument('foo', new Type('string')), )), array('bar'), @@ -186,7 +186,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase ); $messages[] = array( - new Method('string_int_arguments', null, array( + new Method('string_int_arguments', null, array(), array( new Argument('foo', new Type('string')), new Argument('bar', new Type('int')), )), @@ -197,7 +197,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $strings = new \stdClass(); $strings->item = array('foo', 'bar', 'barfoo'); $messages[] = array( - new Method('array_string_arguments', null, array( + new Method('array_string_arguments', null, array(), array( new Argument('foo', new Type('string[]')), new Argument('bar', new Type('int')), )), diff --git a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php index bc6129f..9da41e8 100644 --- a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php @@ -47,7 +47,7 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $attributes->bar = 20349; $messageBinder = new RpcLiteralResponseMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), + new Method('complextype', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), $attributes, $definitionComplexTypes ); @@ -65,7 +65,7 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $message = array($attributes1, $attributes2); $messageBinder = new RpcLiteralResponseMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), + new Method('complextype_argument', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), $message, $definitionComplexTypes ); @@ -89,7 +89,7 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralResponseMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_methods', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), + new Method('complextype_methods', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), $setters, $this->getDefinitionComplexTypes() ); @@ -115,7 +115,7 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $messageBinder = new RpcLiteralResponseMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_complextype', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), + new Method('complextype_complextype', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), $complexType, $this->getDefinitionComplexTypes() ); @@ -140,7 +140,7 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $message = array($attributes, $attributes); $messageBinder = new RpcLiteralResponseMessageBinder(); $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), + new Method('complextype_argument', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), $message, $this->getDefinitionComplexTypes() ); @@ -154,13 +154,13 @@ class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase $messages = array(); $messages[] = array( - new Method('boolean', null, array(), new Type('boolean')), + new Method('boolean', null, array(), array(), new Type('boolean')), true, true, ); $messages[] = array( - new Method('strings', null, array(), new Type('string[]')), + new Method('strings', null, array(), array(), new Type('string[]')), array('hello', 'world'), array('hello', 'world'), ); From 0e177bd067184dd01422e54531aa2ab61e5f5ee0 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 14 Aug 2011 21:59:03 +0200 Subject: [PATCH 096/195] Moved stylesheet option in WsdlDumper service and add the possibility to configure --- DependencyInjection/BeSimpleSoapExtension.php | 2 ++ DependencyInjection/Configuration.php | 25 +++++++++++++++++-- Resources/config/webservice.xml | 3 +++ ServiceDefinition/Dumper/DumperInterface.php | 2 +- ServiceDefinition/Dumper/WsdlDumper.php | 17 +++++++------ WebServiceContext.php | 2 +- 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index faeb6bf..15a92d1 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -43,6 +43,8 @@ class BeSimpleSoapExtension extends Extension $config = $processor->process($configuration->getConfigTree(), $configs); + $container->setParameter('besimple.soap.definition.dumper.options.stylesheet', $config['wsdl_dumper']['stylesheet']); + foreach($config['services'] as $name => $serviceConfig) { $serviceConfig['name'] = $name; $this->createWebServiceContext($serviceConfig, $container); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ded0ae1..0f538cc 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -10,6 +10,7 @@ namespace BeSimple\SoapBundle\DependencyInjection; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; /** @@ -27,8 +28,16 @@ class Configuration public function getConfigTree() { $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('web_service'); + $rootNode = $treeBuilder->root('be_simple_soap'); + $this->addServicesSection($rootNode); + $this->addWsdlDumperSection($rootNode); + + return $treeBuilder->buildTree(); + } + + private function addServicesSection(ArrayNodeDefinition $rootNode) + { $rootNode ->children() ->arrayNode('services') @@ -55,7 +64,19 @@ class Configuration ->end() ->end() ; + } - return $treeBuilder->buildTree(); + private function addWsdlDumperSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('wsdl_dumper') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('stylesheet')->defaultNull() + ->end() + ->end() + ->end() + ; } } \ No newline at end of file diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 5b7798f..b4e0b24 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -44,6 +44,9 @@ + + %besimple.soap.definition.dumper.options.stylesheet% + diff --git a/ServiceDefinition/Dumper/DumperInterface.php b/ServiceDefinition/Dumper/DumperInterface.php index e1dcb11..3b8b257 100644 --- a/ServiceDefinition/Dumper/DumperInterface.php +++ b/ServiceDefinition/Dumper/DumperInterface.php @@ -14,5 +14,5 @@ use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; interface DumperInterface { - function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()); + function dumpServiceDefinition(ServiceDefinition $definition, $endpoint); } \ No newline at end of file diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 7c07064..4653923 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -25,27 +25,28 @@ use Zend\Soap\Wsdl; class WsdlDumper implements DumperInterface { private $loader; + private $options; + private $wsdl; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader) + public function __construct(AnnotationComplexTypeLoader $loader, array $options) { - $this->loader = $loader; + $this->loader = $loader; + $this->options = $options; } - public function dumpServiceDefinition(ServiceDefinition $definition, array $options = array()) + public function dumpServiceDefinition(ServiceDefinition $definition, $endpoint) { Assert::thatArgumentNotNull('definition', $definition); - $options = array_merge(array('endpoint' => '', 'stylesheet' => null), $options); - $this->definition = $definition; $this->wsdl = new Wsdl($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()), $options['endpoint']); + $this->wsdl->addService($this->getServiceName(), $this->getPortName(), $this->qualify($this->getBindingName()), $endpoint); foreach ($definition->getMethods() as $method) { $requestParts = array(); @@ -87,8 +88,8 @@ class WsdlDumper implements DumperInterface $dom = $this->wsdl->toDomDocument(); $dom->formatOutput = true; - if (null !== $options['stylesheet']) { - $stylesheet = $dom->createProcessingInstruction('xml-stylesheet', sprintf('type="text/xsl" href="%s"', $options['stylesheet'])); + if ($this->options['stylesheet']) { + $stylesheet = $dom->createProcessingInstruction('xml-stylesheet', sprintf('type="text/xsl" href="%s"', $this->options['stylesheet'])); $dom->insertBefore($stylesheet, $dom->documentElement); } diff --git a/WebServiceContext.php b/WebServiceContext.php index 7303809..531e027 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -76,7 +76,7 @@ class WebServiceContext $cache = new ConfigCache($file, $this->options['debug']); if(!$cache->isFresh()) { - $cache->write($this->wsdlFileDumper->dumpServiceDefinition($this->getServiceDefinition(), array('endpoint' => $endpoint))); + $cache->write($this->wsdlFileDumper->dumpServiceDefinition($this->getServiceDefinition(), $endpoint)); } return (string) $cache; From d38e0c03b756bf194211ef89c84698bc16f01e74 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 16 Aug 2011 20:06:24 +0300 Subject: [PATCH 097/195] Fixed typo in webservice services definition --- Resources/config/webservice.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 045039b..22e5a88 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -25,7 +25,7 @@ %besimple.soap.cache_dir% %kernel.debug% - %%besimple.soap.binder.request_header.rpcliteral.class%% + %besimple.soap.binder.request_header.rpcliteral.class% %besimple.soap.binder.request.rpcliteral.class% %besimple.soap.binder.response.rpcliteral.class% @@ -39,7 +39,7 @@ %besimple.soap.cache_dir% %kernel.debug% - %%besimple.soap.binder.request_header.documentwrapped.class%% + %besimple.soap.binder.request_header.documentwrapped.class% %besimple.soap.binder.request.documentwrapped.class% %besimple.soap.binder.response.documentwrapped.class% From bf2f88aa056f716606d3a636df10f46e8082e95c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 16 Aug 2011 21:18:44 +0300 Subject: [PATCH 098/195] Added message exception if the "setter" is not specified to hydrate a complex type. --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 58ac675..cb4f5c6 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -84,7 +84,7 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $instanceType->{$type->getOriginalName()} = $value; } elseif ($type instanceof MethodComplexType) { if (!$type->getSetter()) { - throw new \LogicException(); + throw new \LogicException(sprintf('"setter" option must be specified to hydrate "%s::%s()"', $phpType, $type->getOriginalName())); } $instanceType->{$type->getSetter()}($value); From 0368461b1211c79cb9c12ede2e1f525da91b9aa4 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 16 Aug 2011 20:41:14 +0200 Subject: [PATCH 099/195] Fixed typo --- Resources/config/webservice.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 22e5a88..999af0d 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -10,6 +10,7 @@ BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder + BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestHeaderMessageBinder BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper BeSimple\SoapBundle\Converter\ConverterRepository From 9f7ff62449c10cb00c11530fc6506362ad89300e Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 16 Aug 2011 21:06:10 +0200 Subject: [PATCH 100/195] Check if a value is null in RpcLiteralRequestMessageBinder --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index cb4f5c6..4d215b4 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -80,6 +80,10 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface foreach ($definitionComplexTypes[$phpType] as $type) { $value = $this->processType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); + if (null === $value && $type->isNillable()) { + continue; + } + if ($type instanceof PropertyComplexType) { $instanceType->{$type->getOriginalName()} = $value; } elseif ($type instanceof MethodComplexType) { From c154463b33a0391937a2c586892f6faf20a4c47f Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 24 Aug 2011 23:36:49 +0200 Subject: [PATCH 101/195] Updated definition of ComplexType and use classmap option of SoapServer Please to refer to the documentation for the changes: http://besim.pl/SoapBundle/tutorial/complex_type.html --- Controller/SoapWebServiceController.php | 5 +- Resources/doc/tutorial/complex_type.rst | 78 ++++++------------- .../RpcLiteralRequestMessageBinder.php | 61 +++++++-------- .../RpcLiteralResponseMessageBinder.php | 56 ++++++------- ...ropertyComplexType.php => ComplexType.php} | 4 +- .../Annotation/MethodComplexType.php | 67 ---------------- .../BaseComplexType.php => ComplexType.php} | 15 +--- .../Loader/AnnotationComplexTypeLoader.php | 54 +++---------- .../Strategy/MethodComplexType.php | 29 ------- .../Strategy/PropertyComplexType.php | 18 ----- Soap/SoapServerFactory.php | 14 +++- WebServiceContext.php | 7 +- 12 files changed, 117 insertions(+), 291 deletions(-) rename ServiceDefinition/Annotation/{PropertyComplexType.php => ComplexType.php} (91%) delete mode 100644 ServiceDefinition/Annotation/MethodComplexType.php rename ServiceDefinition/{Strategy/BaseComplexType.php => ComplexType.php} (72%) delete mode 100644 ServiceDefinition/Strategy/MethodComplexType.php delete mode 100644 ServiceDefinition/Strategy/PropertyComplexType.php diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 0a57bfb..4d6f315 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -53,10 +53,13 @@ class SoapWebServiceController extends ContainerAware */ public function callAction($webservice) { - $webServiceContext = $this->getWebServiceContext($webservice); + $webServiceContext = $this->getWebServiceContext($webservice); + $this->serviceBinder = $webServiceContext->getServiceBinder(); + //$this->serviceBinder->fixXmlRequestContent(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); + //$this->soapRequest->setContent($this->serviceBinder->fixXmlRequestContent($this->soapRequest->getContent())); $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); $this->soapServer->setObject($this); diff --git a/Resources/doc/tutorial/complex_type.rst b/Resources/doc/tutorial/complex_type.rst index de60eb8..edf03cd 100644 --- a/Resources/doc/tutorial/complex_type.rst +++ b/Resources/doc/tutorial/complex_type.rst @@ -23,14 +23,13 @@ Controller /** * @Soap\Method("getUser") * @Soap\Param("name", phpType = "string") - * - * Specify \My\App\Entity\User phpType - * Warning: Do not forget the first backslash - * @Soap\Result(phpType = "\My\App\Entity\User") + * @Soap\Result(phpType = "My\App\Entity\User") */ public function getUserAction($name) { - $user = $this->container->getDoctrine()->getRepository('MyApp:User')->findOneByName($name); + $user = $this->container->getDoctrine()->getRepository('MyApp:User')->findOneBy(array( + 'name' => $name, + ); if (!$user) { throw new \SoapFault('USER_NOT_FOUND', sprintf('The user with the name "%s" can not be found', $name)); @@ -43,7 +42,7 @@ Controller User class ---------- -You can expose public property and public method (getter and setter). +You can expose only the properties (public, protected or private) of a complex type. .. code-block:: php @@ -54,67 +53,34 @@ You can expose public property and public method (getter and setter). class User { /** - * @Soap\PropertyComplexType("string") + * @Soap\ComplexType("string") */ public $firstname; /** - * @Soap\PropertyComplexType("string") + * @Soap\ComplexType("string") */ public $lastname; + /** + * @Soap\ComplexType("int", nillable=true) + */ private $id; + + /** + * @Soap\ComplexType("string") + */ private $username; + + /** + * @Soap\ComplexType("string") + */ private $email; - - /** - * @Soap\MethodComplexType("int", name="user_id", nillable=true) - */ - public function getId() - { - return $this->id; - } - - /** - * @Soap\MethodComplexType("string", setter="setUsername") - */ - public function getUsername() - { - return $this->username; - } - - /** - * @Soap\MethodComplexType("string", setter="setEmail") - */ - public function getEmail() - { - return $this->email; - } - - public function setUsername($username) - { - $this->username = $username; - } - - public function setEmail($email) - { - $this->email = $email; - } } -PropertyComplexType -------------------- +ComplexType +----------- -`PropertyComplexType` accepts the following options: +`ComplexType` accepts the following options: - * **name**: To override the original name of the property - * **nillable**: To specify that the value can be null - -MethodComplexType -------------------- - -`MethodComplexType` accepts the following options: - - * **name**: To override the original name of the property - * **nillable**: To specify that the value can be null - * **setter**: The set method name value. *Mandatory if the complex type is passed as a parameter to a function.* \ No newline at end of file + * nillable: To specify that the value can be null \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 4d215b4..557ff4b 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -14,6 +14,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; +use Zend\Soap\Wsdl; + /** * @author Christian Kerl * @author Francis Besset @@ -21,15 +23,18 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; class RpcLiteralRequestMessageBinder implements MessageBinderInterface { private $messageRefs = array(); + private $definitionComplexTypes; 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], $definitionComplexTypes); + $result[$argument->getName()] = $this->processType($argument->getType()->getPhpType(), $message[$i]); } $i++; @@ -38,27 +43,27 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface return $result; } - protected function processType($phpType, $message, array $definitionComplexTypes) + protected function processType($phpType, $message) { + $isArray = false; + if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; - $type = $match[1]; - } else { - $isArray = false; - $type = $phpType; + $phpType = $match[1]; } - if (isset($definitionComplexTypes[$type])) { + // @TODO Fix array reference + if (isset($this->definitionComplexTypes[$phpType])) { if ($isArray) { $array = array(); foreach ($message->item as $complexType) { - $array[] = $this->getInstanceOfType($type, $complexType, $definitionComplexTypes); + $array[] = $this->checkComplexType($phpType, $complexType); } $message = $array; } else { - $message = $this->getInstanceOfType($type, $message, $definitionComplexTypes); + $message = $this->checkComplexType($phpType, $message); } } elseif ($isArray) { $message = $message->item; @@ -67,36 +72,30 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface return $message; } - private function getInstanceOfType($phpType, $message, array $definitionComplexTypes) + protected function checkComplexType($phpType, $message) { $hash = spl_object_hash($message); if (isset($this->messageRefs[$hash])) { - return $this->messageRefs[$hash]; + return $message; } - $this->messageRefs[$hash] = - $instanceType = new $phpType(); - - foreach ($definitionComplexTypes[$phpType] as $type) { - $value = $this->processType($type->getValue(), $message->{$type->getName()}, $definitionComplexTypes); - - if (null === $value && $type->isNillable()) { - continue; - } - - if ($type instanceof PropertyComplexType) { - $instanceType->{$type->getOriginalName()} = $value; - } elseif ($type instanceof MethodComplexType) { - if (!$type->getSetter()) { - throw new \LogicException(sprintf('"setter" option must be specified to hydrate "%s::%s()"', $phpType, $type->getOriginalName())); - } - - $instanceType->{$type->getSetter()}($value); + $r = new \ReflectionClass($message); + foreach ($this->definitionComplexTypes[$phpType] as $type) { + $p = $r->getProperty($type->getName()); + if ($p->isPublic()) { + $value = $message->{$type->getName()}; } else { - throw new \InvalidArgumentException(); + $p->setAccessible(true); + $value = $p->getValue($message); + } + + $value = $this->processType($type->getValue(), $value); + + if (!$type->isNillable() && null === $value) { + throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst(Wsdl::translateType($phpType)), $type->getName())); } } - return $instanceType; + return $this->messageRefs[$hash] = $message; } } \ No newline at end of file diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index fcf5f77..2a9c8cb 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -14,6 +14,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +use Zend\Soap\Wsdl; + /** * @author Christian Kerl * @author Francis Besset @@ -21,45 +23,42 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; class RpcLiteralResponseMessageBinder implements MessageBinderInterface { private $messageRefs = array(); + private $definitionComplexTypes; public function processMessage(Method $messageDefinition, $message, array $definitionComplexTypes = array()) { - $return = $messageDefinition->getReturn(); - $class = $return->getPhpType(); + $this->definitionComplexTypes = $definitionComplexTypes; - $message = $this->processType($messageDefinition->getReturn()->getPhpType(), $message, $definitionComplexTypes); - - return $message; + return $this->processType($messageDefinition->getReturn()->getPhpType(), $message); } - private function processType($phpType, $message, array $definitionComplexTypes) + private function processType($phpType, $message) { + $isArray = false; + if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; - $type = $match[1]; - } else { - $isArray = false; - $type = $phpType; + $phpType = $match[1]; } - if (isset($definitionComplexTypes[$type])) { + if (isset($this->definitionComplexTypes[$phpType])) { if ($isArray) { $array = array(); foreach ($message as $complexType) { - $array[] = $this->getInstanceOfStdClass($type, $complexType, $definitionComplexTypes); + $array[] = $this->checkComplexType($phpType, $complexType); } $message = $array; } else { - $message = $this->getInstanceOfStdClass($type, $message, $definitionComplexTypes); + $message = $this->checkComplexType($phpType, $message); } } return $message; } - private function getInstanceOfStdClass($phpType, $message, $definitionComplexTypes) + private function checkComplexType($phpType, $message) { $hash = spl_object_hash($message); if (isset($this->messageRefs[$hash])) { @@ -71,26 +70,27 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $class = substr($class, 1); } - if (get_class($message) !== $class) { - throw new \InvalidArgumentException(); + if (!$message instanceof $class) { + throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', get_class($message), $class)); } - $stdClass = new \stdClass(); - $this->messageRefs[$hash] = $stdClass; - - foreach ($definitionComplexTypes[$phpType] as $type) { - - if ($type instanceof PropertyComplexType) { - $value = $message->{$type->getOriginalName()}; - } elseif ($type instanceof MethodComplexType) { - $value = $message->{$type->getOriginalName()}(); + $r = new \ReflectionClass($message); + foreach ($this->definitionComplexTypes[$class] as $type) { + $p = $r->getProperty($type->getName()); + if ($p->isPublic()) { + $value = $message->{$type->getName()}; } else { - throw new \InvalidArgumentException(); + $p->setAccessible(true); + $value = $p->getValue($message); } - $stdClass->{$type->getName()} = $this->processType($type->getValue(), $value, $definitionComplexTypes); + $value = $this->processType($type->getValue(), $value); + + if (!$type->isNillable() && null === $value) { + throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $class, $type->getName())); + } } - return $stdClass; + return $this->messageRefs[$hash] = $message; } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/PropertyComplexType.php b/ServiceDefinition/Annotation/ComplexType.php similarity index 91% rename from ServiceDefinition/Annotation/PropertyComplexType.php rename to ServiceDefinition/Annotation/ComplexType.php index 6f1f046..85072d4 100644 --- a/ServiceDefinition/Annotation/PropertyComplexType.php +++ b/ServiceDefinition/Annotation/ComplexType.php @@ -13,7 +13,7 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Annotation; /** * @Annotation */ -class PropertyComplexType extends Configuration +class ComplexType extends Configuration { private $name; private $value; @@ -51,6 +51,6 @@ class PropertyComplexType extends Configuration public function getAliasName() { - return 'propertycomplextype'; + return 'complextype'; } } \ No newline at end of file diff --git a/ServiceDefinition/Annotation/MethodComplexType.php b/ServiceDefinition/Annotation/MethodComplexType.php deleted file mode 100644 index cf1cdaf..0000000 --- a/ServiceDefinition/Annotation/MethodComplexType.php +++ /dev/null @@ -1,67 +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\Annotation; - -/** - * @Annotation - */ -class MethodComplexType extends Configuration -{ - private $name; - private $value; - private $setter; - private $isNillable = false; - - public function getName() - { - return $this->name; - } - - public function getValue() - { - return $this->value; - } - - public function getSetter() - { - return $this->setter; - } - - public function isNillable() - { - return $this->isNillable; - } - - public function setName($name) - { - $this->name = $name; - } - - public function setValue($value) - { - $this->value = $value; - } - - public function setSetter($setter) - { - $this->setter = $setter; - } - - public function setNillable($isNillable) - { - $this->isNillable = (bool) $isNillable; - } - - public function getAliasName() - { - return 'methodcomplextype'; - } -} \ No newline at end of file diff --git a/ServiceDefinition/Strategy/BaseComplexType.php b/ServiceDefinition/ComplexType.php similarity index 72% rename from ServiceDefinition/Strategy/BaseComplexType.php rename to ServiceDefinition/ComplexType.php index 917fb57..2d78bbe 100644 --- a/ServiceDefinition/Strategy/BaseComplexType.php +++ b/ServiceDefinition/ComplexType.php @@ -8,15 +8,14 @@ * with this source code in the file LICENSE. */ -namespace BeSimple\SoapBundle\ServiceDefinition\Strategy; +namespace BeSimple\SoapBundle\ServiceDefinition; /** * @author Francis Besset */ -abstract class BaseComplexType +class ComplexType { private $name; - private $originalName; private $value; private $isNillable = false; @@ -25,11 +24,6 @@ abstract class BaseComplexType return $this->name; } - public function getOriginalName() - { - return $this->originalName ?: $this->name; - } - public function getValue() { return $this->value; @@ -45,11 +39,6 @@ abstract class BaseComplexType $this->name = $name; } - public function setOriginalName($originalName) - { - $this->originalName = $originalName; - } - public function setValue($value) { $this->value = $value; diff --git a/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php b/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php index 21c9085..0cc7579 100644 --- a/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php +++ b/ServiceDefinition/Loader/AnnotationComplexTypeLoader.php @@ -10,9 +10,7 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Loader; -use BeSimple\SoapBundle\ServiceDefinition\Annotation\ComplexType; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; +use BeSimple\SoapBundle\ServiceDefinition\ComplexType; use BeSimple\SoapBundle\Util\Collection; /** @@ -24,8 +22,7 @@ use BeSimple\SoapBundle\Util\Collection; */ class AnnotationComplexTypeLoader extends AnnotationClassLoader { - private $propertyComplexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\PropertyComplexType'; - private $methodComplexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\MethodComplexType'; + private $complexTypeClass = 'BeSimple\SoapBundle\ServiceDefinition\Annotation\ComplexType'; /** * Loads a ServiceDefinition from annotations from a class. @@ -44,48 +41,17 @@ class AnnotationComplexTypeLoader extends AnnotationClassLoader } $class = new \ReflectionClass($class); - $collection = new Collection('getName'); + $collection = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\ComplexType'); foreach ($class->getProperties() as $property) { - if ($property->isPublic()) { - $complexType = $this->reader->getPropertyAnnotation($property, $this->propertyComplexTypeClass); + $complexType = $this->reader->getPropertyAnnotation($property, $this->complexTypeClass); - if ($complexType) { - $propertyComplexType = new PropertyComplexType(); - $propertyComplexType->setValue($complexType->getValue()); - $propertyComplexType->setNillable($complexType->isNillable()); - - if (!$complexType->getName()) { - $propertyComplexType->setName($property->getName()); - } else { - $propertyComplexType->setName($complexType->getName()); - $propertyComplexType->setOriginalName($property->getName()); - } - - $collection->add($propertyComplexType); - } - } - } - - foreach ($class->getMethods() as $method) { - if ($method->isPublic()) { - $complexType = $this->reader->getMethodAnnotation($method, $this->methodComplexTypeClass); - - if ($complexType) { - $methodComplexType = new MethodComplexType(); - $methodComplexType->setValue($complexType->getValue()); - $methodComplexType->setSetter($complexType->getSetter()); - $methodComplexType->setNillable($complexType->isNillable()); - - if (!$complexType->getName()) { - $methodComplexType->setName($property->getName()); - } else { - $methodComplexType->setName($complexType->getName()); - $methodComplexType->setOriginalName($method->getName()); - } - - $collection->add($methodComplexType); - } + if ($complexType) { + $propertyComplexType = new ComplexType(); + $propertyComplexType->setValue($complexType->getValue()); + $propertyComplexType->setNillable($complexType->isNillable()); + $propertyComplexType->setName($property->getName()); + $collection->add($propertyComplexType); } } diff --git a/ServiceDefinition/Strategy/MethodComplexType.php b/ServiceDefinition/Strategy/MethodComplexType.php deleted file mode 100644 index 7205ab5..0000000 --- a/ServiceDefinition/Strategy/MethodComplexType.php +++ /dev/null @@ -1,29 +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\Strategy; - -/** - * @author Francis Besset - */ -class MethodComplexType extends BaseComplexType -{ - private $setter; - - public function getSetter() - { - return $this->setter; - } - - public function setSetter($setter) - { - $this->setter = $setter; - } -} \ No newline at end of file diff --git a/ServiceDefinition/Strategy/PropertyComplexType.php b/ServiceDefinition/Strategy/PropertyComplexType.php deleted file mode 100644 index 7545f0e..0000000 --- a/ServiceDefinition/Strategy/PropertyComplexType.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\Strategy; - -/** - * @author Francis Besset - */ -class PropertyComplexType extends BaseComplexType -{ -} \ No newline at end of file diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 1c83499..1e18767 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -11,6 +11,7 @@ namespace BeSimple\SoapBundle\Soap; use BeSimple\SoapBundle\Converter\ConverterRepository; +use Zend\Soap\Wsdl; /** * @author Christian Kerl @@ -25,7 +26,7 @@ class SoapServerFactory public function __construct($wsdlFile, array $classmap, ConverterRepository $converters, $debug = false) { $this->wsdlFile = $wsdlFile; - $this->classmap = $classmap; + $this->classmap = $this->fixSoapServerClassmap($classmap); $this->converters = $converters; $this->debug = $debug; } @@ -62,4 +63,15 @@ class SoapServerFactory return $typemap; } + + private function fixSoapServerClassmap($classmap) + { + $classmapFixed = array(); + + foreach ($classmap as $class => $definition) { + $classmapFixed[Wsdl::translateType($class)] = $class; + } + + return $classmapFixed; + } } \ No newline at end of file diff --git a/WebServiceContext.php b/WebServiceContext.php index 4728d1b..ccf1ad9 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -99,7 +99,12 @@ class WebServiceContext public function getServerFactory() { if (null === $this->serverFactory) { - $this->serverFactory = new SoapServerFactory($this->getWsdlFile(), array(), $this->converterRepository, $this->options['debug']); + $this->serverFactory = new SoapServerFactory( + $this->getWsdlFile(), + $this->serviceDefinition->getDefinitionComplexTypes(), + $this->converterRepository, + $this->options['debug'] + ); } return $this->serverFactory; From 2dd65d2acaf808da5a87be080b25d436c633590a Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 17:23:24 +0200 Subject: [PATCH 102/195] fixed fixture path in unit test --- Tests/Soap/SoapRequestTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Soap/SoapRequestTest.php b/Tests/Soap/SoapRequestTest.php index 53375a2..f95b034 100644 --- a/Tests/Soap/SoapRequestTest.php +++ b/Tests/Soap/SoapRequestTest.php @@ -40,6 +40,6 @@ class SoapRequestTest extends \PHPUnit_Framework_TestCase private function loadRequestContentFixture($name) { - return file_get_contents(__DIR__.'/../Fixtures/Soap/'.$name); + return file_get_contents(__DIR__.'/../fixtures/Soap/'.$name); } } From a256288a23b127071d50276c135e6a4f4854a6e7 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 18:00:56 +0200 Subject: [PATCH 103/195] removed unused method --- Converter/ConverterRepository.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php index 3a3e1f6..a3d9392 100644 --- a/Converter/ConverterRepository.php +++ b/Converter/ConverterRepository.php @@ -28,8 +28,4 @@ class ConverterRepository { return $this->typeConverters; } - - public function registerTypeConverterServices(ContainerInterface $container) - { - } -} \ No newline at end of file +} From 8bc2d1aa204eac2f0af4b90dd2eb0d3894c95879 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 18:00:31 +0200 Subject: [PATCH 104/195] added TypeConverter for PHP's DateTime to XML's dateTime --- Converter/DateTimeTypeConverter.php | 41 ++++++++++++++++++ Tests/Converter/DateTimeTypeConverterTest.php | 43 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Converter/DateTimeTypeConverter.php create mode 100644 Tests/Converter/DateTimeTypeConverterTest.php diff --git a/Converter/DateTimeTypeConverter.php b/Converter/DateTimeTypeConverter.php new file mode 100644 index 0000000..da84758 --- /dev/null +++ b/Converter/DateTimeTypeConverter.php @@ -0,0 +1,41 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Converter; + +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Util\String; + +/** + * @author Christian Kerl + */ +class DateTimeTypeConverter implements TypeConverterInterface +{ + public function getTypeNamespace() + { + return 'http://www.w3.org/2001/XMLSchema'; + } + + public function getTypeName() + { + return 'dateTime'; + } + + public function convertXmlToPhp(SoapRequest $request, $data) + { + return new \DateTime(strip_tags($data)); + } + + public function convertPhpToXml(SoapResponse $response, $data) + { + return sprintf('%s', $data->format('Y-m-d\TH:i:sP')); + } +} diff --git a/Tests/Converter/DateTimeTypeConverterTest.php b/Tests/Converter/DateTimeTypeConverterTest.php new file mode 100644 index 0000000..197ca3d --- /dev/null +++ b/Tests/Converter/DateTimeTypeConverterTest.php @@ -0,0 +1,43 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Tests\ServiceBinding; + +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Converter\DateTimeTypeConverter; + +/** + * UnitTest for \BeSimple\SoapBundle\Converter\DateTimeTypeConverter. + * + * @author Christian Kerl + */ +class DateTimeTypeConverterTest extends \PHPUnit_Framework_TestCase +{ + public function testConvertXmlToPhp() + { + $converter = new DateTimeTypeConverter(); + $dateXml = '2002-10-10T12:00:00-05:00'; + + $date = $converter->convertXmlToPhp(new SoapRequest(), $dateXml); + + $this->assertEquals(new \DateTime('2002-10-10T12:00:00-05:00'), $date); + } + + public function testConvertPhpToXml() + { + $converter = new DateTimeTypeConverter(); + $date = new \DateTime('2002-10-10T12:00:00-05:00'); + + $dateXml = $converter->convertPhpToXml(new SoapResponse(), $date); + + $this->assertEquals('2002-10-10T12:00:00-05:00', $dateXml); + } +} From 5d8d7b4ad58b1f4067a38109703654ac3c5e6566 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 18:01:35 +0200 Subject: [PATCH 105/195] added default type mapping from DateTime to xsd:dateTime --- Resources/config/webservice.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index e50cdbc..599af0a 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -76,6 +76,10 @@ float xsd:float + + DateTime + xsd:dateTime + From f62a8bdd67f3c526e8a9e141c2ecc4bfbff8dfe5 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 18:11:29 +0200 Subject: [PATCH 106/195] added compiler pass to register TypeConverter implementations in ConverterRepository --- BeSimpleSoapBundle.php | 2 ++ .../Compiler/TypeConverterPass.php | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 DependencyInjection/Compiler/TypeConverterPass.php diff --git a/BeSimpleSoapBundle.php b/BeSimpleSoapBundle.php index e6c692d..06797a8 100644 --- a/BeSimpleSoapBundle.php +++ b/BeSimpleSoapBundle.php @@ -11,6 +11,7 @@ namespace BeSimple\SoapBundle; use BeSimple\SoapBundle\DependencyInjection\Compiler\WebServiceResolverPass; +use BeSimple\SoapBundle\DependencyInjection\Compiler\TypeConverterPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -27,5 +28,6 @@ class BeSimpleSoapBundle extends Bundle parent::build($container); $container->addCompilerPass(new WebServiceResolverPass()); + $container->addCompilerPass(new TypeConverterPass()); } } diff --git a/DependencyInjection/Compiler/TypeConverterPass.php b/DependencyInjection/Compiler/TypeConverterPass.php new file mode 100644 index 0000000..be97bb6 --- /dev/null +++ b/DependencyInjection/Compiler/TypeConverterPass.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Adds tagged besimple.soap.converter services to besimple.soap.converter.repository service + * + * @author Christian Kerl + */ +class TypeConverterPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('besimple.soap.converter.repository')) { + return; + } + + $definition = $container->getDefinition('besimple.soap.converter.repository'); + + foreach ($container->findTaggedServiceIds('besimple.soap.converter') as $id => $attributes) { + $definition->addMethodCall('addTypeConverter', array(new Reference($id))); + } + } +} From 6290ea268a85952ebae3dd5439a7fa240d742e04 Mon Sep 17 00:00:00 2001 From: Christian Kerl Date: Wed, 24 Aug 2011 18:12:32 +0200 Subject: [PATCH 107/195] created DIC configuration for TypeConverter implementations and ConverterRepository --- DependencyInjection/BeSimpleSoapExtension.php | 1 + Resources/config/converters.xml | 19 +++++++++++++++++++ Resources/config/webservice.xml | 3 --- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 Resources/config/converters.xml diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index db2c8f4..5870366 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -36,6 +36,7 @@ class BeSimpleSoapExtension extends Extension $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('loaders.xml'); + $loader->load('converters.xml'); $loader->load('webservice.xml'); $processor = new Processor(); diff --git a/Resources/config/converters.xml b/Resources/config/converters.xml new file mode 100644 index 0000000..25b7cd1 --- /dev/null +++ b/Resources/config/converters.xml @@ -0,0 +1,19 @@ + + + + + + BeSimple\SoapBundle\Converter\ConverterRepository + BeSimple\SoapBundle\Converter\DateTimeTypeConverter + + + + + + + + + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 599af0a..80ebcb5 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -13,7 +13,6 @@ BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedRequestHeaderMessageBinder BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper - BeSimple\SoapBundle\Converter\ConverterRepository BeSimple\SoapBundle\Converter\TypeRepository @@ -53,8 +52,6 @@ - - xsd From ce5c46408a074e89bd4c768c0b240e2c51231f50 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Fri, 26 Aug 2011 23:39:43 +0200 Subject: [PATCH 108/195] Fixed issue #5 --- Controller/SoapWebServiceController.php | 4 +-- Converter/TypeRepository.php | 37 ++++++------------------- Resources/config/webservice.xml | 5 ++-- ServiceDefinition/Dumper/Wsdl.php | 22 +++++++++++++++ ServiceDefinition/Dumper/WsdlDumper.php | 11 +++++--- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 4d6f315..250d99d 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -56,11 +56,9 @@ class SoapWebServiceController extends ContainerAware $webServiceContext = $this->getWebServiceContext($webservice); $this->serviceBinder = $webServiceContext->getServiceBinder(); - //$this->serviceBinder->fixXmlRequestContent(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); - //$this->soapRequest->setContent($this->serviceBinder->fixXmlRequestContent($this->soapRequest->getContent())); - $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->soapResponse); + $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, new SoapResponse()); $this->soapServer->setObject($this); diff --git a/Converter/TypeRepository.php b/Converter/TypeRepository.php index 2167a49..462dd75 100644 --- a/Converter/TypeRepository.php +++ b/Converter/TypeRepository.php @@ -40,7 +40,12 @@ class TypeRepository Assert::thatArgumentNotNull('phpType', $phpType); Assert::thatArgumentNotNull('xmlType', $xmlType); - $this->defaultTypeMap[$phpType] = $this->getQName($xmlType); + $this->defaultTypeMap[$phpType] = $xmlType; + } + + public function getXmlTypeMapping($phpType) + { + return isset($this->defaultTypeMap[$phpType]) ? $this->defaultTypeMap[$phpType] : null; } public function fixTypeInformation(ServiceDefinition $definition) @@ -56,36 +61,10 @@ class TypeRepository } if (null === $xmlType) { - if (!isset($typeMap[$phpType])) { - $parts = explode('\\', $phpType); - $xmlTypeName = ucfirst(end($parts)); - - if (String::endsWith($phpType, self::ARRAY_SUFFIX)) { - $xmlTypeName = str_replace(self::ARRAY_SUFFIX, 'Array', $xmlTypeName); - } - - $typeMap[$phpType] = new QName($definition->getNamespace(), $xmlTypeName); - } - - $xmlType = $typeMap[$phpType]; - } else { - $xmlType = $this->getQName($xmlType); + $xmlType = $this->getXmlTypeMapping($phpType); } - $type->setXmlType((string) $xmlType); + $type->setXmlType($xmlType); } } - - private function getQName($xmlType) - { - if (QName::isPrefixedQName($xmlType)) { - return QName::fromPrefixedQName($xmlType, array($this, 'getXmlNamespace')); - } else { - return QName::fromPackedQName($xmlType); - } - } - - public function createComplexTypeMap(ServiceDefinition $definition) - { - } } \ No newline at end of file diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 80ebcb5..b1cd5f6 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -47,6 +47,7 @@ + %besimple.soap.definition.dumper.options.stylesheet% @@ -66,7 +67,7 @@ xsd:int - bool + boolean xsd:boolean @@ -74,7 +75,7 @@ xsd:float - DateTime + dateTime xsd:dateTime diff --git a/ServiceDefinition/Dumper/Wsdl.php b/ServiceDefinition/Dumper/Wsdl.php index 4410f9a..eeee674 100644 --- a/ServiceDefinition/Dumper/Wsdl.php +++ b/ServiceDefinition/Dumper/Wsdl.php @@ -10,6 +10,8 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Dumper; +use BeSimple\SoapBundle\Converter\TypeRepository; +use BeSimple\SoapBundle\ServiceDefinition\Type; use Zend\Soap\Wsdl as BaseWsdl; /** @@ -17,6 +19,26 @@ use Zend\Soap\Wsdl as BaseWsdl; */ 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) { + $xmlType = $type->getXmlType(); + } else { + $xmlType = $this->typeRepository->getXmlTypeMapping($type); + } + + return $xmlType ?: $this->addComplexType($type); + } + public function addBindingOperationHeader(\DOMElement $bindingOperation, array $headers, array $baseBinding) { foreach ($headers as $header) { diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 4979465..97517f7 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -10,6 +10,7 @@ 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; @@ -23,15 +24,17 @@ use BeSimple\SoapBundle\Util\QName; class WsdlDumper implements DumperInterface { private $loader; + private $typeRepository; private $options; private $wsdl; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader, array $options) + public function __construct(AnnotationComplexTypeLoader $loader, TypeRepository $typeRepository, array $options) { - $this->loader = $loader; - $this->options = $options; + $this->loader = $loader; + $this->typeRepository = $typeRepository; + $this->options = $options; } public function dumpServiceDefinition(ServiceDefinition $definition, $endpoint) @@ -39,7 +42,7 @@ class WsdlDumper implements DumperInterface Assert::thatArgumentNotNull('definition', $definition); $this->definition = $definition; - $this->wsdl = new Wsdl($definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy($this->loader, $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())); From db4c599af6f89823c9acf01752e38b7925ce2e77 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 27 Aug 2011 18:07:30 +0200 Subject: [PATCH 109/195] Use DOMDocument to retrieve the value in DateTimeTypeConverter --- Converter/DateTimeTypeConverter.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Converter/DateTimeTypeConverter.php b/Converter/DateTimeTypeConverter.php index da84758..47a9ace 100644 --- a/Converter/DateTimeTypeConverter.php +++ b/Converter/DateTimeTypeConverter.php @@ -31,7 +31,10 @@ class DateTimeTypeConverter implements TypeConverterInterface public function convertXmlToPhp(SoapRequest $request, $data) { - return new \DateTime(strip_tags($data)); + $doc = new \DOMDocument(); + $doc->loadXML($data); + + return new \DateTime($doc->textContent); } public function convertPhpToXml(SoapResponse $response, $data) From 3141adcfadcd28917e180e56ddaf4b298ab570a3 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 27 Aug 2011 18:09:48 +0200 Subject: [PATCH 110/195] Fixed namespace --- Tests/Converter/DateTimeTypeConverterTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Converter/DateTimeTypeConverterTest.php b/Tests/Converter/DateTimeTypeConverterTest.php index 197ca3d..b04acd3 100644 --- a/Tests/Converter/DateTimeTypeConverterTest.php +++ b/Tests/Converter/DateTimeTypeConverterTest.php @@ -8,7 +8,7 @@ * with this source code in the file LICENSE. */ -namespace BeSimple\SoapBundle\Tests\ServiceBinding; +namespace BeSimple\SoapBundle\Tests\Converter; use BeSimple\SoapBundle\Soap\SoapRequest; use BeSimple\SoapBundle\Soap\SoapResponse; @@ -24,8 +24,8 @@ class DateTimeTypeConverterTest extends \PHPUnit_Framework_TestCase public function testConvertXmlToPhp() { $converter = new DateTimeTypeConverter(); - $dateXml = '2002-10-10T12:00:00-05:00'; + $dateXml = '2002-10-10T12:00:00-05:00'; $date = $converter->convertXmlToPhp(new SoapRequest(), $dateXml); $this->assertEquals(new \DateTime('2002-10-10T12:00:00-05:00'), $date); @@ -34,8 +34,8 @@ class DateTimeTypeConverterTest extends \PHPUnit_Framework_TestCase public function testConvertPhpToXml() { $converter = new DateTimeTypeConverter(); - $date = new \DateTime('2002-10-10T12:00:00-05:00'); + $date = new \DateTime('2002-10-10T12:00:00-05:00'); $dateXml = $converter->convertPhpToXml(new SoapResponse(), $date); $this->assertEquals('2002-10-10T12:00:00-05:00', $dateXml); From d4662ffe206bac9b296504f444e54545c3cee2a7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 27 Aug 2011 22:12:38 +0200 Subject: [PATCH 111/195] Updated RpcLiteralRequestMessageBinderTest --- .../RpcLiteralRequestMessageBinderTest.php | 240 +++++++----------- Tests/fixtures/ServiceBinding/Bar.php | 15 ++ Tests/fixtures/ServiceBinding/Foo.php | 15 ++ Tests/fixtures/ServiceBinding/FooBar.php | 15 ++ 4 files changed, 131 insertions(+), 154 deletions(-) create mode 100644 Tests/fixtures/ServiceBinding/Bar.php create mode 100644 Tests/fixtures/ServiceBinding/Foo.php create mode 100644 Tests/fixtures/ServiceBinding/FooBar.php diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index befb786..dcef0f7 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -10,25 +10,17 @@ namespace BeSimple\SoapBundle\Tests\ServiceBinding; -use BeSimple\SoapBundle\ServiceDefinition\Method; -use BeSimple\SoapBundle\ServiceDefinition\Argument; -use BeSimple\SoapBundle\ServiceDefinition\Type; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder; +use BeSimple\SoapBundle\ServiceDefinition as Definition; +use BeSimple\SoapBundle\Tests\fixtures\ServiceBinding as Fixtures; use BeSimple\SoapBundle\Util\Collection; -/** - * UnitTest for \BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder. - * - * @author Francis Besset - */ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase { /** * @dataProvider messageProvider */ - public function testProcessMessage(Method $method, $message, $assert) + public function testProcessMessage(Definition\Method $method, $message, $assert) { $messageBinder = new RpcLiteralRequestMessageBinder(); $result = $messageBinder->processMessage($method, $message); @@ -38,133 +30,89 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase public function testProcessMessageWithComplexType() { - $attributes = new \stdClass(); - $attributes->foo = 'bar'; - $attributes->bar = 10; - $messageBinder = new RpcLiteralRequestMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), array( - new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), + + $foo = new Fixtures\Foo('foobar', 19395); + $result = $messageBinder->processMessage( + new Definition\Method('complextype_argument', null, array(), array( + new Definition\Argument('foo', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo')), )), - array($attributes), + array($foo), $this->getDefinitionComplexTypes() ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes']); - $this->assertSame('bar', $result['attributes']->foo); - $this->assertSame(10, $result['attributes']->bar); + $this->assertEquals(array('foo' => $foo), $result); - $attributes1 = new \stdClass(); - $attributes1->foo = 'foobar'; - $attributes1->bar = 11; - $attributes2 = new \stdClass(); - $attributes2->foo = 'barfoo'; - $attributes2->bar = 12; - $message = new \stdClass(); - $message->item = array($attributes1, $attributes2); + $foo1 = new Fixtures\Foo('foobar', 29291); + $foo2 = new Fixtures\Foo('barfoo', 39392); + $foos = new \stdClass(); + $foos->item = array($foo1, $foo2); - $messageBinder = new RpcLiteralRequestMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), array( - new Argument('attributes', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), + $result = $messageBinder->processMessage( + new Definition\Method('complextype_argument', null, array(), array( + new Definition\Argument('foos', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo[]')), )), - array($message), + array($foos), $this->getDefinitionComplexTypes() ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes'][0]); - $this->assertSame('foobar', $result['attributes'][0]->foo); - $this->assertSame(11, $result['attributes'][0]->bar); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['attributes'][1]); - $this->assertSame('barfoo', $result['attributes'][1]->foo); - $this->assertSame(12, $result['attributes'][1]->bar); + $this->assertEquals(array('foos' => array($foo1, $foo2)), $result); } - public function testProcessMessageWithComplexTypeMethods() + /** + * @expectedException SoapFault + */ + public function testProcessMessageSoapFault() { - $methods = new \stdClass(); - $methods->foo = 'bar'; - $methods->bar = 23; - $messageBinder = new RpcLiteralRequestMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_methods', null, array(), array( - new Argument('setters', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), + + $foo = new Fixtures\Foo('foo', null); + $result = $messageBinder->processMessage( + new Definition\Method('complextype_argument', null, array(), array( + new Definition\Argument('foo', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo')), )), - array($methods), + array($foo), + $this->getDefinitionComplexTypes() + ); + } + + public function testProcessMessageWithComplexTypeReference() + { + $messageBinder = new RpcLiteralRequestMessageBinder(); + + $foo = new Fixtures\Foo('foo', 2499104); + $foos = new \stdClass(); + $foos->item = array($foo, $foo); + + $result = $messageBinder->processMessage( + new Definition\Method('complextype_argument', null, array(), array( + new Definition\Argument('foos', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo[]')), + )), + array($foos), $this->getDefinitionComplexTypes() ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters', $result['setters']); - $this->assertSame('bar', $result['setters']->getFoo()); - $this->assertSame(23, $result['setters']->getBar()); + $this->assertEquals(array('foos' => array($foo, $foo)), $result); } public function testProcessMessageWithComplexTypeIntoComplexType() { - $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(), array( - new Argument('complex_type', new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), + + $foo = new Fixtures\Foo('foo', 38845); + $bar = new Fixtures\Bar('bar', null); + $fooBar = new Fixtures\FooBar($foo, $bar); + + $result = $messageBinder->processMessage( + new Definition\Method('complextype_argument', null, array(), array( + new Definition\Argument('fooBar', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooBar')), )), - array($complexType), + array($fooBar), $this->getDefinitionComplexTypes() ); - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType', $result['complex_type']); - - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', $result['complex_type']->getFoo()); - $this->assertSame('hello', $result['complex_type']->getFoo()->foo); - $this->assertSame(24, $result['complex_type']->getFoo()->bar); - - $this->assertInstanceOf('BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters', $result['complex_type']->bar); - $this->assertSame('bonjour', $result['complex_type']->bar->getFoo()); - $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(), 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); + $this->assertEquals(array('fooBar' => $fooBar), $result); } public function messageProvider() @@ -172,23 +120,23 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $messages = array(); $messages[] = array( - new Method('no_argument'), + new Definition\Method('no_argument'), array(), array(), ); $messages[] = array( - new Method('string_argument', null, array(), array( - new Argument('foo', new Type('string')), + new Definition\Method('string_argument', null, array(), array( + new Definition\Argument('foo', new Definition\Type('string')), )), array('bar'), array('foo' => 'bar'), ); $messages[] = array( - new Method('string_int_arguments', null, array(), array( - new Argument('foo', new Type('string')), - new Argument('bar', new Type('int')), + new Definition\Method('string_int_arguments', null, array(), array( + new Definition\Argument('foo', new Definition\Type('string')), + new Definition\Argument('bar', new Definition\Type('int')), )), array('test', 20), array('foo' => 'test', 'bar' => 20), @@ -197,9 +145,9 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $strings = new \stdClass(); $strings->item = array('foo', 'bar', 'barfoo'); $messages[] = array( - new Method('array_string_arguments', null, array(), array( - new Argument('foo', new Type('string[]')), - new Argument('bar', new Type('int')), + new Definition\Method('array_string_arguments', null, array(), array( + new Definition\Argument('foo', new Definition\Type('string[]')), + new Definition\Argument('bar', new Definition\Type('int')), )), array($strings, 4), array('foo' => array('foo', 'bar', 'barfoo'), 'bar' => 4), @@ -210,58 +158,42 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase private function getDefinitionComplexTypes() { - $this->definitionComplexTypes = array(); + $definitionComplexTypes = array(); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes'] = $this->createPropertiesCollection(array( + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo'] = $this->createComplexTypeCollection(array( array('foo', 'string'), array('bar', 'int'), )); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'] = $this->createMethodsCollection(array( - array('foo', 'string', 'getFoo', 'setFoo'), - array('bar', 'int', 'getBar', 'setBar'), + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Bar'] = $this->createComplexTypeCollection(array( + array('foo', 'string'), + array('bar', 'int', true), )); - $collection = $this->createMethodsCollection(array( - array('foo', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', 'getFoo', 'setFoo'), + $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\FooBar'] = $this->createComplexTypeCollection(array( + array('foo', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo'), + array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Bar'), )); - $this->createPropertiesCollection(array( - array('bar', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'), - ), $collection); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType'] = $collection; - return $this->definitionComplexTypes; + return $definitionComplexTypes; } - private function createPropertiesCollection(array $properties, Collection $collection = null) + private function createComplexTypeCollection(array $properties) { - $collection = $collection ?: new Collection('getName'); + $collection = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\ComplexType'); foreach ($properties as $property) { - $collectionProperty = new PropertyComplexType(); - $collectionProperty->setName($property[0]); - $collectionProperty->setValue($property[1]); + $complexType = new Definition\ComplexType(); + $complexType->setName($property[0]); + $complexType->setValue($property[1]); - $collection->add($collectionProperty); + if (isset($property[2])) { + $complexType->setNillable($property[2]); + } + + $collection->add($complexType); } return $collection; } - - private function createMethodsCollection(array $methods, Collection $collection = null) - { - $collection = $collection ?: new Collection('getName'); - - foreach ($methods as $method) { - $collectionMethod = new MethodComplexType(); - $collectionMethod->setName($method[0]); - $collectionMethod->setValue($method[1]); - $collectionMethod->setOriginalName($method[2]); - $collectionMethod->setSetter($method[3]); - - $collection->add($collectionMethod); - } - - return $collection; - } -} +} \ No newline at end of file diff --git a/Tests/fixtures/ServiceBinding/Bar.php b/Tests/fixtures/ServiceBinding/Bar.php new file mode 100644 index 0000000..fac87cb --- /dev/null +++ b/Tests/fixtures/ServiceBinding/Bar.php @@ -0,0 +1,15 @@ +foo = $foo; + $this->bar = $bar; + } +} \ No newline at end of file diff --git a/Tests/fixtures/ServiceBinding/Foo.php b/Tests/fixtures/ServiceBinding/Foo.php new file mode 100644 index 0000000..e635b8e --- /dev/null +++ b/Tests/fixtures/ServiceBinding/Foo.php @@ -0,0 +1,15 @@ +foo = $foo; + $this->bar = $bar; + } +} \ No newline at end of file diff --git a/Tests/fixtures/ServiceBinding/FooBar.php b/Tests/fixtures/ServiceBinding/FooBar.php new file mode 100644 index 0000000..103dfc9 --- /dev/null +++ b/Tests/fixtures/ServiceBinding/FooBar.php @@ -0,0 +1,15 @@ +foo = $foo; + $this->bar = $bar; + } +} \ No newline at end of file From b4da2f727e146751555ce5d36d15bac35a855b25 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 27 Aug 2011 22:47:58 +0200 Subject: [PATCH 112/195] Added besimple.soap.response service It is highly recommended not to instantiate BeSimple\SoapBundle\Soap\SoapResponse but to use the service besimple.soap.response Before: public function helloAction($name) { return new SoapResponse("Hello ".$name); } After: public function helloAction($name) { return $this ->container ->get('besimple.soap.response') ->setReturnValue("Hello ".$name) ; } --- Controller/SoapWebServiceController.php | 16 ++++++++-------- Resources/config/webservice.xml | 3 +++ Resources/doc/reference/configuration.rst | 12 +++++++----- Resources/doc/tutorial/array.rst | 3 +-- Resources/doc/tutorial/complex_type.rst | 5 ++--- Resources/doc/tutorial/header.rst | 3 +-- Soap/SoapResponse.php | 2 ++ 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 250d99d..fc93eb8 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -58,15 +58,15 @@ class SoapWebServiceController extends ContainerAware $this->serviceBinder = $webServiceContext->getServiceBinder(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); - $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, new SoapResponse()); + $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->getResponse()); $this->soapServer->setObject($this); ob_start(); $this->soapServer->handle($this->soapRequest->getSoapMessage()); - $this->soapResponse->setContent(ob_get_clean()); + $this->getResponse()->setContent(ob_get_clean()); - return $this->soapResponse; + return $this->getResponse(); } /** @@ -127,14 +127,14 @@ class SoapWebServiceController extends ContainerAware $this->soapResponse = $this->checkResponse($response); // add response soap headers to soap server - foreach ($this->soapResponse->getSoapHeaders() as $header) { + foreach ($this->getResponse()->getSoapHeaders() as $header) { $this->soapServer->addSoapHeader($header->toNativeSoapHeader()); } // return operation return value to soap server return $this->serviceBinder->processServiceMethodReturnValue( $method, - $this->soapResponse->getReturnValue() + $this->getResponse()->getReturnValue() ); } else { // collect request soap headers @@ -155,7 +155,7 @@ class SoapWebServiceController extends ContainerAware */ public function getResponse() { - return $this->soapResponse; + return $this->soapResponse ?: $this->soapResponse = $this->container->get('besimple.soap.response'); } /** @@ -165,12 +165,12 @@ class SoapWebServiceController extends ContainerAware * * @return SoapResponse A valid SoapResponse * - * @throws InvalidArgumentException if the given Response is null or not a SoapResponse + * @throws InvalidArgumentException if the given Response is not an instance of SoapResponse */ protected function checkResponse(Response $response) { if (!$response instanceof SoapResponse) { - throw new \InvalidArgumentException(); + throw new \InvalidArgumentException('You must return an instance of BeSimple\SoapBundle\Soap\SoapResponse'); } return $response; diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index b1cd5f6..873148a 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -4,6 +4,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + BeSimple\SoapBundle\Soap\SoapResponse BeSimple\SoapBundle\WebServiceContext %kernel.cache_dir%/webservice BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestHeaderMessageBinder @@ -17,6 +18,8 @@ + + diff --git a/Resources/doc/reference/configuration.rst b/Resources/doc/reference/configuration.rst index 4c2d469..1ccd620 100644 --- a/Resources/doc/reference/configuration.rst +++ b/Resources/doc/reference/configuration.rst @@ -34,18 +34,20 @@ Annotations for Controllers .. code-block:: php - use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; - use BeSimple\SoapBundle\Soap\SoapResponse; + namespace My\App\Controller; - class DemoController extends Controller + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware { /** - * @Soap\Method("Hello") + * @Soap\Method("hello") * @Soap\Param("name", phpType = "string") * @Soap\Result(phpType = "string") */ public function helloAction($name) { - return new SoapResponse(sprintf('Hello %s!', $name)); + return $this->container->get('besimple.soap.response')->setReturnValue(sprintf('Hello %s!', $name)); } } \ No newline at end of file diff --git a/Resources/doc/tutorial/array.rst b/Resources/doc/tutorial/array.rst index 7972624..aa12f33 100644 --- a/Resources/doc/tutorial/array.rst +++ b/Resources/doc/tutorial/array.rst @@ -9,7 +9,6 @@ Controller namespace My\App\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; - use BeSimple\SoapBundle\Soap\SoapResponse; use Symfony\Component\DependencyInjection\ContainerAware; class DemoController extends ContainerAware @@ -21,6 +20,6 @@ Controller */ public function helloAction(array $names) { - return new SoapResponse("Hello ".implode(', ', $names)); + return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); } } \ No newline at end of file diff --git a/Resources/doc/tutorial/complex_type.rst b/Resources/doc/tutorial/complex_type.rst index edf03cd..24514ea 100644 --- a/Resources/doc/tutorial/complex_type.rst +++ b/Resources/doc/tutorial/complex_type.rst @@ -15,7 +15,6 @@ Controller namespace My\App\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; - use BeSimple\SoapBundle\Soap\SoapResponse; use Symfony\Component\DependencyInjection\ContainerAware; class DemoController extends ContainerAware @@ -29,13 +28,13 @@ Controller { $user = $this->container->getDoctrine()->getRepository('MyApp:User')->findOneBy(array( 'name' => $name, - ); + )); if (!$user) { throw new \SoapFault('USER_NOT_FOUND', sprintf('The user with the name "%s" can not be found', $name)); } - return new SoapResponse($user); + return $this->container->get('besimple.soap.response')->setReturnValue($user); } } diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/tutorial/header.rst index b71bd89..d1dc849 100644 --- a/Resources/doc/tutorial/header.rst +++ b/Resources/doc/tutorial/header.rst @@ -9,7 +9,6 @@ Controller namespace My\App\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; - use BeSimple\SoapBundle\Soap\SoapResponse; use Symfony\Component\DependencyInjection\ContainerAware; class DemoController extends ContainerAware @@ -27,6 +26,6 @@ Controller throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); } - return new SoapResponse("Hello ".implode(', ', $names)); + return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); } } \ No newline at end of file diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 5fba41b..1574b00 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -58,6 +58,8 @@ class SoapResponse extends Response public function setReturnValue($value) { $this->soapReturnValue = $value; + + return $this; } public function getReturnValue() From c18cede7ab2b3a8288b7a3759f99c641d011785c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 29 Aug 2011 21:34:49 +0200 Subject: [PATCH 113/195] Added xsd:date type and DateTypeConverter --- Converter/DateTimeTypeConverter.php | 2 +- Converter/DateTypeConverter.php | 44 +++++++++++++++++++++++ Resources/config/converters.xml | 5 +++ Resources/config/webservice.xml | 4 +++ Tests/Converter/DateTypeConverterTest.php | 41 +++++++++++++++++++++ 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Converter/DateTypeConverter.php create mode 100644 Tests/Converter/DateTypeConverterTest.php diff --git a/Converter/DateTimeTypeConverter.php b/Converter/DateTimeTypeConverter.php index 47a9ace..9f692fc 100644 --- a/Converter/DateTimeTypeConverter.php +++ b/Converter/DateTimeTypeConverter.php @@ -39,6 +39,6 @@ class DateTimeTypeConverter implements TypeConverterInterface public function convertPhpToXml(SoapResponse $response, $data) { - return sprintf('%s', $data->format('Y-m-d\TH:i:sP')); + return sprintf('<%1$s>%2$s', $this->getTypeName(), $data->format('Y-m-d\TH:i:sP')); } } diff --git a/Converter/DateTypeConverter.php b/Converter/DateTypeConverter.php new file mode 100644 index 0000000..61f7119 --- /dev/null +++ b/Converter/DateTypeConverter.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Converter; + +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Util\String; + +/** + * @author Francis Besset + */ +class DateTypeConverter implements TypeConverterInterface +{ + public function getTypeNamespace() + { + return 'http://www.w3.org/2001/XMLSchema'; + } + + public function getTypeName() + { + return 'date'; + } + + public function convertXmlToPhp(SoapRequest $request, $data) + { + $doc = new \DOMDocument(); + $doc->loadXML($data); + + return new \DateTime($doc->textContent); + } + + public function convertPhpToXml(SoapResponse $response, $data) + { + return sprintf('<%1$s>%2$s', $this->getTypeName(), $data->format('Y-m-d')); + } +} diff --git a/Resources/config/converters.xml b/Resources/config/converters.xml index 25b7cd1..ec6e5c5 100644 --- a/Resources/config/converters.xml +++ b/Resources/config/converters.xml @@ -7,6 +7,7 @@ BeSimple\SoapBundle\Converter\ConverterRepository BeSimple\SoapBundle\Converter\DateTimeTypeConverter + BeSimple\SoapBundle\Converter\DateTypeConverter @@ -15,5 +16,9 @@ + + + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 873148a..5b0f211 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -81,6 +81,10 @@ dateTime xsd:dateTime + + date + xsd:date + diff --git a/Tests/Converter/DateTypeConverterTest.php b/Tests/Converter/DateTypeConverterTest.php new file mode 100644 index 0000000..db53dd1 --- /dev/null +++ b/Tests/Converter/DateTypeConverterTest.php @@ -0,0 +1,41 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace BeSimple\SoapBundle\Tests\Converter; + +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\Converter\DateTypeConverter; + +/** + * UnitTest for \BeSimple\SoapBundle\Converter\DateTimeTypeConverter. + */ +class DateTypeConverterTest extends \PHPUnit_Framework_TestCase +{ + public function testConvertXmlToPhp() + { + $converter = new DateTypeConverter(); + + $dateXml = '2002-10-10'; + $date = $converter->convertXmlToPhp(new SoapRequest(), $dateXml); + + $this->assertEquals(new \DateTime('2002-10-10'), $date); + } + + public function testConvertPhpToXml() + { + $converter = new DateTypeConverter(); + + $date = new \DateTime('2002-10-10'); + $dateXml = $converter->convertPhpToXml(new SoapResponse(), $date); + + $this->assertEquals('2002-10-10', $dateXml); + } +} From 57b35c5e622c8e42efd86924e966822c63a18665 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 29 Aug 2011 22:20:24 +0200 Subject: [PATCH 114/195] [Doc] Added types available --- Resources/config/webservice.xml | 16 ++++++++-------- Resources/doc/index.rst | 1 + Resources/doc/reference/types.rst | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 Resources/doc/reference/types.rst diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 5b0f211..a33b0c2 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -65,26 +65,26 @@ string xsd:string - - int - xsd:int - boolean xsd:boolean + + int + xsd:int + float xsd:float - - dateTime - xsd:dateTime - date xsd:date + + dateTime + xsd:dateTime + diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index f7ca83b..19be4f2 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -13,6 +13,7 @@ Reference Guide reference/installation reference/configuration + reference/types Tutorial -------- diff --git a/Resources/doc/reference/types.rst b/Resources/doc/reference/types.rst new file mode 100644 index 0000000..af2345f --- /dev/null +++ b/Resources/doc/reference/types.rst @@ -0,0 +1,25 @@ +Types available +=============== + ++----------+-----------------+ +| Php Type | XML Type | ++==========+=================+ +| string | `xsd:string`_ | ++----------+-----------------+ +| boolean | `xsd:boolean`_ | ++----------+-----------------+ +| int | `xsd:int`_ | ++----------+-----------------+ +| float | `xsd:float`_ | ++----------+-----------------+ +| date | `xsd:date`_ | ++----------+-----------------+ +| dateTime | `xsd:dateTime`_ | ++----------+-----------------+ + +.. _`xsd:string`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string +.. _`xsd:boolean`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#boolean +.. _`xsd:int`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int +.. _`xsd:float`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#float +.. _`xsd:date`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date +.. _`xsd:dateTime`: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime \ No newline at end of file From 958efd34319a4de8c9c7ae2b47ce5095a6d2958c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 1 Sep 2011 19:40:44 +0200 Subject: [PATCH 115/195] Replaced QName->getNamespace() by ServiceDefinition->getNamespace() for headers --- Resources/doc/tutorial/header.rst | 2 ++ ServiceBinding/ServiceBinder.php | 9 +-------- Soap/SoapHeader.php | 5 +++++ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/tutorial/header.rst index d1dc849..c3928df 100644 --- a/Resources/doc/tutorial/header.rst +++ b/Resources/doc/tutorial/header.rst @@ -22,6 +22,8 @@ Controller public function helloAction(array $names) { $soapHeaders = $this->container->get('request')->getSoapHeaders(); + + // You can use '1234' !== (string) $soapHeaders->get('api_key') if (!$soapHeaders->has('api_key') || '1234' !== $soapHeaders->get('api_key')->getData()) { throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); } diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index 01c4ebd..f85d32c 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -67,7 +67,7 @@ class ServiceBinder $this->requestHeaderMessageBinder->setHeader($header); $data = $this->requestHeaderMessageBinder->processMessage($methodDefinition, $data, $this->definition->getDefinitionComplexTypes()); - return $this->createSoapHeader($headerDefinition, $data); + return new SoapHeader($this->definition->getNamespace(), $headerDefinition->getName(), $data); } public function processServiceMethodArguments($method, $arguments) @@ -86,11 +86,4 @@ class ServiceBinder return $this->responseMessageBinder->processMessage($methodDefinition, $return, $this->definition->getDefinitionComplexTypes()); } - - protected function createSoapHeader(Header $headerDefinition, $data) - { - $qname = QName::fromPackedQName($headerDefinition->getType()->getXmlType()); - - return new SoapHeader($qname->getNamespace(), $headerDefinition->getName(), $data); - } } \ No newline at end of file diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php index e24d58c..22b0fbd 100644 --- a/Soap/SoapHeader.php +++ b/Soap/SoapHeader.php @@ -23,6 +23,11 @@ class SoapHeader $this->data = $data; } + public function __toString() + { + return $this->data; + } + public function getNamespace() { return $this->namespace; From faf8b5810841d4447c5ed676aac1881391e8e1bb Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 1 Sep 2011 20:18:28 +0200 Subject: [PATCH 116/195] Fixed error if an array is empty in RpcLiteralRequestMessageBinder --- .../RpcLiteralRequestMessageBinder.php | 15 +++++++---- .../RpcLiteralRequestMessageBinderTest.php | 25 ++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 557ff4b..5929c9f 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -49,16 +49,17 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface if (preg_match('/^([^\[]+)\[\]$/', $phpType, $match)) { $isArray = true; + $array = array(); $phpType = $match[1]; } // @TODO Fix array reference if (isset($this->definitionComplexTypes[$phpType])) { if ($isArray) { - $array = array(); - - foreach ($message->item as $complexType) { - $array[] = $this->checkComplexType($phpType, $complexType); + if (isset($message->item)) { + foreach ($message->item as $complexType) { + $array[] = $this->checkComplexType($phpType, $complexType); + } } $message = $array; @@ -66,7 +67,11 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $message = $this->checkComplexType($phpType, $message); } } elseif ($isArray) { - $message = $message->item; + if (isset($message->item)) { + $message = $message->item; + } else { + $message = $array; + } } return $message; diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index dcef0f7..dac112a 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -61,7 +61,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException SoapFault + * @expectedException SoapFault */ public function testProcessMessageSoapFault() { @@ -115,6 +115,21 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('fooBar' => $fooBar), $result); } + public function testProcessMessageWithEmptyArrayComplexType() + { + $messageBinder = new RpcLiteralRequestMessageBinder(); + + $result = $messageBinder->processMessage( + new Definition\Method('empty_array_complex_type', null, array(), array( + new Definition\Argument('foo', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo[]')), + )), + array(new \stdClass()), + $this->getDefinitionComplexTypes() + ); + + $this->assertEquals(array('foo' => array()), $result); + } + public function messageProvider() { $messages = array(); @@ -153,6 +168,14 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase array('foo' => array('foo', 'bar', 'barfoo'), 'bar' => 4), ); + $messages[] = array( + new Definition\Method('empty_array', null, array(), array( + new Definition\Argument('foo', new Definition\Type('string[]')), + )), + array(new \stdClass()), + array('foo' => array()), + ); + return $messages; } From e9864b1d02154bfd0fadbdafa20d08215d672ff3 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 1 Sep 2011 21:15:40 +0200 Subject: [PATCH 117/195] Deleted unused namespace and added PHPDoc on ServiceBinder --- ServiceBinding/ServiceBinder.php | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php index f85d32c..e9e4254 100644 --- a/ServiceBinding/ServiceBinder.php +++ b/ServiceBinding/ServiceBinder.php @@ -13,7 +13,6 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Header; use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition; use BeSimple\SoapBundle\Soap\SoapHeader; -use BeSimple\SoapBundle\Util\QName; /** * @author Christian Kerl @@ -40,6 +39,12 @@ class ServiceBinder */ private $responseMessageBinder; + /** + * @param ServiceDefinition $definition + * @param MessageBinderInterface $requestHeaderMessageBinder + * @param MessageBinderInterface $requestMessageBinder + * @param MessageBinderInterface $responseMessageBinder + */ public function __construct(ServiceDefinition $definition, MessageBinderInterface $requestHeaderMessageBinder, MessageBinderInterface $requestMessageBinder, MessageBinderInterface $responseMessageBinder) { $this->definition = $definition; @@ -49,16 +54,34 @@ class ServiceBinder $this->responseMessageBinder = $responseMessageBinder; } + /** + * @param string $method + * @param string $header + * + * @return boolean + */ public function isServiceHeader($method, $header) { return $this->definition->getMethods()->get($method)->getHeaders()->has($header); } + /** + * @param $string + * + * @return boolean + */ public function isServiceMethod($method) { return $this->definition->getMethods()->has($method); } + /** + * @param string $method + * @param string $header + * @param mixed $data + * + * @return SoapHeader + */ public function processServiceHeader($method, $header, $data) { $methodDefinition = $this->definition->getMethods()->get($method); @@ -70,6 +93,12 @@ class ServiceBinder return new SoapHeader($this->definition->getNamespace(), $headerDefinition->getName(), $data); } + /** + * @param string $method + * @param array $arguments + * + * @return array + */ public function processServiceMethodArguments($method, $arguments) { $methodDefinition = $this->definition->getMethods()->get($method); @@ -80,6 +109,12 @@ class ServiceBinder ); } + /** + * @param string $name + * @param mixed + * + * @return mixed + */ public function processServiceMethodReturnValue($name, $return) { $methodDefinition = $this->definition->getMethods()->get($name); From 17fdd6448907adf085265bc0fbf90362bc714238 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 3 Sep 2011 21:17:57 +0200 Subject: [PATCH 118/195] Added soap client --- DependencyInjection/BeSimpleSoapExtension.php | 16 ++++++++++++++++ DependencyInjection/Configuration.php | 18 ++++++++++++++++++ Resources/config/client.xml | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 Resources/config/client.xml diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 5870366..9b492b7 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -44,6 +44,10 @@ class BeSimpleSoapExtension extends Extension $config = $processor->process($configuration->getConfigTree(), $configs); + if (isset($config['clients'])) { + $this->registerClientConfiguration($config['clients'], $container, $loader); + } + $container->setParameter('besimple.soap.definition.dumper.options.stylesheet', $config['wsdl_dumper']['stylesheet']); foreach($config['services'] as $name => $serviceConfig) { @@ -52,6 +56,18 @@ class BeSimpleSoapExtension extends Extension } } + private function registerClientConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('client.xml'); + + foreach ($config as $client => $options) { + $definition = new DefinitionDecorator('besimple.soap.client'); + $context = $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition); + + $definition->replaceArgument(0, $options['wsdl']); + } + } + private function createWebServiceContext(array $config, ContainerBuilder $container) { $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 0f538cc..2228f37 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -30,12 +30,30 @@ class Configuration $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('be_simple_soap'); + $this->addClientSection($rootNode); $this->addServicesSection($rootNode); $this->addWsdlDumperSection($rootNode); return $treeBuilder->buildTree(); } + private function addClientSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('clients') + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ->scalarNode('wsdl') + ->isRequired() + ->end() + ->end() + ->end() + ->end() + ; + } + private function addServicesSection(ArrayNodeDefinition $rootNode) { $rootNode diff --git a/Resources/config/client.xml b/Resources/config/client.xml new file mode 100644 index 0000000..1fc90f1 --- /dev/null +++ b/Resources/config/client.xml @@ -0,0 +1,19 @@ + + + + + BeSimple\SoapClient\Soap\SoapClient + + + + + wsdl + + %kernel.debug% + + + + + From 502ba419351745d6ab4297596e74b0e9559cc5c0 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 00:48:45 +0200 Subject: [PATCH 119/195] Updated namespace for soap client --- Resources/config/client.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 1fc90f1..405a4de 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - BeSimple\SoapClient\Soap\SoapClient + BeSimple\SoapClient\SoapClient From 1a4e9246db265cc5f5656d0a607e729dd970ee76 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 01:59:32 +0200 Subject: [PATCH 120/195] Added besimple.soap.cache service --- Cache.php | 39 +++++++++++++++++++ DependencyInjection/BeSimpleSoapExtension.php | 34 ++++++++++++++++ DependencyInjection/Configuration.php | 25 ++++++++++++ Resources/config/client.xml | 1 + Resources/config/soap.xml | 21 ++++++++++ Resources/config/webservice.xml | 2 + Soap/SoapServerFactory.php | 3 +- 7 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 Cache.php create mode 100644 Resources/config/soap.xml diff --git a/Cache.php b/Cache.php new file mode 100644 index 0000000..71d8927 --- /dev/null +++ b/Cache.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\SoapBundle; + +use BeSimple\SoapCommon\Cache as BaseCache; + +/** + * @author Francis Besset + */ +class Cache +{ + public function __construct($disabled, $type, $directory, $lifetime = null, $limit = null) + { + BaseCache::setEnabled(!$disabled); + + if (BaseCache::ENABLED == BaseCache::isEnabled()) { + BaseCache::setType($type); + BaseCache::setDirectory($directory); + + if (null !== $lifetime) { + BaseCache::setLifetime($lifetime); + } + + if (null !== $limit) { + BaseCache::setLimit($limit); + } + } + } +} \ No newline at end of file diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 9b492b7..5abd6de 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.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,6 +12,8 @@ namespace BeSimple\SoapBundle\DependencyInjection; +use BeSimple\SoapCommon\Cache; + use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -22,6 +26,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; * BeSimpleSoapExtension. * * @author Christian Kerl + * @author Francis Besset */ class BeSimpleSoapExtension extends Extension { @@ -44,6 +49,8 @@ class BeSimpleSoapExtension extends Extension $config = $processor->process($configuration->getConfigTree(), $configs); + $this->registerCacheConfiguration($config['cache'], $container, $loader); + if (isset($config['clients'])) { $this->registerClientConfiguration($config['clients'], $container, $loader); } @@ -56,6 +63,33 @@ class BeSimpleSoapExtension extends Extension } } + private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + { + $loader->load('soap.xml'); + + switch ($config['type']) { + case 'none': + $config['type'] = Cache::TYPE_NONE; + break; + + case 'disk': + $config['type'] = Cache::TYPE_DISK; + break; + + case 'memory': + $config['type'] = Cache::TYPE_MEMORY; + break; + + case 'disk_memory': + $config['type'] = Cache::TYPE_DISK_MEMORY; + break; + } + + foreach (array('type', 'lifetime', 'limit') as $key) { + $container->setParameter('besimple.soap.cache.'.$key, $config[$key]); + } + } + private function registerClientConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { $loader->load('client.xml'); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 2228f37..dde299d 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.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. @@ -17,6 +19,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; * WebServiceExtension configuration structure. * * @author Christian Kerl + * @author Francis Besset */ class Configuration { @@ -30,6 +33,7 @@ class Configuration $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('be_simple_soap'); + $this->addCacheSection($rootNode); $this->addClientSection($rootNode); $this->addServicesSection($rootNode); $this->addWsdlDumperSection($rootNode); @@ -37,6 +41,27 @@ class Configuration return $treeBuilder->buildTree(); } + private function addCacheSection(ArrayNodeDefinition $rootNode) + { + $rootNode + ->children() + ->arrayNode('cache') + ->children() + ->scalarNode('type') + ->defaultValue('disk') + ->validate() + ->ifNotInArray(array('none', 'disk', 'memory', 'disk_memory')) + ->thenInvalid('The cache type has to be either "none", "disk", "memory" or "disk_memory"') + ->end() + ->end() + ->scalarNode('lifetime')->defaultNull()->end() + ->scalarNode('limit')->defaultNull()->end() + ->end() + ->end() + ->end() + ; + } + private function addClientSection(ArrayNodeDefinition $rootNode) { $rootNode diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 405a4de..7869c80 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -13,6 +13,7 @@ %kernel.debug% + diff --git a/Resources/config/soap.xml b/Resources/config/soap.xml new file mode 100644 index 0000000..3fb3d4c --- /dev/null +++ b/Resources/config/soap.xml @@ -0,0 +1,21 @@ + + + + + BeSimple\SoapBundle\Cache + %kernel.cache_dir%/besimple/soap + + + + + %kernel.debug% + %besimple.soap.cache.type% + %besimple.soap.cache.directory% + %besimple.soap.cache.lifetime% + %besimple.soap.cache.limit% + + + + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index a33b0c2..081e3b3 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -32,6 +32,7 @@ %besimple.soap.binder.request.rpcliteral.class% %besimple.soap.binder.response.rpcliteral.class% + @@ -46,6 +47,7 @@ %besimple.soap.binder.request.documentwrapped.class% %besimple.soap.binder.response.documentwrapped.class% + diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 1e18767..eee5fd2 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -11,6 +11,7 @@ namespace BeSimple\SoapBundle\Soap; use BeSimple\SoapBundle\Converter\ConverterRepository; +use BeSimple\SoapCommon\Cache; use Zend\Soap\Wsdl; /** @@ -39,7 +40,7 @@ class SoapServerFactory 'classmap' => $this->classmap, 'typemap' => $this->createSoapServerTypemap($request, $response), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, - 'cache_wsdl' => $this->debug ? WSDL_CACHE_NONE : WSDL_CACHE_DISK, + 'cache_wsdl' => Cache::getType(), ) ); } From 2ea1704a1eb94b9a1f26a395e8fae885f1a5d97d Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 02:42:53 +0200 Subject: [PATCH 121/195] Added the possibility to choice an other type cache for a client --- DependencyInjection/BeSimpleSoapExtension.php | 46 ++++++++++++------- DependencyInjection/Configuration.php | 13 +++++- Resources/config/client.xml | 1 + 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 5abd6de..f44f2a5 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -67,23 +67,7 @@ class BeSimpleSoapExtension extends Extension { $loader->load('soap.xml'); - switch ($config['type']) { - case 'none': - $config['type'] = Cache::TYPE_NONE; - break; - - case 'disk': - $config['type'] = Cache::TYPE_DISK; - break; - - case 'memory': - $config['type'] = Cache::TYPE_MEMORY; - break; - - case 'disk_memory': - $config['type'] = Cache::TYPE_DISK_MEMORY; - break; - } + $config['type'] = $this->getCacheType($config['type']); foreach (array('type', 'lifetime', 'limit') as $key) { $container->setParameter('besimple.soap.cache.'.$key, $config[$key]); @@ -99,6 +83,17 @@ class BeSimpleSoapExtension extends Extension $context = $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition); $definition->replaceArgument(0, $options['wsdl']); + + if (isset($options['cache_wsdl'])) { + $options['cache_wsdl'] = $this->getCacheType($options['cache_wsdl']); + + $defOptions = $container + ->getDefinition('besimple.soap.client') + ->getArgument(1); + + $defOptions['cache_wsdl'] = $options['cache_wsdl']; + $definition->replaceArgument(1, $defOptions); + } } } @@ -117,4 +112,21 @@ class BeSimpleSoapExtension extends Extension $definition->replaceArgument(4, array_merge($options, $config)); } + + private function getCacheType($type) + { + switch ($type) { + case 'none': + return Cache::TYPE_NONE; + + case 'disk': + return Cache::TYPE_DISK; + + case 'memory': + return Cache::TYPE_MEMORY; + + case 'disk_memory': + return Cache::TYPE_DISK_MEMORY; + } + } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index dde299d..f856ee8 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -23,6 +23,8 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; */ class Configuration { + private $cacheTypes = array('none', 'disk', 'memory', 'disk_memory'); + /** * Generates the configuration tree. * @@ -46,12 +48,13 @@ class Configuration $rootNode ->children() ->arrayNode('cache') + ->addDefaultsIfNotSet() ->children() ->scalarNode('type') ->defaultValue('disk') ->validate() - ->ifNotInArray(array('none', 'disk', 'memory', 'disk_memory')) - ->thenInvalid('The cache type has to be either "none", "disk", "memory" or "disk_memory"') + ->ifNotInArray($this->cacheTypes) + ->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes))) ->end() ->end() ->scalarNode('lifetime')->defaultNull()->end() @@ -73,6 +76,12 @@ class Configuration ->scalarNode('wsdl') ->isRequired() ->end() + ->scalarNode('cache_wsdl') + ->validate() + ->ifNotInArray($this->cacheTypes) + ->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes))) + ->end() + ->end() ->end() ->end() ->end() diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 7869c80..72acfef 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -12,6 +12,7 @@ wsdl %kernel.debug% + null From b1da32bc97a6560e0a1afdac4512828722acb45f Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 12:24:51 +0200 Subject: [PATCH 122/195] Renamed client cache_wsdl option to cache_type --- DependencyInjection/BeSimpleSoapExtension.php | 6 +++--- DependencyInjection/Configuration.php | 2 +- Resources/config/client.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index f44f2a5..e14d6df 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -84,14 +84,14 @@ class BeSimpleSoapExtension extends Extension $definition->replaceArgument(0, $options['wsdl']); - if (isset($options['cache_wsdl'])) { - $options['cache_wsdl'] = $this->getCacheType($options['cache_wsdl']); + if (isset($options['cache_type'])) { + $options['cache_type'] = $this->getCacheType($options['cache_type']); $defOptions = $container ->getDefinition('besimple.soap.client') ->getArgument(1); - $defOptions['cache_wsdl'] = $options['cache_wsdl']; + $defOptions['cache_type'] = $options['cache_type']; $definition->replaceArgument(1, $defOptions); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index f856ee8..a15bc22 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -76,7 +76,7 @@ class Configuration ->scalarNode('wsdl') ->isRequired() ->end() - ->scalarNode('cache_wsdl') + ->scalarNode('cache_type') ->validate() ->ifNotInArray($this->cacheTypes) ->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes))) diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 72acfef..d98220e 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -12,7 +12,7 @@ wsdl %kernel.debug% - null + null From 4e33819eca94b774aaf9c43957d2e2586b1986db Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 12:59:19 +0200 Subject: [PATCH 123/195] Added cache_type option for soap server definition --- DependencyInjection/BeSimpleSoapExtension.php | 4 +++ DependencyInjection/Configuration.php | 6 ++++ Resources/config/webservice.xml | 2 ++ Soap/SoapServerFactory.php | 36 ++++++++++++++++--- WebServiceContext.php | 5 ++- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index e14d6df..7625b57 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -106,6 +106,10 @@ class BeSimpleSoapExtension extends Extension $definition = new DefinitionDecorator('besimple.soap.context.'.$bindingSuffix); $context = $container->setDefinition($contextId, $definition); + if (isset($config['cache_type'])) { + $config['cache_type'] = $this->getCacheType($config['cache_type']); + } + $options = $container ->getDefinition('besimple.soap.context.'.$bindingSuffix) ->getArgument(4); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index a15bc22..cf95cc4 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -112,6 +112,12 @@ class Configuration ->thenInvalid("Service binding style has to be either 'rpc-literal' or 'document-wrapped'") ->end() ->end() + ->scalarNode('cache_type') + ->validate() + ->ifNotInArray($this->cacheTypes) + ->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes))) + ->end() + ->end() ->end() ->end() ->end() diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 081e3b3..71adcfa 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -28,6 +28,7 @@ %besimple.soap.cache_dir% %kernel.debug% + null %besimple.soap.binder.request_header.rpcliteral.class% %besimple.soap.binder.request.rpcliteral.class% %besimple.soap.binder.response.rpcliteral.class% @@ -43,6 +44,7 @@ %besimple.soap.cache_dir% %kernel.debug% + null %besimple.soap.binder.request_header.documentwrapped.class% %besimple.soap.binder.request.documentwrapped.class% %besimple.soap.binder.response.documentwrapped.class% diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index eee5fd2..00d9204 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -22,14 +22,42 @@ class SoapServerFactory private $wsdlFile; private $classmap; private $converters; - private $debug; + private $options; - public function __construct($wsdlFile, array $classmap, ConverterRepository $converters, $debug = false) + public function __construct($wsdlFile, array $classmap, ConverterRepository $converters, array $options = array()) { $this->wsdlFile = $wsdlFile; $this->classmap = $this->fixSoapServerClassmap($classmap); $this->converters = $converters; - $this->debug = $debug; + $this->setOptions($options); + } + + public function setOptions(array $options) + { + $this->options = array( + 'debug' => false, + 'cache_type' => null, + ); + + // check option names and live merge, if errors are encountered Exception will be thrown + $invalid = array(); + $isInvalid = false; + foreach ($options as $key => $value) { + if (array_key_exists($key, $this->options)) { + $this->options[$key] = $value; + } else { + $isInvalid = true; + $invalid[] = $key; + } + } + + if ($isInvalid) { + throw new \InvalidArgumentException(sprintf( + 'The "%s" class does not support the following options: "%s".', + get_class($this), + implode('\', \'', $invalid) + )); + } } public function create($request, $response) @@ -40,7 +68,7 @@ class SoapServerFactory 'classmap' => $this->classmap, 'typemap' => $this->createSoapServerTypemap($request, $response), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, - 'cache_wsdl' => Cache::getType(), + 'cache_wsdl' => null !== $this->options['cache_type'] ? $this->options['cache_type'] : Cache::getType(), ) ); } diff --git a/WebServiceContext.php b/WebServiceContext.php index ccf1ad9..a5d4e4a 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -103,7 +103,10 @@ class WebServiceContext $this->getWsdlFile(), $this->serviceDefinition->getDefinitionComplexTypes(), $this->converterRepository, - $this->options['debug'] + array( + 'debug' => $this->options['debug'], + 'cache_type' => isset($this->options['cache_type']) ? $this->options['cache_type'] : null, + ) ); } From 294058a59c928c8e70a322e52e8d41aa0bdd18b5 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 4 Sep 2011 23:43:20 +0200 Subject: [PATCH 124/195] Added namespace option in client definition --- DependencyInjection/BeSimpleSoapExtension.php | 2 ++ DependencyInjection/Configuration.php | 5 ++--- Resources/config/client.xml | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 7625b57..a2840ba 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -92,6 +92,8 @@ class BeSimpleSoapExtension extends Extension ->getArgument(1); $defOptions['cache_type'] = $options['cache_type']; + $defOptions['namespace'] = $options['namespace']; + $definition->replaceArgument(1, $defOptions); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index cf95cc4..3b15368 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -73,9 +73,8 @@ class Configuration ->useAttributeAsKey('name') ->prototype('array') ->children() - ->scalarNode('wsdl') - ->isRequired() - ->end() + ->scalarNode('wsdl')->isRequired()->end() + ->scalarNode('namespace')->defaultNull()->end() ->scalarNode('cache_type') ->validate() ->ifNotInArray($this->cacheTypes) diff --git a/Resources/config/client.xml b/Resources/config/client.xml index d98220e..8ef5918 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -13,6 +13,7 @@ %kernel.debug% null + null From ade1584448625329c2fcdaca57d494010b1ec18f Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 8 Sep 2011 20:42:09 +0200 Subject: [PATCH 125/195] Fixed issue #8 --- ServiceBinding/RpcLiteralResponseMessageBinder.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 2a9c8cb..a212ad9 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -79,12 +79,14 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $p = $r->getProperty($type->getName()); if ($p->isPublic()) { $value = $message->{$type->getName()}; + + $message->{$type->getName()} = $this->processType($type->getValue(), $value); } else { $p->setAccessible(true); $value = $p->getValue($message); - } - $value = $this->processType($type->getValue(), $value); + $p->setValue($message, $this->processType($type->getValue(), $value)); + } if (!$type->isNillable() && null === $value) { throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $class, $type->getName())); From 4850f782d5fd25657716bd5995dd119645aad352 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 8 Sep 2011 20:44:06 +0200 Subject: [PATCH 126/195] Updated RpcLiteralResponseMessageBinder to prevent infinite recursion --- ServiceBinding/RpcLiteralResponseMessageBinder.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index a212ad9..ed3f2e4 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -65,6 +65,8 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface return $this->messageRefs[$hash]; } + $this->messageRefs[$hash] = $message; + $class = $phpType; if ($class[0] == '\\') { $class = substr($class, 1); @@ -93,6 +95,6 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface } } - return $this->messageRefs[$hash] = $message; + return $message; } } \ No newline at end of file From 08c51aebcf30b303bf979a420a4a6114198e8d57 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 8 Sep 2011 21:24:40 +0200 Subject: [PATCH 127/195] Fixed typo --- Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index dac112a..4aab753 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -188,12 +188,12 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase array('bar', 'int'), )); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Bar'] = $this->createComplexTypeCollection(array( + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Bar'] = $this->createComplexTypeCollection(array( array('foo', 'string'), array('bar', 'int', true), )); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\FooBar'] = $this->createComplexTypeCollection(array( + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooBar'] = $this->createComplexTypeCollection(array( array('foo', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Foo'), array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Bar'), )); From 154863cc8451d37f5cec7e994238c66aa6d20d4a Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 8 Sep 2011 21:25:45 +0200 Subject: [PATCH 128/195] Prevent infinite recursion in RpcLiteralRequestMessageBinder --- .../RpcLiteralRequestMessageBinder.php | 6 +++-- .../RpcLiteralRequestMessageBinderTest.php | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 5929c9f..edef394 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -81,9 +81,11 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface { $hash = spl_object_hash($message); if (isset($this->messageRefs[$hash])) { - return $message; + return $this->messageRefs[$hash]; } + $this->messageRefs[$hash] = $message; + $r = new \ReflectionClass($message); foreach ($this->definitionComplexTypes[$phpType] as $type) { $p = $r->getProperty($type->getName()); @@ -101,6 +103,6 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface } } - return $this->messageRefs[$hash] = $message; + return $message; } } \ No newline at end of file diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index 4aab753..e021e94 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -130,6 +130,25 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('foo' => array()), $result); } + public function testProccessMessagePreventInfiniteRecursion() + { + $messageBinder = new RpcLiteralRequestMessageBinder(); + + $foo = new Fixtures\FooRecursive('foo', ''); + $bar = new Fixtures\BarRecursive($foo, 10394); + $foo->setBar($bar); + + $result = $messageBinder->processMessage( + new Definition\Method('prevent_infinite_recursion', null, array(), array( + new Definition\Argument('foo_recursive', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooRecursive')), + )), + array($foo), + $this->getDefinitionComplexTypes() + ); + + $this->assertEquals(array('foo_recursive' => $foo), $result); + } + public function messageProvider() { $messages = array(); @@ -198,6 +217,14 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Bar'), )); + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooRecursive'] = $this->createComplexTypeCollection(array( + array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\BarRecursive'), + )); + + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\BarRecursive'] = $this->createComplexTypeCollection(array( + array('foo', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooRecursive'), + )); + return $definitionComplexTypes; } From ecc3ec3c93217bd38289b88bb4ca1331f71746db Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 10 Sep 2011 19:39:14 +0200 Subject: [PATCH 129/195] Updated besimple.soap.client service --- DependencyInjection/BeSimpleSoapExtension.php | 4 ++-- Resources/config/client.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index a2840ba..b129e12 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -89,12 +89,12 @@ class BeSimpleSoapExtension extends Extension $defOptions = $container ->getDefinition('besimple.soap.client') - ->getArgument(1); + ->getArgument(2); $defOptions['cache_type'] = $options['cache_type']; $defOptions['namespace'] = $options['namespace']; - $definition->replaceArgument(1, $defOptions); + $definition->replaceArgument(2, $defOptions); } } } diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 8ef5918..741bfc1 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -10,6 +10,7 @@ wsdl + null %kernel.debug% null From 864cf228951cb0bc4fc2a2c9789225d7da87d15c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 13 Sep 2011 20:47:35 +0200 Subject: [PATCH 130/195] Used converters of BeSimple\SoapCommon for SoapServer --- Converter/ConverterRepository.php | 31 ------------- Converter/DateTimeTypeConverter.php | 44 ------------------- Converter/DateTypeConverter.php | 44 ------------------- Converter/TypeConverterInterface.php | 28 ------------ .../Compiler/TypeConverterPass.php | 6 +-- Resources/config/converters.xml | 8 ++-- Resources/config/webservice.xml | 4 +- Soap/SoapServerFactory.php | 15 ++++--- Tests/Converter/DateTimeTypeConverterTest.php | 43 ------------------ Tests/Converter/DateTypeConverterTest.php | 41 ----------------- WebServiceContext.php | 11 ++--- 11 files changed, 23 insertions(+), 252 deletions(-) delete mode 100644 Converter/ConverterRepository.php delete mode 100644 Converter/DateTimeTypeConverter.php delete mode 100644 Converter/DateTypeConverter.php delete mode 100644 Converter/TypeConverterInterface.php delete mode 100644 Tests/Converter/DateTimeTypeConverterTest.php delete mode 100644 Tests/Converter/DateTypeConverterTest.php diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php deleted file mode 100644 index a3d9392..0000000 --- a/Converter/ConverterRepository.php +++ /dev/null @@ -1,31 +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\Converter; - -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * @author Christian Kerl - */ -class ConverterRepository -{ - private $typeConverters = array(); - - public function addTypeConverter(TypeConverterInterface $converter) - { - $this->typeConverters[] = $converter; - } - - public function getTypeConverters() - { - return $this->typeConverters; - } -} diff --git a/Converter/DateTimeTypeConverter.php b/Converter/DateTimeTypeConverter.php deleted file mode 100644 index 9f692fc..0000000 --- a/Converter/DateTimeTypeConverter.php +++ /dev/null @@ -1,44 +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\Converter; - -use BeSimple\SoapBundle\Soap\SoapRequest; -use BeSimple\SoapBundle\Soap\SoapResponse; -use BeSimple\SoapBundle\Util\String; - -/** - * @author Christian Kerl - */ -class DateTimeTypeConverter implements TypeConverterInterface -{ - public function getTypeNamespace() - { - return 'http://www.w3.org/2001/XMLSchema'; - } - - public function getTypeName() - { - return 'dateTime'; - } - - public function convertXmlToPhp(SoapRequest $request, $data) - { - $doc = new \DOMDocument(); - $doc->loadXML($data); - - return new \DateTime($doc->textContent); - } - - public function convertPhpToXml(SoapResponse $response, $data) - { - return sprintf('<%1$s>%2$s', $this->getTypeName(), $data->format('Y-m-d\TH:i:sP')); - } -} diff --git a/Converter/DateTypeConverter.php b/Converter/DateTypeConverter.php deleted file mode 100644 index 61f7119..0000000 --- a/Converter/DateTypeConverter.php +++ /dev/null @@ -1,44 +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\Converter; - -use BeSimple\SoapBundle\Soap\SoapRequest; -use BeSimple\SoapBundle\Soap\SoapResponse; -use BeSimple\SoapBundle\Util\String; - -/** - * @author Francis Besset - */ -class DateTypeConverter implements TypeConverterInterface -{ - public function getTypeNamespace() - { - return 'http://www.w3.org/2001/XMLSchema'; - } - - public function getTypeName() - { - return 'date'; - } - - public function convertXmlToPhp(SoapRequest $request, $data) - { - $doc = new \DOMDocument(); - $doc->loadXML($data); - - return new \DateTime($doc->textContent); - } - - public function convertPhpToXml(SoapResponse $response, $data) - { - return sprintf('<%1$s>%2$s', $this->getTypeName(), $data->format('Y-m-d')); - } -} diff --git a/Converter/TypeConverterInterface.php b/Converter/TypeConverterInterface.php deleted file mode 100644 index ae74ed3..0000000 --- a/Converter/TypeConverterInterface.php +++ /dev/null @@ -1,28 +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\Converter; - -use BeSimple\SoapBundle\Soap\SoapRequest; -use BeSimple\SoapBundle\Soap\SoapResponse; - -/** - * @author Christian Kerl - */ -interface TypeConverterInterface -{ - function getTypeNamespace(); - - function getTypeName(); - - function convertXmlToPhp(SoapRequest $request, $data); - - function convertPhpToXml(SoapResponse $response, $data); -} \ No newline at end of file diff --git a/DependencyInjection/Compiler/TypeConverterPass.php b/DependencyInjection/Compiler/TypeConverterPass.php index be97bb6..828c9c9 100644 --- a/DependencyInjection/Compiler/TypeConverterPass.php +++ b/DependencyInjection/Compiler/TypeConverterPass.php @@ -23,14 +23,14 @@ class TypeConverterPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (false === $container->hasDefinition('besimple.soap.converter.repository')) { + if (false === $container->hasDefinition('besimple.soap.converter.collection')) { return; } - $definition = $container->getDefinition('besimple.soap.converter.repository'); + $definition = $container->getDefinition('besimple.soap.converter.collection'); foreach ($container->findTaggedServiceIds('besimple.soap.converter') as $id => $attributes) { - $definition->addMethodCall('addTypeConverter', array(new Reference($id))); + $definition->addMethodCall('add', array(new Reference($id))); } } } diff --git a/Resources/config/converters.xml b/Resources/config/converters.xml index ec6e5c5..f3f9c52 100644 --- a/Resources/config/converters.xml +++ b/Resources/config/converters.xml @@ -5,13 +5,13 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - BeSimple\SoapBundle\Converter\ConverterRepository - BeSimple\SoapBundle\Converter\DateTimeTypeConverter - BeSimple\SoapBundle\Converter\DateTypeConverter + BeSimple\SoapCommon\Converter\TypeConverterCollection + BeSimple\SoapCommon\Converter\DateTimeTypeConverter + BeSimple\SoapCommon\Converter\DateTypeConverter - + diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 71adcfa..d23f7ed 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -24,7 +24,7 @@ - + %besimple.soap.cache_dir% %kernel.debug% @@ -40,7 +40,7 @@ - + %besimple.soap.cache_dir% %kernel.debug% diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 00d9204..8db8b85 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -10,8 +10,9 @@ namespace BeSimple\SoapBundle\Soap; -use BeSimple\SoapBundle\Converter\ConverterRepository; use BeSimple\SoapCommon\Cache; +use BeSimple\SoapCommon\Converter\TypeConverterCollection; + use Zend\Soap\Wsdl; /** @@ -24,7 +25,7 @@ class SoapServerFactory private $converters; private $options; - public function __construct($wsdlFile, array $classmap, ConverterRepository $converters, array $options = array()) + public function __construct($wsdlFile, array $classmap, TypeConverterCollection $converters, array $options = array()) { $this->wsdlFile = $wsdlFile; $this->classmap = $this->fixSoapServerClassmap($classmap); @@ -77,15 +78,15 @@ class SoapServerFactory { $typemap = array(); - foreach($this->converters->getTypeConverters() as $typeConverter) { + foreach($this->converters->all() as $typeConverter) { $typemap[] = array( 'type_name' => $typeConverter->getTypeName(), 'type_ns' => $typeConverter->getTypeNamespace(), - 'from_xml' => function($input) use ($request, $typeConverter) { - return $typeConverter->convertXmlToPhp($request, $input); + 'from_xml' => function($input) use ($typeConverter) { + return $typeConverter->convertXmlToPhp($input); }, - 'to_xml' => function($input) use ($response, $typeConverter) { - return $typeConverter->convertPhpToXml($response, $input); + 'to_xml' => function($input) use ($typeConverter) { + return $typeConverter->convertPhpToXml($input); }, ); } diff --git a/Tests/Converter/DateTimeTypeConverterTest.php b/Tests/Converter/DateTimeTypeConverterTest.php deleted file mode 100644 index b04acd3..0000000 --- a/Tests/Converter/DateTimeTypeConverterTest.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\Tests\Converter; - -use BeSimple\SoapBundle\Soap\SoapRequest; -use BeSimple\SoapBundle\Soap\SoapResponse; -use BeSimple\SoapBundle\Converter\DateTimeTypeConverter; - -/** - * UnitTest for \BeSimple\SoapBundle\Converter\DateTimeTypeConverter. - * - * @author Christian Kerl - */ -class DateTimeTypeConverterTest extends \PHPUnit_Framework_TestCase -{ - public function testConvertXmlToPhp() - { - $converter = new DateTimeTypeConverter(); - - $dateXml = '2002-10-10T12:00:00-05:00'; - $date = $converter->convertXmlToPhp(new SoapRequest(), $dateXml); - - $this->assertEquals(new \DateTime('2002-10-10T12:00:00-05:00'), $date); - } - - public function testConvertPhpToXml() - { - $converter = new DateTimeTypeConverter(); - - $date = new \DateTime('2002-10-10T12:00:00-05:00'); - $dateXml = $converter->convertPhpToXml(new SoapResponse(), $date); - - $this->assertEquals('2002-10-10T12:00:00-05:00', $dateXml); - } -} diff --git a/Tests/Converter/DateTypeConverterTest.php b/Tests/Converter/DateTypeConverterTest.php deleted file mode 100644 index db53dd1..0000000 --- a/Tests/Converter/DateTypeConverterTest.php +++ /dev/null @@ -1,41 +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\Tests\Converter; - -use BeSimple\SoapBundle\Soap\SoapRequest; -use BeSimple\SoapBundle\Soap\SoapResponse; -use BeSimple\SoapBundle\Converter\DateTypeConverter; - -/** - * UnitTest for \BeSimple\SoapBundle\Converter\DateTimeTypeConverter. - */ -class DateTypeConverterTest extends \PHPUnit_Framework_TestCase -{ - public function testConvertXmlToPhp() - { - $converter = new DateTypeConverter(); - - $dateXml = '2002-10-10'; - $date = $converter->convertXmlToPhp(new SoapRequest(), $dateXml); - - $this->assertEquals(new \DateTime('2002-10-10'), $date); - } - - public function testConvertPhpToXml() - { - $converter = new DateTypeConverter(); - - $date = new \DateTime('2002-10-10'); - $dateXml = $converter->convertPhpToXml(new SoapResponse(), $date); - - $this->assertEquals('2002-10-10', $dateXml); - } -} diff --git a/WebServiceContext.php b/WebServiceContext.php index a5d4e4a..e03b200 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -10,13 +10,14 @@ namespace BeSimple\SoapBundle; -use BeSimple\SoapBundle\Converter\ConverterRepository; use BeSimple\SoapBundle\Converter\TypeRepository; use BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface; use BeSimple\SoapBundle\ServiceBinding\ServiceBinder; use BeSimple\SoapBundle\ServiceDefinition\Dumper\DumperInterface; use BeSimple\SoapBundle\Soap\SoapServerFactory; +use BeSimple\SoapCommon\Converter\TypeConverterCollection; + use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Loader\LoaderInterface; @@ -38,12 +39,12 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, TypeRepository $typeRepository, ConverterRepository $converterRepository, array $options) { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) { $this->loader = $loader; $this->wsdlFileDumper = $dumper; - $this->typeRepository = $typeRepository; - $this->converterRepository = $converterRepository; + $this->typeRepository = $typeRepository; + $this->converters = $converters; $this->options = $options; } @@ -102,7 +103,7 @@ class WebServiceContext $this->serverFactory = new SoapServerFactory( $this->getWsdlFile(), $this->serviceDefinition->getDefinitionComplexTypes(), - $this->converterRepository, + $this->converters, array( 'debug' => $this->options['debug'], 'cache_type' => isset($this->options['cache_type']) ? $this->options['cache_type'] : null, From 95c08c6edf0a40c9aa1dd026e66edaef5f0f227f Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 13 Sep 2011 20:50:16 +0200 Subject: [PATCH 131/195] Used converters of BeSimpleSoapCommon for SoapClient --- Resources/config/client.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 741bfc1..4c2299d 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -9,8 +9,8 @@ - wsdl - null + + %kernel.debug% null From 3de0636bb8613c61158c65391ea496ac219ffebe Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 13 Sep 2011 21:08:33 +0200 Subject: [PATCH 132/195] Used TypeConverterCollection::getTypemap() to build the typemap for SoapServer --- Soap/SoapServerFactory.php | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 8db8b85..7282f09 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -67,33 +67,13 @@ class SoapServerFactory $this->wsdlFile, array( 'classmap' => $this->classmap, - 'typemap' => $this->createSoapServerTypemap($request, $response), + 'typemap' => $this->converters->getTypemap(), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'cache_wsdl' => null !== $this->options['cache_type'] ? $this->options['cache_type'] : Cache::getType(), ) ); } - private function createSoapServerTypemap($request, $response) - { - $typemap = array(); - - foreach($this->converters->all() as $typeConverter) { - $typemap[] = array( - 'type_name' => $typeConverter->getTypeName(), - 'type_ns' => $typeConverter->getTypeNamespace(), - 'from_xml' => function($input) use ($typeConverter) { - return $typeConverter->convertXmlToPhp($input); - }, - 'to_xml' => function($input) use ($typeConverter) { - return $typeConverter->convertPhpToXml($input); - }, - ); - } - - return $typemap; - } - private function fixSoapServerClassmap($classmap) { $classmapFixed = array(); From a0a92dd1b419f632566f8ab8bb789ff5e4c0ce73 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 13 Sep 2011 21:34:39 +0200 Subject: [PATCH 133/195] Added fixtures files --- .../RpcLiteralRequestMessageBinderTest.php | 2 +- .../RpcLiteralResponseMessageBinderTest.php | 227 ------------------ .../fixtures/ServiceBinding/BarRecursive.php | 13 + .../fixtures/ServiceBinding/FooRecursive.php | 8 + 4 files changed, 22 insertions(+), 228 deletions(-) delete mode 100644 Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php create mode 100644 Tests/fixtures/ServiceBinding/BarRecursive.php create mode 100644 Tests/fixtures/ServiceBinding/FooRecursive.php diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index e021e94..c656611 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -136,7 +136,7 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $foo = new Fixtures\FooRecursive('foo', ''); $bar = new Fixtures\BarRecursive($foo, 10394); - $foo->setBar($bar); + $foo->bar = $bar; $result = $messageBinder->processMessage( new Definition\Method('prevent_infinite_recursion', null, array(), array( diff --git a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php deleted file mode 100644 index 9da41e8..0000000 --- a/Tests/ServiceBinding/RpcLiteralResponseMessageBinderTest.php +++ /dev/null @@ -1,227 +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\Tests\ServiceBinding; - -use BeSimple\SoapBundle\ServiceDefinition\Method; -use BeSimple\SoapBundle\ServiceDefinition\Type; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; -use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; -use BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder; -use BeSimple\SoapBundle\Util\Collection; -use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes; -use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType; -use BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters; - -/** - * UnitTest for \BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder. - * - * @author Francis Besset - */ -class RpcLiteralResponseMessageBinderTest extends \PHPUnit_Framework_TestCase -{ - /** - * @dataProvider messageProvider - */ - public function testProcessMessage(Method $method, $message, $assert) - { - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage($method, $message); - - $this->assertSame($assert, $result); - } - - public function testProcessMessageWithComplexType() - { - $definitionComplexTypes = $this->getDefinitionComplexTypes(); - - $attributes = new Attributes(); - $attributes->foo = 'foobar'; - $attributes->bar = 20349; - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes')), - $attributes, - $definitionComplexTypes - ); - - $this->assertInstanceOf('stdClass', $result); - $this->assertSame('foobar', $result->foo); - $this->assertSame(20349, $result->bar); - - $attributes1 = new Attributes(); - $attributes1->foo = 'bar'; - $attributes1->bar = 2929; - $attributes2 = new Attributes(); - $attributes2->foo = 'foo'; - $attributes2->bar = 123992; - $message = array($attributes1, $attributes2); - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), - $message, - $definitionComplexTypes - ); - - $this->assertTrue(is_array($result)); - - $this->assertInstanceOf('stdClass', $result[0]); - $this->assertSame('bar', $result[0]->foo); - $this->assertSame(2929, $result[0]->bar); - - $this->assertInstanceOf('stdClass', $result[1]); - $this->assertSame('foo', $result[1]->foo); - $this->assertSame(123992, $result[1]->bar); - } - - public function testProcessMessageWithComplexTypeMethods() - { - $setters = new Setters(); - $setters->setFoo('foobar'); - $setters->setBar(42); - - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_methods', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters')), - $setters, - $this->getDefinitionComplexTypes() - ); - - $this->assertInstanceOf('stdClass', $result); - $this->assertSame('foobar', $result->foo); - $this->assertSame(42, $result->bar); - } - - public function testProcessMessageWithComplexTypeIntoComplexType() - { - $complexType = new ComplexType(); - - $foo = new Attributes(); - $foo->foo = 'Hello world!'; - $foo->bar = 4242; - $complexType->setFoo($foo); - - $bar = new Setters(); - $bar->setFoo('bar foo'); - $bar->setBar(2424); - $complexType->bar = $bar; - - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_complextype', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType')), - $complexType, - $this->getDefinitionComplexTypes() - ); - - $this->assertInstanceOf('stdClass', $result); - - $this->assertInstanceOf('stdClass', $result->foo); - $this->assertSame('Hello world!', $result->foo->foo); - $this->assertSame(4242, $result->foo->bar); - - $this->assertInstanceOf('stdClass', $result->bar); - $this->assertSame('bar foo', $result->bar->foo); - $this->assertSame(2424, $result->bar->bar); - } - - public function testProcessMessageWithComplexTypeReferences() - { - $attributes = new Attributes(); - $attributes->foo = 'bar'; - $attributes->bar = 2929; - - $message = array($attributes, $attributes); - $messageBinder = new RpcLiteralResponseMessageBinder(); - $result = $messageBinder->processMessage( - new Method('complextype_argument', null, array(), array(), new Type('\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes[]')), - $message, - $this->getDefinitionComplexTypes() - ); - - $this->assertInstanceOf('stdClass', $result[0]); - $this->assertSame($result[0], $result[1]); - } - - public function messageProvider() - { - $messages = array(); - - $messages[] = array( - new Method('boolean', null, array(), array(), new Type('boolean')), - true, - true, - ); - - $messages[] = array( - new Method('strings', null, array(), array(), new Type('string[]')), - array('hello', 'world'), - array('hello', 'world'), - ); - - return $messages; - } - - private function getDefinitionComplexTypes() - { - $this->definitionComplexTypes = array(); - - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes'] = $this->createPropertiesCollection(array( - array('foo', 'string'), - array('bar', 'int'), - )); - - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'] = $this->createMethodsCollection(array( - array('foo', 'string', 'getFoo', 'setFoo'), - array('bar', 'int', 'getBar', 'setBar'), - )); - - $collection = $this->createMethodsCollection(array( - array('foo', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Attributes', 'getFoo', 'setFoo'), - )); - $this->createPropertiesCollection(array( - array('bar', '\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\Setters'), - ), $collection); - $this->definitionComplexTypes['\BeSimple\SoapBundle\Tests\ServiceBinding\fixtures\ComplexType'] = $collection; - - return $this->definitionComplexTypes; - } - - private function createPropertiesCollection(array $properties, Collection $collection = null) - { - $collection = $collection ?: new Collection('getName'); - - foreach ($properties as $property) { - $collectionProperty = new PropertyComplexType(); - $collectionProperty->setName($property[0]); - $collectionProperty->setValue($property[1]); - - $collection->add($collectionProperty); - } - - return $collection; - } - - private function createMethodsCollection(array $methods, Collection $collection = null) - { - $collection = $collection ?: new Collection('getName'); - - foreach ($methods as $method) { - $collectionMethod = new MethodComplexType(); - $collectionMethod->setName($method[0]); - $collectionMethod->setValue($method[1]); - $collectionMethod->setOriginalName($method[2]); - $collectionMethod->setSetter($method[3]); - - $collection->add($collectionMethod); - } - - return $collection; - } -} diff --git a/Tests/fixtures/ServiceBinding/BarRecursive.php b/Tests/fixtures/ServiceBinding/BarRecursive.php new file mode 100644 index 0000000..c7d3d14 --- /dev/null +++ b/Tests/fixtures/ServiceBinding/BarRecursive.php @@ -0,0 +1,13 @@ +foo = $foo; + } +} \ No newline at end of file diff --git a/Tests/fixtures/ServiceBinding/FooRecursive.php b/Tests/fixtures/ServiceBinding/FooRecursive.php new file mode 100644 index 0000000..b39c9f1 --- /dev/null +++ b/Tests/fixtures/ServiceBinding/FooRecursive.php @@ -0,0 +1,8 @@ + Date: Wed, 14 Sep 2011 22:03:46 +0200 Subject: [PATCH 134/195] Fixed issue #10 --- ServiceBinding/RpcLiteralResponseMessageBinder.php | 13 ++++--------- ServiceDefinition/Type.php | 5 +++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index ed3f2e4..5cb6310 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -67,17 +67,12 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $this->messageRefs[$hash] = $message; - $class = $phpType; - if ($class[0] == '\\') { - $class = substr($class, 1); - } - - if (!$message instanceof $class) { - throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', get_class($message), $class)); + if (!$message instanceof $phpType) { + throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', get_class($message), $phpType)); } $r = new \ReflectionClass($message); - foreach ($this->definitionComplexTypes[$class] as $type) { + foreach ($this->definitionComplexTypes[$phpType] as $type) { $p = $r->getProperty($type->getName()); if ($p->isPublic()) { $value = $message->{$type->getName()}; @@ -91,7 +86,7 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface } if (!$type->isNillable() && null === $value) { - throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $class, $type->getName())); + throw new \InvalidArgumentException(sprintf('"%s::%s" cannot be null.', $phpType, $type->getName())); } } diff --git a/ServiceDefinition/Type.php b/ServiceDefinition/Type.php index bf2c1d1..2855689 100644 --- a/ServiceDefinition/Type.php +++ b/ServiceDefinition/Type.php @@ -30,6 +30,11 @@ class Type public function setPhpType($phpType) { + $phpType = $phpType; + if ($phpType[0] == '\\') { + $phpType = substr($phpType, 1); + } + $this->phpType = $phpType; } From dbeb00eae2ad129192e2cd189dc2d3aea562ad91 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 20 Sep 2011 22:34:16 +0200 Subject: [PATCH 135/195] Added the possibility to add headers for a controller Example: reader->getClassAnnotations($class) as $annotation) { + if ($annotation instanceof Annotation\Header) { + $serviceMethodHeaders[$annotation->getValue()] = $annotation; + } + } + foreach ($class->getMethods() as $method) { $serviceArguments = $serviceHeaders = array(); $serviceMethod = $serviceReturn = null; - foreach ($this->reader->getMethodAnnotations($method) as $i => $annotation) { + 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[] = new Definition\Header( + $serviceHeaders[$annotation->getValue()] = new Definition\Header( $annotation->getValue(), $this->getArgumentType($method, $annotation) ); From edee6a4c72fda9c8505c15e3e8a4f83ae76a5d62 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 22 Sep 2011 00:16:11 +0200 Subject: [PATCH 136/195] [Doc] Updated header tutorial to specify global headers functionality --- Resources/doc/tutorial/header.rst | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/tutorial/header.rst index c3928df..687dfef 100644 --- a/Resources/doc/tutorial/header.rst +++ b/Resources/doc/tutorial/header.rst @@ -30,4 +30,60 @@ Controller return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); } + } + +Global header +------------- + +If you want use a header for all actions of your controller you can declare the header like this: + +.. code-block:: php + + namespace My\App\Controller; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use Symfony\Component\DependencyInjection\ContainerAware; + use Symfony\Component\DependencyInjection\ContainerInterface; + + /** + * @Soap\Header("api_key", phpType = "string") + */ + class DemoController extends ContainerAware + { + /** + * @Soap\Method("hello") + * @Soap\Param("names", phpType = "string[]") + * @Soap\Result(phpType = "string") + */ + public function helloAction(array $names) + { + return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); + } + + /** + * @Soap\Method("welcome") + * @Soap\Param("names", phpType = "string[]") + * @Soap\Result(phpType = "string") + */ + public function welcomeAction() + { + return $this->container->get('besimple.soap.response')->setReturnValue("Welcome ".implode(', ', $names)); + } + + public function setContainer(ContainerInterface $container = null) + { + parent::setContainer($container); + + $this->checkApiKeyHeader(); + } + + private function checkApiKeyHeader() + { + $soapHeaders = $this->container->get('request')->getSoapHeaders(); + + // You can use '1234' !== (string) $soapHeaders->get('api_key') + if (!$soapHeaders->has('api_key') || '1234' !== $soapHeaders->get('api_key')->getData()) { + throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); + } + } } \ No newline at end of file From 0f86292fcbf025552e8ac0b44d8bd7168c998bdf Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 24 Sep 2011 13:44:10 +0300 Subject: [PATCH 137/195] [Doc] Fixed typo --- Resources/doc/tutorial/header.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/tutorial/header.rst index 687dfef..efd042f 100644 --- a/Resources/doc/tutorial/header.rst +++ b/Resources/doc/tutorial/header.rst @@ -65,7 +65,7 @@ If you want use a header for all actions of your controller you can declare the * @Soap\Param("names", phpType = "string[]") * @Soap\Result(phpType = "string") */ - public function welcomeAction() + public function welcomeAction($names) { return $this->container->get('besimple.soap.response')->setReturnValue("Welcome ".implode(', ', $names)); } From 94a8a8fec1aafb4c78b60f4790e94324f33cf753 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 8 Oct 2011 12:41:47 +0200 Subject: [PATCH 138/195] Updated SoapClient definition --- DependencyInjection/BeSimpleSoapExtension.php | 4 ++-- Resources/config/client.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index b129e12..a2840ba 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -89,12 +89,12 @@ class BeSimpleSoapExtension extends Extension $defOptions = $container ->getDefinition('besimple.soap.client') - ->getArgument(2); + ->getArgument(1); $defOptions['cache_type'] = $options['cache_type']; $defOptions['namespace'] = $options['namespace']; - $definition->replaceArgument(2, $defOptions); + $definition->replaceArgument(1, $defOptions); } } } diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 4c2299d..102f34b 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -10,12 +10,12 @@ - %kernel.debug% null null + From 1d9bd2cdd376645d99846f92e851f00263e50bd0 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 8 Oct 2011 18:03:27 +0200 Subject: [PATCH 139/195] Added besimple.soap.classmap service --- DependencyInjection/BeSimpleSoapExtension.php | 19 +++++++++++++++++++ DependencyInjection/Configuration.php | 4 ++++ Resources/config/client.xml | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index a2840ba..02bb008 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -96,9 +96,28 @@ class BeSimpleSoapExtension extends Extension $definition->replaceArgument(1, $defOptions); } + + if (!empty($options['classmap'])) { + $classmap = $this->createClientClassmap($client, $options['classmap'], $container); + $definition->replaceArgument(2, new Reference($classmap)); + } else { + $definition->replaceArgument(2, null); + } } } + private function createClientClassmap($client, array $classmap, ContainerBuilder $container) + { + $definition = new DefinitionDecorator('besimple.soap.classmap'); + $context = $container->setDefinition(sprintf('besimple.soap.classmap.%s', $client), $definition); + + $definition->setMethodCalls(array( + array('set', array($classmap)), + )); + + return sprintf('besimple.soap.classmap.%s', $client); + } + private function createWebServiceContext(array $config, ContainerBuilder $container) { $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 3b15368..bb8bedf 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -81,6 +81,10 @@ class Configuration ->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes))) ->end() ->end() + ->arrayNode('classmap') + ->useAttributeAsKey('name') + ->prototype('scalar') + ->end() ->end() ->end() ->end() diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 102f34b..efc63ca 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -5,6 +5,7 @@ BeSimple\SoapClient\SoapClient + BeSimple\SoapCommon\Classmap @@ -15,9 +16,12 @@ null null + + + From 6d2e9d763476398e71cc44a46eb5f395f67c3179 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 8 Oct 2011 22:04:18 +0200 Subject: [PATCH 140/195] Added user_agent option --- DependencyInjection/BeSimpleSoapExtension.php | 19 +++++++++++-------- DependencyInjection/Configuration.php | 3 ++- Resources/config/client.xml | 2 -- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 02bb008..c462bca 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -84,19 +84,22 @@ class BeSimpleSoapExtension extends Extension $definition->replaceArgument(0, $options['wsdl']); - if (isset($options['cache_type'])) { - $options['cache_type'] = $this->getCacheType($options['cache_type']); - - $defOptions = $container + $defOptions = $container ->getDefinition('besimple.soap.client') ->getArgument(1); - $defOptions['cache_type'] = $options['cache_type']; - $defOptions['namespace'] = $options['namespace']; - - $definition->replaceArgument(1, $defOptions); + foreach (array('cache_type', 'namespace', 'user_agent') as $key) { + if (isset($options[$key])) { + $defOptions[$key] = $options[$key]; + } } + if (isset($defOptions['cache_type'])) { + $$defOptions['cache_type'] = $this->getCacheType($defOptions['cache_type']); + } + + $definition->replaceArgument(1, $defOptions); + if (!empty($options['classmap'])) { $classmap = $this->createClientClassmap($client, $options['classmap'], $container); $definition->replaceArgument(2, new Reference($classmap)); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index bb8bedf..658a283 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -74,7 +74,8 @@ class Configuration ->prototype('array') ->children() ->scalarNode('wsdl')->isRequired()->end() - ->scalarNode('namespace')->defaultNull()->end() + ->scalarNode('namespace')->end() + ->scalarNode('user_agent')->end() ->scalarNode('cache_type') ->validate() ->ifNotInArray($this->cacheTypes) diff --git a/Resources/config/client.xml b/Resources/config/client.xml index efc63ca..7ea688b 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -13,8 +13,6 @@ %kernel.debug% - null - null From d3c31116c7994624d670f57712a34265176f19aa Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 10 Oct 2011 22:19:43 +0200 Subject: [PATCH 141/195] Replaced soap.client by soap.client.builder --- DependencyInjection/BeSimpleSoapExtension.php | 20 +++-- DependencyInjection/Configuration.php | 1 - Resources/config/client.xml | 6 +- Soap/SoapClientBuilder.php | 77 +++++++++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 Soap/SoapClientBuilder.php diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index c462bca..62fc3aa 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -79,23 +79,23 @@ class BeSimpleSoapExtension extends Extension $loader->load('client.xml'); foreach ($config as $client => $options) { - $definition = new DefinitionDecorator('besimple.soap.client'); - $context = $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition); + $definition = new DefinitionDecorator('besimple.soap.client.builder'); + $context = $container->setDefinition(sprintf('besimple.soap.client.builder.%s', $client), $definition); $definition->replaceArgument(0, $options['wsdl']); $defOptions = $container - ->getDefinition('besimple.soap.client') + ->getDefinition('besimple.soap.client.builder') ->getArgument(1); - foreach (array('cache_type', 'namespace', 'user_agent') as $key) { + foreach (array('cache_type', 'user_agent') as $key) { if (isset($options[$key])) { $defOptions[$key] = $options[$key]; } } if (isset($defOptions['cache_type'])) { - $$defOptions['cache_type'] = $this->getCacheType($defOptions['cache_type']); + $defOptions['cache_type'] = $this->getCacheType($defOptions['cache_type']); } $definition->replaceArgument(1, $defOptions); @@ -106,6 +106,8 @@ class BeSimpleSoapExtension extends Extension } else { $definition->replaceArgument(2, null); } + + $this->createClient($client, $container); } } @@ -121,6 +123,14 @@ class BeSimpleSoapExtension extends Extension return sprintf('besimple.soap.classmap.%s', $client); } + private function createClient($client, ContainerBuilder $container) + { + $definition = new DefinitionDecorator('besimple.soap.client'); + $context = $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition); + + $definition->setFactoryService(sprintf('besimple.soap.client.builder.%s', $client)); + } + private function createWebServiceContext(array $config, ContainerBuilder $container) { $bindingSuffix = $this->bindingConfigToServiceSuffixMap[$config['binding']]; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 658a283..c56f3c9 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -74,7 +74,6 @@ class Configuration ->prototype('array') ->children() ->scalarNode('wsdl')->isRequired()->end() - ->scalarNode('namespace')->end() ->scalarNode('user_agent')->end() ->scalarNode('cache_type') ->validate() diff --git a/Resources/config/client.xml b/Resources/config/client.xml index 7ea688b..939e470 100644 --- a/Resources/config/client.xml +++ b/Resources/config/client.xml @@ -4,12 +4,12 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - BeSimple\SoapClient\SoapClient + BeSimple\SoapBundle\Soap\SoapClientBuilder BeSimple\SoapCommon\Classmap - + %kernel.debug% @@ -19,6 +19,8 @@ + + diff --git a/Soap/SoapClientBuilder.php b/Soap/SoapClientBuilder.php new file mode 100644 index 0000000..c21993f --- /dev/null +++ b/Soap/SoapClientBuilder.php @@ -0,0 +1,77 @@ +checkOptions($options); + + $this + ->withWsdl($wsdl) + ->withTrace($options['debug']) + ; + + if (isset($options['user_agent'])) { + $this->withUserAgent($options['user_agent']); + } + + if (isset($options['cache_type'])) { + $this->withWsdlCache($options['cache_type']); + } + + if ($classmap) { + $this->withClassmap($classmap); + } + + if ($converters) { + $this->withTypeConverters($converters); + } + } + + public function build() + { + if (!$this->soapClient) { + $this->soapClient = parent::build(); + } + + return $this->soapClient; + } + + protected function checkOptions(array $options) + { + $checkOptions = array( + 'debug' => false, + 'cache_type' => null, + 'exceptions' => true, + 'user_agent' => 'BeSimpleSoap', + ); + + // check option names and live merge, if errors are encountered Exception will be thrown + $invalid = array(); + $isInvalid = false; + foreach ($options as $key => $value) { + if (!array_key_exists($key, $checkOptions)) { + $isInvalid = true; + $invalid[] = $key; + } + } + + if ($isInvalid) { + throw new \InvalidArgumentException(sprintf( + 'The "%s" class does not support the following options: "%s".', + get_class($this), + implode('\', \'', $invalid) + )); + } + } +} \ No newline at end of file From 4a7ec164e5eed75073ad378d4d4958738935e0f8 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 11 Oct 2011 22:41:32 +0200 Subject: [PATCH 142/195] Updated Cache class --- Cache.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Cache.php b/Cache.php index 71d8927..f5a4f88 100644 --- a/Cache.php +++ b/Cache.php @@ -21,7 +21,9 @@ class Cache { public function __construct($disabled, $type, $directory, $lifetime = null, $limit = null) { - BaseCache::setEnabled(!$disabled); + $isEnabled = $disabled ? BaseCache::DISABLED : BaseCache::ENABLED; + + BaseCache::setEnabled($isEnabled); if (BaseCache::ENABLED == BaseCache::isEnabled()) { BaseCache::setType($type); From 70a85460c9a30be214485a19455fba7673ed0326 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 12 Oct 2011 21:08:59 +0200 Subject: [PATCH 143/195] Used BeSimple\SoapCommon\Classmap for the webservice context --- DependencyInjection/BeSimpleSoapExtension.php | 6 +++--- Resources/config/webservice.xml | 6 ++++++ ServiceDefinition/Dumper/WsdlDumper.php | 8 +++++-- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 8 +++++-- ServiceDefinition/Strategy/ComplexType.php | 7 ++++++- Soap/SoapServerFactory.php | 21 ++++++------------- WebServiceContext.php | 7 +++++-- 7 files changed, 38 insertions(+), 25 deletions(-) diff --git a/DependencyInjection/BeSimpleSoapExtension.php b/DependencyInjection/BeSimpleSoapExtension.php index 62fc3aa..941cbf0 100644 --- a/DependencyInjection/BeSimpleSoapExtension.php +++ b/DependencyInjection/BeSimpleSoapExtension.php @@ -51,7 +51,7 @@ class BeSimpleSoapExtension extends Extension $this->registerCacheConfiguration($config['cache'], $container, $loader); - if (isset($config['clients'])) { + if (!empty($config['clients'])) { $this->registerClientConfiguration($config['clients'], $container, $loader); } @@ -146,9 +146,9 @@ class BeSimpleSoapExtension extends Extension $options = $container ->getDefinition('besimple.soap.context.'.$bindingSuffix) - ->getArgument(4); + ->getArgument(5); - $definition->replaceArgument(4, array_merge($options, $config)); + $definition->replaceArgument(5, array_merge($options, $config)); } private function getCacheType($type) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index d23f7ed..95e97b6 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -15,6 +15,7 @@ BeSimple\SoapBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder BeSimple\SoapBundle\ServiceDefinition\Dumper\WsdlDumper BeSimple\SoapBundle\Converter\TypeRepository + BeSimple\SoapCommon\Classmap @@ -23,6 +24,7 @@ + @@ -39,6 +41,7 @@ + @@ -54,12 +57,15 @@ + %besimple.soap.definition.dumper.options.stylesheet% + + xsd diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 97517f7..bf348e2 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -18,21 +18,25 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use BeSimple\SoapBundle\Util\Assert; use BeSimple\SoapBundle\Util\QName; +use BeSimple\SoapCommon\Classmap; + /** * @author Christian Kerl */ class WsdlDumper implements DumperInterface { private $loader; + private $classmap; private $typeRepository; private $options; private $wsdl; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader, TypeRepository $typeRepository, array $options) + public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, TypeRepository $typeRepository, array $options) { $this->loader = $loader; + $this->classmap = $classmap; $this->typeRepository = $typeRepository; $this->options = $options; } @@ -42,7 +46,7 @@ class WsdlDumper implements DumperInterface Assert::thatArgumentNotNull('definition', $definition); $this->definition = $definition; - $this->wsdl = new Wsdl($this->typeRepository, $definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy($this->loader, $definition)); + $this->wsdl = new Wsdl($this->typeRepository, $definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy($this->loader, $this->classmap, $definition)); $port = $this->wsdl->addPortType($this->getPortTypeName()); $binding = $this->wsdl->addBinding($this->getBindingName(), $this->qualify($this->getPortTypeName())); diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 62610e8..1d35d9c 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -15,6 +15,8 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use BeSimple\SoapBundle\ServiceDefinition\Strategy\ComplexType; use BeSimple\SoapBundle\Util\String; +use BeSimple\SoapCommon\Classmap; + use Zend\Soap\Exception; use Zend\Soap\Wsdl as BaseWsdl; use Zend\Soap\Wsdl\Strategy; @@ -30,14 +32,16 @@ class WsdlTypeStrategy implements Strategy private $context; private $loader; + private $classmap; private $definition; private $typeStrategy; private $arrayStrategy; - public function __construct(AnnotationComplexTypeLoader $loader, ServiceDefinition $definition) + public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, ServiceDefinition $definition) { $this->loader = $loader; + $this->classmap = $classmap; $this->definition = $definition; } @@ -86,7 +90,7 @@ class WsdlTypeStrategy implements Strategy private function getTypeStrategy() { if (!$this->typeStrategy) { - $this->typeStrategy = new ComplexType($this->loader, $this->definition); + $this->typeStrategy = new ComplexType($this->loader, $this->classmap, $this->definition); $this->typeStrategy->setContext($this->context); } diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php index 8af3fb1..b608902 100644 --- a/ServiceDefinition/Strategy/ComplexType.php +++ b/ServiceDefinition/Strategy/ComplexType.php @@ -12,6 +12,7 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Strategy; use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; +use BeSimple\SoapCommon\Classmap; use Zend\Soap\Wsdl; use Zend\Soap\Wsdl\Strategy\AbstractStrategy; @@ -21,11 +22,13 @@ use Zend\Soap\Wsdl\Strategy\AbstractStrategy; class ComplexType extends AbstractStrategy { private $loader; + private $classmap; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader, $definition) + public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, $definition) { $this->loader = $loader; + $this->classmap = $classmap; $this->definition = $definition; } @@ -50,6 +53,8 @@ class ComplexType extends AbstractStrategy $soapTypeName = Wsdl::translateType($type); $soapType = 'tns:'.$soapTypeName; + $this->classmap->add($soapTypeName, $type); + // Register type here to avoid recursion $this->getContext()->addType($type, $soapType); diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php index 7282f09..caa133f 100644 --- a/Soap/SoapServerFactory.php +++ b/Soap/SoapServerFactory.php @@ -11,6 +11,7 @@ namespace BeSimple\SoapBundle\Soap; use BeSimple\SoapCommon\Cache; +use BeSimple\SoapCommon\Classmap; use BeSimple\SoapCommon\Converter\TypeConverterCollection; use Zend\Soap\Wsdl; @@ -25,11 +26,12 @@ class SoapServerFactory private $converters; private $options; - public function __construct($wsdlFile, array $classmap, TypeConverterCollection $converters, array $options = array()) + public function __construct($wsdlFile, Classmap $classmap, TypeConverterCollection $converters, array $options = array()) { $this->wsdlFile = $wsdlFile; - $this->classmap = $this->fixSoapServerClassmap($classmap); + $this->classmap = $classmap; $this->converters = $converters; + $this->setOptions($options); } @@ -66,22 +68,11 @@ class SoapServerFactory return new \SoapServer( $this->wsdlFile, array( - 'classmap' => $this->classmap, + 'classmap' => $this->classmap->all(), 'typemap' => $this->converters->getTypemap(), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'cache_wsdl' => null !== $this->options['cache_type'] ? $this->options['cache_type'] : Cache::getType(), ) ); } - - private function fixSoapServerClassmap($classmap) - { - $classmapFixed = array(); - - foreach ($classmap as $class => $definition) { - $classmapFixed[Wsdl::translateType($class)] = $class; - } - - return $classmapFixed; - } -} \ No newline at end of file +} diff --git a/WebServiceContext.php b/WebServiceContext.php index e03b200..666c806 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -16,6 +16,7 @@ use BeSimple\SoapBundle\ServiceBinding\ServiceBinder; use BeSimple\SoapBundle\ServiceDefinition\Dumper\DumperInterface; use BeSimple\SoapBundle\Soap\SoapServerFactory; +use BeSimple\SoapCommon\Classmap; use BeSimple\SoapCommon\Converter\TypeConverterCollection; use Symfony\Component\Config\ConfigCache; @@ -39,10 +40,12 @@ class WebServiceContext private $serviceBinder; private $serverFactory; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, Classmap $classmap, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) { $this->loader = $loader; $this->wsdlFileDumper = $dumper; + $this->classmap = $classmap; + $this->typeRepository = $typeRepository; $this->converters = $converters; @@ -102,7 +105,7 @@ class WebServiceContext if (null === $this->serverFactory) { $this->serverFactory = new SoapServerFactory( $this->getWsdlFile(), - $this->serviceDefinition->getDefinitionComplexTypes(), + $this->classmap, $this->converters, array( 'debug' => $this->options['debug'], From 32259355d6def8b81dc61d1fd3d5a5237c7c5fbf Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 12 Oct 2011 22:01:50 +0200 Subject: [PATCH 144/195] Deleted SoapServerFactory and used BeSimple\SoapServer\SoapServerBuilder to build the SoapServer --- Controller/SoapWebServiceController.php | 8 ++- Soap/SoapServerFactory.php | 78 ------------------------- WebServiceContext.php | 30 +++++----- 3 files changed, 21 insertions(+), 95 deletions(-) delete mode 100644 Soap/SoapServerFactory.php diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index fc93eb8..fee611d 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -58,9 +58,11 @@ class SoapWebServiceController extends ContainerAware $this->serviceBinder = $webServiceContext->getServiceBinder(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request')); - $this->soapServer = $webServiceContext->getServerFactory()->create($this->soapRequest, $this->getResponse()); - - $this->soapServer->setObject($this); + $this->soapServer = $webServiceContext + ->getServerBuilder() + ->withHandler($this) + ->build() + ; ob_start(); $this->soapServer->handle($this->soapRequest->getSoapMessage()); diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php deleted file mode 100644 index caa133f..0000000 --- a/Soap/SoapServerFactory.php +++ /dev/null @@ -1,78 +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\Soap; - -use BeSimple\SoapCommon\Cache; -use BeSimple\SoapCommon\Classmap; -use BeSimple\SoapCommon\Converter\TypeConverterCollection; - -use Zend\Soap\Wsdl; - -/** - * @author Christian Kerl - */ -class SoapServerFactory -{ - private $wsdlFile; - private $classmap; - private $converters; - private $options; - - public function __construct($wsdlFile, Classmap $classmap, TypeConverterCollection $converters, array $options = array()) - { - $this->wsdlFile = $wsdlFile; - $this->classmap = $classmap; - $this->converters = $converters; - - $this->setOptions($options); - } - - public function setOptions(array $options) - { - $this->options = array( - 'debug' => false, - 'cache_type' => null, - ); - - // check option names and live merge, if errors are encountered Exception will be thrown - $invalid = array(); - $isInvalid = false; - foreach ($options as $key => $value) { - if (array_key_exists($key, $this->options)) { - $this->options[$key] = $value; - } else { - $isInvalid = true; - $invalid[] = $key; - } - } - - if ($isInvalid) { - throw new \InvalidArgumentException(sprintf( - 'The "%s" class does not support the following options: "%s".', - get_class($this), - implode('\', \'', $invalid) - )); - } - } - - public function create($request, $response) - { - return new \SoapServer( - $this->wsdlFile, - array( - 'classmap' => $this->classmap->all(), - 'typemap' => $this->converters->getTypemap(), - 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, - 'cache_wsdl' => null !== $this->options['cache_type'] ? $this->options['cache_type'] : Cache::getType(), - ) - ); - } -} diff --git a/WebServiceContext.php b/WebServiceContext.php index 666c806..eaeb588 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -14,10 +14,10 @@ use BeSimple\SoapBundle\Converter\TypeRepository; use BeSimple\SoapBundle\ServiceBinding\MessageBinderInterface; use BeSimple\SoapBundle\ServiceBinding\ServiceBinder; use BeSimple\SoapBundle\ServiceDefinition\Dumper\DumperInterface; -use BeSimple\SoapBundle\Soap\SoapServerFactory; use BeSimple\SoapCommon\Classmap; use BeSimple\SoapCommon\Converter\TypeConverterCollection; +use BeSimple\SoapServer\SoapServerBuilder; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\Loader\LoaderInterface; @@ -38,7 +38,7 @@ class WebServiceContext private $serviceDefinition; private $serviceBinder; - private $serverFactory; + private $serverBuilder; public function __construct(LoaderInterface $loader, DumperInterface $dumper, Classmap $classmap, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) { $this->loader = $loader; @@ -100,20 +100,22 @@ class WebServiceContext return $this->serviceBinder; } - public function getServerFactory() + public function getServerBuilder() { - if (null === $this->serverFactory) { - $this->serverFactory = new SoapServerFactory( - $this->getWsdlFile(), - $this->classmap, - $this->converters, - array( - 'debug' => $this->options['debug'], - 'cache_type' => isset($this->options['cache_type']) ? $this->options['cache_type'] : null, - ) - ); + if (null === $this->serverBuilder) { + $this->serverBuilder = SoapServerBuilder::createWithDefaults() + ->withWsdl($this->getWsdlFile()) + ->withClassmap($this->classmap) + ->withTypeConverters($this->converters) + ; + + if (!$this->options['debug']) { + $this->serverBuilder->withWsdlCacheNone(); + } elseif (null !== $this->options['cache_type']) { + $this->serverBuilder->withWsdlCache($this->options['cache_type']); + } } - return $this->serverFactory; + return $this->serverBuilder; } } \ No newline at end of file From 4abf5a59edddf3348f10f01df90e476793e7e164 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 13 Nov 2011 21:55:26 +0100 Subject: [PATCH 145/195] [Doc] Add the WSDL address --- Resources/doc/reference/configuration.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Resources/doc/reference/configuration.rst b/Resources/doc/reference/configuration.rst index 1ccd620..1662e86 100644 --- a/Resources/doc/reference/configuration.rst +++ b/Resources/doc/reference/configuration.rst @@ -50,4 +50,9 @@ Annotations for Controllers { return $this->container->get('besimple.soap.response')->setReturnValue(sprintf('Hello %s!', $name)); } - } \ No newline at end of file + } + +Get your WSDL +------------- + +To access your WSDL go to the following address: http://localhost/app_dev.php/ws/DemoApi?wsdl From 0ac7a78870468423f8bf0dd76d11424921c9ef4d Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 13 Nov 2011 22:40:42 +0100 Subject: [PATCH 146/195] [Doc] Global update --- Resources/doc/cache.rst | 26 +++++++++++++ Resources/doc/index.rst | 24 ++++++++---- .../doc/{reference => }/installation.rst | 38 ++++++++++++++++++- .../configuration.rst | 0 .../doc/{ => soapserver}/tutorial/array.rst | 0 .../tutorial/complex_type.rst | 0 .../doc/{ => soapserver}/tutorial/header.rst | 0 Resources/doc/soapserver/tutorials.rst | 9 +++++ .../doc/{reference => soapserver}/types.rst | 0 9 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 Resources/doc/cache.rst rename Resources/doc/{reference => }/installation.rst (52%) rename Resources/doc/{reference => soapserver}/configuration.rst (100%) rename Resources/doc/{ => soapserver}/tutorial/array.rst (100%) rename Resources/doc/{ => soapserver}/tutorial/complex_type.rst (100%) rename Resources/doc/{ => soapserver}/tutorial/header.rst (100%) create mode 100644 Resources/doc/soapserver/tutorials.rst rename Resources/doc/{reference => soapserver}/types.rst (100%) diff --git a/Resources/doc/cache.rst b/Resources/doc/cache.rst new file mode 100644 index 0000000..0090361 --- /dev/null +++ b/Resources/doc/cache.rst @@ -0,0 +1,26 @@ +Cache +===== + +Configuration +------------- + +Configure the cache of PHP Soap WSDL in your config file: + +.. code-block:: yaml + + # app/config/config.yml + be_simple_soap: + cache: + type: disk + lifetime: 86400 + limit: 5 + +The cache type can be: **none**, **disk** (default value), **memory**, **disk_memory**. + +The lifetime in seconds of a WSDL file in the cache (**86400 is the default value by PHP**). + +The limit is the maximum number of in-memory cached WSDL files (**5 is the default value by PHP**). + +If you want more information you can visit the following page `PHP Soap runtime configuration`_. + +.. _`PHP Soap runtime configuration`: http://www.php.net/manual/en/soap.configuration.php \ No newline at end of file diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index 19be4f2..9182aa0 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -1,9 +1,11 @@ +================== BeSimpleSoapBundle ================== The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. It is based on the `ckWebServicePlugin`_ for symfony. +--------------- Reference Guide --------------- @@ -11,19 +13,25 @@ Reference Guide :maxdepth: 1 :numbered: - reference/installation - reference/configuration - reference/types + installation + cache -Tutorial --------- +---------- +SoapServer +---------- .. toctree:: :maxdepth: 1 :numbered: - tutorial/array - tutorial/complex_type - tutorial/header + soapserver/configuration + soapserver/types + soapserver/tutorials + +---------- +SoapClient +---------- + +Coming soon. .. _`ckWebServicePlugin`: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file diff --git a/Resources/doc/reference/installation.rst b/Resources/doc/installation.rst similarity index 52% rename from Resources/doc/reference/installation.rst rename to Resources/doc/installation.rst index 495bec3..7a6c2e1 100644 --- a/Resources/doc/reference/installation.rst +++ b/Resources/doc/installation.rst @@ -4,8 +4,39 @@ Installation Requirements ------------ -Install and enable PHP's SOAP extension -Download `Zend\\Soap`_ and `Zend\\Mime`_ or add in `deps` file +Install and enable PHP's SOAP extension. + +Download `BeSimple\\SoapCommon`_ and `BeSimple\\SoapServer`_ (only for the server part) and/or `BeSimple\\SoapClient`_ (only for ther client part). + +.. code-block:: ini + + ; deps file + [BeSimple\SoapCommon] + git=http://github.com/BeSimple/SoapCommon + target=/besimple-soapcommon + + [BeSimple\SoapClient] + git=http://github.com/BeSimple/SoapClient + target=/besimple-soapclient + + [BeSimple\SoapServer] + git=http://github.com/BeSimple/SoapServer + target=/besimple-soapserver + + +Add `BeSimple` libraries in autoload.php + +.. code-block:: php + + // app/autoload.php + $loader->registerNamespaces(array( + 'BeSimple\\SoapCommon' => __DIR__.'/../vendor/besimple-soapcommon', + 'BeSimple\\SoapServer' => __DIR__.'/../vendor/besimple-soapserver', + 'BeSimple\\SoapClient' => __DIR__.'/../vendor/besimple-soapclient', + // your other namespaces + )); + +Download `Zend\\Soap`_ and `Zend\\Mime`_ or add in `deps` file. `Zend` library is required only for the server part. .. code-block:: ini @@ -67,4 +98,7 @@ Add `BeSimpleSoapBundle` in your Kernel class .. _`Zend\\Soap`: http://github.com/BeSimple/zend-soap .. _`Zend\\Mime`: http://github.com/BeSimple/zend-mime +.. _`BeSimple\\SoapCommon`: http://github.com/BeSimple/BeSimpleSoapCommon +.. _`BeSimple\\SoapServer`: http://github.com/BeSimple/BeSimpleSoapServer +.. _`BeSimple\\SoapClient`: http://github.com/BeSimple/BeSimpleSoapClient .. _`Download`: http://github.com/BeSimple/BeSimpleSoapBundle diff --git a/Resources/doc/reference/configuration.rst b/Resources/doc/soapserver/configuration.rst similarity index 100% rename from Resources/doc/reference/configuration.rst rename to Resources/doc/soapserver/configuration.rst diff --git a/Resources/doc/tutorial/array.rst b/Resources/doc/soapserver/tutorial/array.rst similarity index 100% rename from Resources/doc/tutorial/array.rst rename to Resources/doc/soapserver/tutorial/array.rst diff --git a/Resources/doc/tutorial/complex_type.rst b/Resources/doc/soapserver/tutorial/complex_type.rst similarity index 100% rename from Resources/doc/tutorial/complex_type.rst rename to Resources/doc/soapserver/tutorial/complex_type.rst diff --git a/Resources/doc/tutorial/header.rst b/Resources/doc/soapserver/tutorial/header.rst similarity index 100% rename from Resources/doc/tutorial/header.rst rename to Resources/doc/soapserver/tutorial/header.rst diff --git a/Resources/doc/soapserver/tutorials.rst b/Resources/doc/soapserver/tutorials.rst new file mode 100644 index 0000000..d1d36a4 --- /dev/null +++ b/Resources/doc/soapserver/tutorials.rst @@ -0,0 +1,9 @@ +Tutorials +========= + +.. toctree:: + :maxdepth: 1 + + tutorial/array + tutorial/complex_type + tutorial/header diff --git a/Resources/doc/reference/types.rst b/Resources/doc/soapserver/types.rst similarity index 100% rename from Resources/doc/reference/types.rst rename to Resources/doc/soapserver/types.rst From ebb5343e11422888fc37d803553d79263f5b5820 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sun, 13 Nov 2011 22:51:29 +0100 Subject: [PATCH 147/195] [Doc] Updated cache documentation --- Resources/doc/cache.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/doc/cache.rst b/Resources/doc/cache.rst index 0090361..1c12010 100644 --- a/Resources/doc/cache.rst +++ b/Resources/doc/cache.rst @@ -21,6 +21,8 @@ The lifetime in seconds of a WSDL file in the cache (**86400 is the default valu The limit is the maximum number of in-memory cached WSDL files (**5 is the default value by PHP**). +The WSDL files cached are written in cache folder of your Symfony2 application. + If you want more information you can visit the following page `PHP Soap runtime configuration`_. .. _`PHP Soap runtime configuration`: http://www.php.net/manual/en/soap.configuration.php \ No newline at end of file From 8f79b3392a70c560d066216e02a9f8e53b8967a0 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 14 Nov 2011 20:23:40 +0100 Subject: [PATCH 148/195] Deleted condition to disable caching the WSDL in WebServiceContext --- WebServiceContext.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WebServiceContext.php b/WebServiceContext.php index eaeb588..49d447a 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -109,9 +109,7 @@ class WebServiceContext ->withTypeConverters($this->converters) ; - if (!$this->options['debug']) { - $this->serverBuilder->withWsdlCacheNone(); - } elseif (null !== $this->options['cache_type']) { + if (null !== $this->options['cache_type']) { $this->serverBuilder->withWsdlCache($this->options['cache_type']); } } From 65fc380fa2801cc92d1b6761b7aad7b197083ac6 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 17 Nov 2011 19:58:23 +0100 Subject: [PATCH 149/195] Fixed issue #16 --- ServiceDefinition/Dumper/WsdlDumper.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index bf348e2..1d31687 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -82,7 +82,10 @@ class WsdlDumper implements DumperInterface $this->qualify($this->getRequestMessageName($method)), $this->qualify($this->getResponseMessageName($method)) ); - $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); + + if (!empty($requestParts)) { + $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); + } $baseBinding = array( 'use' => 'literal', From 64e1759f45361fe681e335f8e7359a01fb1b67ca Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 22 Nov 2011 10:08:36 +0100 Subject: [PATCH 150/195] [Doc] Updated SoapServer configuration --- Resources/doc/soapserver/configuration.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Resources/doc/soapserver/configuration.rst b/Resources/doc/soapserver/configuration.rst index 1662e86..0549b4b 100644 --- a/Resources/doc/soapserver/configuration.rst +++ b/Resources/doc/soapserver/configuration.rst @@ -56,3 +56,6 @@ Get your WSDL ------------- To access your WSDL go to the following address: http://localhost/app_dev.php/ws/DemoApi?wsdl + +To read the WSDL in your browser you can call this address: http://localhost/app_dev.php/ws/DemoApi + From b1b0fb87f1707d05620dd9dab013abfa7a37c137 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 22 Nov 2011 23:00:59 +0100 Subject: [PATCH 151/195] Fixed issue #15 and #18 --- WebServiceContext.php | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/WebServiceContext.php b/WebServiceContext.php index 49d447a..556db5d 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -29,6 +29,8 @@ use Symfony\Component\Config\Loader\LoaderInterface; */ class WebServiceContext { + private $classmap; + private $typeRepository; private $converterRepository; @@ -55,15 +57,20 @@ class WebServiceContext public function getServiceDefinition() { if (null === $this->serviceDefinition) { - 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'])); + $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; + } 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'])); + } + + $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->typeRepository->fixTypeInformation($this->serviceDefinition); } - - $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->typeRepository->fixTypeInformation($this->serviceDefinition); } return $this->serviceDefinition; @@ -76,14 +83,19 @@ class WebServiceContext public function getWsdlFile($endpoint = null) { - $file = sprintf('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint)); - $cache = new ConfigCache($file, $this->options['debug']); + $file = sprintf('%s/%s.%s.wsdl', $this->options['cache_dir'], $this->options['name'], md5($endpoint)); + $cacheWsdl = new ConfigCache($file, $this->options['debug']); - if(!$cache->isFresh()) { - $cache->write($this->wsdlFileDumper->dumpServiceDefinition($this->getServiceDefinition(), $endpoint)); + if(!$cacheWsdl->isFresh()) { + $serviceDefinition = $this->getServiceDefinition(); + + $cacheWsdl->write($this->wsdlFileDumper->dumpServiceDefinition($serviceDefinition, $endpoint)); + + $cacheDefinition = new ConfigCache(sprintf('%s/%s.definition.php', $this->options['cache_dir'], $this->options['name']), $this->options['debug']); + $cacheDefinition->write('serverBuilder; } -} \ No newline at end of file +} From ea65831c128cd098cafeebecb927f2a5f2c990d2 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 22 Nov 2011 23:05:55 +0100 Subject: [PATCH 152/195] Fixed typo on definition of cache directory --- Resources/config/soap.xml | 4 ++-- Resources/config/webservice.xml | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Resources/config/soap.xml b/Resources/config/soap.xml index 3fb3d4c..1d54d67 100644 --- a/Resources/config/soap.xml +++ b/Resources/config/soap.xml @@ -5,14 +5,14 @@ BeSimple\SoapBundle\Cache - %kernel.cache_dir%/besimple/soap + %kernel.cache_dir%/besimple/soap %kernel.debug% %besimple.soap.cache.type% - %besimple.soap.cache.directory% + %besimple.soap.cache.dir%/php %besimple.soap.cache.lifetime% %besimple.soap.cache.limit% diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index 95e97b6..abdf1a9 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -6,7 +6,6 @@ BeSimple\SoapBundle\Soap\SoapResponse BeSimple\SoapBundle\WebServiceContext - %kernel.cache_dir%/webservice BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestHeaderMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralResponseMessageBinder @@ -28,7 +27,7 @@ - %besimple.soap.cache_dir% + %besimple.soap.cache.dir% %kernel.debug% null %besimple.soap.binder.request_header.rpcliteral.class% @@ -45,7 +44,7 @@ - %besimple.soap.cache_dir% + %besimple.soap.cache.dir% %kernel.debug% null %besimple.soap.binder.request_header.documentwrapped.class% From bacdc908703199ea89ef43070d4a1462534ab325 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 26 Nov 2011 12:18:29 +0100 Subject: [PATCH 153/195] Moved Classmap instance in ServiceDefinition --- Resources/config/webservice.xml | 1 - ServiceDefinition/Dumper/WsdlDumper.php | 8 ++----- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 8 ++----- ServiceDefinition/ServiceDefinition.php | 21 +++++++++++++++++-- ServiceDefinition/Strategy/ComplexType.php | 8 ++----- WebServiceContext.php | 5 ++++- 6 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index abdf1a9..ae07e99 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -56,7 +56,6 @@ - %besimple.soap.definition.dumper.options.stylesheet% diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 1d31687..5fbdf6f 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -18,25 +18,21 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use BeSimple\SoapBundle\Util\Assert; use BeSimple\SoapBundle\Util\QName; -use BeSimple\SoapCommon\Classmap; - /** * @author Christian Kerl */ class WsdlDumper implements DumperInterface { private $loader; - private $classmap; private $typeRepository; private $options; private $wsdl; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, TypeRepository $typeRepository, array $options) + public function __construct(AnnotationComplexTypeLoader $loader, TypeRepository $typeRepository, array $options) { $this->loader = $loader; - $this->classmap = $classmap; $this->typeRepository = $typeRepository; $this->options = $options; } @@ -46,7 +42,7 @@ class WsdlDumper implements DumperInterface Assert::thatArgumentNotNull('definition', $definition); $this->definition = $definition; - $this->wsdl = new Wsdl($this->typeRepository, $definition->getName(), $definition->getNamespace(), new WsdlTypeStrategy($this->loader, $this->classmap, $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())); diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 1d35d9c..62610e8 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -15,8 +15,6 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use BeSimple\SoapBundle\ServiceDefinition\Strategy\ComplexType; use BeSimple\SoapBundle\Util\String; -use BeSimple\SoapCommon\Classmap; - use Zend\Soap\Exception; use Zend\Soap\Wsdl as BaseWsdl; use Zend\Soap\Wsdl\Strategy; @@ -32,16 +30,14 @@ class WsdlTypeStrategy implements Strategy private $context; private $loader; - private $classmap; private $definition; private $typeStrategy; private $arrayStrategy; - public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, ServiceDefinition $definition) + public function __construct(AnnotationComplexTypeLoader $loader, ServiceDefinition $definition) { $this->loader = $loader; - $this->classmap = $classmap; $this->definition = $definition; } @@ -90,7 +86,7 @@ class WsdlTypeStrategy implements Strategy private function getTypeStrategy() { if (!$this->typeStrategy) { - $this->typeStrategy = new ComplexType($this->loader, $this->classmap, $this->definition); + $this->typeStrategy = new ComplexType($this->loader, $this->definition); $this->typeStrategy->setContext($this->context); } diff --git a/ServiceDefinition/ServiceDefinition.php b/ServiceDefinition/ServiceDefinition.php index adfd50b..458f23d 100644 --- a/ServiceDefinition/ServiceDefinition.php +++ b/ServiceDefinition/ServiceDefinition.php @@ -11,6 +11,7 @@ namespace BeSimple\SoapBundle\ServiceDefinition; use BeSimple\SoapBundle\Util\Collection; +use BeSimple\SoapCommon\Classmap; class ServiceDefinition { @@ -29,16 +30,22 @@ class ServiceDefinition */ private $methods; + /** + * @var \BeSimple\SoapCommon\Classmap + */ + private $classmap; + private $complexTypes = array(); - public function __construct($name = null, $namespace = null, array $methods = 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; } /** @@ -111,6 +118,16 @@ class ServiceDefinition return $types; } + public function getClassmap() + { + return $this->classmap ?: array(); + } + + public function setClassmap(Classmap $classmap) + { + $this->classmap = $classmap; + } + public function addDefinitionComplexType($type, Collection $complexType) { $this->complexTypes[$type] = $complexType; diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php index b608902..696f425 100644 --- a/ServiceDefinition/Strategy/ComplexType.php +++ b/ServiceDefinition/Strategy/ComplexType.php @@ -11,8 +11,6 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Strategy; use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; - -use BeSimple\SoapCommon\Classmap; use Zend\Soap\Wsdl; use Zend\Soap\Wsdl\Strategy\AbstractStrategy; @@ -22,13 +20,11 @@ use Zend\Soap\Wsdl\Strategy\AbstractStrategy; class ComplexType extends AbstractStrategy { private $loader; - private $classmap; private $definition; - public function __construct(AnnotationComplexTypeLoader $loader, Classmap $classmap, $definition) + public function __construct(AnnotationComplexTypeLoader $loader, $definition) { $this->loader = $loader; - $this->classmap = $classmap; $this->definition = $definition; } @@ -53,7 +49,7 @@ class ComplexType extends AbstractStrategy $soapTypeName = Wsdl::translateType($type); $soapType = 'tns:'.$soapTypeName; - $this->classmap->add($soapTypeName, $type); + $this->definition->getClassmap()->add($soapTypeName, $type); // Register type here to avoid recursion $this->getContext()->addType($type, $soapType); diff --git a/WebServiceContext.php b/WebServiceContext.php index 556db5d..2cc879d 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -69,6 +69,9 @@ 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); } } @@ -117,7 +120,7 @@ class WebServiceContext if (null === $this->serverBuilder) { $this->serverBuilder = SoapServerBuilder::createWithDefaults() ->withWsdl($this->getWsdlFile()) - ->withClassmap($this->classmap) + ->withClassmap($this->getServiceDefinition()->getClassmap()) ->withTypeConverters($this->converters) ; From 16ee889230a74071611dd0030e889ab8c5295948 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Sat, 26 Nov 2011 19:59:09 +0100 Subject: [PATCH 154/195] Check that complex type has not in classmap before adding --- ServiceDefinition/Strategy/ComplexType.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php index 696f425..88c1adf 100644 --- a/ServiceDefinition/Strategy/ComplexType.php +++ b/ServiceDefinition/Strategy/ComplexType.php @@ -36,6 +36,8 @@ class ComplexType extends AbstractStrategy */ public function addComplexType($type) { + $classmap = $this->definition->getClassmap(); + if (null !== $soapType = $this->scanRegisteredTypes($type)) { return $soapType; } @@ -49,7 +51,9 @@ class ComplexType extends AbstractStrategy $soapTypeName = Wsdl::translateType($type); $soapType = 'tns:'.$soapTypeName; - $this->definition->getClassmap()->add($soapTypeName, $type); + if (!$classmap->has($soapTypeName)) { + $classmap->add($soapTypeName, $type); + } // Register type here to avoid recursion $this->getContext()->addType($type, $soapType); From 5cb8249218fb629bf6d918a971673b00f03add4f Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 1 Dec 2011 11:12:40 +0100 Subject: [PATCH 155/195] Fixed issue #20 --- Resources/doc/installation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/doc/installation.rst b/Resources/doc/installation.rst index 7a6c2e1..b98f9d1 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation.rst @@ -30,9 +30,9 @@ Add `BeSimple` libraries in autoload.php // app/autoload.php $loader->registerNamespaces(array( - 'BeSimple\\SoapCommon' => __DIR__.'/../vendor/besimple-soapcommon', - 'BeSimple\\SoapServer' => __DIR__.'/../vendor/besimple-soapserver', - 'BeSimple\\SoapClient' => __DIR__.'/../vendor/besimple-soapclient', + 'BeSimple\\SoapCommon' => __DIR__.'/../vendor/besimple-soapcommon/src', + 'BeSimple\\SoapServer' => __DIR__.'/../vendor/besimple-soapserver/src', + 'BeSimple\\SoapClient' => __DIR__.'/../vendor/besimple-soapclient/src', // your other namespaces )); From f0031e8923ba52e66bc4964859a3afa4f2e12856 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 1 Dec 2011 11:18:05 +0100 Subject: [PATCH 156/195] Fixed issue #17 --- ServiceDefinition/Dumper/WsdlDumper.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/ServiceDefinition/Dumper/WsdlDumper.php b/ServiceDefinition/Dumper/WsdlDumper.php index 5fbdf6f..abe64c3 100644 --- a/ServiceDefinition/Dumper/WsdlDumper.php +++ b/ServiceDefinition/Dumper/WsdlDumper.php @@ -79,21 +79,29 @@ class WsdlDumper implements DumperInterface $this->qualify($this->getResponseMessageName($method)) ); - if (!empty($requestParts)) { - $portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts))); - } - - $baseBinding = array( + $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(), - array_merge(array('parts' => implode(' ', array_keys($requestParts))), $baseBinding), - array_merge(array('parts' => implode(' ', array_keys($responseParts))), $baseBinding) + $inputBinding, + $outputBinding ); $bindingOperation = $this->wsdl->addBindingOperationHeader( $bindingOperation, From d2cdc9ccad77b764a0b0e87b34c5669fec0fd492 Mon Sep 17 00:00:00 2001 From: craigmarvelley Date: Wed, 4 Jan 2012 11:47:45 +0000 Subject: [PATCH 157/195] Updated to work with latest version of Zend\Soap --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 2 +- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 6 +++--- ServiceDefinition/Strategy/ComplexType.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index edef394..7a5934d 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -99,7 +99,7 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $value = $this->processType($type->getValue(), $value); if (!$type->isNillable() && null === $value) { - throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst(Wsdl::translateType($phpType)), $type->getName())); + throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst($phpType), $type->getName())); } } diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index 62610e8..b6f18fa 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -17,10 +17,10 @@ use BeSimple\SoapBundle\Util\String; use Zend\Soap\Exception; use Zend\Soap\Wsdl as BaseWsdl; -use Zend\Soap\Wsdl\Strategy; -use Zend\Soap\Wsdl\Strategy\ArrayOfTypeSequence; +use Zend\Soap\Wsdl\ComplexTypeStrategy; +use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence; -class WsdlTypeStrategy implements Strategy +class WsdlTypeStrategy implements ComplexTypeStrategy { /** * Context WSDL file diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php index 88c1adf..9913619 100644 --- a/ServiceDefinition/Strategy/ComplexType.php +++ b/ServiceDefinition/Strategy/ComplexType.php @@ -48,7 +48,7 @@ class ComplexType extends AbstractStrategy $dom = $this->getContext()->toDomDocument(); - $soapTypeName = Wsdl::translateType($type); + $soapTypeName = $this->getContext()->translateType($type); $soapType = 'tns:'.$soapTypeName; if (!$classmap->has($soapTypeName)) { From a8c2fbb13ab716a7580825c515a1b9358a5eeb4a Mon Sep 17 00:00:00 2001 From: craigmarvelley Date: Thu, 5 Jan 2012 16:37:12 +0000 Subject: [PATCH 158/195] Fixed bug causing annotations in inheriting controllers to be ignored --- ServiceDefinition/Loader/AnnotationClassLoader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index d76ec56..f545786 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -96,7 +96,7 @@ class AnnotationClassLoader implements LoaderInterface $serviceMethod = new Definition\Method( $annotation->getValue(), - $this->getController($method, $annotation) + $this->getController($class, $method, $annotation) ); } elseif ($annotation instanceof Annotation\Result) { if ($serviceReturn) { @@ -134,12 +134,12 @@ class AnnotationClassLoader implements LoaderInterface * * @return string */ - private function getController(\ReflectionMethod $method, Annotation\Method $annotation) + private function getController(\ReflectionClass $class, \ReflectionMethod $method, Annotation\Method $annotation) { if(null !== $annotation->getService()) { return $annotation->getService() . ':' . $method->name; } else { - return $method->class . '::' . $method->name; + return $class->name . '::' . $method->name; } } From 63d3611006fa338978f9794943278c5f955d0e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Dubinskas?= Date: Wed, 11 Jan 2012 15:11:55 +0200 Subject: [PATCH 159/195] Fix to allow ComplexType to be nillable --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 4 +++- ServiceBinding/RpcLiteralResponseMessageBinder.php | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index edef394..edcaecc 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -96,7 +96,9 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $value = $p->getValue($message); } - $value = $this->processType($type->getValue(), $value); + if ($value !== null) { + $value = $this->processType($type->getValue(), $value); + } if (!$type->isNillable() && null === $value) { throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst(Wsdl::translateType($phpType)), $type->getName())); diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 5cb6310..f894d97 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -82,7 +82,11 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $p->setAccessible(true); $value = $p->getValue($message); - $p->setValue($message, $this->processType($type->getValue(), $value)); + if ($value !== null) { + $value = $this->processType($type->getValue(), $value); + } + + $p->setValue($message, $value); } if (!$type->isNillable() && null === $value) { From 383d24e86b4090cc1b185c0a1b6013ece0d5e649 Mon Sep 17 00:00:00 2001 From: Vytautas Gimbutas Date: Thu, 12 Jan 2012 11:22:08 +0200 Subject: [PATCH 160/195] Fix for ComplexType --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index edcaecc..210d6a2 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -98,6 +98,7 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface if ($value !== null) { $value = $this->processType($type->getValue(), $value); + $p->setValue($message, $value); } if (!$type->isNillable() && null === $value) { From cfe949b78159031cc46a08ae81ac44d8228c4c9c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 12 Jan 2012 11:45:15 +0100 Subject: [PATCH 161/195] Fixed bug if a complex type contains a collection --- .../RpcLiteralRequestMessageBinder.php | 6 ++++ .../RpcLiteralResponseMessageBinder.php | 12 ++++--- .../RpcLiteralRequestMessageBinderTest.php | 31 ++++++++++++++++++- .../fixtures/ServiceBinding/SimpleArrays.php | 28 +++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 Tests/fixtures/ServiceBinding/SimpleArrays.php diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index edef394..21cfe17 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -98,6 +98,12 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $value = $this->processType($type->getValue(), $value); + if ($p->isPublic()) { + $message->{$type->getName()} = $value; + } else { + $p->setValue($message, $value); + } + if (!$type->isNillable() && null === $value) { throw new \SoapFault('SOAP_ERROR_COMPLEX_TYPE', sprintf('"%s:%s" cannot be null.', ucfirst(Wsdl::translateType($phpType)), $type->getName())); } diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index 5cb6310..d4e57df 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -76,13 +76,17 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface $p = $r->getProperty($type->getName()); if ($p->isPublic()) { $value = $message->{$type->getName()}; - - $message->{$type->getName()} = $this->processType($type->getValue(), $value); } else { $p->setAccessible(true); $value = $p->getValue($message); + } - $p->setValue($message, $this->processType($type->getValue(), $value)); + $value = $this->processType($type->getValue(), $value); + + if ($p->isPublic()) { + $message->{$type->getName()} = $value; + } else { + $p->setValue($message, $value); } if (!$type->isNillable() && null === $value) { @@ -92,4 +96,4 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface return $message; } -} \ No newline at end of file +} diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index c656611..b48adf7 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php @@ -115,6 +115,29 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('fooBar' => $fooBar), $result); } + public function testProcessMessageComplexTypeWithArrays() + { + $messageBinder = new RpcLiteralRequestMessageBinder(); + + $array = array(1, 2, 3, 4); + $stdClass = new \stdClass(); + $stdClass->item = $array; + $simpleArrays = new Fixtures\SimpleArrays(null, new \stdClass(), $stdClass); + + $result = $messageBinder->processMessage( + new Definition\Method('complextype_with_array', null, array(), array( + new Definition\Argument('simple_arrays', new Definition\Type('BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\SimpleArrays')), + )), + array($simpleArrays), + $this->getDefinitionComplexTypes() + ); + + $result = $result['simple_arrays']; + $this->assertEquals(array(), $result->array1); + $this->assertEquals(array(), $result->getArray2()); + $this->assertEquals($array, $result->getArray3()); + } + public function testProcessMessageWithEmptyArrayComplexType() { $messageBinder = new RpcLiteralRequestMessageBinder(); @@ -217,6 +240,12 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\Bar'), )); + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\SimpleArrays'] = $this->createComplexTypeCollection(array( + array('array1', 'string[]', true), + array('array2', 'string[]'), + array('array3', 'string[]'), + )); + $definitionComplexTypes['BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\FooRecursive'] = $this->createComplexTypeCollection(array( array('bar', 'BeSimple\SoapBundle\Tests\fixtures\ServiceBinding\BarRecursive'), )); @@ -246,4 +275,4 @@ class RpcLiteralRequestMessageBinderTest extends \PHPUnit_Framework_TestCase return $collection; } -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/SimpleArrays.php b/Tests/fixtures/ServiceBinding/SimpleArrays.php new file mode 100644 index 0000000..e17a640 --- /dev/null +++ b/Tests/fixtures/ServiceBinding/SimpleArrays.php @@ -0,0 +1,28 @@ +array1 = $array1; + $this->array2 = $array2; + $this->array3 = $array3; + } + + public function getArray2() + { + return $this->array2; + } + + public function getArray3() + { + return $this->array3; + } +} From 80f999675a0b6ee08a1a8fead6ffd2a2aac65049 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 12 Jan 2012 11:56:39 +0100 Subject: [PATCH 162/195] =?UTF-8?q?Added=20=C5=A0ar=C5=ABnas=20Dubinskas?= =?UTF-8?q?=20in=20contributors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTORS.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.markdown b/CONTRIBUTORS.markdown index d78d2c3..afe3528 100644 --- a/CONTRIBUTORS.markdown +++ b/CONTRIBUTORS.markdown @@ -1,2 +1,4 @@ * [Christian Kerl](https://github.com/christiankerl) * [Francis Besset](https://github.com/francisbesset) +* [Šarūnas Dubinskas](https://github.com/sarunas) + From 4741e142d0222e7f037278420db4bd40bf9872a6 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 1 Aug 2012 09:36:30 +0300 Subject: [PATCH 163/195] Added Craig Marvelley in contributors file --- CONTRIBUTORS.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.markdown b/CONTRIBUTORS.markdown index afe3528..7d12a30 100644 --- a/CONTRIBUTORS.markdown +++ b/CONTRIBUTORS.markdown @@ -1,4 +1,4 @@ * [Christian Kerl](https://github.com/christiankerl) * [Francis Besset](https://github.com/francisbesset) * [Šarūnas Dubinskas](https://github.com/sarunas) - +* [Craig Marvelley](https://github.com/craigmarvelley) From 5a8864806029dda3ecc8972e0dd28606838d8d3e Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Mon, 27 Aug 2012 08:59:29 +0200 Subject: [PATCH 164/195] Refactoring of SoapWebServiceController::definitionAction() --- Controller/SoapWebServiceController.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index fee611d..c67e1a9 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -76,17 +76,18 @@ class SoapWebServiceController extends ContainerAware */ public function definitionAction($webservice) { - $webServiceContext = $this->getWebServiceContext($webservice); - $request = $this->container->get('request'); + $response = new Response($this->getWebServiceContext($webservice)->getWsdlFileContent( + $this->container->get('router')->generate( + '_webservice_call', + array('webservice' => $webservice), + true + ) + )); + $request = $this->container->get('request'); if ($request->query->has('wsdl') || $request->query->has('WSDL')) { - $endpoint = $this->container->get('router')->generate('_webservice_call', array('webservice' => $webservice), true); - - $response = new Response($webServiceContext->getWsdlFileContent($endpoint)); $response->headers->set('Content-Type', 'application/wsdl+xml'); } else { - // TODO: replace with better representation - $response = new Response($webServiceContext->getWsdlFileContent()); $response->headers->set('Content-Type', 'text/xml'); } From 76bd41018e98d480bd2f0d411c93fcf73a25ce5a Mon Sep 17 00:00:00 2001 From: Matthias Noback Date: Thu, 15 Nov 2012 10:34:29 +0100 Subject: [PATCH 165/195] Fixed git URLs for the deps file --- Resources/doc/installation.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/doc/installation.rst b/Resources/doc/installation.rst index b98f9d1..00088a3 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation.rst @@ -12,16 +12,16 @@ Download `BeSimple\\SoapCommon`_ and `BeSimple\\SoapServer`_ (only for the serve ; deps file [BeSimple\SoapCommon] - git=http://github.com/BeSimple/SoapCommon - target=/besimple-soapcommon - + git=https://github.com/BeSimple/BeSimpleSoapCommon.git + target=besimple-soapcommon + [BeSimple\SoapClient] - git=http://github.com/BeSimple/SoapClient - target=/besimple-soapclient - + git=https://github.com/BeSimple/BeSimpleSoapClient.git + target=besimple-soapclient + [BeSimple\SoapServer] - git=http://github.com/BeSimple/SoapServer - target=/besimple-soapserver + git=https://github.com/BeSimple/BeSimpleSoapServer.git + target=besimple-soapserver Add `BeSimple` libraries in autoload.php From baa586e268a599904f73cf52e76054a0eae20041 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Tue, 15 Jan 2013 22:49:57 +0100 Subject: [PATCH 166/195] Added composer.json --- composer.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..f0941eb --- /dev/null +++ b/composer.json @@ -0,0 +1,38 @@ +{ + "name": "besimple/soap-bundle", + "type": "symfony-bundle", + "description": "Build and consume SOAP and WSDL based web services with Symfony2", + "keywords": [ "soap", "soap-bundle" ], + "homepage": "https://github.com/BeSimple/BeSimpleSoapBundle", + "license": "MIT", + "authors": [ + { + "name": "Francis Besset", + "email": "francis.besset@gmail.com" + }, + { + "name": "Christian Kerl", + "email": "christian-kerl@web.de" + }, + { + "name": "Andreas Schamberger", + "email": "mail@andreass.net" + } + ], + "require": { + "php": ">=5.3.0", + "besimple/soap-common": "dev-master", + "burti/zend-soap": "dev-master", + "burti/zend-mime": "dev-master" + }, + "suggest": { + "besimple/soap-client": "dev-master", + "besimple/soap-server": "dev-master" + }, + "autoload": { + "psr-0": { + "BeSimple\\SoapBundle": "" + } + }, + "target-dir": "BeSimple/SoapBundle" +} From 1f41d88f8beac82a0422565465140926198d134c Mon Sep 17 00:00:00 2001 From: ldantunez Date: Tue, 18 Sep 2012 17:33:29 -0300 Subject: [PATCH 167/195] Update ServiceDefinition/Loader/AnnotationClassLoader.php Solving Symfony 2.1.* issue with the bundle. --- ServiceDefinition/Loader/AnnotationClassLoader.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index f545786..99da112 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -16,7 +16,7 @@ use BeSimple\SoapBundle\ServiceDefinition\Annotation; use Doctrine\Common\Annotations\Reader; use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\LoaderResolverInterface; /** * AnnotationClassLoader loads ServiceDefinition from a PHP class and its methods. @@ -183,18 +183,18 @@ class AnnotationClassLoader implements LoaderInterface /** * Sets the loader resolver. * - * @param LoaderResolver $resolver A LoaderResolver instance + * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance */ - public function setResolver(LoaderResolver $resolver) - { + public function setResolver(LoaderResolverInterface $resolver){ + } /** * Gets the loader resolver. * - * @return LoaderResolver A LoaderResolver instance + * @return LoaderResolverInterface A LoaderResolverInterface instance */ - public function getResolver() - { + public function getResolver(){ + } } From 030561521ee9e9c4c798c85709b2518055c078c7 Mon Sep 17 00:00:00 2001 From: Rekky Date: Wed, 30 Jan 2013 22:16:55 +0400 Subject: [PATCH 168/195] Fix code styling --- ServiceDefinition/Loader/AnnotationClassLoader.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ServiceDefinition/Loader/AnnotationClassLoader.php b/ServiceDefinition/Loader/AnnotationClassLoader.php index 99da112..b4253e4 100644 --- a/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -185,8 +185,8 @@ class AnnotationClassLoader implements LoaderInterface * * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance */ - public function setResolver(LoaderResolverInterface $resolver){ - + public function setResolver(LoaderResolverInterface $resolver) + { } /** @@ -194,7 +194,7 @@ class AnnotationClassLoader implements LoaderInterface * * @return LoaderResolverInterface A LoaderResolverInterface instance */ - public function getResolver(){ - + public function getResolver() + { } } From 0ee09df973793dc51ee13d5bef639d27ae969391 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 11:53:52 +0100 Subject: [PATCH 169/195] Fixed zend-(soap|mime) vendors --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index f0941eb..dc688dd 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,8 @@ "require": { "php": ">=5.3.0", "besimple/soap-common": "dev-master", - "burti/zend-soap": "dev-master", - "burti/zend-mime": "dev-master" + "zendframework/zend-soap": "2.1.1", + "zendframework/zend-mime": "2.1.1" }, "suggest": { "besimple/soap-client": "dev-master", From 2e34b1ce1dc554658bdf0ba8227e7684f629fdf3 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 13:43:54 +0100 Subject: [PATCH 170/195] Used new interface for WdslTypeStrategy --- ServiceDefinition/Dumper/WsdlTypeStrategy.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ServiceDefinition/Dumper/WsdlTypeStrategy.php b/ServiceDefinition/Dumper/WsdlTypeStrategy.php index b6f18fa..96207ea 100644 --- a/ServiceDefinition/Dumper/WsdlTypeStrategy.php +++ b/ServiceDefinition/Dumper/WsdlTypeStrategy.php @@ -17,10 +17,10 @@ use BeSimple\SoapBundle\Util\String; use Zend\Soap\Exception; use Zend\Soap\Wsdl as BaseWsdl; -use Zend\Soap\Wsdl\ComplexTypeStrategy; +use Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface; use Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence; -class WsdlTypeStrategy implements ComplexTypeStrategy +class WsdlTypeStrategy implements ComplexTypeStrategyInterface { /** * Context WSDL file From e3ddebfea407bd974daaf397f2767bdd0e813605 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 14:45:47 +0100 Subject: [PATCH 171/195] Added SoapResponseListener This listener allow return a raw result from the action. Before: /** * @Soap\Method("hello") * @Soap\Param("name", phpType = "string") * @Soap\Result(phpType = "string") */ public function helloAction($name) { return $this->container->get('besimple.soap.response')->setReturnValue(sprintf('Hello %s!', $name)); } After: /** * @Soap\Method("hello") * @Soap\Param("name", phpType = "string") * @Soap\Result(phpType = "string") */ public function helloAction($name) { return sprintf('Hello %s!', $name); } --- EventListener/SoapResponseListener.php | 56 ++++++++++++++++++++++ Resources/config/webservice.xml | 6 +++ Resources/doc/soapserver/configuration.rst | 17 +++++-- 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 EventListener/SoapResponseListener.php diff --git a/EventListener/SoapResponseListener.php b/EventListener/SoapResponseListener.php new file mode 100644 index 0000000..57e23e0 --- /dev/null +++ b/EventListener/SoapResponseListener.php @@ -0,0 +1,56 @@ + + * (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\EventListener; + +use BeSimple\SoapBundle\Soap\SoapRequest; +use BeSimple\SoapBundle\Soap\SoapResponse; +use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; + +/** + * SoapResponseListener. + * + * @author Francis Besset + */ +class SoapResponseListener +{ + /** + * @var SoapResponse + */ + protected $response; + + /** + * Constructor. + * + * @param SoapResponse $response The SoapResponse instance + */ + public function __construct(SoapResponse $response) + { + $this->response = $response; + } + + /** + * Set the controller result in SoapResponse. + * + * @param GetResponseForControllerResultEvent $event A GetResponseForControllerResultEvent instance + */ + public function onKernelView(GetResponseForControllerResultEvent $event) + { + $request = $event->getRequest(); + if (!$request instanceof SoapRequest) { + return; + } + + $this->response->setReturnValue($event->getControllerResult()); + $event->setResponse($this->response); + } +} diff --git a/Resources/config/webservice.xml b/Resources/config/webservice.xml index ae07e99..122cd86 100644 --- a/Resources/config/webservice.xml +++ b/Resources/config/webservice.xml @@ -5,6 +5,7 @@ BeSimple\SoapBundle\Soap\SoapResponse + BeSimple\SoapBundle\EventListener\SoapResponseListener BeSimple\SoapBundle\WebServiceContext BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestHeaderMessageBinder BeSimple\SoapBundle\ServiceBinding\RpcLiteralRequestMessageBinder @@ -20,6 +21,11 @@ + + + + + diff --git a/Resources/doc/soapserver/configuration.rst b/Resources/doc/soapserver/configuration.rst index 0549b4b..ee3c7bc 100644 --- a/Resources/doc/soapserver/configuration.rst +++ b/Resources/doc/soapserver/configuration.rst @@ -34,7 +34,7 @@ Annotations for Controllers .. code-block:: php - namespace My\App\Controller; + namespace Acme\DemoBundle\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use Symfony\Component\DependencyInjection\ContainerAware; @@ -48,7 +48,17 @@ Annotations for Controllers */ public function helloAction($name) { - return $this->container->get('besimple.soap.response')->setReturnValue(sprintf('Hello %s!', $name)); + return sprintf('Hello %s!', $name); + } + + /** + * @Soap\Method("goodbye") + * @Soap\Param("name", phpType = "string") + * @Soap\Result(phpType = "string") + */ + public function goodbyeAction($name) + { + return $this->container->get('besimple.soap.response')->setReturnValue(sprintf('Goodbye %s!', $name)); } } @@ -57,5 +67,4 @@ Get your WSDL To access your WSDL go to the following address: http://localhost/app_dev.php/ws/DemoApi?wsdl -To read the WSDL in your browser you can call this address: http://localhost/app_dev.php/ws/DemoApi - +To read the WSDL in your browser you can call this address (without `wsdl` parameter): http://localhost/app_dev.php/ws/DemoApi From f26fc4f72a0fa045e960bc3152d664a4d7cb2fe8 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 15:26:26 +0100 Subject: [PATCH 172/195] Updated installation doc with Composer --- Resources/doc/installation.rst | 63 +++++++++++++++++++++++++++++++--- Soap/SoapAttachment.php | 2 +- Soap/SoapClientBuilder.php | 2 +- Soap/SoapHeader.php | 2 +- Soap/SoapRequest.php | 2 +- Soap/SoapResponse.php | 2 +- WebServiceContext.php | 5 +-- 7 files changed, 67 insertions(+), 11 deletions(-) diff --git a/Resources/doc/installation.rst b/Resources/doc/installation.rst index 00088a3..2b8f81a 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation.rst @@ -6,6 +6,62 @@ Requirements Install and enable PHP's SOAP extension. +With Composer +~~~~~~~~~~~~~ + +Add `besimple/soap-bundle` (with vendors) in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-bundle": "dev-master", + "besimple/soap-common": "dev-master", + "ass/xmlsecurity": "dev-master" + } + } + +To install the server please add `besimple/soap-server` in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-server": "dev-master" + } + } + +To install the client please add `besimple/soap-client` in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-client": "dev-master" + } + } + +.. code-block:: bash + + $ php composer.phar update + +Enable the `BeSimpleSoapBundle` in your Kernel class + +.. code-block:: php + + // app/AppKernel.php + public function registerBundles() + { + return array( + // ... + new BeSimple\SoapBundle\BeSimpleSoapBundle(), + // ... + ); + } + +With deps file (outdated) +~~~~~~~~~~~~~~~~~~~~~~~~~ + Download `BeSimple\\SoapCommon`_ and `BeSimple\\SoapServer`_ (only for the server part) and/or `BeSimple\\SoapClient`_ (only for ther client part). .. code-block:: ini @@ -14,11 +70,11 @@ Download `BeSimple\\SoapCommon`_ and `BeSimple\\SoapServer`_ (only for the serve [BeSimple\SoapCommon] git=https://github.com/BeSimple/BeSimpleSoapCommon.git target=besimple-soapcommon - + [BeSimple\SoapClient] git=https://github.com/BeSimple/BeSimpleSoapClient.git target=besimple-soapclient - + [BeSimple\SoapServer] git=https://github.com/BeSimple/BeSimpleSoapServer.git target=besimple-soapserver @@ -60,7 +116,7 @@ Add `Zend` library in autoload.php )); Installation ------------- +```````````` `Download`_ the bundle or add in `deps` file @@ -95,7 +151,6 @@ Add `BeSimpleSoapBundle` in your Kernel class ); } - .. _`Zend\\Soap`: http://github.com/BeSimple/zend-soap .. _`Zend\\Mime`: http://github.com/BeSimple/zend-mime .. _`BeSimple\\SoapCommon`: http://github.com/BeSimple/BeSimpleSoapCommon diff --git a/Soap/SoapAttachment.php b/Soap/SoapAttachment.php index 15e8a1e..5bd360b 100644 --- a/Soap/SoapAttachment.php +++ b/Soap/SoapAttachment.php @@ -37,4 +37,4 @@ class SoapAttachment { return $this->content; } -} \ No newline at end of file +} diff --git a/Soap/SoapClientBuilder.php b/Soap/SoapClientBuilder.php index c21993f..977b92b 100644 --- a/Soap/SoapClientBuilder.php +++ b/Soap/SoapClientBuilder.php @@ -74,4 +74,4 @@ class SoapClientBuilder extends BaseSoapClientBuilder )); } } -} \ No newline at end of file +} diff --git a/Soap/SoapHeader.php b/Soap/SoapHeader.php index 22b0fbd..14bf2b3 100644 --- a/Soap/SoapHeader.php +++ b/Soap/SoapHeader.php @@ -47,4 +47,4 @@ class SoapHeader { return new \SoapHeader($this->namespace, $this->name, $this->data); } -} \ No newline at end of file +} diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php index 0b20161..2127670 100644 --- a/Soap/SoapRequest.php +++ b/Soap/SoapRequest.php @@ -164,4 +164,4 @@ class SoapRequest extends Request return $result; } -} \ No newline at end of file +} diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php index 1574b00..cb63f2b 100644 --- a/Soap/SoapResponse.php +++ b/Soap/SoapResponse.php @@ -66,4 +66,4 @@ class SoapResponse extends Response { return $this->soapReturnValue; } -} \ No newline at end of file +} diff --git a/WebServiceContext.php b/WebServiceContext.php index 2cc879d..d18bb04 100644 --- a/WebServiceContext.php +++ b/WebServiceContext.php @@ -42,7 +42,8 @@ class WebServiceContext private $serviceBinder; private $serverBuilder; - public function __construct(LoaderInterface $loader, DumperInterface $dumper, Classmap $classmap, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) { + public function __construct(LoaderInterface $loader, DumperInterface $dumper, Classmap $classmap, TypeRepository $typeRepository, TypeConverterCollection $converters, array $options) + { $this->loader = $loader; $this->wsdlFileDumper = $dumper; @@ -51,7 +52,7 @@ class WebServiceContext $this->typeRepository = $typeRepository; $this->converters = $converters; - $this->options = $options; + $this->options = $options; } public function getServiceDefinition() From 55ae5e7e994c97b52059ad38ab953fc1f4e534ce Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 15:30:01 +0100 Subject: [PATCH 173/195] Updated Cache --- Cache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cache.php b/Cache.php index f5a4f88..e1c6cf0 100644 --- a/Cache.php +++ b/Cache.php @@ -19,9 +19,9 @@ use BeSimple\SoapCommon\Cache as BaseCache; */ class Cache { - public function __construct($disabled, $type, $directory, $lifetime = null, $limit = null) + public function __construct($cacheDisabled, $type, $directory, $lifetime = null, $limit = null) { - $isEnabled = $disabled ? BaseCache::DISABLED : BaseCache::ENABLED; + $isEnabled = (Boolean) $cacheDisabled ? BaseCache::DISABLED : BaseCache::ENABLED; BaseCache::setEnabled($isEnabled); From b5fbb9192c8bbd45e41d6215b9f1c7dd05fcd587 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 15:58:12 +0100 Subject: [PATCH 174/195] Updated doc --- Resources/doc/cache.rst | 4 +- Resources/doc/index.rst | 8 +- Resources/doc/installation_composer.rst | 54 ++++++++++++ ...installation.rst => installation_deps.rst} | 82 ++----------------- Resources/doc/requirements.rst | 4 + Resources/doc/soapserver/tutorial/array.rst | 6 +- .../doc/soapserver/tutorial/complex_type.rst | 10 +-- Resources/doc/soapserver/tutorial/header.rst | 12 +-- 8 files changed, 84 insertions(+), 96 deletions(-) create mode 100644 Resources/doc/installation_composer.rst rename Resources/doc/{installation.rst => installation_deps.rst} (50%) create mode 100644 Resources/doc/requirements.rst diff --git a/Resources/doc/cache.rst b/Resources/doc/cache.rst index 1c12010..aeea03b 100644 --- a/Resources/doc/cache.rst +++ b/Resources/doc/cache.rst @@ -23,6 +23,4 @@ The limit is the maximum number of in-memory cached WSDL files (**5 is the defau The WSDL files cached are written in cache folder of your Symfony2 application. -If you want more information you can visit the following page `PHP Soap runtime configuration`_. - -.. _`PHP Soap runtime configuration`: http://www.php.net/manual/en/soap.configuration.php \ No newline at end of file +If you want more information you can visit the following page `PHP Soap runtime configuration `_. diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index 9182aa0..39200c6 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -3,7 +3,7 @@ BeSimpleSoapBundle ================== The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. -It is based on the `ckWebServicePlugin`_ for symfony. +It is based on the `ckWebServicePlugin `_ for symfony. --------------- Reference Guide @@ -13,7 +13,9 @@ Reference Guide :maxdepth: 1 :numbered: - installation + requirements + installation_composer + installation_deps cache ---------- @@ -33,5 +35,3 @@ SoapClient ---------- Coming soon. - -.. _`ckWebServicePlugin`: http://www.symfony-project.org/plugins/ckWebServicePlugin \ No newline at end of file diff --git a/Resources/doc/installation_composer.rst b/Resources/doc/installation_composer.rst new file mode 100644 index 0000000..b99e0e7 --- /dev/null +++ b/Resources/doc/installation_composer.rst @@ -0,0 +1,54 @@ +Installation with Composer +========================== + +Add `besimple/soap-bundle `_ (with vendors) in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-bundle": "dev-master", + "besimple/soap-common": "dev-master", + "ass/xmlsecurity": "dev-master" + } + } + +To install the server please add `besimple/soap-server `_ in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-server": "dev-master" + } + } + +To install the client please add `besimple/soap-client `_ in your composer.json: + +.. code-block:: json + + { + "require": { + "besimple/soap-client": "dev-master" + } + } + +Run this command to download the new vendors: + +.. code-block:: bash + + $ php composer.phar update + +Enable the `BeSimpleSoapBundle `_ in your Kernel class + +.. code-block:: php + + // app/AppKernel.php + public function registerBundles() + { + return array( + // ... + new BeSimple\SoapBundle\BeSimpleSoapBundle(), + // ... + ); + } diff --git a/Resources/doc/installation.rst b/Resources/doc/installation_deps.rst similarity index 50% rename from Resources/doc/installation.rst rename to Resources/doc/installation_deps.rst index 2b8f81a..529d837 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation_deps.rst @@ -1,68 +1,10 @@ -Installation -============ +Installation with deps file (deprecated) +======================================== -Requirements ------------- +**The installation with deps file is deprecated. +Please prefer install the** `BeSimpleSoapBundle `_ **with** `Composer `_. -Install and enable PHP's SOAP extension. - -With Composer -~~~~~~~~~~~~~ - -Add `besimple/soap-bundle` (with vendors) in your composer.json: - -.. code-block:: json - - { - "require": { - "besimple/soap-bundle": "dev-master", - "besimple/soap-common": "dev-master", - "ass/xmlsecurity": "dev-master" - } - } - -To install the server please add `besimple/soap-server` in your composer.json: - -.. code-block:: json - - { - "require": { - "besimple/soap-server": "dev-master" - } - } - -To install the client please add `besimple/soap-client` in your composer.json: - -.. code-block:: json - - { - "require": { - "besimple/soap-client": "dev-master" - } - } - -.. code-block:: bash - - $ php composer.phar update - -Enable the `BeSimpleSoapBundle` in your Kernel class - -.. code-block:: php - - // app/AppKernel.php - public function registerBundles() - { - return array( - // ... - new BeSimple\SoapBundle\BeSimpleSoapBundle(), - // ... - ); - } - -With deps file (outdated) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Download `BeSimple\\SoapCommon`_ and `BeSimple\\SoapServer`_ (only for the server part) and/or `BeSimple\\SoapClient`_ (only for ther client part). +Download `BeSimple\\SoapCommon `_ and `BeSimple\\SoapServer `_ (only for the server part) and/or `BeSimple\\SoapClient `_ (only for ther client part). .. code-block:: ini @@ -92,7 +34,7 @@ Add `BeSimple` libraries in autoload.php // your other namespaces )); -Download `Zend\\Soap`_ and `Zend\\Mime`_ or add in `deps` file. `Zend` library is required only for the server part. +Download `Zend\\Soap `_ and `Zend\\Mime `_ or add in `deps` file. `Zend` library is required only for the server part. .. code-block:: ini @@ -115,10 +57,7 @@ Add `Zend` library in autoload.php // your other namespaces )); -Installation -```````````` - -`Download`_ the bundle or add in `deps` file +`Download `_ the bundle or add in `deps` file .. code-block:: ini @@ -150,10 +89,3 @@ Add `BeSimpleSoapBundle` in your Kernel class // ... ); } - -.. _`Zend\\Soap`: http://github.com/BeSimple/zend-soap -.. _`Zend\\Mime`: http://github.com/BeSimple/zend-mime -.. _`BeSimple\\SoapCommon`: http://github.com/BeSimple/BeSimpleSoapCommon -.. _`BeSimple\\SoapServer`: http://github.com/BeSimple/BeSimpleSoapServer -.. _`BeSimple\\SoapClient`: http://github.com/BeSimple/BeSimpleSoapClient -.. _`Download`: http://github.com/BeSimple/BeSimpleSoapBundle diff --git a/Resources/doc/requirements.rst b/Resources/doc/requirements.rst new file mode 100644 index 0000000..d7a5525 --- /dev/null +++ b/Resources/doc/requirements.rst @@ -0,0 +1,4 @@ +Requirements +============ + +Install and enable PHP's `SOAP extension `. diff --git a/Resources/doc/soapserver/tutorial/array.rst b/Resources/doc/soapserver/tutorial/array.rst index aa12f33..7561d37 100644 --- a/Resources/doc/soapserver/tutorial/array.rst +++ b/Resources/doc/soapserver/tutorial/array.rst @@ -6,7 +6,7 @@ Controller .. code-block:: php - namespace My\App\Controller; + namespace Acme\DemoBundle\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use Symfony\Component\DependencyInjection\ContainerAware; @@ -20,6 +20,6 @@ Controller */ public function helloAction(array $names) { - return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); + return "Hello ".implode(', ', $names); } - } \ No newline at end of file + } diff --git a/Resources/doc/soapserver/tutorial/complex_type.rst b/Resources/doc/soapserver/tutorial/complex_type.rst index 24514ea..f6ac0e3 100644 --- a/Resources/doc/soapserver/tutorial/complex_type.rst +++ b/Resources/doc/soapserver/tutorial/complex_type.rst @@ -12,7 +12,7 @@ Controller .. code-block:: php - namespace My\App\Controller; + namespace Acme\DemoBundle\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use Symfony\Component\DependencyInjection\ContainerAware; @@ -22,7 +22,7 @@ Controller /** * @Soap\Method("getUser") * @Soap\Param("name", phpType = "string") - * @Soap\Result(phpType = "My\App\Entity\User") + * @Soap\Result(phpType = "Acme\DemoBundle\Entity\User") */ public function getUserAction($name) { @@ -34,7 +34,7 @@ Controller throw new \SoapFault('USER_NOT_FOUND', sprintf('The user with the name "%s" can not be found', $name)); } - return $this->container->get('besimple.soap.response')->setReturnValue($user); + return $user; } } @@ -45,7 +45,7 @@ You can expose only the properties (public, protected or private) of a complex t .. code-block:: php - namespace My\App\Entity; + namespace Acme\DemoBundle\Entity; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; @@ -82,4 +82,4 @@ ComplexType `ComplexType` accepts the following options: - * nillable: To specify that the value can be null \ No newline at end of file + * nillable: To specify that the value can be null diff --git a/Resources/doc/soapserver/tutorial/header.rst b/Resources/doc/soapserver/tutorial/header.rst index efd042f..6b731d7 100644 --- a/Resources/doc/soapserver/tutorial/header.rst +++ b/Resources/doc/soapserver/tutorial/header.rst @@ -6,7 +6,7 @@ Controller .. code-block:: php - namespace My\App\Controller; + namespace Acme\DemoBundle\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use Symfony\Component\DependencyInjection\ContainerAware; @@ -28,7 +28,7 @@ Controller throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); } - return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); + return "Hello ".implode(', ', $names); } } @@ -39,7 +39,7 @@ If you want use a header for all actions of your controller you can declare the .. code-block:: php - namespace My\App\Controller; + namespace Acme\DemoBundle\Controller; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use Symfony\Component\DependencyInjection\ContainerAware; @@ -57,7 +57,7 @@ If you want use a header for all actions of your controller you can declare the */ public function helloAction(array $names) { - return $this->container->get('besimple.soap.response')->setReturnValue("Hello ".implode(', ', $names)); + return "Hello ".implode(', ', $names); } /** @@ -67,7 +67,7 @@ If you want use a header for all actions of your controller you can declare the */ public function welcomeAction($names) { - return $this->container->get('besimple.soap.response')->setReturnValue("Welcome ".implode(', ', $names)); + return "Welcome ".implode(', ', $names); } public function setContainer(ContainerInterface $container = null) @@ -86,4 +86,4 @@ If you want use a header for all actions of your controller you can declare the throw new \SoapFault("INVALID_API_KEY", "The api_key is invalid."); } } - } \ No newline at end of file + } From 332872443eeaf06b06fad0ba716c14117a5f669d Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 16:00:12 +0100 Subject: [PATCH 175/195] Renamed README.markdown to README.md --- README.markdown => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.markdown => README.md (100%) diff --git a/README.markdown b/README.md similarity index 100% rename from README.markdown rename to README.md From f5d49a0236b282967e4fdaf7ead752fbcca26d8c Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 16:16:47 +0100 Subject: [PATCH 176/195] Updated bootsrap tests (use composer for vendors) --- .../RpcLiteralRequestMessageBinderTest.php | 2 ++ Tests/ServiceBinding/fixtures/Attributes.php | 3 ++- Tests/ServiceBinding/fixtures/ComplexType.php | 2 +- Tests/ServiceBinding/fixtures/Setters.php | 3 ++- Tests/Soap/SoapRequestTest.php | 2 ++ Tests/bootstrap.php | 25 ------------------- Tests/fixtures/ServiceBinding/Bar.php | 3 ++- .../fixtures/ServiceBinding/BarRecursive.php | 2 +- Tests/fixtures/ServiceBinding/Foo.php | 2 +- Tests/fixtures/ServiceBinding/FooBar.php | 2 +- .../fixtures/ServiceBinding/FooRecursive.php | 2 +- .../fixtures/ServiceBinding/SimpleArrays.php | 1 + composer.json | 5 +++- phpunit.xml.dist | 7 ++---- 14 files changed, 22 insertions(+), 39 deletions(-) delete mode 100644 Tests/bootstrap.php diff --git a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php index d1e9786..966edf8 100644 --- a/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.php +++ b/Tests/ServiceBinding/RpcLiteralRequestMessageBinderTest.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. diff --git a/Tests/ServiceBinding/fixtures/Attributes.php b/Tests/ServiceBinding/fixtures/Attributes.php index 53d4aee..1626464 100644 --- a/Tests/ServiceBinding/fixtures/Attributes.php +++ b/Tests/ServiceBinding/fixtures/Attributes.php @@ -5,5 +5,6 @@ namespace BeSimple\SoapBundle\Tests\ServiceBinding\fixtures; class Attributes { public $foo; + public $bar; -} \ No newline at end of file +} diff --git a/Tests/ServiceBinding/fixtures/ComplexType.php b/Tests/ServiceBinding/fixtures/ComplexType.php index 2bbabd0..f5c3332 100644 --- a/Tests/ServiceBinding/fixtures/ComplexType.php +++ b/Tests/ServiceBinding/fixtures/ComplexType.php @@ -17,4 +17,4 @@ class ComplexType { $this->foo = $foo; } -} \ No newline at end of file +} diff --git a/Tests/ServiceBinding/fixtures/Setters.php b/Tests/ServiceBinding/fixtures/Setters.php index a8de35a..73a16d1 100644 --- a/Tests/ServiceBinding/fixtures/Setters.php +++ b/Tests/ServiceBinding/fixtures/Setters.php @@ -5,6 +5,7 @@ namespace BeSimple\SoapBundle\Tests\ServiceBinding\fixtures; class Setters { private $foo; + private $bar; public function getFoo() @@ -26,4 +27,4 @@ class Setters { $this->bar = $bar; } -} \ No newline at end of file +} diff --git a/Tests/Soap/SoapRequestTest.php b/Tests/Soap/SoapRequestTest.php index f95b034..58f3404 100644 --- a/Tests/Soap/SoapRequestTest.php +++ b/Tests/Soap/SoapRequestTest.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. diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php deleted file mode 100644 index 4d7062a..0000000 --- a/Tests/bootstrap.php +++ /dev/null @@ -1,25 +0,0 @@ -registerNamespace('Symfony', $_SERVER['SYMFONY']); -$loader->registerNamespace('Zend', $_SERVER['ZEND']); -$loader->register(); - -spl_autoload_register(function($class) { - //if (0 === strpos($class, 'BeSimple\\SoapBundle\\')) { - if (0 === strpos($class, 'BeSimple\\SoapBundle\\')) { - $path = __DIR__.'/../'.implode('/', array_slice(explode('\\', $class), 2)).'.php'; - - if (file_exists($path)) { - require_once $path; - - return true; - } - - return false; - } -}); diff --git a/Tests/fixtures/ServiceBinding/Bar.php b/Tests/fixtures/ServiceBinding/Bar.php index fac87cb..d837ae9 100644 --- a/Tests/fixtures/ServiceBinding/Bar.php +++ b/Tests/fixtures/ServiceBinding/Bar.php @@ -5,6 +5,7 @@ namespace BeSimple\SoapBundle\Tests\fixtures\ServiceBinding; class Bar { private $foo; + private $bar; public function __construct($foo, $bar) @@ -12,4 +13,4 @@ class Bar $this->foo = $foo; $this->bar = $bar; } -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/BarRecursive.php b/Tests/fixtures/ServiceBinding/BarRecursive.php index c7d3d14..1344fa3 100644 --- a/Tests/fixtures/ServiceBinding/BarRecursive.php +++ b/Tests/fixtures/ServiceBinding/BarRecursive.php @@ -10,4 +10,4 @@ class BarRecursive { $this->foo = $foo; } -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/Foo.php b/Tests/fixtures/ServiceBinding/Foo.php index e635b8e..bfac544 100644 --- a/Tests/fixtures/ServiceBinding/Foo.php +++ b/Tests/fixtures/ServiceBinding/Foo.php @@ -12,4 +12,4 @@ class Foo $this->foo = $foo; $this->bar = $bar; } -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/FooBar.php b/Tests/fixtures/ServiceBinding/FooBar.php index 103dfc9..f1b847b 100644 --- a/Tests/fixtures/ServiceBinding/FooBar.php +++ b/Tests/fixtures/ServiceBinding/FooBar.php @@ -12,4 +12,4 @@ class FooBar $this->foo = $foo; $this->bar = $bar; } -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/FooRecursive.php b/Tests/fixtures/ServiceBinding/FooRecursive.php index b39c9f1..5ae9688 100644 --- a/Tests/fixtures/ServiceBinding/FooRecursive.php +++ b/Tests/fixtures/ServiceBinding/FooRecursive.php @@ -5,4 +5,4 @@ namespace BeSimple\SoapBundle\Tests\fixtures\ServiceBinding; class FooRecursive { public $bar; -} \ No newline at end of file +} diff --git a/Tests/fixtures/ServiceBinding/SimpleArrays.php b/Tests/fixtures/ServiceBinding/SimpleArrays.php index e17a640..2c1dba7 100644 --- a/Tests/fixtures/ServiceBinding/SimpleArrays.php +++ b/Tests/fixtures/ServiceBinding/SimpleArrays.php @@ -7,6 +7,7 @@ class SimpleArrays public $array1; private $array2; + private $array3; public function __construct($array1, $array2, $array3) diff --git a/composer.json b/composer.json index dc688dd..aa790a2 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,11 @@ "require": { "php": ">=5.3.0", "besimple/soap-common": "dev-master", + "ass/xmlsecurity": "dev-master", "zendframework/zend-soap": "2.1.1", - "zendframework/zend-mime": "2.1.1" + "zendframework/zend-mime": "2.1.1", + "zendframework/zend-mail": "2.1.1", + "symfony/http-foundation": ">=2.0,<2.3-dev" }, "suggest": { "besimple/soap-client": "dev-master", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c40be1e..2db5db8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,16 +9,13 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" - bootstrap="Tests/bootstrap.php" + bootstrap="vendor/autoload.php" > - - - - ./Tests + From 29ab80c06ceb11720c1c99a06958777955c18b2b Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 16:28:11 +0100 Subject: [PATCH 177/195] Added travis --- .travis.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..dba3221 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + +matrix: + allow_failures: + - php: 5.5 + +before_script: composer install --dev --prefer-source + +notifications: + email: francis.besset@gmail.com From 6994f7712bbdd3437da479b1cc2744d7cd082316 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 16:32:51 +0100 Subject: [PATCH 178/195] Added build status from travis in README --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 63c8aa0..9171451 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -BeSimpleSoapBundle -================== +# BeSimpleSoapBundle [![Build Status](https://travis-ci.org/BeSimple/BeSimpleSoapBundle.png?branch=master)](https://travis-ci.org/BeSimple/BeSimpleSoapBundle) The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. It is based on the [ckWebServicePlugin](http://www.symfony-project.org/plugins/ckWebServicePlugin) for symfony. From 9cce7a02e5407f54e7e52ec174a0b4410b1dc7d8 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 16:37:00 +0100 Subject: [PATCH 179/195] Updated composer.json --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index aa790a2..00f1c69 100644 --- a/composer.json +++ b/composer.json @@ -23,9 +23,9 @@ "php": ">=5.3.0", "besimple/soap-common": "dev-master", "ass/xmlsecurity": "dev-master", - "zendframework/zend-soap": "2.1.1", - "zendframework/zend-mime": "2.1.1", - "zendframework/zend-mail": "2.1.1", + "zendframework/zend-soap": "2.1.*", + "zendframework/zend-mime": "2.1.*", + "zendframework/zend-mail": "2.1.*", "symfony/http-foundation": ">=2.0,<2.3-dev" }, "suggest": { From 9e18ef7693948f407662deb447823a795204f8aa Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 17:04:58 +0100 Subject: [PATCH 180/195] Updated travis file --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dba3221..620eb40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,9 @@ matrix: allow_failures: - php: 5.5 -before_script: composer install --dev --prefer-source +before_script: + - composer self-update + - composer install --dev --prefer-source notifications: email: francis.besset@gmail.com From 3c44c543b13c2eab746ba6db6d6eec28081a8ca1 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 17:18:03 +0100 Subject: [PATCH 181/195] Renamed CONTRIBUTORS.markdown to CONTRIBUTORS.md --- CONTRIBUTORS.markdown => CONTRIBUTORS.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTORS.markdown => CONTRIBUTORS.md (100%) diff --git a/CONTRIBUTORS.markdown b/CONTRIBUTORS.md similarity index 100% rename from CONTRIBUTORS.markdown rename to CONTRIBUTORS.md From b7d9705891a10799e0ef306b787ae412482c9470 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 20:41:15 +0100 Subject: [PATCH 182/195] Added TODO.md file --- TODO.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..46c1a60 --- /dev/null +++ b/TODO.md @@ -0,0 +1,5 @@ +TODO +==== + +* Move RequestBinding in a future ParamConverterListener + * See SensioFrameworkExtraBundle From a86c680263ed5335ccddacb2442ef1e73bfd6eba Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 20 Feb 2013 20:42:08 +0100 Subject: [PATCH 183/195] Fixed ComplexType strategy --- ServiceDefinition/Strategy/ComplexType.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ServiceDefinition/Strategy/ComplexType.php b/ServiceDefinition/Strategy/ComplexType.php index 9913619..c8df45f 100644 --- a/ServiceDefinition/Strategy/ComplexType.php +++ b/ServiceDefinition/Strategy/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. @@ -12,12 +14,12 @@ namespace BeSimple\SoapBundle\ServiceDefinition\Strategy; use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader; use Zend\Soap\Wsdl; -use Zend\Soap\Wsdl\Strategy\AbstractStrategy; +use Zend\Soap\Wsdl\ComplexTypeStrategy\AbstractComplexTypeStrategy; /** * @author Francis Besset */ -class ComplexType extends AbstractStrategy +class ComplexType extends AbstractComplexTypeStrategy { private $loader; private $definition; @@ -46,7 +48,7 @@ class ComplexType extends AbstractStrategy 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)); } - $dom = $this->getContext()->toDomDocument(); + $dom = $this->getContext()->toDomDocument(); $soapTypeName = $this->getContext()->translateType($type); $soapType = 'tns:'.$soapTypeName; @@ -83,4 +85,4 @@ class ComplexType extends AbstractStrategy return $soapType; } -} \ No newline at end of file +} From 794d6cf8c2babee56a2343f9a411140d557d33d7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 08:22:55 +0100 Subject: [PATCH 184/195] Used MessageBinder of BeSimpleSoapCommon component --- .../doc/soapserver/tutorial/complex_type.rst | 52 +++++++++++++++++++ .../RpcLiteralRequestMessageBinder.php | 22 +++----- .../RpcLiteralResponseMessageBinder.php | 22 +++----- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Resources/doc/soapserver/tutorial/complex_type.rst b/Resources/doc/soapserver/tutorial/complex_type.rst index f6ac0e3..034d762 100644 --- a/Resources/doc/soapserver/tutorial/complex_type.rst +++ b/Resources/doc/soapserver/tutorial/complex_type.rst @@ -43,6 +43,8 @@ User class You can expose only the properties (public, protected or private) of a complex type. +**For performance reasons, we advise to create getter and setter for each property.** + .. code-block:: php namespace Acme\DemoBundle\Entity; @@ -75,6 +77,56 @@ You can expose only the properties (public, protected or private) of a complex t * @Soap\ComplexType("string") */ private $email; + + /** + * @Soap\ComplexType("boolean") + */ + private $newsletter; + + public function getId() + { + return $this->id; + } + + public function getUsername() + { + return $this->username; + } + + public function getEmail() + { + return $this->email; + } + + public function getFirstname() + { + return $this->firstname; + } + + public function setFirstname($firstname) + { + $this->firstname = $firstname; + } + + public function getLastname() + { + return $this->lastname; + } + + public function setLastname($lastname) + { + $this->lastname = $lastname; + } + + public function hasNewsletter() + { + return $this->newsletter; + } + + public function setNewsletter($newsletter) + { + $this->newletter = (Boolean) $newsletter + } } ComplexType diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index 917f50c..f3c0b99 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.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. @@ -13,8 +15,7 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; - -use Zend\Soap\Wsdl; +use BeSimple\SoapCommon\Util\MessageBinder; /** * @author Christian Kerl @@ -86,24 +87,15 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface $this->messageRefs[$hash] = $message; - $r = new \ReflectionClass($message); + $messageBinder = new MessageBinder($message); foreach ($this->definitionComplexTypes[$phpType] as $type) { - $p = $r->getProperty($type->getName()); - if ($p->isPublic()) { - $value = $message->{$type->getName()}; - } else { - $p->setAccessible(true); - $value = $p->getValue($message); - } + $property = $type->getName(); + $value = $messageBinder->readProperty($property); if (null !== $value) { $value = $this->processType($type->getValue(), $value); - if ($p->isPublic()) { - $message->{$type->getName()} = $value; - } else { - $p->setValue($message, $value); - } + $messageBinder->writeProperty($property, $value); } if (!$type->isNillable() && null === $value) { diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index cb6635b..bfb752d 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.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. @@ -13,8 +15,7 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Strategy\PropertyComplexType; use BeSimple\SoapBundle\ServiceDefinition\Strategy\MethodComplexType; - -use Zend\Soap\Wsdl; +use BeSimple\SoapCommon\Util\MessageBinder; /** * @author Christian Kerl @@ -71,24 +72,15 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface throw new \InvalidArgumentException(sprintf('The instance class must be "%s", "%s" given.', get_class($message), $phpType)); } - $r = new \ReflectionClass($message); + $messageBinder = new MessageBinder($message); foreach ($this->definitionComplexTypes[$phpType] as $type) { - $p = $r->getProperty($type->getName()); - if ($p->isPublic()) { - $value = $message->{$type->getName()}; - } else { - $p->setAccessible(true); - $value = $p->getValue($message); - } + $property = $type->getName(); + $value = $messageBinder->readProperty($property); if (null !== $value) { $value = $this->processType($type->getValue(), $value); - if ($p->isPublic()) { - $message->{$type->getName()} = $value; - } else { - $p->setValue($message, $value); - } + $messageBinder->writeProperty($property, $value); } if (!$type->isNillable() && null === $value) { From 03f19a0e612227b53638c87e0bba195fad374780 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 08:27:36 +0100 Subject: [PATCH 185/195] Refactored SoapWebServiceController --- Controller/SoapWebServiceController.php | 40 ++++++++++++++----------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index c67e1a9..2576fa5 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.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. @@ -20,6 +22,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; /** * @author Christian Kerl + * @author Francis Besset */ class SoapWebServiceController extends ContainerAware { @@ -66,9 +69,8 @@ class SoapWebServiceController extends ContainerAware ob_start(); $this->soapServer->handle($this->soapRequest->getSoapMessage()); - $this->getResponse()->setContent(ob_get_clean()); - return $this->getResponse(); + return $this->getResponse()->setContent(ob_get_clean()); } /** @@ -84,8 +86,8 @@ class SoapWebServiceController extends ContainerAware ) )); - $request = $this->container->get('request'); - if ($request->query->has('wsdl') || $request->query->has('WSDL')) { + $query = $this->container->get('request')->query; + if ($query->has('wsdl') || $query->has('WSDL')) { $response->headers->set('Content-Type', 'application/wsdl+xml'); } else { $response->headers->set('Content-Type', 'text/xml'); @@ -127,17 +129,17 @@ class SoapWebServiceController extends ContainerAware throw $e; } - $this->soapResponse = $this->checkResponse($response); + $this->setResponse($response); // add response soap headers to soap server - foreach ($this->getResponse()->getSoapHeaders() as $header) { + foreach ($response->getSoapHeaders() as $header) { $this->soapServer->addSoapHeader($header->toNativeSoapHeader()); } // return operation return value to soap server return $this->serviceBinder->processServiceMethodReturnValue( $method, - $this->getResponse()->getReturnValue() + $response->getReturnValue() ); } else { // collect request soap headers @@ -148,7 +150,7 @@ class SoapWebServiceController extends ContainerAware /** * @return \BeSimple\SoapBundle\Soap\SoapRequest */ - public function getRequest() + protected function getRequest() { return $this->soapRequest; } @@ -156,35 +158,37 @@ class SoapWebServiceController extends ContainerAware /** * @return \BeSimple\SoapBundle\Soap\SoapResponse */ - public function getResponse() + protected function getResponse() { return $this->soapResponse ?: $this->soapResponse = $this->container->get('besimple.soap.response'); } /** - * Checks that the given Response is a SoapResponse. + * Set the SoapResponse * - * @param Response $response A response to check + * @param Response $response A response to check and set * - * @return SoapResponse A valid SoapResponse + * @return \BeSimple\SoapBundle\Soap\SoapResponse A valid SoapResponse * - * @throws InvalidArgumentException if the given Response is not an instance of SoapResponse + * @throws InvalidArgumentException If the given Response is not an instance of SoapResponse */ - protected function checkResponse(Response $response) + protected function setResponse(Response $response) { if (!$response instanceof SoapResponse) { throw new \InvalidArgumentException('You must return an instance of BeSimple\SoapBundle\Soap\SoapResponse'); } - return $response; + return $this->soapResponse = $response; } private function getWebServiceContext($webservice) { - if (!$this->container->has('besimple.soap.context.'.$webservice)) { - throw new NotFoundHttpException(sprintf('No webservice with name "%s" found.', $webservice)); + $context = sprintf('besimple.soap.context.%s', $webservice); + + if (!$this->container->has($context)) { + throw new NotFoundHttpException(sprintf('No WebService with name "%s" found.', $webservice)); } - return $this->container->get('besimple.soap.context.'.$webservice); + return $this->container->get($context); } } From 67adf2e77a1f3a5a305148757aee1de6653d88a7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 08:47:10 +0100 Subject: [PATCH 186/195] Updated phpunit.xml.dist --- .gitignore | 1 + phpunit.xml.dist | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/.gitignore b/.gitignore index e4cd1e1..fd42ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build/* phpunit.xml vendor *.swp diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2db5db8..9d142b1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -18,4 +18,21 @@ + + + + + . + + Tests + vendor + vendors.php + + + + From f44e23136878d393305c923ee7455530b00e67c3 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 09:42:43 +0100 Subject: [PATCH 187/195] Updated installation with composer doc --- Resources/doc/installation_composer.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/doc/installation_composer.rst b/Resources/doc/installation_composer.rst index b99e0e7..e741a36 100644 --- a/Resources/doc/installation_composer.rst +++ b/Resources/doc/installation_composer.rst @@ -37,6 +37,7 @@ Run this command to download the new vendors: .. code-block:: bash + $ php composer.phar self-update $ php composer.phar update Enable the `BeSimpleSoapBundle `_ in your Kernel class From e0feb94de1eaa9cdb645968344f37744d11732eb Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 10:49:18 +0100 Subject: [PATCH 188/195] Updated LICENSE file --- Resources/meta/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/meta/LICENSE b/Resources/meta/LICENSE index f6307bc..8183ed5 100644 --- a/Resources/meta/LICENSE +++ b/Resources/meta/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010 Christian Kerl +Copyright (c) 2010-2013 Christian Kerl, Francis Besset Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From 9b585dedb795131a069c96eb99d3500b0496a2dc Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Thu, 21 Feb 2013 10:56:06 +0100 Subject: [PATCH 189/195] Updated TODO --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 46c1a60..0503147 100644 --- a/TODO.md +++ b/TODO.md @@ -3,3 +3,4 @@ TODO * Move RequestBinding in a future ParamConverterListener * See SensioFrameworkExtraBundle +* Add a security layer to log an user with Symfony2 Security Component From a50215b6498c346ed0dc67582f0fb1a257478fa7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Feb 2013 17:04:44 +0100 Subject: [PATCH 190/195] Fixed bug with Zend Soap --- ServiceDefinition/Dumper/Wsdl.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ServiceDefinition/Dumper/Wsdl.php b/ServiceDefinition/Dumper/Wsdl.php index eeee674..455d382 100644 --- a/ServiceDefinition/Dumper/Wsdl.php +++ b/ServiceDefinition/Dumper/Wsdl.php @@ -39,6 +39,25 @@ class Wsdl extends BaseWsdl return $xmlType ?: $this->addComplexType($type); } + /** + * 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]; + } + + if ($type[0] == '\\') { + $type = substr($type, 1); + } + + return str_replace('\\', '.', $type); + } + public function addBindingOperationHeader(\DOMElement $bindingOperation, array $headers, array $baseBinding) { foreach ($headers as $header) { From ea4d031084485c79a613a72f6038124068523df7 Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Feb 2013 17:06:00 +0100 Subject: [PATCH 191/195] Fixed issue #29 --- ServiceBinding/RpcLiteralRequestMessageBinder.php | 10 ++++++++++ ServiceBinding/RpcLiteralResponseMessageBinder.php | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/ServiceBinding/RpcLiteralRequestMessageBinder.php b/ServiceBinding/RpcLiteralRequestMessageBinder.php index f3c0b99..e058547 100644 --- a/ServiceBinding/RpcLiteralRequestMessageBinder.php +++ b/ServiceBinding/RpcLiteralRequestMessageBinder.php @@ -61,6 +61,16 @@ class RpcLiteralRequestMessageBinder implements MessageBinderInterface 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; diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php index bfb752d..dfdd509 100644 --- a/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -46,6 +46,16 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface 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); } From 9d79916a6213bb2aee6c2e0cb96fd941587845ca Mon Sep 17 00:00:00 2001 From: Francis Besset Date: Wed, 27 Feb 2013 17:08:32 +0100 Subject: [PATCH 192/195] Updated documentation for previous commit --- .../soapserver/tutorial/associative_array.rst | 99 +++++++++++++++++++ Resources/doc/soapserver/tutorials.rst | 1 + 2 files changed, 100 insertions(+) create mode 100644 Resources/doc/soapserver/tutorial/associative_array.rst diff --git a/Resources/doc/soapserver/tutorial/associative_array.rst b/Resources/doc/soapserver/tutorial/associative_array.rst new file mode 100644 index 0000000..55e8f25 --- /dev/null +++ b/Resources/doc/soapserver/tutorial/associative_array.rst @@ -0,0 +1,99 @@ +Associative Array +================= + +Pre-existent Type +----------------- + ++------------------------------------------------+-----------------+ +| Php Type | Value Type | ++================================================+=================+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\String | String | ++------------------------------------------------+-----------------+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\Boolean | Boolean | ++------------------------------------------------+-----------------+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\Int | Int | ++------------------------------------------------+-----------------+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\Float | Float | ++------------------------------------------------+-----------------+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\Date | DateTime object | ++------------------------------------------------+-----------------+ +| BeSimple\\SoapCommon\\Type\\KeyValue\\DateTime | DateTime object | ++------------------------------------------------+-----------------+ + +Controller +---------- + +.. code-block:: php + + namespace Acme\DemoBundle\Controller; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware + { + /** + * @Soap\Method("returnAssocArray") + * @Soap\Result(phpType = "BeSimple\SoapCommon\Type\KeyValue\String[]") + */ + public function assocArrayOfStringAction() + { + return array( + 'foo' => 'bar', + 'bar' => 'foo', + ); + } + + /** + * @Soap\Method("sendAssocArray") + * @Soap\Param("assocArray", phpType = "BeSimple\SoapCommon\Type\KeyValue\String[]") + * @Soap\Return(phpType = "BeSimple\SoapCommon\Type\KeyValue\String[]") + */ + public function assocArrayOfStringAction(array $assocArray) + { + // The $assocArray it's a real associative array + // var_dump($assocArray);die; + + return $assocArray; + } + } + +How to create my Associative Array? +----------------------------------- + +.. code-block:: php + + namespace Acme\DemoBundle\Soap\Type; + + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use BeSimple\SoapCommon\Type\AbstractKeyValue; + + class User extends AbstractKeyValue + { + /** + * @Soap\ComplexType("Acme\DemoBundle\Entity\User") + */ + protected $value; + } + +.. code-block:: php + + namespace Acme\DemoBundle\Controller; + + use Acme\DemoBundle\Entity\User; + use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; + use Symfony\Component\DependencyInjection\ContainerAware; + + class DemoController extends ContainerAware + { + /** + * @Soap\Method("getUsers") + * @Soap\Result(phpType = "Acme\DemoBundle\Soap\Type\User[]") + */ + public function getUsers() + { + return array( + 'user1' => new User('user1', 'user1@user.com'), + 'user2' => new User('user2', 'user2@user.com'), + ); + } diff --git a/Resources/doc/soapserver/tutorials.rst b/Resources/doc/soapserver/tutorials.rst index d1d36a4..1321cc2 100644 --- a/Resources/doc/soapserver/tutorials.rst +++ b/Resources/doc/soapserver/tutorials.rst @@ -5,5 +5,6 @@ Tutorials :maxdepth: 1 tutorial/array + tutorial/associative_array tutorial/complex_type tutorial/header From 55e9f6f07732d6fbe0502a393444e43be2bc055e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mar=C3=ADn?= Date: Thu, 6 Jun 2013 09:40:26 +0200 Subject: [PATCH 193/195] Marking as compatible with Symfony 2.3 After making a test, both server and client work with Symfony 2.3 with no changes --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 00f1c69..29d60ad 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "zendframework/zend-soap": "2.1.*", "zendframework/zend-mime": "2.1.*", "zendframework/zend-mail": "2.1.*", - "symfony/http-foundation": ">=2.0,<2.3-dev" + "symfony/http-foundation": ">=2.0,<2.4-dev" }, "suggest": { "besimple/soap-client": "dev-master", From 5dc1c4f917d0a70b0a49eade7e51e69336e2ee8c Mon Sep 17 00:00:00 2001 From: Pierre-Yves LEBECQ Date: Wed, 17 Jul 2013 10:48:21 +0200 Subject: [PATCH 194/195] [Controller] Any kind of exception are now re-thrown as SoapFault. --- Controller/SoapWebServiceController.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index 2576fa5..becd6f5 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -123,10 +123,14 @@ class SoapWebServiceController extends ContainerAware // forward to controller try { $response = $this->container->get('http_kernel')->handle($this->soapRequest, HttpKernelInterface::SUB_REQUEST, false); - } catch (\SoapFault $e) { + } catch (\Exception $e) { $this->soapResponse = new Response(null, 500); - throw $e; + if ($this->container->getParameter('kernel.debug')) { + throw $e; + } + + throw new \SoapFault('Receiver', $e->getMessage()); } $this->setResponse($response); From faa1a84c0bcb4cee0c63080bd5d82fdafb8c6a1e Mon Sep 17 00:00:00 2001 From: Pierre-Yves LEBECQ Date: Wed, 17 Jul 2013 11:20:59 +0200 Subject: [PATCH 195/195] [Controller] Prevented instanciation of a new SoapFault if the catched exception is already a SoapFault. --- Controller/SoapWebServiceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Controller/SoapWebServiceController.php b/Controller/SoapWebServiceController.php index becd6f5..c2d7c1c 100644 --- a/Controller/SoapWebServiceController.php +++ b/Controller/SoapWebServiceController.php @@ -126,7 +126,7 @@ class SoapWebServiceController extends ContainerAware } catch (\Exception $e) { $this->soapResponse = new Response(null, 500); - if ($this->container->getParameter('kernel.debug')) { + if ($e instanceof \SoapFault || $this->container->getParameter('kernel.debug')) { throw $e; }