diff --git a/.gitignore b/.gitignore index fdf19e2..fb4dbce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ composer.lock composer.phar phpunit.xml -.php_cs.cache \ No newline at end of file +.idea +.php_cs.cache diff --git a/.travis.yml b/.travis.yml index 6458c71..4432c30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,16 @@ language: php php: - - 5.3 - - 5.4 - - 5.5 - 5.6 + - 7.0 + - 7.1 env: - - SYMFONY_VERSION=2.6.* - - SYMFONY_VERSION="dev-master symfony/debug:~2.7@dev symfony/http-kernel:~2.7@dev" + - SYMFONY_VERSION=2.8.* + - SYMFONY_VERSION="dev-master symfony/debug:~2.8@dev symfony/http-kernel:~2.8@dev" before_script: + - phpenv config-add myphp.ini - composer self-update - composer require symfony/framework-bundle:${SYMFONY_VERSION} --no-update - composer update --no-interaction --prefer-source @@ -22,4 +22,4 @@ script: matrix: allow_failures: - - env: SYMFONY_VERSION="dev-master symfony/debug:~2.7@dev symfony/http-kernel:~2.7@dev" + - env: SYMFONY_VERSION="dev-master symfony/debug:~2.8@dev symfony/http-kernel:~2.8@dev" diff --git a/README.md b/README.md index 1f30fbf..2ca917a 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,146 @@ -# BeSimpleSoap (Symfony 3.0) +# BeSimpleSoap (Symfony 3.4 / 4.x) -This fork aims to provide the BeSimpleSoap bundles compatibles with Symfony 3. +This fork provides the BeSimpleSoap bundle, updated to be compatible with Symfony 3.4 and 4.x (as well as with PHP 7.0-7.4). -We forked the official -[BeSimpleSoap](https://github.com/BeSimple/BeSimpleSoap) repository in -order to sucessfully maintain some projects of ours. Therefore, **we are -not going to maintain this library**. +We forked the official [BeSimpleSoap](https://github.com/BeSimple/BeSimpleSoap) repository in order to sucessfully maintain some of our projects. + +We now have integrated changes and fixes from sub-forks (thank you guys!), and we should be up to date now :) + +This fork is maintained by people from [Cadoles](https://www.cadoles.com/). + +# Contributing + +We do welcome pull requests :) please include tests if you can. + +Running tests can be done by running `php vendor/bin/phpunit`. # Installation -If you do not yet have composer, install it like this: +If you do not yet have composer, follow instructions on the [Composer website](https://getcomposer.org/download/) to install it. -```sh -curl -s http://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin +Then just running: + +``` +$ composer require cadoles/soap ``` -Create a `composer.json` file: +should be enough to get you up and running. -```json +# Components + +BeSimpleSoap consists of five components ... + +## BeSimpleSoapClient + +**Refactored** BeSimpleSoapClient is a component that extends the native PHP SoapClient with further features like SwA and WS-Security. + +## BeSimpleSoapServer + +**Refactored** BeSimpleSoapServer is a component that extends the native PHP SoapServer with further features like SwA and WS-Security. + +## BeSimpleSoapCommon + +**Refactored** BeSimpleSoapCommon component contains functionality shared by both the server and client implementations. + +## BeSimpleSoapWsdl + +**Untouched!** +The component is not affected by refactoring so it should work properly. +For further information see the original [README](https://github.com/BeSimple/BeSimpleSoap/blob/master/src/BeSimple/SoapWsdl/README.md). + +## BeSimpleSoapBundle + +**Unsupported!** +The BeSimpleSoapBundle is a Symfony2 bundle to build WSDL and SOAP based web services. +For further information see the the original [README](https://github.com/BeSimple/BeSimpleSoap/blob/master/src/BeSimple/SoapBundle/README.md). +*Will not work since the Symfony libraries were removed and usages of other components were not refactored. Feel free to fork this repository and fix it!* + +# How to use + +You can investigate the unit tests dir ``tests`` in order to get a clue. +Forget about associative arrays, vague configurations, multiple extension and silent errors! +This may look a bit more complex at the first sight, +but it will guide you to configure and set up your client or server properly. + +## Example of soap client call + +```php +$soapClientBuilder = new SoapClientBuilder(); +$soapClient = $soapClientBuilder->build( + SoapClientOptionsBuilder::createWithDefaults(), + SoapOptionsBuilder::createWithDefaults('http://path/to/wsdlfile.wsdl') +); +$myRequest = new MyRequest(); +$myRequest->attribute = 'string value'; +$soapResponse = $soapClient->soapCall('myMethod', [$myRequest]); + +var_dump($soapResponse); // Contains Response, Attachments +``` + +### Something wrong?! + +Turn on the tracking and catch `SoapFaultWithTracingData` exception to get some sweets :) + +```php +try { + $soapResponse = $soapClient->soapCall('myMethod', [$myRequest]); +} catch (SoapFaultWithTracingData $fault) { + var_dump($fault->getSoapResponseTracingData()->getLastRequest()); +} +``` +In this example, a ``MyRequest`` object has been used to describe request. +Using a ClassMap, you help SoapClient to turn it into XML request. + +## Example of soap server handling + +Starting a SOAP server is a bit more complex. +I recommend you to inspect SoapServer unit tests for inspiration. + +```php +$dummyService = new DummyService(); +$classMap = new ClassMap(); +foreach ($dummyService->getClassMap() as $type => $className) { + $classMap->add($type, $className); +} +$soapServerBuilder = new SoapServerBuilder(); +$soapServerOptions = SoapServerOptionsBuilder::createWithDefaults($dummyService); +$soapOptions = SoapOptionsBuilder::createWithClassMap($dummyService->getWsdlPath(), $classMap); +$soapServer = $soapServerBuilder->build($soapServerOptions, $soapOptions); + +$request = $soapServer->createRequest( + $dummyService->getEndpoint(), + 'DummyService.dummyServiceMethod', + 'text/xml;charset=UTF-8', + '' +); +$response = $soapServer->handleRequest($request); + +var_dump($response); // Contains Response, Attachments +``` + +In this example, a ``DummyService`` service has been used to handle request. +Using a service can help you create coherent SoapServer endpoints. +Service can hold an endpoint URL, WSDL path and a class map as associative array. +You can hold a class map as ``ClassMap`` object directly in the ``DummyService`` instead of array. + +In the service you should describe SOAP methods from given WSDL. +In the example, the dummyServiceMethod is called. +The method will receive request object and return response object that are matched according to the class map. + +See a simplified implementation of ``dummyServiceMethod`` to get a clue: + +```php +/** + * @param DummyServiceRequest $dummyServiceRequest + * @return DummyServiceResponse + */ +public function dummyServiceMethod(DummyServiceRequest $dummyServiceRequest) { - "require": { - "cadoles/soap": "0.3.*@dev" - } + $response = new DummyServiceResponse(); + $response->status = true; + + return $response; } ``` -Now you are ready to install the library: - -```sh -php /usr/local/bin/composer.phar install -``` +For further information and getting inspiration for your implementation, see the unit tests in ``tests`` dir. \ No newline at end of file diff --git a/composer.json b/composer.json index b45f925..ec001c5 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "type": "library", "description": "Build and consume SOAP and WSDL based web services", "keywords": ["soap"], - "homepage": "http://besim.pl", + "homepage": "https://github.com/Cadoles/BeSimpleSoap", "license": "MIT", "authors": [ { @@ -20,12 +20,12 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=7.0", "ext-soap": "*", "ext-curl": "*", "ass/xmlsecurity": "~1.0", - "symfony/framework-bundle": "~2.0|~3.0", - "symfony/twig-bundle": "~2.0|~3.0", + "symfony/framework-bundle": "~3.4|~4.0", + "symfony/twig-bundle": "~3.4|~4.0", "zendframework/zend-mime": "2.1.*" }, "replace": { @@ -33,20 +33,21 @@ "besimple/soap-client": "self.version", "besimple/soap-common": "self.version", "besimple/soap-server": "self.version", - "besimple/soap-wsdl": "self.version" + "besimple/soap-wsdl": "self.version", + "cocciagialla/soap": "self.version" }, "require-dev": { - "ext-mcrypt": "*", - "mikey179/vfsStream": "~1.0", - "symfony/filesystem": "~2.0", - "symfony/process": "~2.3" + "mikey179/vfsstream": "~1.6.5", + "symfony/filesystem": "~2.3", + "symfony/process": "~2.3", + "phpunit/phpunit": "^5.7" }, "autoload": { "psr-0": { "BeSimple\\": "src/" } }, "extra": { "branch-alias": { - "dev-master": "0.3-dev" + "dev-master": "master-dev" } } } diff --git a/src/BeSimple/SoapBundle/.gitignore b/src/BeSimple/SoapBundle/.gitignore index c49a5d8..a934131 100644 --- a/src/BeSimple/SoapBundle/.gitignore +++ b/src/BeSimple/SoapBundle/.gitignore @@ -1,3 +1,4 @@ vendor/ composer.lock phpunit.xml +.idea/ diff --git a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php index 43b72e8..5ad6f18 100644 --- a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php +++ b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php @@ -15,15 +15,17 @@ namespace BeSimple\SoapBundle\Controller; use BeSimple\SoapBundle\Handler\ExceptionHandler; use BeSimple\SoapBundle\Soap\SoapRequest; use BeSimple\SoapBundle\Soap\SoapResponse; +use BeSimple\SoapBundle\WebServiceContext; use BeSimple\SoapServer\SoapServerBuilder; use Symfony\Component\DependencyInjection\ContainerAwareInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\FlattenException; +use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; /** * @author Christian Kerl @@ -31,11 +33,7 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; */ class SoapWebServiceController implements ContainerAwareInterface { - - /** - * @var ContainerInterface - */ - private $container; + use ContainerAwareTrait; /** * @var \SoapServer @@ -60,27 +58,20 @@ class SoapWebServiceController implements ContainerAwareInterface /** * @var array */ - private $headers = array(); - - /** - * {@inheritDoc} - */ - public function setContainer(ContainerInterface $container = null) - { - $this->container = $container; - } + private $headers = []; /** * @return \BeSimple\SoapBundle\Soap\SoapResponse */ public function callAction($webservice) { - $webServiceContext = $this->getWebServiceContext($webservice); + /** @var WebServiceContext $webServiceContext */ + $webServiceContext = $this->getWebServiceContext($webservice); $this->serviceBinder = $webServiceContext->getServiceBinder(); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request_stack')->getCurrentRequest()); - $this->soapServer = $webServiceContext + $this->soapServer = $webServiceContext ->getServerBuilder() ->withSoapVersion11() ->withHandler($this) @@ -98,19 +89,26 @@ class SoapWebServiceController implements ContainerAwareInterface } /** - * @return Symfony\Component\HttpFoundation\Response + * @return Response */ public function definitionAction($webservice) { + $routeName = $webservice.'_webservice_call'; + $result = $this->container->get('router')->getRouteCollection()->get($routeName); + if (null === $result) { + $routeName = '_webservice_call'; + } + $response = new Response($this->getWebServiceContext($webservice)->getWsdlFileContent( $this->container->get('router')->generate( - '_webservice_call', - array('webservice' => $webservice), - true + $routeName, + ['webservice' => $webservice], + UrlGeneratorInterface::ABSOLUTE_URL ) )); - $request = $this->container->get('request'); + /** @var Request $request */ + $request = $this->container->get('request_stack')->getCurrentRequest(); $query = $request->query; if ($query->has('wsdl') || $query->has('WSDL')) { $request->setRequestFormat('wsdl'); @@ -136,14 +134,14 @@ class SoapWebServiceController implements ContainerAwareInterface throw new \LogicException(sprintf('The parameter "%s" is required in Request::$query parameter bag to generate the SoapFault.', '_besimple_soap_webservice'), null, $e); } - $view = 'TwigBundle:Exception:'.($this->container->get('kernel')->isDebug() ? 'exception' : 'error').'.txt.twig'; + $view = '@Twig/Exception/'.($this->container->get('kernel')->isDebug() ? 'exception' : 'error').'.txt.twig'; $code = $exception->getStatusCode(); - $details = $this->container->get('templating')->render($view, array( + $details = $this->container->get('twig')->render($view, [ 'status_code' => $code, 'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', - 'exception' => $exception, - 'logger' => $logger, - )); + 'exception' => $exception, + 'logger' => $logger, + ]); $handler = new ExceptionHandler($exception, $details); if ($soapFault = $request->query->get('_besimple_soap_fault')) { @@ -177,8 +175,8 @@ class SoapWebServiceController implements ContainerAwareInterface * 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 + * @param string $method The SOAP header or SOAP operation name + * @param array $arguments * * @return mixed */ @@ -235,7 +233,7 @@ class SoapWebServiceController implements ContainerAwareInterface } /** - * Set the SoapResponse + * Set the SoapResponse. * * @param Response $response A response to check and set * @@ -252,7 +250,7 @@ class SoapWebServiceController implements ContainerAwareInterface return $this->soapResponse = $response; } - private function getWebServiceContext($webservice) + protected function getWebServiceContext($webservice) { $context = sprintf('besimple.soap.context.%s', $webservice); diff --git a/src/BeSimple/SoapBundle/Converter/XopIncludeTypeConverter.php b/src/BeSimple/SoapBundle/Converter/XopIncludeTypeConverter.php index b83e38d..773e175 100644 --- a/src/BeSimple/SoapBundle/Converter/XopIncludeTypeConverter.php +++ b/src/BeSimple/SoapBundle/Converter/XopIncludeTypeConverter.php @@ -12,7 +12,7 @@ namespace BeSimple\SoapBundle\Converter; use BeSimple\SoapBundle\Soap\SoapRequest; use BeSimple\SoapBundle\Soap\SoapResponse; -use BeSimple\SoapBundle\Util\String; +use BeSimple\SoapBundle\Util\BsString; use BeSimple\SoapCommon\Converter\TypeConverterInterface; /** @@ -40,7 +40,7 @@ class XopIncludeTypeConverter implements TypeConverterInterface $ref = $include->getAttribute('href'); - if (String::startsWith($ref, 'cid:')) { + if (BsString::startsWith($ref, 'cid:')) { $cid = urldecode(substr($ref, 4)); return $request->getSoapAttachments()->get($cid)->getContent(); diff --git a/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php b/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php index a9e7bcf..11ff49a 100644 --- a/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php +++ b/src/BeSimple/SoapBundle/DependencyInjection/BeSimpleSoapExtension.php @@ -17,7 +17,7 @@ use BeSimple\SoapCommon\Cache; 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\ChildDefinition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; @@ -88,14 +88,14 @@ class BeSimpleSoapExtension extends Extension } foreach ($config as $client => $options) { - $definition = new DefinitionDecorator('besimple.soap.client.builder'); + $definition = new ChildDefinition('besimple.soap.client.builder'); $container->setDefinition(sprintf('besimple.soap.client.builder.%s', $client), $definition); $definition->replaceArgument(0, $options['wsdl']); $defOptions = $container - ->getDefinition('besimple.soap.client.builder') - ->getArgument(1); + ->getDefinition('besimple.soap.client.builder') + ->getArgument(1); foreach (array('cache_type', 'user_agent') as $key) { if (isset($options[$key])) { @@ -135,7 +135,7 @@ class BeSimpleSoapExtension extends Extension private function createClientClassmap($client, array $classmap, ContainerBuilder $container) { - $definition = new DefinitionDecorator('besimple.soap.classmap'); + $definition = new ChildDefinition('besimple.soap.classmap'); $container->setDefinition(sprintf('besimple.soap.classmap.%s', $client), $definition); if (!empty($classmap)) { @@ -149,7 +149,7 @@ class BeSimpleSoapExtension extends Extension private function createClient($client, ContainerBuilder $container) { - $definition = new DefinitionDecorator('besimple.soap.client'); + $definition = new ChildDefinition('besimple.soap.client'); $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition); if (3 === Kernel::MAJOR_VERSION) { @@ -168,7 +168,7 @@ class BeSimpleSoapExtension extends Extension unset($config['binding']); $contextId = 'besimple.soap.context.'.$config['name']; - $definition = new DefinitionDecorator('besimple.soap.context.'.$bindingSuffix); + $definition = new ChildDefinition('besimple.soap.context.'.$bindingSuffix); $container->setDefinition($contextId, $definition); if (isset($config['cache_type'])) { @@ -177,6 +177,7 @@ class BeSimpleSoapExtension extends Extension $options = $container ->getDefinition('besimple.soap.context.'.$bindingSuffix) + ->setPublic(true) ->getArgument(2); $definition->replaceArgument(2, array_merge($options, $config)); diff --git a/src/BeSimple/SoapBundle/Handler/ExceptionHandler.php b/src/BeSimple/SoapBundle/Handler/ExceptionHandler.php index 54c12b4..2a2d613 100644 --- a/src/BeSimple/SoapBundle/Handler/ExceptionHandler.php +++ b/src/BeSimple/SoapBundle/Handler/ExceptionHandler.php @@ -13,8 +13,8 @@ namespace BeSimple\SoapBundle\Handler; use BeSimple\SoapServer\Exception\ReceiverSoapFault; +use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\FlattenException; /** * @author Francis Besset diff --git a/src/BeSimple/SoapBundle/Resources/config/routing/webservicecontroller.xml b/src/BeSimple/SoapBundle/Resources/config/routing/webservicecontroller.xml index cd370b9..0a055c3 100644 --- a/src/BeSimple/SoapBundle/Resources/config/routing/webservicecontroller.xml +++ b/src/BeSimple/SoapBundle/Resources/config/routing/webservicecontroller.xml @@ -1,18 +1,16 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + BeSimpleSoapBundle:SoapWebService:Call xml - POST - + BeSimpleSoapBundle:SoapWebService:Definition xml - GET diff --git a/src/BeSimple/SoapBundle/Resources/config/webservice.xml b/src/BeSimple/SoapBundle/Resources/config/webservice.xml index 343885c..444e2ff 100644 --- a/src/BeSimple/SoapBundle/Resources/config/webservice.xml +++ b/src/BeSimple/SoapBundle/Resources/config/webservice.xml @@ -19,7 +19,7 @@ - + @@ -96,6 +96,14 @@ dateTime xsd:dateTime + + base64Binary + xsd:base64Binary + + + hexBinary + xsd:hexBinary + diff --git a/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.php new file mode 100644 index 0000000..21a6c60 --- /dev/null +++ b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestHeaderMessageBinder.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; +use BeSimple\SoapCommon\Definition\Type\TypeRepository; + +/** + * @author Francis Besset + */ +class DocumentLiteralWrappedRequestHeaderMessageBinder extends DocumentLiteralWrappedRequestMessageBinder +{ + private $header; + + public function setHeader($header) + { + $this->header = $header; + } + + public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository) + { + $headerDefinition = $messageDefinition->getHeaders()->get($this->header); + return []; + } +} diff --git a/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php index 8afb04e..249031f 100644 --- a/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php +++ b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php @@ -11,23 +11,24 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapCommon\Definition\Type\TypeRepository; /** * @author Christian Kerl */ class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface { - public function processMessage(Method $messageDefinition, $message) + public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository) { if (count($message) > 1) { throw new \InvalidArgumentException(); } - $result = array(); + $result = array(); $message = $message[0]; - foreach ($messageDefinition->getArguments() as $argument) { - $result[$argument->getName()] = $message->{$argument->getName()}; + foreach ($messageDefinition->getInput()->all() as $argument) { + $result[$argument->getName()] = $message; } return $result; diff --git a/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php index 2f46a0b..7a3fcef 100644 --- a/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php +++ b/src/BeSimple/SoapBundle/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php @@ -11,17 +11,15 @@ namespace BeSimple\SoapBundle\ServiceBinding; use BeSimple\SoapBundle\ServiceDefinition\Method; +use BeSimple\SoapCommon\Definition\Type\TypeRepository; /** * @author Christian Kerl */ class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface { - public function processMessage(Method $messageDefinition, $message) + public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository) { - $result = new \stdClass(); - $result->{$messageDefinition->getName().'Result'} = $message; - - return $result; + return $message; } } diff --git a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php index b6b4361..ba2e54f 100644 --- a/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php +++ b/src/BeSimple/SoapBundle/ServiceBinding/RpcLiteralResponseMessageBinder.php @@ -32,7 +32,10 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface { $this->typeRepository = $typeRepository; - return $this->processType($messageDefinition->getOutput()->get('return')->getType(), $message); + $parts = $messageDefinition->getOutput()->all(); + $part = array_shift($parts); + + return $this->processType($part->getType(), $message); } private function processType($phpType, $message) diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php index b98175a..49122cf 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Annotation/ComplexType.php @@ -34,6 +34,11 @@ class ComplexType extends Configuration return $this->isNillable; } + public function getIsNillable() + { + return $this->isNillable; + } + public function setName($name) { $this->name = $name; @@ -49,6 +54,11 @@ class ComplexType extends Configuration $this->isNillable = (bool) $isNillable; } + public function setIsNillable($isNillable) + { + $this->isNillable = (bool) $isNillable; + } + public function getAliasName() { return 'complextype'; diff --git a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php index 1b5a597..b5b6eda 100644 --- a/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php +++ b/src/BeSimple/SoapBundle/ServiceDefinition/Loader/AnnotationClassLoader.php @@ -96,6 +96,7 @@ class AnnotationClassLoader extends Loader } $serviceReturn = $annotation->getPhpType(); + $serviceXmlReturn = $annotation->getXmlType(); } } @@ -116,7 +117,11 @@ class AnnotationClassLoader extends Loader throw new \LogicException(sprintf('@Soap\Result non-existent for "%s".', $method->getName())); } - $serviceMethod->setOutput($this->loadType($serviceReturn)); + if (!isset($serviceXmlReturn) || !$serviceXmlReturn) { + $serviceXmlReturn = 'return'; + } + + $serviceMethod->setOutput($this->loadType($serviceReturn), $serviceXmlReturn); $definition->addMethod($serviceMethod); } diff --git a/src/BeSimple/SoapBundle/Util/String.php b/src/BeSimple/SoapBundle/Util/BsString.php similarity index 98% rename from src/BeSimple/SoapBundle/Util/String.php rename to src/BeSimple/SoapBundle/Util/BsString.php index 0a70057..b708c3b 100644 --- a/src/BeSimple/SoapBundle/Util/String.php +++ b/src/BeSimple/SoapBundle/Util/BsString.php @@ -15,7 +15,7 @@ namespace BeSimple\SoapBundle\Util; * * @author Christian Kerl */ -class String +class BsString { /** * Checks if a string starts with a given string. diff --git a/src/BeSimple/SoapClient/Tests/AbstractWebserverTest.php b/src/BeSimple/SoapClient/Tests/AbstractWebserverTest.php index 187d2cb..1f3fd53 100644 --- a/src/BeSimple/SoapClient/Tests/AbstractWebserverTest.php +++ b/src/BeSimple/SoapClient/Tests/AbstractWebserverTest.php @@ -24,7 +24,6 @@ abstract class AbstractWebServerTest extends \PHPUnit_Framework_TestCase * @var ProcessBuilder */ protected static $webserver; - protected static $websererPortLength; public static function setUpBeforeClass() { @@ -44,8 +43,6 @@ abstract class AbstractWebServerTest extends \PHPUnit_Framework_TestCase self::$webserver->start(); usleep(100000); - - self::$websererPortLength = strlen(WEBSERVER_PORT); } public static function tearDownAfterClass() diff --git a/src/BeSimple/SoapClient/Tests/CurlTest.php b/src/BeSimple/SoapClient/Tests/CurlTest.php index 28b6311..bcfb2f6 100644 --- a/src/BeSimple/SoapClient/Tests/CurlTest.php +++ b/src/BeSimple/SoapClient/Tests/CurlTest.php @@ -45,19 +45,6 @@ class CurlTest extends AbstractWebserverTest $this->assertEquals('Unable to parse URL', $curl->getErrorMessage()); } - public function testGetRequestHeaders() - { - $curl = new Curl(array( - 'proxy_host' => false, - )); - - $curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT)); - $this->assertEquals(132 + self::$websererPortLength, strlen($curl->getRequestHeaders())); - - $curl->exec(sprintf('http://localhost:%s/404.txt', WEBSERVER_PORT)); - $this->assertEquals(131 + self::$websererPortLength, strlen($curl->getRequestHeaders())); - } - public function testGetResponse() { $curl = new Curl(array( @@ -66,7 +53,6 @@ class CurlTest extends AbstractWebserverTest $curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT)); $this->assertSame('OK', $curl->getResponseStatusMessage()); - $this->assertEquals(145 + self::$websererPortLength, strlen($curl->getResponse())); $curl->exec(sprintf('http://localhost:%d/404.txt', WEBSERVER_PORT)); $this->assertSame('Not Found', $curl->getResponseStatusMessage()); @@ -95,19 +81,6 @@ class CurlTest extends AbstractWebserverTest $this->assertEquals('text/html; charset=UTF-8', $curl->getResponseContentType()); } - public function testGetResponseHeaders() - { - $curl = new Curl(array( - 'proxy_host' => false, - )); - - $curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT)); - $this->assertEquals(117 + self::$websererPortLength, strlen($curl->getResponseHeaders())); - - $curl->exec(sprintf('http://localhost:%d/404.txt', WEBSERVER_PORT)); - $this->assertEquals(124 + self::$websererPortLength, strlen($curl->getResponseHeaders())); - } - public function testGetResponseStatusCode() { $curl = new Curl(array( diff --git a/src/BeSimple/SoapCommon/Definition/Method.php b/src/BeSimple/SoapCommon/Definition/Method.php index e79e9d2..99b1f4c 100644 --- a/src/BeSimple/SoapCommon/Definition/Method.php +++ b/src/BeSimple/SoapCommon/Definition/Method.php @@ -12,8 +12,6 @@ namespace BeSimple\SoapCommon\Definition; -use BeSimple\SoapCommon\Definition\Type\TypeRepository; - /** * @author Francis Besset */ @@ -66,7 +64,7 @@ class Method $this->input->add($name, $type); } - public function setOutput($type) + public function setOutput($type, $name = 'return') { $this->output->add('return', $type); } diff --git a/src/BeSimple/SoapCommon/Type/KeyValue/Boolean.php b/src/BeSimple/SoapCommon/Type/KeyValue/BsBoolean.php similarity index 85% rename from src/BeSimple/SoapCommon/Type/KeyValue/Boolean.php rename to src/BeSimple/SoapCommon/Type/KeyValue/BsBoolean.php index bfe684a..7e81c90 100644 --- a/src/BeSimple/SoapCommon/Type/KeyValue/Boolean.php +++ b/src/BeSimple/SoapCommon/Type/KeyValue/BsBoolean.php @@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapCommon\Type\AbstractKeyValue; -class Boolean extends AbstractKeyValue +class BsBoolean extends AbstractKeyValue { /** * @Soap\ComplexType("boolean") diff --git a/src/BeSimple/SoapCommon/Type/KeyValue/Float.php b/src/BeSimple/SoapCommon/Type/KeyValue/BsFloat.php similarity index 85% rename from src/BeSimple/SoapCommon/Type/KeyValue/Float.php rename to src/BeSimple/SoapCommon/Type/KeyValue/BsFloat.php index 6d286b0..fe63c9a 100644 --- a/src/BeSimple/SoapCommon/Type/KeyValue/Float.php +++ b/src/BeSimple/SoapCommon/Type/KeyValue/BsFloat.php @@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapCommon\Type\AbstractKeyValue; -class Float extends AbstractKeyValue +class BsFloat extends AbstractKeyValue { /** * @Soap\ComplexType("float") diff --git a/src/BeSimple/SoapCommon/Type/KeyValue/Int.php b/src/BeSimple/SoapCommon/Type/KeyValue/BsInt.php similarity index 86% rename from src/BeSimple/SoapCommon/Type/KeyValue/Int.php rename to src/BeSimple/SoapCommon/Type/KeyValue/BsInt.php index 0e0c190..369423c 100644 --- a/src/BeSimple/SoapCommon/Type/KeyValue/Int.php +++ b/src/BeSimple/SoapCommon/Type/KeyValue/BsInt.php @@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapCommon\Type\AbstractKeyValue; -class Int extends AbstractKeyValue +class BsInt extends AbstractKeyValue { /** * @Soap\ComplexType("int") diff --git a/src/BeSimple/SoapCommon/Type/KeyValue/String.php b/src/BeSimple/SoapCommon/Type/KeyValue/BsString.php similarity index 85% rename from src/BeSimple/SoapCommon/Type/KeyValue/String.php rename to src/BeSimple/SoapCommon/Type/KeyValue/BsString.php index 29473a9..7b11b9a 100644 --- a/src/BeSimple/SoapCommon/Type/KeyValue/String.php +++ b/src/BeSimple/SoapCommon/Type/KeyValue/BsString.php @@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapCommon\Type\AbstractKeyValue; -class String extends AbstractKeyValue +class BsString extends AbstractKeyValue { /** * @Soap\ComplexType("string") diff --git a/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php b/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php index 8c1ef9d..bd50a89 100644 --- a/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php +++ b/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php @@ -30,7 +30,7 @@ abstract class WsSecurityFilterClientServer /** * The date format to be used with {@link \DateTime} */ - const DATETIME_FORMAT = 'Y-m-d\TH:i:s.000\Z'; + const DATETIME_FORMAT = 'Y-m-d\TH:i:s.u\Z'; /** * (X509 3.2.1) Reference to a Subject Key Identifier diff --git a/src/BeSimple/SoapCommon/composer.json b/src/BeSimple/SoapCommon/composer.json index bf1ec6d..6948063 100644 --- a/src/BeSimple/SoapCommon/composer.json +++ b/src/BeSimple/SoapCommon/composer.json @@ -25,8 +25,7 @@ "ass/xmlsecurity": "~1.0" }, "require-dev": { - "ext-mcrypt": "*", - "mikey179/vfsStream": "~1.0" + "mikey179/vfsstream": "~1.0" }, "autoload": { "psr-0": { "BeSimple\\SoapCommon": "" } diff --git a/src/BeSimple/SoapServer/SoapServer.php b/src/BeSimple/SoapServer/SoapServer.php index efad1f6..f12c16d 100644 --- a/src/BeSimple/SoapServer/SoapServer.php +++ b/src/BeSimple/SoapServer/SoapServer.php @@ -131,9 +131,7 @@ class SoapServer extends \SoapServer /** * Configure filter and type converter for SwA/MTOM. * - * @param array &$options SOAP constructor options array. - * - * @return void + * @param array &$options SOAP constructor options array */ private function configureMime(array &$options) { @@ -157,11 +155,11 @@ class SoapServer extends \SoapServer } $options['typemap'][] = array( 'type_name' => $converter->getTypeName(), - 'type_ns' => $converter->getTypeNamespace(), - 'from_xml' => function ($input) use ($converter) { + 'type_ns' => $converter->getTypeNamespace(), + 'from_xml' => function ($input) use ($converter) { return $converter->convertXmlToPhp($input); }, - 'to_xml' => function ($input) use ($converter) { + 'to_xml' => function ($input) use ($converter) { return $converter->convertPhpToXml($input); }, ); diff --git a/src/BeSimple/SoapServer/WsSecurityFilter.php b/src/BeSimple/SoapServer/WsSecurityFilter.php index b2e86a0..234283a 100644 --- a/src/BeSimple/SoapServer/WsSecurityFilter.php +++ b/src/BeSimple/SoapServer/WsSecurityFilter.php @@ -86,7 +86,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque $expires = $xpath->query($query, $security)->item(0); if (null !== $expires) { - $expiresDatetime = \DateTime::createFromFormat(self::DATETIME_FORMAT, $expires->textContent, new \DateTimeZone('UTC')); + $expiresDatetime = \DateTime::createFromFormat(static::DATETIME_FORMAT, $expires->textContent, new \DateTimeZone('UTC')); $currentDatetime = new \DateTime('now', new \DateTimeZone('UTC')); if ($currentDatetime > $expiresDatetime) { @@ -170,7 +170,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque // init timestamp $dt = new \DateTime('now', new \DateTimeZone('UTC')); - $createdTimestamp = $dt->format(self::DATETIME_FORMAT); + $createdTimestamp = $dt->format(static::DATETIME_FORMAT); // create security header $security = $filterHelper->createElement(Helper::NS_WSS, 'Security'); @@ -182,7 +182,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque $timestamp->appendChild($created); if (null !== $this->expires) { $dt->modify('+' . $this->expires . ' seconds'); - $expiresTimestamp = $dt->format(self::DATETIME_FORMAT); + $expiresTimestamp = $dt->format(static::DATETIME_FORMAT); $expires = $filterHelper->createElement(Helper::NS_WSU, 'Expires', $expiresTimestamp); $timestamp->appendChild($expires); }