From 0a157748a8e2fe433ccadcc97a6c04cf3b9b69cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Bechyn=C4=9B?= Date: Thu, 27 Oct 2016 16:24:44 +0200 Subject: [PATCH] Large refactoring removing states, abstract magic, vague fluent interfaces --- composer.json | 2 +- .../Controller/SoapWebServiceController.php | 4 +- src/BeSimple/SoapClient/Curl.php | 1 + src/BeSimple/SoapClient/SoapClient.php | 67 ++--- src/BeSimple/SoapClient/SoapClientBuilder.php | 231 +--------------- .../SoapClient/SoapClientOptionsBuilder.php | 35 +++ .../SoapOptions/SoapClientOptions.php | 107 ++++++++ .../SoapServerAuthenticationBasic.php | 39 +++ .../SoapServerAuthenticationDigest.php | 52 ++++ .../SoapServerAuthenticationInterface.php | 16 ++ .../SoapServerProxy/SoapServerProxy.php | 84 ++++++ src/BeSimple/SoapClient/SoapRequest.php | 48 ---- src/BeSimple/SoapClient/SoapResponse.php | 2 +- .../Tests/SoapClientBuilderTest.php | 2 +- .../SoapCommon/AbstractSoapBuilder.php | 246 ------------------ src/BeSimple/SoapCommon/Cache.php | 9 +- .../SoapCommon/{Classmap.php => ClassMap.php} | 50 ++-- .../Converter/TypeConverterCollection.php | 4 +- .../SoapOptions/SoapFeatures/SoapFeatures.php | 70 +++++ .../SoapCommon/SoapOptions/SoapOptions.php | 124 +++++++++ .../SoapCommon/SoapOptionsBuilder.php | 44 ++++ src/BeSimple/SoapCommon/SoapRequest.php | 25 +- .../Tests/AbstractSoapBuilderTest.php | 2 +- .../SoapCommon/Tests/ClassMapTest.php | 65 +++++ .../SoapCommon/Tests/ClassmapTest.php | 81 ------ .../Converter/TypeConverterCollectionTest.php | 8 +- .../SoapOptions/SoapServerOptions.php | 137 ++++++++++ ...SoapRequest.php => SoapRequestFactory.php} | 8 +- src/BeSimple/SoapServer/SoapResponse.php | 12 +- src/BeSimple/SoapServer/SoapServer.php | 103 +++----- src/BeSimple/SoapServer/SoapServerBuilder.php | 189 ++------------ .../SoapServer/SoapServerOptionsBuilder.php | 19 ++ 32 files changed, 953 insertions(+), 933 deletions(-) create mode 100644 src/BeSimple/SoapClient/SoapClientOptionsBuilder.php create mode 100644 src/BeSimple/SoapClient/SoapOptions/SoapClientOptions.php create mode 100644 src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationBasic.php create mode 100644 src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationDigest.php create mode 100644 src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationInterface.php create mode 100644 src/BeSimple/SoapClient/SoapOptions/SoapServerProxy/SoapServerProxy.php delete mode 100644 src/BeSimple/SoapClient/SoapRequest.php delete mode 100644 src/BeSimple/SoapCommon/AbstractSoapBuilder.php rename src/BeSimple/SoapCommon/{Classmap.php => ClassMap.php} (62%) create mode 100644 src/BeSimple/SoapCommon/SoapOptions/SoapFeatures/SoapFeatures.php create mode 100644 src/BeSimple/SoapCommon/SoapOptions/SoapOptions.php create mode 100644 src/BeSimple/SoapCommon/SoapOptionsBuilder.php create mode 100644 src/BeSimple/SoapCommon/Tests/ClassMapTest.php delete mode 100644 src/BeSimple/SoapCommon/Tests/ClassmapTest.php create mode 100644 src/BeSimple/SoapServer/SoapOptions/SoapServerOptions.php rename src/BeSimple/SoapServer/{SoapRequest.php => SoapRequestFactory.php} (89%) create mode 100644 src/BeSimple/SoapServer/SoapServerOptionsBuilder.php diff --git a/composer.json b/composer.json index 49d58c5..30738df 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "catch-of-the-day/soap", + "name": "tuscanicz/soap", "type": "library", "description": "A fork of the abandoned besimple/soap package with added support for Symfony 3.0", "keywords": ["soap"], diff --git a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php index 977a3a2..53af035 100644 --- a/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php +++ b/src/BeSimple/SoapBundle/Controller/SoapWebServiceController.php @@ -141,8 +141,8 @@ class SoapWebServiceController implements ContainerAwareInterface $request->query->remove('_besimple_soap_fault'); } - $server = SoapServerBuilder::createWithDefaults() - ->withWsdl(__DIR__.'/../Handler/wsdl/exception.wsdl') + $server = SoapServerBuilder::createWithDefaults(__DIR__.'/../Handler/wsdl/exception.wsdl') + ->withWsdl() ->withWsdlCacheNone() ->withHandler($handler) ->build() diff --git a/src/BeSimple/SoapClient/Curl.php b/src/BeSimple/SoapClient/Curl.php index e777fc8..7efee35 100644 --- a/src/BeSimple/SoapClient/Curl.php +++ b/src/BeSimple/SoapClient/Curl.php @@ -50,6 +50,7 @@ class Curl /** * Constructor. * + * @todo: do not use options as Array * @param array $options Options array from SoapClient constructor * @param int $followLocationMaxRedirects Redirection limit for Location header */ diff --git a/src/BeSimple/SoapClient/SoapClient.php b/src/BeSimple/SoapClient/SoapClient.php index 0fa3c7d..1e5ed87 100644 --- a/src/BeSimple/SoapClient/SoapClient.php +++ b/src/BeSimple/SoapClient/SoapClient.php @@ -15,7 +15,8 @@ namespace BeSimple\SoapClient; use BeSimple\SoapCommon\Helper; use BeSimple\SoapCommon\Converter\MtomTypeConverter; use BeSimple\SoapCommon\Converter\SwaTypeConverter; -use BeSimple\SoapCommon\SoapMessage; +use BeSimple\SoapCommon\SoapOptions\SoapOptions; +use BeSimple\SoapCommon\SoapRequest; /** * Extended SoapClient that uses a a cURL wrapper for all underlying HTTP @@ -27,12 +28,7 @@ use BeSimple\SoapCommon\SoapMessage; */ class SoapClient extends \SoapClient { - /** - * Soap version. - * - * @var int - */ - protected $soapVersion = SOAP_1_1; + protected $soapVersion; /** * Tracing enabled? @@ -86,37 +82,24 @@ class SoapClient extends \SoapClient /** * Constructor. * - * @param string $wsdl WSDL file - * @param array(string=>mixed) $options Options array + * @param SoapClientOptions $soapClientOptions + * @param SoapOptions $soapOptions */ - public function __construct($wsdl, array $options = array()) + public function __construct(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions) { - // tracing enabled: store last request/response header and body - if (isset($options['trace']) && $options['trace'] === true) { - $this->tracingEnabled = true; - } - // store SOAP version - if (isset($options['soap_version'])) { - $this->soapVersion = $options['soap_version']; - } - - $this->curl = new Curl($options); - - if (isset($options['extra_options'])) { - unset($options['extra_options']); - } - - $wsdlFile = $this->loadWsdl($wsdl, $options); - // TODO $wsdlHandler = new WsdlHandler($wsdlFile, $this->soapVersion); $this->soapKernel = new SoapKernel(); - // set up type converter and mime filter - $this->configureMime($options); - // we want the exceptions option to be set - $options['exceptions'] = true; - // disable obsolete trace option for native SoapClient as we need to do our own tracing anyways - $options['trace'] = false; - // disable WSDL caching as we handle WSDL caching for remote URLs ourself - $options['cache_wsdl'] = WSDL_CACHE_NONE; + $this->soapVersion = $soapOptions->getSoapVersion(); + $this->tracingEnabled = $soapClientOptions->getTrace(); + + // @todo: refactor SoapClient: do not use $options as array + $options = $this->configureMime($soapOptions->toArray()); + + // @todo: refactor SoapClient: do not use $options as array + $this->curl = new Curl($soapClientOptions->toArray()); + + // @todo: refactor SoapClient: do not use $options as array + $wsdlFile = $this->loadWsdl($soapOptions->getWsdlFile(), $soapOptions->toArray()); + parent::__construct($wsdlFile, $options); } @@ -191,6 +174,7 @@ class SoapClient extends \SoapClient * Custom request method to be able to modify the SOAP messages. * $oneWay parameter is not used at the moment. * + * @todo: refactor SoapClient: refactoring starts from here * @param string $request Request string * @param string $location Location * @param string $action SOAP action @@ -308,16 +292,9 @@ class SoapClient extends \SoapClient return $this->soapKernel; } - /** - * Configure filter and type converter for SwA/MTOM. - * - * @param array &$options SOAP constructor options array. - * - * @return void - */ - private function configureMime(array &$options) + private function configureMime(array $options) { - if (isset($options['attachment_type']) && Helper::ATTACHMENTS_TYPE_BASE64 !== $options['attachment_type']) { + if (Helper::ATTACHMENTS_TYPE_BASE64 !== $options['attachment_type']) { // register mime filter in SoapKernel $mimeFilter = new MimeFilter($options['attachment_type']); $this->soapKernel->registerFilter($mimeFilter); @@ -346,6 +323,8 @@ class SoapClient extends \SoapClient }, ); } + + return $options; } /** diff --git a/src/BeSimple/SoapClient/SoapClientBuilder.php b/src/BeSimple/SoapClient/SoapClientBuilder.php index 59b5bba..00a406f 100644 --- a/src/BeSimple/SoapClient/SoapClientBuilder.php +++ b/src/BeSimple/SoapClient/SoapClientBuilder.php @@ -12,237 +12,22 @@ namespace BeSimple\SoapClient; -use BeSimple\SoapCommon\AbstractSoapBuilder; -use BeSimple\SoapCommon\Helper; +use BeSimple\SoapCommon\SoapOptions\SoapOptions; /** - * Fluent interface builder for SoapClient instance. + * Provides a SoapClient instance. * * @author Francis Besset * @author Christian Kerl + * @author Petr Bechyně */ -class SoapClientBuilder extends AbstractSoapBuilder +class SoapClientBuilder { - /** - * Authentication options. - * - * @var array(string=>mixed) - */ - protected $soapOptionAuthentication = array(); - - /** - * Create new instance with default options. - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public static function createWithDefaults() + public function build(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions) { - return parent::createWithDefaults() - ->withUserAgent('BeSimpleSoap'); - } - - /** - * Finally returns a SoapClient instance. - * - * @return \BeSimple\SoapClient\SoapClient - */ - public function build() - { - $this->validateOptions(); - - return new SoapClient($this->wsdl, $this->getSoapOptions()); - } - - /** - * Get final array of SOAP options. - * - * @return array(string=>mixed) - */ - public function getSoapOptions() - { - return parent::getSoapOptions() + $this->soapOptionAuthentication; - } - - /** - * Configure option 'trace'. - * - * @param boolean $trace Enable/Disable - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withTrace($trace = true) - { - $this->soapOptions['trace'] = $trace; - - return $this; - } - - /** - * Configure option 'exceptions'. - * - * @param boolean $exceptions Enable/Disable - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withExceptions($exceptions = true) - { - $this->soapOptions['exceptions'] = $exceptions; - - return $this; - } - - /** - * Configure option 'user_agent'. - * - * @param string $userAgent User agent string - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withUserAgent($userAgent) - { - $this->soapOptions['user_agent'] = $userAgent; - - return $this; - } - - /** - * Enable gzip compression. - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withCompressionGzip() - { - $this->soapOptions['compression'] = SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP; - - return $this; - } - - /** - * Enable deflate compression. - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withCompressionDeflate() - { - $this->soapOptions['compression'] = SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE; - - return $this; - } - - /** - * Configure basic authentication - * - * @param string $username Username - * @param string $password Password - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withBasicAuthentication($username, $password) - { - $this->soapOptionAuthentication = array( - 'authentication' => SOAP_AUTHENTICATION_BASIC, - 'login' => $username, - 'password' => $password, + return new SoapClient( + $soapClientOptions, + $soapOptions ); - - return $this; - } - - /** - * Configure digest authentication. - * - * @param string $certificate Certificate - * @param string $passphrase Passphrase - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withDigestAuthentication($certificate, $passphrase = null) - { - $this->soapOptionAuthentication = array( - 'authentication' => SOAP_AUTHENTICATION_DIGEST, - 'local_cert' => $certificate, - ); - - if ($passphrase) { - $this->soapOptionAuthentication['passphrase'] = $passphrase; - } - - return $this; - } - - /** - * Configure proxy. - * - * @param string $host Host - * @param int $port Port - * @param string $login Login - * @param string $password Password - * @param int $auth Authentication method - * - * @return \BeSimple\SoapClient\SoapClientBuilder - */ - public function withProxy($host, $port, $login = null, $password = null, $auth = null) - { - $this->soapOptions['proxy_host'] = $host; - $this->soapOptions['proxy_port'] = $port; - - if ($login) { - $this->soapOptions['proxy_login'] = $login; - $this->soapOptions['proxy_password'] = $password; - - if ($auth) { - if (!in_array($auth, array(\CURLAUTH_BASIC, \CURLAUTH_NTLM), true)) { - throw new \InvalidArgumentException('Invalid authentication method: CURLAUTH_BASIC or CURLAUTH_NTLM constants are availables.'); - } - - $this->soapOptions['proxy_auth'] = $auth; - } - } - - return $this; - } - - /** - * SOAP attachment type Base64. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withBase64Attachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_BASE64; - - return $this; - } - - /** - * SOAP attachment type SwA. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withSwaAttachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_SWA; - - return $this; - } - - /** - * SOAP attachment type MTOM. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withMtomAttachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_MTOM; - - return $this; - } - - /** - * Validate options. - */ - protected function validateOptions() - { - $this->validateWsdl(); } } diff --git a/src/BeSimple/SoapClient/SoapClientOptionsBuilder.php b/src/BeSimple/SoapClient/SoapClientOptionsBuilder.php new file mode 100644 index 0000000..342346d --- /dev/null +++ b/src/BeSimple/SoapClient/SoapClientOptionsBuilder.php @@ -0,0 +1,35 @@ + + * (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\SoapClient; + +use BeSimple\SoapCommon\SoapOptions\SoapOptions; + +/** + * Provides a SoapClient instance. + * + * @author Francis Besset + * @author Christian Kerl + * @author Petr Bechyně + */ +class SoapClientOptionsBuilder +{ + public static function createWithDefaults() + { + return new SoapClientOptions( + SoapClientOptions::SOAP_CLIENT_TRACE_OFF, + SoapClientOptions::SOAP_CLIENT_EXCEPTIONS_ON, + 'BeSimpleSoap', + SoapClientOptions::SOAP_CLIENT_COMPRESSION_NONE + ); + } +} diff --git a/src/BeSimple/SoapClient/SoapOptions/SoapClientOptions.php b/src/BeSimple/SoapClient/SoapOptions/SoapClientOptions.php new file mode 100644 index 0000000..4f3a141 --- /dev/null +++ b/src/BeSimple/SoapClient/SoapOptions/SoapClientOptions.php @@ -0,0 +1,107 @@ +trace = $trace; + $this->exceptions = $exceptions; + $this->userAgent = $userAgent; + $this->compression = $compression; + $this->authentication = $authentication; + $this->proxy = $proxy; + } + + public function getTrace() + { + return $this->trace; + } + + public function getExceptions() + { + return $this->exceptions; + } + + public function getUserAgent() + { + return $this->userAgent; + } + + public function hasCompression() + { + return $this->compression !== self::SOAP_CLIENT_COMPRESSION_NONE; + } + + public function getCompression() + { + return $this->compression; + } + + public function hasAuthentication() + { + return $this->authentication !== null; + } + + public function hasProxy() + { + return $this->proxy !== null; + } + + public function getAuthentication() + { + return $this->authentication; + } + + public function getProxy() + { + return $this->proxy; + } + + public function toArray() + { + $optionsAsArray = [ + 'trace' => $this->getTrace(), + 'exceptions' => $this->getExceptions(), + 'user_agent' => $this->getUserAgent(), + ]; + if ($this->hasCompression()) { + $optionsAsArray['compression'] = $this->getCompression(); + } + if ($this->hasAuthentication()) { + $optionsAsArray += $this->getAuthentication()->toArray(); + } + if ($this->hasProxy()) { + $optionsAsArray += $this->getProxy()->toArray(); + } + + return $optionsAsArray; + } +} diff --git a/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationBasic.php b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationBasic.php new file mode 100644 index 0000000..95d2d5d --- /dev/null +++ b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationBasic.php @@ -0,0 +1,39 @@ +login = $login; + $this->password = $password; + } + + public function getAuthentication() + { + return \SOAP_AUTHENTICATION_BASIC; + } + + public function getLogin() + { + return $this->login; + } + + public function getPassword() + { + return $this->password; + } + + public function toArray() + { + return [ + 'authentication' => $this->getAuthentication(), + 'login' => $this->getLogin(), + 'password' => $this->getPassword(), + ]; + } +} diff --git a/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationDigest.php b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationDigest.php new file mode 100644 index 0000000..b0ff162 --- /dev/null +++ b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationDigest.php @@ -0,0 +1,52 @@ +localCert = $localCert; + $this->passPhrase = $passPhrase; + } + + public function getLocalCert() + { + return $this->localCert; + } + + public function hasPassPhrase() + { + return $this->passPhrase !== null; + } + + public function getPassPhrase() + { + return $this->passPhrase; + } + + public function getAuthentication() + { + return \SOAP_AUTHENTICATION_DIGEST; + } + + public function toArray() + { + $authenticationAsArray = [ + 'authentication' => $this->getAuthentication(), + 'local_cert' => $this->getLocalCert() + ]; + if ($this->hasPassPhrase()) { + $authenticationAsArray['passphrase'] = $this->getPassPhrase(); + } + + return $authenticationAsArray; + } +} diff --git a/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationInterface.php b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationInterface.php new file mode 100644 index 0000000..694d44c --- /dev/null +++ b/src/BeSimple/SoapClient/SoapOptions/SoapServerAuthentication/SoapServerAuthenticationInterface.php @@ -0,0 +1,16 @@ +host = $host; + $this->port = $port; + $this->login = $login; + $this->password = $password; + $this->authenticationType = $authenticationType; + } + + public function getHost() + { + return $this->host; + } + + public function getPort() + { + return $this->port; + } + + public function hasCredentials() + { + return $this->login !== null; + } + + public function getLogin() + { + return $this->login; + } + + public function getPassword() + { + return $this->password; + } + + public function hasAuthenticationType() + { + return $this->authenticationType !== self::PROXY_AUTHENTICATION_TYPE_NONE; + } + + public function getAuthenticationType() + { + return $this->authenticationType; + } + + public function toArray() + { + $proxyAsArray = [ + 'proxy_host' => $this->getHost(), + 'proxy_port' => $this->getPort(), + ]; + if ($this->hasCredentials()) { + $proxyAsArray['proxy_login'] = $this->getLogin(); + $proxyAsArray['proxy_password'] = $this->getPassword(); + } + if ($this->hasAuthenticationType()) { + $proxyAsArray['proxy_auth'] = $this->getAuthenticationType(); + } + + return $proxyAsArray; + } +} diff --git a/src/BeSimple/SoapClient/SoapRequest.php b/src/BeSimple/SoapClient/SoapRequest.php deleted file mode 100644 index 00580cb..0000000 --- a/src/BeSimple/SoapClient/SoapRequest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * (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\SoapClient; - -use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest; -use BeSimple\SoapCommon\SoapMessage; - -/** - * SoapRequest class for SoapClient. Provides factory function for request object. - * - * @author Andreas Schamberger - */ -class SoapRequest extends CommonSoapRequest -{ - /** - * Factory function for SoapRequest. - * - * @param string $content Content - * @param string $location Location - * @param string $action SOAP action - * @param string $version SOAP version - * - * @return BeSimple\SoapClient\SoapRequest - */ - public static function create($content, $location, $action, $version) - { - $request = new SoapRequest(); - // $content is if unmodified from SoapClient not a php string type! - $request->setContent((string) $content); - $request->setLocation($location); - $request->setAction($action); - $request->setVersion($version); - $contentType = SoapMessage::getContentTypeForVersion($version); - $request->setContentType($contentType); - - return $request; - } -} \ No newline at end of file diff --git a/src/BeSimple/SoapClient/SoapResponse.php b/src/BeSimple/SoapClient/SoapResponse.php index 0541f43..cafee41 100644 --- a/src/BeSimple/SoapClient/SoapResponse.php +++ b/src/BeSimple/SoapClient/SoapResponse.php @@ -30,7 +30,7 @@ class SoapResponse extends CommonSoapResponse * @param string $version SOAP version * @param string $contentType Content type header * - * @return BeSimple\SoapClient\SoapResponse + * @return SoapResponse */ public static function create($content, $location, $action, $version, $contentType) { diff --git a/src/BeSimple/SoapClient/Tests/SoapClientBuilderTest.php b/src/BeSimple/SoapClient/Tests/SoapClientBuilderTest.php index e9aecfb..0fc68aa 100644 --- a/src/BeSimple/SoapClient/Tests/SoapClientBuilderTest.php +++ b/src/BeSimple/SoapClient/Tests/SoapClientBuilderTest.php @@ -114,7 +114,7 @@ class SoapClientBuilderTest extends \PHPUnit_Framework_TestCase public function testCreateWithDefaults() { - $builder = SoapClientBuilder::createWithDefaults(); + $builder = SoapClientBuilder::createClientWithDefaults(); $this->assertInstanceOf('BeSimple\SoapClient\SoapClientBuilder', $builder); diff --git a/src/BeSimple/SoapCommon/AbstractSoapBuilder.php b/src/BeSimple/SoapCommon/AbstractSoapBuilder.php deleted file mode 100644 index 7c4dfdf..0000000 --- a/src/BeSimple/SoapCommon/AbstractSoapBuilder.php +++ /dev/null @@ -1,246 +0,0 @@ - - * (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\SoapCommon; - -use BeSimple\SoapCommon\Converter\TypeConverterCollection; -use BeSimple\SoapCommon\Converter\TypeConverterInterface; - -/** - * @author Christian Kerl - * @author Francis Besset - */ -abstract class AbstractSoapBuilder -{ - protected $wsdl; - protected $soapOptions = array(); - - /** - * @return AbstractSoapBuilder - */ - static public function createWithDefaults() - { - $builder = new static(); - - return $builder - ->withSoapVersion12() - ->withEncoding('UTF-8') - ->withSingleElementArrays() - ; - } - - public function __construct() - { - $this->soapOptions['features'] = 0; - $this->soapOptions['classmap'] = new Classmap(); - $this->soapOptions['typemap'] = new TypeConverterCollection(); - } - - public function getWsdl() - { - return $this->wsdl; - } - - public function getSoapOptions() - { - $options = $this->soapOptions; - - $options['classmap'] = $this->soapOptions['classmap']->all(); - $options['typemap'] = $this->soapOptions['typemap']->getTypemap(); - - return $options; - } - - /** - * @return AbstractSoapBuilder - */ - public function withWsdl($wsdl) - { - $this->wsdl = $wsdl; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withSoapVersion11() - { - $this->soapOptions['soap_version'] = \SOAP_1_1; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withSoapVersion12() - { - $this->soapOptions['soap_version'] = \SOAP_1_2; - - return $this; - } - - public function withEncoding($encoding) - { - $this->soapOptions['encoding'] = $encoding; - - return $this; - } - - public function withWsdlCache($cache) - { - if (!in_array($cache, Cache::getTypes(), true)) { - throw new \InvalidArgumentException(); - } - - $this->soapOptions['cache_wsdl'] = $cache; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withWsdlCacheNone() - { - $this->soapOptions['cache_wsdl'] = Cache::TYPE_NONE; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withWsdlCacheDisk() - { - $this->soapOptions['cache_wsdl'] = Cache::TYPE_DISK; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withWsdlCacheMemory() - { - $this->soapOptions['cache_wsdl'] = Cache::TYPE_MEMORY; - - return $this; - } - - /** - * @return AbstractSoapBuilder - */ - public function withWsdlCacheDiskAndMemory() - { - $this->soapOptions['cache_wsdl'] = Cache::TYPE_DISK_MEMORY; - - return $this; - } - - /** - * Enables the SOAP_SINGLE_ELEMENT_ARRAYS feature. - * If enabled arrays containing only one element will be passed as arrays otherwise the single element is extracted and directly passed. - * - * @return AbstractSoapBuilder - */ - public function withSingleElementArrays() - { - $this->soapOptions['features'] |= \SOAP_SINGLE_ELEMENT_ARRAYS; - - return $this; - } - - /** - * Enables the SOAP_WAIT_ONE_WAY_CALLS feature. - * - * @return AbstractSoapBuilder - */ - public function withWaitOneWayCalls() - { - $this->soapOptions['features'] |= \SOAP_WAIT_ONE_WAY_CALLS; - - return $this; - } - - /** - * Enables the SOAP_USE_XSI_ARRAY_TYPE feature. - * - * @return AbstractSoapBuilder - */ - public function withUseXsiArrayType() - { - $this->soapOptions['features'] |= \SOAP_USE_XSI_ARRAY_TYPE; - - return $this; - } - - public function withTypeConverter(TypeConverterInterface $converter) - { - $this->soapOptions['typemap']->add($converter); - - return $this; - } - - public function withTypeConverters(TypeConverterCollection $converters, $merge = true) - { - if ($merge) { - $this->soapOptions['typemap']->addCollection($converters); - } else { - $this->soapOptions['typemap']->set($converters->all()); - } - - return $this; - } - - /** - * Adds a class mapping to the classmap. - * - * @param string $xmlType - * @param string $phpType - * - * @return AbstractSoapBuilder - */ - public function withClassMapping($xmlType, $phpType) - { - $this->soapOptions['classmap']->add($xmlType, $phpType); - - return $this; - } - - /** - * Sets the classmap. - * - * @param array $classmap The classmap. - * @param boolean $merge If true the given classmap is merged into the existing one, otherwise the existing one is overwritten. - * - * @return AbstractSoapBuilder - */ - public function withClassmap(Classmap $classmap, $merge = true) - { - if ($merge) { - $this->soapOptions['classmap']->addClassmap($classmap); - } else { - $this->soapOptions['classmap']->set($classmap->all()); - } - - return $this; - } - - protected function validateWsdl() - { - if (null === $this->wsdl) { - throw new \InvalidArgumentException('The WSDL has to be configured!'); - } - } -} diff --git a/src/BeSimple/SoapCommon/Cache.php b/src/BeSimple/SoapCommon/Cache.php index 547879f..1029fa6 100644 --- a/src/BeSimple/SoapCommon/Cache.php +++ b/src/BeSimple/SoapCommon/Cache.php @@ -25,18 +25,23 @@ class Cache const TYPE_MEMORY = WSDL_CACHE_MEMORY; const TYPE_DISK_MEMORY = WSDL_CACHE_BOTH; - static protected $types = array( + static protected $types = [ self::TYPE_NONE, self::TYPE_DISK, self::TYPE_MEMORY, self::TYPE_DISK_MEMORY, - ); + ]; static public function getTypes() { return self::$types; } + static public function hasType($cacheType) + { + return in_array($cacheType, self::$types); + } + static public function isEnabled() { return self::iniGet('soap.wsdl_cache_enabled'); diff --git a/src/BeSimple/SoapCommon/Classmap.php b/src/BeSimple/SoapCommon/ClassMap.php similarity index 62% rename from src/BeSimple/SoapCommon/Classmap.php rename to src/BeSimple/SoapCommon/ClassMap.php index 6f5fc4c..f2ec016 100644 --- a/src/BeSimple/SoapCommon/Classmap.php +++ b/src/BeSimple/SoapCommon/ClassMap.php @@ -15,27 +15,29 @@ namespace BeSimple\SoapCommon; /** * @author Francis Besset */ -class Classmap +class ClassMap { - /** - * @var array - */ - protected $classmap = array(); + protected $classMap; + public function __construct(array $classMap = []) + { + $this->classmap = []; + foreach ($classMap as $type => $className) { + $this->add($type, $className); + } + } /** * @return array */ - public function all() + public function getAll() { - return $this->classmap; + return $this->classMap; } /** * @param string $type - * * @return string - * * @throws \InvalidArgumentException */ public function get($type) @@ -44,39 +46,25 @@ class Classmap throw new \InvalidArgumentException(sprintf('The type "%s" does not exists', $type)); } - return $this->classmap[$type]; + return $this->classMap[$type]; } /** * @param string $type - * @param string $classname - * + * @param string $className * @throws \InvalidArgumentException */ - public function add($type, $classname) + public function add($type, $className) { if ($this->has($type)) { throw new \InvalidArgumentException(sprintf('The type "%s" already exists', $type)); } - $this->classmap[$type] = $classname; - } - - /** - * @param array $classmap - */ - public function set(array $classmap) - { - $this->classmap = array(); - - foreach ($classmap as $type => $classname) { - $this->add($type, $classname); - } + $this->classMap[$type] = $className; } /** * @param string $type - * * @return boolean */ public function has($type) @@ -84,10 +72,10 @@ class Classmap return isset($this->classmap[$type]); } - public function addClassmap(Classmap $classmap) + public function addClassMap(ClassMap $classMap) { - foreach ($classmap->all() as $type => $classname) { - $this->add($type, $classname); + foreach ($classMap->getAll() as $type => $className) { + $this->add($type, $className); } } -} \ No newline at end of file +} diff --git a/src/BeSimple/SoapCommon/Converter/TypeConverterCollection.php b/src/BeSimple/SoapCommon/Converter/TypeConverterCollection.php index 7f06142..02ea70e 100644 --- a/src/BeSimple/SoapCommon/Converter/TypeConverterCollection.php +++ b/src/BeSimple/SoapCommon/Converter/TypeConverterCollection.php @@ -19,7 +19,7 @@ class TypeConverterCollection { private $converters = array(); - public function all() + public function getAll() { return array_values($this->converters); } @@ -58,7 +58,7 @@ class TypeConverterCollection public function addCollection(TypeConverterCollection $converterCollection) { - foreach ($converterCollection->all() as $converter) { + foreach ($converterCollection->getAll() as $converter) { $this->add($converter); } } diff --git a/src/BeSimple/SoapCommon/SoapOptions/SoapFeatures/SoapFeatures.php b/src/BeSimple/SoapCommon/SoapOptions/SoapFeatures/SoapFeatures.php new file mode 100644 index 0000000..7ffd201 --- /dev/null +++ b/src/BeSimple/SoapCommon/SoapOptions/SoapFeatures/SoapFeatures.php @@ -0,0 +1,70 @@ +resolveFeatures($features); + } + + public function isSingleElementArrays() + { + return $this->singleElementArrays; + } + + public function isOneWayCallsOn() + { + return $this->oneWayCallsOn; + } + + public function isUseXsiArrayType() + { + return $this->useXsiArrayType; + } + + public function getFeaturesSum() + { + return $this->featuresSum; + } + + private function resolveFeatures(array $features) + { + $featuresSum = 0; + foreach ($features as $feature) { + switch ($feature) { + case self::SINGLE_ELEMENT_ARRAYS: + $this->singleElementArrays = true; + $featuresSum += $feature; + break; + case self::WAIT_ONE_WAY_CALLS: + $this->oneWayCallsOn = true; + $featuresSum += $feature; + break; + case self::USE_XSI_ARRAY_TYPE: + $this->useXsiArrayType = true; + $featuresSum += $feature; + break; + default: + throw new Exception('Unknown SOAP feature: ' . $feature); + } + } + $this->featuresSum = $featuresSum; + } +} diff --git a/src/BeSimple/SoapCommon/SoapOptions/SoapOptions.php b/src/BeSimple/SoapCommon/SoapOptions/SoapOptions.php new file mode 100644 index 0000000..25633f3 --- /dev/null +++ b/src/BeSimple/SoapCommon/SoapOptions/SoapOptions.php @@ -0,0 +1,124 @@ +soapVersion = $soapVersion; + $this->encoding = $encoding; + $this->soapFeatures = $features; + $this->wsdlFile = $wsdlFile; + $this->wsdlCacheType = $wsdlCacheType; + $this->classMap = $classMap; + $this->typeConverterCollection = $typeConverterCollection; + $this->attachmentType = $attachmentType; + } + + public function getSoapVersion() + { + return $this->soapVersion; + } + + public function getEncoding() + { + return $this->encoding; + } + + public function getWsdlFile() + { + return $this->wsdlFile; + } + + public function getWsdlCacheType() + { + return $this->wsdlCacheType; + } + + public function hasAttachments() + { + return $this->attachmentType !== self::SOAP_ATTACHMENTS_OFF; + } + + public function getAttachmentType() + { + return $this->attachmentType; + } + + public function getSoapFeatures() + { + return $this->soapFeatures; + } + + public function getClassMap() + { + return $this->classMap; + } + + public function getTypeConverterCollection() + { + return $this->typeConverterCollection; + } + + public function toArray() + { + $optionsAsArray = [ + 'soap_version' => $this->getSoapVersion(), + 'encoding' => $this->getEncoding(), + 'features' => $this->getSoapFeatures(), + 'wsdl' => $this->getWsdlFile(), + 'cache_wsdl' => $this->getWsdlCacheType(), + 'classmap' => $this->getClassMap()->getAll(), + 'typemap' => $this->getTypeConverterCollection()->getTypemap(), + ]; + + return $optionsAsArray; + } +} diff --git a/src/BeSimple/SoapCommon/SoapOptionsBuilder.php b/src/BeSimple/SoapCommon/SoapOptionsBuilder.php new file mode 100644 index 0000000..afb6366 --- /dev/null +++ b/src/BeSimple/SoapCommon/SoapOptionsBuilder.php @@ -0,0 +1,44 @@ + + * (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\SoapCommon; + +use BeSimple\SoapCommon\Converter\TypeConverterCollection; +use BeSimple\SoapCommon\SoapOptions\SoapFeatures\SoapFeatures; +use BeSimple\SoapCommon\SoapOptions\SoapOptions; +use InvalidArgumentException; + +/** + * @author Petr Bechyně + */ +class SoapOptionsBuilder +{ + static public function createWithDefaults($wsdlFile, $wsdlCacheType = Cache::TYPE_NONE) + { + if (!Cache::hasType($wsdlCacheType)) { + throw new InvalidArgumentException; + } + $soapOptions = new SoapOptions( + SoapOptions::SOAP_VERSION_1_2, + SoapOptions::SOAP_ENCODING_UTF8, + new SoapFeatures([ + SoapFeatures::SINGLE_ELEMENT_ARRAYS + ]), + $wsdlFile, + $wsdlCacheType, + new ClassMap(), + new TypeConverterCollection() + ); + + return $soapOptions; + } +} diff --git a/src/BeSimple/SoapCommon/SoapRequest.php b/src/BeSimple/SoapCommon/SoapRequest.php index 314d157..a35a358 100644 --- a/src/BeSimple/SoapCommon/SoapRequest.php +++ b/src/BeSimple/SoapCommon/SoapRequest.php @@ -13,7 +13,6 @@ namespace BeSimple\SoapCommon; -use BeSimple\SoapCommon\SoapMessage; /** * SOAP request message. @@ -22,5 +21,27 @@ use BeSimple\SoapCommon\SoapMessage; */ class SoapRequest extends SoapMessage { + /** + * Factory function for SoapRequest. + * + * @param string $content Content + * @param string $location Location + * @param string $action SOAP action + * @param string $version SOAP version + * + * @return SoapRequest + */ + public static function create($content, $location, $action, $version) + { + $request = new SoapRequest(); + // $content is if unmodified from SoapClient not a php string type! + $request->setContent((string) $content); + $request->setLocation($location); + $request->setAction($action); + $request->setVersion($version); + $contentType = SoapMessage::getContentTypeForVersion($version); + $request->setContentType($contentType); -} \ No newline at end of file + return $request; + } +} diff --git a/src/BeSimple/SoapCommon/Tests/AbstractSoapBuilderTest.php b/src/BeSimple/SoapCommon/Tests/AbstractSoapBuilderTest.php index b809e1f..33fda1e 100644 --- a/src/BeSimple/SoapCommon/Tests/AbstractSoapBuilderTest.php +++ b/src/BeSimple/SoapCommon/Tests/AbstractSoapBuilderTest.php @@ -177,7 +177,7 @@ class AbstractSoapBuilderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(1, count($options['classmap'])); - $classmap = new Classmap(); + $classmap = new ClassMap(); $classmap->add('bar', __CLASS__); $builder->withClassmap($classmap); $options = $builder->getSoapOptions(); diff --git a/src/BeSimple/SoapCommon/Tests/ClassMapTest.php b/src/BeSimple/SoapCommon/Tests/ClassMapTest.php new file mode 100644 index 0000000..1722bb1 --- /dev/null +++ b/src/BeSimple/SoapCommon/Tests/ClassMapTest.php @@ -0,0 +1,65 @@ + + * (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\SoapCommon\Tests; + +use BeSimple\SoapCommon\ClassMap; + +/** + * UnitTest for \BeSimple\SoapCommon\ClassMap. + * + * @author Francis Besset + */ +class ClassMapTest extends \PHPUnit_Framework_TestCase +{ + public function testAll() + { + $classmap = new ClassMap(); + + $this->assertSame(array(), $classmap->getAll()); + } + + public function testAdd() + { + $classmap = new ClassMap(); + + $classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap'); + + $this->setExpectedException('InvalidArgumentException'); + $classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap'); + } + + public function testGet() + { + $classmap = new ClassMap(); + + $classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap'); + $this->assertSame('BeSimple\SoapCommon\ClassMap', $classmap->get('foobar')); + + $this->setExpectedException('InvalidArgumentException'); + $classmap->get('bar'); + } + + public function testAddClassMap() + { + $classmap1 = new ClassMap(); + $classmap2 = new ClassMap(); + + $classmap2->add('foobar', 'BeSimple\SoapCommon\ClassMap'); + $classmap1->addClassMap($classmap2); + + $this->assertEquals(array('foobar' => 'BeSimple\SoapCommon\ClassMap'), $classmap1->getAll()); + + $this->setExpectedException('InvalidArgumentException'); + $classmap1->addClassMap($classmap2); + } +} \ No newline at end of file diff --git a/src/BeSimple/SoapCommon/Tests/ClassmapTest.php b/src/BeSimple/SoapCommon/Tests/ClassmapTest.php deleted file mode 100644 index 2358244..0000000 --- a/src/BeSimple/SoapCommon/Tests/ClassmapTest.php +++ /dev/null @@ -1,81 +0,0 @@ - - * (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\SoapCommon\Tests; - -use BeSimple\SoapCommon\Classmap; - -/** - * UnitTest for \BeSimple\SoapCommon\Classmap. - * - * @author Francis Besset - */ -class ClassmapTest extends \PHPUnit_Framework_TestCase -{ - public function testAll() - { - $classmap = new Classmap(); - - $this->assertSame(array(), $classmap->all()); - } - - public function testAdd() - { - $classmap = new Classmap(); - - $classmap->add('foobar', 'BeSimple\SoapCommon\Classmap'); - - $this->setExpectedException('InvalidArgumentException'); - $classmap->add('foobar', 'BeSimple\SoapCommon\Classmap'); - } - - public function testGet() - { - $classmap = new Classmap(); - - $classmap->add('foobar', 'BeSimple\SoapCommon\Classmap'); - $this->assertSame('BeSimple\SoapCommon\Classmap', $classmap->get('foobar')); - - $this->setExpectedException('InvalidArgumentException'); - $classmap->get('bar'); - } - - public function testSet() - { - $classmap = new Classmap(); - - $classmap->add('foobar', 'BeSimple\SoapCommon\Tests\ClassmapTest'); - $classmap->add('foo', 'BeSimple\SoapCommon\Tests\Classmap'); - - $map = array( - 'foobar' => 'BeSimple\SoapCommon\Classmap', - 'barfoo' => 'BeSimple\SoapCommon\Tests\ClassmapTest', - ); - $classmap->set($map); - - $this->assertSame($map, $classmap->all()); - } - - public function testAddClassmap() - { - $classmap1 = new Classmap(); - $classmap2 = new Classmap(); - - $classmap2->add('foobar', 'BeSimple\SoapCommon\Classmap'); - $classmap1->addClassmap($classmap2); - - $this->assertEquals(array('foobar' => 'BeSimple\SoapCommon\Classmap'), $classmap1->all()); - - $this->setExpectedException('InvalidArgumentException'); - $classmap1->addClassmap($classmap2); - } -} \ No newline at end of file diff --git a/src/BeSimple/SoapCommon/Tests/Converter/TypeConverterCollectionTest.php b/src/BeSimple/SoapCommon/Tests/Converter/TypeConverterCollectionTest.php index 0a955cd..b445075 100644 --- a/src/BeSimple/SoapCommon/Tests/Converter/TypeConverterCollectionTest.php +++ b/src/BeSimple/SoapCommon/Tests/Converter/TypeConverterCollectionTest.php @@ -30,12 +30,12 @@ class TypeConverterCollectionTest extends \PHPUnit_Framework_TestCase $dateTimeTypeConverter = new DateTimeTypeConverter(); $converters->add($dateTimeTypeConverter); - $this->assertSame(array($dateTimeTypeConverter), $converters->all()); + $this->assertSame(array($dateTimeTypeConverter), $converters->getAll()); $dateTypeConverter = new DateTypeConverter(); $converters->add($dateTypeConverter); - $this->assertSame(array($dateTimeTypeConverter, $dateTypeConverter), $converters->all()); + $this->assertSame(array($dateTimeTypeConverter, $dateTypeConverter), $converters->getAll()); } public function testGetTypemap() @@ -73,7 +73,7 @@ class TypeConverterCollectionTest extends \PHPUnit_Framework_TestCase $converter = array(new DateTypeConverter); $converters->set($converter); - $this->assertSame($converter, $converters->all()); + $this->assertSame($converter, $converters->getAll()); } public function testAddCollection() @@ -85,7 +85,7 @@ class TypeConverterCollectionTest extends \PHPUnit_Framework_TestCase $converters2->add($dateTimeTypeConverter); $converters1->addCollection($converters2); - $this->assertSame(array($dateTimeTypeConverter), $converters1->all()); + $this->assertSame(array($dateTimeTypeConverter), $converters1->getAll()); $this->setExpectedException('InvalidArgumentException'); $converters1->addCollection($converters2); diff --git a/src/BeSimple/SoapServer/SoapOptions/SoapServerOptions.php b/src/BeSimple/SoapServer/SoapOptions/SoapServerOptions.php new file mode 100644 index 0000000..04b3457 --- /dev/null +++ b/src/BeSimple/SoapServer/SoapOptions/SoapServerOptions.php @@ -0,0 +1,137 @@ +handlerClass = $this->resolveHandlerClass($handlerClassOrObject); + $this->handlerObject = $this->resolveHandlerObject($handlerClassOrObject); + $this->keepAlive = $keepAlive; + $this->errorReporting = $errorReporting; + $this->exceptions = $exceptions; + $this->persistence = $persistence; + } + + public function hasHandlerClass() + { + return $this->handlerClass !== null; + } + + public function getHandlerClass() + { + return $this->handlerClass; + } + + public function hasHandlerObject() + { + return $this->handlerObject !== null; + } + + public function getHandlerObject() + { + return $this->handlerObject; + } + + public function hasPersistence() + { + return $this->persistence !== SoapServerOptions::SOAP_SERVER_PERSISTENCE_NONE; + } + + public function getPersistence() + { + return $this->persistence; + } + + public function isErrorReporting() + { + return $this->errorReporting; + } + + public function isExceptions() + { + return $this->exceptions; + } + + public function isKeepAlive() + { + return $this->keepAlive; + } + + public function toArray() + { + $optionsAsArray = [ + 'keep_alive' => $this->isKeepAlive(), + ]; + + return $optionsAsArray; + } + + /** + * @param mixed $handler + * @return mixed|null + */ + private function resolveHandlerObject($handler) + { + if (is_string($handler) && class_exists($handler)) { + + return null; + + } elseif (is_object($handler)) { + + return $handler; + + } else { + throw new \InvalidArgumentException('The handler has to be a class name or an object'); + } + } + + /** + * @param mixed $handler + * @return mixed|null + */ + private function resolveHandlerClass($handler) + { + if (is_string($handler) && class_exists($handler)) { + + return $handler; + + } elseif (is_object($handler)) { + + return null; + + } else { + throw new \InvalidArgumentException('The handler has to be a class name or an object'); + } + } +} diff --git a/src/BeSimple/SoapServer/SoapRequest.php b/src/BeSimple/SoapServer/SoapRequestFactory.php similarity index 89% rename from src/BeSimple/SoapServer/SoapRequest.php rename to src/BeSimple/SoapServer/SoapRequestFactory.php index 7fae123..7f5383a 100644 --- a/src/BeSimple/SoapServer/SoapRequest.php +++ b/src/BeSimple/SoapServer/SoapRequestFactory.php @@ -12,15 +12,15 @@ namespace BeSimple\SoapServer; -use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest; use BeSimple\SoapCommon\SoapMessage; +use BeSimple\SoapCommon\SoapRequest; /** * SoapRequest class for SoapClient. Provides factory function for request object. * * @author Andreas Schamberger */ -class SoapRequest extends CommonSoapRequest +class SoapRequestFactory extends SoapRequest { /** * Factory function for SoapRequest. @@ -28,14 +28,14 @@ class SoapRequest extends CommonSoapRequest * @param string $content Content * @param string $version SOAP version * - * @return BeSimple\SoapClient\SoapRequest + * @return SoapRequest */ public static function create($content, $version) { $request = new SoapRequest(); // $content is if unmodified from SoapClient not a php string type! - $request->setContent((string) (null === $content ? file_get_contents("php://input") : $content)); + $request->setContent($content); $request->setLocation(self::getCurrentUrl()); $request->setAction(isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null); $request->setVersion($version); diff --git a/src/BeSimple/SoapServer/SoapResponse.php b/src/BeSimple/SoapServer/SoapResponse.php index eba70ff..2006abc 100644 --- a/src/BeSimple/SoapServer/SoapResponse.php +++ b/src/BeSimple/SoapServer/SoapResponse.php @@ -29,10 +29,11 @@ class SoapResponse extends CommonSoapResponse * @param string $location Location * @param string $action SOAP action * @param string $version SOAP version + * @param array $attachments SOAP attachments * - * @return BeSimple\SoapClient\SoapResponse + * @return SoapResponse */ - public static function create($content, $location, $action, $version) + public static function create($content, $location, $action, $version, $attachments = []) { $response = new SoapResponse(); $response->setContent($content); @@ -48,12 +49,11 @@ class SoapResponse extends CommonSoapResponse /** * Send SOAP response to client. */ - public function send() + public function getResponseContent() { // set Content-Type header - header('Content-Type: '.$this->getContentType()); + header('Content-Type: ' . $this->getContentType()); - // send content to client - echo $this->getContent(); + return $this->getContent(); } } diff --git a/src/BeSimple/SoapServer/SoapServer.php b/src/BeSimple/SoapServer/SoapServer.php index 9b1deed..c08ba62 100644 --- a/src/BeSimple/SoapServer/SoapServer.php +++ b/src/BeSimple/SoapServer/SoapServer.php @@ -12,73 +12,67 @@ namespace BeSimple\SoapServer; -use BeSimple\SoapCommon\Helper; +use BeSimple\SoapCommon\SoapOptions\SoapOptions; +use BeSimple\SoapCommon\SoapRequest; +use BeSimple\SoapServer\SoapOptions\SoapServerOptions; use BeSimple\SoapCommon\Converter\MtomTypeConverter; use BeSimple\SoapCommon\Converter\SwaTypeConverter; +use Exception; /** * Extended SoapServer that allows adding filters for SwA, MTOM, ... . * * @author Andreas Schamberger * @author Christian Kerl + * @author Petr Bechyně */ class SoapServer extends \SoapServer { - /** - * Soap version. - * - * @var int - */ - protected $soapVersion = SOAP_1_1; + const SOAP_SERVER_REQUEST_FAILED = false; - /** - * Soap kernel. - * - * @var \BeSimple\SoapServer\SoapKernel - */ - protected $soapKernel = null; + protected $soapVersion; + protected $soapKernel; /** * Constructor. * - * @param string $wsdl WSDL file - * @param array(string=>mixed) $options Options array + * @param SoapServerOptions $soapServerOptions + * @param SoapOptions $soapOptions */ - public function __construct($wsdl, array $options = array()) + public function __construct(SoapServerOptions $soapServerOptions, SoapOptions $soapOptions) { - // store SOAP version - if (isset($options['soap_version'])) { - $this->soapVersion = $options['soap_version']; + if ($soapOptions->hasAttachments()) { + $soapOptions = $this->configureMime($soapOptions); } - // create soap kernel instance + $this->soapKernel = new SoapKernel(); - // set up type converter and mime filter - $this->configureMime($options); - // we want the exceptions option to be set - $options['exceptions'] = true; - parent::__construct($wsdl, $options); + $this->soapVersion = $soapOptions->getSoapVersion(); + + parent::__construct( + $soapOptions->getWsdlFile(), + $soapServerOptions->toArray() + $soapOptions->toArray() + ); } /** * Custom handle method to be able to modify the SOAP messages. * * @param string $request Request string + * @return string */ public function handle($request = null) { - // wrap request data in SoapRequest object - $soapRequest = SoapRequest::create($request, $this->soapVersion); + $soapRequest = SoapRequestFactory::create($request, $this->soapVersion); - // handle actual SOAP request try { - $soapResponse = $this->handle2($soapRequest); + $soapResponse = $this->handleSoapRequest($soapRequest); } catch (\SoapFault $fault) { - // issue an error to the client $this->fault($fault->faultcode, $fault->faultstring); + + return self::SOAP_SERVER_REQUEST_FAILED; } - // send SOAP response to client - $soapResponse->send(); + return $soapResponse->getResponseContent(); } /** @@ -90,12 +84,11 @@ class SoapServer extends \SoapServer * * @return SoapResponse */ - public function handle2(SoapRequest $soapRequest) + private function handleSoapRequest(SoapRequest $soapRequest) { // run SoapKernel on SoapRequest $this->soapKernel->filterRequest($soapRequest); - // call parent \SoapServer->handle() and buffer output ob_start(); parent::handle($soapRequest->getContent()); $response = ob_get_clean(); @@ -128,43 +121,25 @@ class SoapServer extends \SoapServer return $this->soapKernel; } - /** - * Configure filter and type converter for SwA/MTOM. - * - * @param array &$options SOAP constructor options array. - * - * @return void - */ - private function configureMime(array &$options) + private function configureMime(SoapOptions $soapOptions) { - if (isset($options['attachment_type']) && Helper::ATTACHMENTS_TYPE_BASE64 !== $options['attachment_type']) { - // register mime filter in SoapKernel - $mimeFilter = new MimeFilter($options['attachment_type']); + if ($soapOptions->getAttachmentType() !== SoapOptions::SOAP_ATTACHMENTS_TYPE_BASE64) { + $mimeFilter = new MimeFilter($soapOptions->getAttachmentType()); $this->soapKernel->registerFilter($mimeFilter); - // configure type converter - if (Helper::ATTACHMENTS_TYPE_SWA === $options['attachment_type']) { + if ($soapOptions->getAttachmentType() === SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA) { $converter = new SwaTypeConverter(); $converter->setKernel($this->soapKernel); - } elseif (Helper::ATTACHMENTS_TYPE_MTOM === $options['attachment_type']) { - $xmlMimeFilter = new XmlMimeFilter($options['attachment_type']); - $this->soapKernel->registerFilter($xmlMimeFilter); + $soapOptions->getTypeConverterCollection()->add($converter); + } elseif ($soapOptions->getAttachmentType() === SoapOptions::SOAP_ATTACHMENTS_TYPE_MTOM) { + $this->soapKernel->registerFilter(new XmlMimeFilter($soapOptions->getAttachmentType())); $converter = new MtomTypeConverter(); $converter->setKernel($this->soapKernel); + $soapOptions->getTypeConverterCollection()->add($converter); + } else { + throw new Exception('Unresolved SOAP_ATTACHMENTS_TYPE: ' . $soapOptions->getAttachmentType()); } - // configure typemap - if (!isset($options['typemap'])) { - $options['typemap'] = array(); - } - $options['typemap'][] = array( - 'type_name' => $converter->getTypeName(), - 'type_ns' => $converter->getTypeNamespace(), - 'from_xml' => function($input) use ($converter) { - return $converter->convertXmlToPhp($input); - }, - 'to_xml' => function($input) use ($converter) { - return $converter->convertPhpToXml($input); - }, - ); } + + return $soapOptions; } } diff --git a/src/BeSimple/SoapServer/SoapServerBuilder.php b/src/BeSimple/SoapServer/SoapServerBuilder.php index 365c812..597abb2 100644 --- a/src/BeSimple/SoapServer/SoapServerBuilder.php +++ b/src/BeSimple/SoapServer/SoapServerBuilder.php @@ -12,189 +12,38 @@ namespace BeSimple\SoapServer; -use BeSimple\SoapCommon\AbstractSoapBuilder; -use BeSimple\SoapCommon\Helper; +use BeSimple\SoapCommon\SoapOptions\SoapOptions; +use BeSimple\SoapServer\SoapOptions\SoapServerOptions; /** - * SoapServerBuilder provides a fluent interface to configure and create a SoapServer instance. + * SoapServerBuilder provides a SoapServer instance from SoapServerOptions and SoapOptions. * - * @author Christian Kerl + * @author Petr Bechyně */ -class SoapServerBuilder extends AbstractSoapBuilder +class SoapServerBuilder { - protected $persistence; - protected $errorReporting; - - protected $handlerClass; - protected $handlerObject; - /** - * Create new instance with default options. + * Builds a SoapServer instance. * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - static public function createWithDefaults() - { - return parent::createWithDefaults() - ->withErrorReporting(false); - } - - /** - * Initializes all options with the defaults used in the native SoapServer. - */ - public function __construct() - { - parent::__construct(); - - // TODO: this is not the default, but safer - $this->withErrorReporting(false); - } - - /** - * Finally returns a SoapClient instance. + * @param SoapServerOptions $soapServerOptions + * @param SoapOptions $soapOptions * - * @return \BeSimple\SoapServer\SoapServer + * @return SoapServer */ - public function build() + public function build(SoapServerOptions $soapServerOptions, SoapOptions $soapOptions) { - $this->validateOptions(); + use_soap_error_handler($soapServerOptions->isErrorReporting()); - use_soap_error_handler($this->errorReporting); - - $server = new SoapServer($this->wsdl, $this->getSoapOptions()); - - if (null !== $this->persistence) { - $server->setPersistence($this->persistence); + $server = new SoapServer($soapServerOptions, $soapOptions); + if ($soapServerOptions->hasPersistence()) { + $server->setPersistence($soapServerOptions->getPersistence()); } - - if (null !== $this->handlerClass) { - $server->setClass($this->handlerClass); - } elseif (null !== $this->handlerObject) { - $server->setObject($this->handlerObject); + if ($soapServerOptions->hasHandlerClass()) { + $server->setClass($soapServerOptions->getHandlerClass()); + } else if ($soapServerOptions->hasHandlerObject()) { + $server->setObject($soapServerOptions->getHandlerObject()); } return $server; } - - /** - * Cofigures the SOAP actor. - * - * @param string $actor Actor name - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withActor($actor) - { - $this->options['actor'] = $actor; - - return $this; - } - - /** - * Enables persistence. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withPersistanceRequest() - { - $this->persistence = SOAP_PERSISTENCE_REQUEST; - - return $this; - } - - /** - * Enables the HTTP session. The handler object is persisted between multiple requests in a session. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withPersistenceSession() - { - $this->persistence = SOAP_PERSISTENCE_SESSION; - - return $this; - } - - /** - * Enables reporting of internal errors to clients. This should only be enabled in development environments. - * - * @param boolean $enable Enable error reporting - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withErrorReporting($enable = true) - { - $this->errorReporting = $enable; - - return $this; - } - - /** - * SOAP attachment type Base64. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withBase64Attachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_BASE64; - - return $this; - } - - /** - * SOAP attachment type SwA. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withSwaAttachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_SWA; - - return $this; - } - - /** - * SOAP attachment type MTOM. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withMtomAttachments() - { - $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_MTOM; - - return $this; - } - - /** - * Configures the handler class or object. - * - * @param mixed $handler Can be either a class name or an object. - * - * @return \BeSimple\SoapServer\SoapServerBuilder - */ - public function withHandler($handler) - { - if (is_string($handler) && class_exists($handler)) { - $this->handlerClass = $handler; - $this->handlerObject = null; - } elseif (is_object($handler)) { - $this->handlerClass = null; - $this->handlerObject = $handler; - } else { - throw new \InvalidArgumentException('The handler has to be a class name or an object'); - } - - return $this; - } - - /** - * Validate options. - */ - protected function validateOptions() - { - $this->validateWsdl(); - - if (null === $this->handlerClass && null === $this->handlerObject) { - throw new \InvalidArgumentException('The handler has to be configured!'); - } - } -} \ No newline at end of file +} diff --git a/src/BeSimple/SoapServer/SoapServerOptionsBuilder.php b/src/BeSimple/SoapServer/SoapServerOptionsBuilder.php new file mode 100644 index 0000000..3c3ed45 --- /dev/null +++ b/src/BeSimple/SoapServer/SoapServerOptionsBuilder.php @@ -0,0 +1,19 @@ +