This commit is contained in:
Teddy Cornaut 2019-09-24 09:17:28 -04:00
commit 85f86469ab
29 changed files with 283 additions and 146 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
composer.lock composer.lock
composer.phar composer.phar
phpunit.xml phpunit.xml
.php_cs.cache .idea
.php_cs.cache

View File

@ -1,16 +1,16 @@
language: php language: php
php: php:
- 5.3
- 5.4
- 5.5
- 5.6 - 5.6
- 7.0
- 7.1
env: env:
- SYMFONY_VERSION=2.6.* - SYMFONY_VERSION=2.8.*
- SYMFONY_VERSION="dev-master symfony/debug:~2.7@dev symfony/http-kernel:~2.7@dev" - SYMFONY_VERSION="dev-master symfony/debug:~2.8@dev symfony/http-kernel:~2.8@dev"
before_script: before_script:
- phpenv config-add myphp.ini
- composer self-update - composer self-update
- composer require symfony/framework-bundle:${SYMFONY_VERSION} --no-update - composer require symfony/framework-bundle:${SYMFONY_VERSION} --no-update
- composer update --no-interaction --prefer-source - composer update --no-interaction --prefer-source
@ -22,4 +22,4 @@ script:
matrix: matrix:
allow_failures: 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"

152
README.md
View File

@ -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 We forked the official [BeSimpleSoap](https://github.com/BeSimple/BeSimpleSoap) repository in order to sucessfully maintain some of our projects.
[BeSimpleSoap](https://github.com/BeSimple/BeSimpleSoap) repository in
order to sucessfully maintain some projects of ours. Therefore, **we are We now have integrated changes and fixes from sub-forks (thank you guys!), and we should be up to date now :)
not going to maintain this library**.
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 # 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 Then just running:
curl -s http://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin
```
$ 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',
'<received><soap><request><here /></request></soap></received>'
);
$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": { $response = new DummyServiceResponse();
"cadoles/soap": "0.3.*@dev" $response->status = true;
}
return $response;
} }
``` ```
Now you are ready to install the library: For further information and getting inspiration for your implementation, see the unit tests in ``tests`` dir.
```sh
php /usr/local/bin/composer.phar install
```

View File

@ -3,7 +3,7 @@
"type": "library", "type": "library",
"description": "Build and consume SOAP and WSDL based web services", "description": "Build and consume SOAP and WSDL based web services",
"keywords": ["soap"], "keywords": ["soap"],
"homepage": "http://besim.pl", "homepage": "https://github.com/Cadoles/BeSimpleSoap",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -20,12 +20,12 @@
} }
], ],
"require": { "require": {
"php": ">=5.3.0", "php": ">=7.0",
"ext-soap": "*", "ext-soap": "*",
"ext-curl": "*", "ext-curl": "*",
"ass/xmlsecurity": "~1.0", "ass/xmlsecurity": "~1.0",
"symfony/framework-bundle": "~2.0|~3.0", "symfony/framework-bundle": "~3.4|~4.0",
"symfony/twig-bundle": "~2.0|~3.0", "symfony/twig-bundle": "~3.4|~4.0",
"zendframework/zend-mime": "2.1.*" "zendframework/zend-mime": "2.1.*"
}, },
"replace": { "replace": {
@ -33,20 +33,21 @@
"besimple/soap-client": "self.version", "besimple/soap-client": "self.version",
"besimple/soap-common": "self.version", "besimple/soap-common": "self.version",
"besimple/soap-server": "self.version", "besimple/soap-server": "self.version",
"besimple/soap-wsdl": "self.version" "besimple/soap-wsdl": "self.version",
"cocciagialla/soap": "self.version"
}, },
"require-dev": { "require-dev": {
"ext-mcrypt": "*", "mikey179/vfsstream": "~1.6.5",
"mikey179/vfsStream": "~1.0", "symfony/filesystem": "~2.3",
"symfony/filesystem": "~2.0", "symfony/process": "~2.3",
"symfony/process": "~2.3" "phpunit/phpunit": "^5.7"
}, },
"autoload": { "autoload": {
"psr-0": { "BeSimple\\": "src/" } "psr-0": { "BeSimple\\": "src/" }
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "0.3-dev" "dev-master": "master-dev"
} }
} }
} }

View File

@ -1,3 +1,4 @@
vendor/ vendor/
composer.lock composer.lock
phpunit.xml phpunit.xml
.idea/

View File

@ -15,15 +15,17 @@ namespace BeSimple\SoapBundle\Controller;
use BeSimple\SoapBundle\Handler\ExceptionHandler; use BeSimple\SoapBundle\Handler\ExceptionHandler;
use BeSimple\SoapBundle\Soap\SoapRequest; use BeSimple\SoapBundle\Soap\SoapRequest;
use BeSimple\SoapBundle\Soap\SoapResponse; use BeSimple\SoapBundle\Soap\SoapResponse;
use BeSimple\SoapBundle\WebServiceContext;
use BeSimple\SoapServer\SoapServerBuilder; use BeSimple\SoapServer\SoapServerBuilder;
use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; 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\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/** /**
* @author Christian Kerl <christian-kerl@web.de> * @author Christian Kerl <christian-kerl@web.de>
@ -31,11 +33,7 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
*/ */
class SoapWebServiceController implements ContainerAwareInterface class SoapWebServiceController implements ContainerAwareInterface
{ {
use ContainerAwareTrait;
/**
* @var ContainerInterface
*/
private $container;
/** /**
* @var \SoapServer * @var \SoapServer
@ -60,27 +58,20 @@ class SoapWebServiceController implements ContainerAwareInterface
/** /**
* @var array * @var array
*/ */
private $headers = array(); private $headers = [];
/**
* {@inheritDoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/** /**
* @return \BeSimple\SoapBundle\Soap\SoapResponse * @return \BeSimple\SoapBundle\Soap\SoapResponse
*/ */
public function callAction($webservice) public function callAction($webservice)
{ {
$webServiceContext = $this->getWebServiceContext($webservice); /** @var WebServiceContext $webServiceContext */
$webServiceContext = $this->getWebServiceContext($webservice);
$this->serviceBinder = $webServiceContext->getServiceBinder(); $this->serviceBinder = $webServiceContext->getServiceBinder();
$this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request_stack')->getCurrentRequest()); $this->soapRequest = SoapRequest::createFromHttpRequest($this->container->get('request_stack')->getCurrentRequest());
$this->soapServer = $webServiceContext $this->soapServer = $webServiceContext
->getServerBuilder() ->getServerBuilder()
->withSoapVersion11() ->withSoapVersion11()
->withHandler($this) ->withHandler($this)
@ -98,19 +89,26 @@ class SoapWebServiceController implements ContainerAwareInterface
} }
/** /**
* @return Symfony\Component\HttpFoundation\Response * @return Response
*/ */
public function definitionAction($webservice) 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( $response = new Response($this->getWebServiceContext($webservice)->getWsdlFileContent(
$this->container->get('router')->generate( $this->container->get('router')->generate(
'_webservice_call', $routeName,
array('webservice' => $webservice), ['webservice' => $webservice],
true UrlGeneratorInterface::ABSOLUTE_URL
) )
)); ));
$request = $this->container->get('request'); /** @var Request $request */
$request = $this->container->get('request_stack')->getCurrentRequest();
$query = $request->query; $query = $request->query;
if ($query->has('wsdl') || $query->has('WSDL')) { if ($query->has('wsdl') || $query->has('WSDL')) {
$request->setRequestFormat('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); 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(); $code = $exception->getStatusCode();
$details = $this->container->get('templating')->render($view, array( $details = $this->container->get('twig')->render($view, [
'status_code' => $code, 'status_code' => $code,
'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', 'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '',
'exception' => $exception, 'exception' => $exception,
'logger' => $logger, 'logger' => $logger,
)); ]);
$handler = new ExceptionHandler($exception, $details); $handler = new ExceptionHandler($exception, $details);
if ($soapFault = $request->query->get('_besimple_soap_fault')) { 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 * This method gets called once for every SOAP header the \SoapServer received
* and afterwards once for the called SOAP operation. * and afterwards once for the called SOAP operation.
* *
* @param string $method The SOAP header or SOAP operation name * @param string $method The SOAP header or SOAP operation name
* @param array $arguments * @param array $arguments
* *
* @return mixed * @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 * @param Response $response A response to check and set
* *
@ -252,7 +250,7 @@ class SoapWebServiceController implements ContainerAwareInterface
return $this->soapResponse = $response; return $this->soapResponse = $response;
} }
private function getWebServiceContext($webservice) protected function getWebServiceContext($webservice)
{ {
$context = sprintf('besimple.soap.context.%s', $webservice); $context = sprintf('besimple.soap.context.%s', $webservice);

View File

@ -12,7 +12,7 @@ namespace BeSimple\SoapBundle\Converter;
use BeSimple\SoapBundle\Soap\SoapRequest; use BeSimple\SoapBundle\Soap\SoapRequest;
use BeSimple\SoapBundle\Soap\SoapResponse; use BeSimple\SoapBundle\Soap\SoapResponse;
use BeSimple\SoapBundle\Util\String; use BeSimple\SoapBundle\Util\BsString;
use BeSimple\SoapCommon\Converter\TypeConverterInterface; use BeSimple\SoapCommon\Converter\TypeConverterInterface;
/** /**
@ -40,7 +40,7 @@ class XopIncludeTypeConverter implements TypeConverterInterface
$ref = $include->getAttribute('href'); $ref = $include->getAttribute('href');
if (String::startsWith($ref, 'cid:')) { if (BsString::startsWith($ref, 'cid:')) {
$cid = urldecode(substr($ref, 4)); $cid = urldecode(substr($ref, 4));
return $request->getSoapAttachments()->get($cid)->getContent(); return $request->getSoapAttachments()->get($cid)->getContent();

View File

@ -17,7 +17,7 @@ use BeSimple\SoapCommon\Cache;
use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@ -88,14 +88,14 @@ class BeSimpleSoapExtension extends Extension
} }
foreach ($config as $client => $options) { 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); $container->setDefinition(sprintf('besimple.soap.client.builder.%s', $client), $definition);
$definition->replaceArgument(0, $options['wsdl']); $definition->replaceArgument(0, $options['wsdl']);
$defOptions = $container $defOptions = $container
->getDefinition('besimple.soap.client.builder') ->getDefinition('besimple.soap.client.builder')
->getArgument(1); ->getArgument(1);
foreach (array('cache_type', 'user_agent') as $key) { foreach (array('cache_type', 'user_agent') as $key) {
if (isset($options[$key])) { if (isset($options[$key])) {
@ -135,7 +135,7 @@ class BeSimpleSoapExtension extends Extension
private function createClientClassmap($client, array $classmap, ContainerBuilder $container) 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); $container->setDefinition(sprintf('besimple.soap.classmap.%s', $client), $definition);
if (!empty($classmap)) { if (!empty($classmap)) {
@ -149,7 +149,7 @@ class BeSimpleSoapExtension extends Extension
private function createClient($client, ContainerBuilder $container) 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); $container->setDefinition(sprintf('besimple.soap.client.%s', $client), $definition);
if (3 === Kernel::MAJOR_VERSION) { if (3 === Kernel::MAJOR_VERSION) {
@ -168,7 +168,7 @@ class BeSimpleSoapExtension extends Extension
unset($config['binding']); unset($config['binding']);
$contextId = 'besimple.soap.context.'.$config['name']; $contextId = 'besimple.soap.context.'.$config['name'];
$definition = new DefinitionDecorator('besimple.soap.context.'.$bindingSuffix); $definition = new ChildDefinition('besimple.soap.context.'.$bindingSuffix);
$container->setDefinition($contextId, $definition); $container->setDefinition($contextId, $definition);
if (isset($config['cache_type'])) { if (isset($config['cache_type'])) {
@ -177,6 +177,7 @@ class BeSimpleSoapExtension extends Extension
$options = $container $options = $container
->getDefinition('besimple.soap.context.'.$bindingSuffix) ->getDefinition('besimple.soap.context.'.$bindingSuffix)
->setPublic(true)
->getArgument(2); ->getArgument(2);
$definition->replaceArgument(2, array_merge($options, $config)); $definition->replaceArgument(2, array_merge($options, $config));

View File

@ -13,8 +13,8 @@
namespace BeSimple\SoapBundle\Handler; namespace BeSimple\SoapBundle\Handler;
use BeSimple\SoapServer\Exception\ReceiverSoapFault; use BeSimple\SoapServer\Exception\ReceiverSoapFault;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\FlattenException;
/** /**
* @author Francis Besset <francis.besset@gmail.com> * @author Francis Besset <francis.besset@gmail.com>

View File

@ -1,18 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing" <routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="_webservice_call" path="/{webservice}"> <route id="_webservice_call" path="/{webservice}" methods="POST">
<default key="_controller">BeSimpleSoapBundle:SoapWebService:Call</default> <default key="_controller">BeSimpleSoapBundle:SoapWebService:Call</default>
<default key="_format">xml</default> <default key="_format">xml</default>
<requirement key="_method">POST</requirement>
</route> </route>
<route id="_webservice_definition" path="/{webservice}"> <route id="_webservice_definition" path="/{webservice}" methods="GET">
<default key="_controller">BeSimpleSoapBundle:SoapWebService:Definition</default> <default key="_controller">BeSimpleSoapBundle:SoapWebService:Definition</default>
<default key="_format">xml</default> <default key="_format">xml</default>
<requirement key="_method">GET</requirement>
</route> </route>
</routes> </routes>

View File

@ -19,7 +19,7 @@
</parameters> </parameters>
<services> <services>
<service id="besimple.soap.response" class="%besimple.soap.response.class%" /> <service id="besimple.soap.response" class="%besimple.soap.response.class%" public="true" />
<service id="besimple.soap.response.listener" class="%besimple.soap.response.listener.class%"> <service id="besimple.soap.response.listener" class="%besimple.soap.response.listener.class%">
<tag name="kernel.event_listener" event="kernel.view" method="onKernelView" /> <tag name="kernel.event_listener" event="kernel.view" method="onKernelView" />
@ -96,6 +96,14 @@
<argument>dateTime</argument> <argument>dateTime</argument>
<argument>xsd:dateTime</argument> <argument>xsd:dateTime</argument>
</call> </call>
<call method="addType">
<argument>base64Binary</argument>
<argument>xsd:base64Binary</argument>
</call>
<call method="addType">
<argument>hexBinary</argument>
<argument>xsd:hexBinary</argument>
</call>
</service> </service>
</services> </services>

View File

@ -0,0 +1,33 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* 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 <francis.besset@gmail.com>
*/
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 [];
}
}

View File

@ -11,23 +11,24 @@
namespace BeSimple\SoapBundle\ServiceBinding; namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapCommon\Definition\Type\TypeRepository;
/** /**
* @author Christian Kerl <christian-kerl@web.de> * @author Christian Kerl <christian-kerl@web.de>
*/ */
class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface class DocumentLiteralWrappedRequestMessageBinder implements MessageBinderInterface
{ {
public function processMessage(Method $messageDefinition, $message) public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
{ {
if (count($message) > 1) { if (count($message) > 1) {
throw new \InvalidArgumentException(); throw new \InvalidArgumentException();
} }
$result = array(); $result = array();
$message = $message[0]; $message = $message[0];
foreach ($messageDefinition->getArguments() as $argument) { foreach ($messageDefinition->getInput()->all() as $argument) {
$result[$argument->getName()] = $message->{$argument->getName()}; $result[$argument->getName()] = $message;
} }
return $result; return $result;

View File

@ -11,17 +11,15 @@
namespace BeSimple\SoapBundle\ServiceBinding; namespace BeSimple\SoapBundle\ServiceBinding;
use BeSimple\SoapBundle\ServiceDefinition\Method; use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapCommon\Definition\Type\TypeRepository;
/** /**
* @author Christian Kerl <christian-kerl@web.de> * @author Christian Kerl <christian-kerl@web.de>
*/ */
class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface class DocumentLiteralWrappedResponseMessageBinder implements MessageBinderInterface
{ {
public function processMessage(Method $messageDefinition, $message) public function processMessage(Method $messageDefinition, $message, TypeRepository $typeRepository)
{ {
$result = new \stdClass(); return $message;
$result->{$messageDefinition->getName().'Result'} = $message;
return $result;
} }
} }

View File

@ -32,7 +32,10 @@ class RpcLiteralResponseMessageBinder implements MessageBinderInterface
{ {
$this->typeRepository = $typeRepository; $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) private function processType($phpType, $message)

View File

@ -34,6 +34,11 @@ class ComplexType extends Configuration
return $this->isNillable; return $this->isNillable;
} }
public function getIsNillable()
{
return $this->isNillable;
}
public function setName($name) public function setName($name)
{ {
$this->name = $name; $this->name = $name;
@ -49,6 +54,11 @@ class ComplexType extends Configuration
$this->isNillable = (bool) $isNillable; $this->isNillable = (bool) $isNillable;
} }
public function setIsNillable($isNillable)
{
$this->isNillable = (bool) $isNillable;
}
public function getAliasName() public function getAliasName()
{ {
return 'complextype'; return 'complextype';

View File

@ -96,6 +96,7 @@ class AnnotationClassLoader extends Loader
} }
$serviceReturn = $annotation->getPhpType(); $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())); 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); $definition->addMethod($serviceMethod);
} }

View File

@ -15,7 +15,7 @@ namespace BeSimple\SoapBundle\Util;
* *
* @author Christian Kerl <christian-kerl@web.de> * @author Christian Kerl <christian-kerl@web.de>
*/ */
class String class BsString
{ {
/** /**
* Checks if a string starts with a given string. * Checks if a string starts with a given string.

View File

@ -24,7 +24,6 @@ abstract class AbstractWebServerTest extends \PHPUnit_Framework_TestCase
* @var ProcessBuilder * @var ProcessBuilder
*/ */
protected static $webserver; protected static $webserver;
protected static $websererPortLength;
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
@ -44,8 +43,6 @@ abstract class AbstractWebServerTest extends \PHPUnit_Framework_TestCase
self::$webserver->start(); self::$webserver->start();
usleep(100000); usleep(100000);
self::$websererPortLength = strlen(WEBSERVER_PORT);
} }
public static function tearDownAfterClass() public static function tearDownAfterClass()

View File

@ -45,19 +45,6 @@ class CurlTest extends AbstractWebserverTest
$this->assertEquals('Unable to parse URL', $curl->getErrorMessage()); $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() public function testGetResponse()
{ {
$curl = new Curl(array( $curl = new Curl(array(
@ -66,7 +53,6 @@ class CurlTest extends AbstractWebserverTest
$curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT)); $curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT));
$this->assertSame('OK', $curl->getResponseStatusMessage()); $this->assertSame('OK', $curl->getResponseStatusMessage());
$this->assertEquals(145 + self::$websererPortLength, strlen($curl->getResponse()));
$curl->exec(sprintf('http://localhost:%d/404.txt', WEBSERVER_PORT)); $curl->exec(sprintf('http://localhost:%d/404.txt', WEBSERVER_PORT));
$this->assertSame('Not Found', $curl->getResponseStatusMessage()); $this->assertSame('Not Found', $curl->getResponseStatusMessage());
@ -95,19 +81,6 @@ class CurlTest extends AbstractWebserverTest
$this->assertEquals('text/html; charset=UTF-8', $curl->getResponseContentType()); $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() public function testGetResponseStatusCode()
{ {
$curl = new Curl(array( $curl = new Curl(array(

View File

@ -12,8 +12,6 @@
namespace BeSimple\SoapCommon\Definition; namespace BeSimple\SoapCommon\Definition;
use BeSimple\SoapCommon\Definition\Type\TypeRepository;
/** /**
* @author Francis Besset <francis.besset@gmail.com> * @author Francis Besset <francis.besset@gmail.com>
*/ */
@ -66,7 +64,7 @@ class Method
$this->input->add($name, $type); $this->input->add($name, $type);
} }
public function setOutput($type) public function setOutput($type, $name = 'return')
{ {
$this->output->add('return', $type); $this->output->add('return', $type);
} }

View File

@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue;
use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap;
use BeSimple\SoapCommon\Type\AbstractKeyValue; use BeSimple\SoapCommon\Type\AbstractKeyValue;
class Boolean extends AbstractKeyValue class BsBoolean extends AbstractKeyValue
{ {
/** /**
* @Soap\ComplexType("boolean") * @Soap\ComplexType("boolean")

View File

@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue;
use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap;
use BeSimple\SoapCommon\Type\AbstractKeyValue; use BeSimple\SoapCommon\Type\AbstractKeyValue;
class Float extends AbstractKeyValue class BsFloat extends AbstractKeyValue
{ {
/** /**
* @Soap\ComplexType("float") * @Soap\ComplexType("float")

View File

@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue;
use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap;
use BeSimple\SoapCommon\Type\AbstractKeyValue; use BeSimple\SoapCommon\Type\AbstractKeyValue;
class Int extends AbstractKeyValue class BsInt extends AbstractKeyValue
{ {
/** /**
* @Soap\ComplexType("int") * @Soap\ComplexType("int")

View File

@ -5,7 +5,7 @@ namespace BeSimple\SoapCommon\Type\KeyValue;
use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap; use BeSimple\SoapBundle\ServiceDefinition\Annotation as Soap;
use BeSimple\SoapCommon\Type\AbstractKeyValue; use BeSimple\SoapCommon\Type\AbstractKeyValue;
class String extends AbstractKeyValue class BsString extends AbstractKeyValue
{ {
/** /**
* @Soap\ComplexType("string") * @Soap\ComplexType("string")

View File

@ -30,7 +30,7 @@ abstract class WsSecurityFilterClientServer
/** /**
* The date format to be used with {@link \DateTime} * 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 * (X509 3.2.1) Reference to a Subject Key Identifier

View File

@ -25,8 +25,7 @@
"ass/xmlsecurity": "~1.0" "ass/xmlsecurity": "~1.0"
}, },
"require-dev": { "require-dev": {
"ext-mcrypt": "*", "mikey179/vfsstream": "~1.0"
"mikey179/vfsStream": "~1.0"
}, },
"autoload": { "autoload": {
"psr-0": { "BeSimple\\SoapCommon": "" } "psr-0": { "BeSimple\\SoapCommon": "" }

View File

@ -131,9 +131,7 @@ class SoapServer extends \SoapServer
/** /**
* Configure filter and type converter for SwA/MTOM. * Configure filter and type converter for SwA/MTOM.
* *
* @param array &$options SOAP constructor options array. * @param array &$options SOAP constructor options array
*
* @return void
*/ */
private function configureMime(array &$options) private function configureMime(array &$options)
{ {
@ -157,11 +155,11 @@ class SoapServer extends \SoapServer
} }
$options['typemap'][] = array( $options['typemap'][] = array(
'type_name' => $converter->getTypeName(), 'type_name' => $converter->getTypeName(),
'type_ns' => $converter->getTypeNamespace(), 'type_ns' => $converter->getTypeNamespace(),
'from_xml' => function ($input) use ($converter) { 'from_xml' => function ($input) use ($converter) {
return $converter->convertXmlToPhp($input); return $converter->convertXmlToPhp($input);
}, },
'to_xml' => function ($input) use ($converter) { 'to_xml' => function ($input) use ($converter) {
return $converter->convertPhpToXml($input); return $converter->convertPhpToXml($input);
}, },
); );

View File

@ -86,7 +86,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque
$expires = $xpath->query($query, $security)->item(0); $expires = $xpath->query($query, $security)->item(0);
if (null !== $expires) { 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')); $currentDatetime = new \DateTime('now', new \DateTimeZone('UTC'));
if ($currentDatetime > $expiresDatetime) { if ($currentDatetime > $expiresDatetime) {
@ -170,7 +170,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque
// init timestamp // init timestamp
$dt = new \DateTime('now', new \DateTimeZone('UTC')); $dt = new \DateTime('now', new \DateTimeZone('UTC'));
$createdTimestamp = $dt->format(self::DATETIME_FORMAT); $createdTimestamp = $dt->format(static::DATETIME_FORMAT);
// create security header // create security header
$security = $filterHelper->createElement(Helper::NS_WSS, 'Security'); $security = $filterHelper->createElement(Helper::NS_WSS, 'Security');
@ -182,7 +182,7 @@ class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapReque
$timestamp->appendChild($created); $timestamp->appendChild($created);
if (null !== $this->expires) { if (null !== $this->expires) {
$dt->modify('+' . $this->expires . ' seconds'); $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); $expires = $filterHelper->createElement(Helper::NS_WSU, 'Expires', $expiresTimestamp);
$timestamp->appendChild($expires); $timestamp->appendChild($expires);
} }