Skip to content

fix(laravel-soap-126): Arguments wrong passed with call method #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 68 additions & 3 deletions src/Driver/ExtSoap/AbusedClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,49 @@

namespace CodeDredd\Soap\Driver\ExtSoap;

use Phpro\SoapClient\Soap\Driver\ExtSoap\AbusedClient as PhproAbusedClient;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptionsResolverFactory;
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;
use Phpro\SoapClient\Xml\SoapXml;

class AbusedClient extends PhproAbusedClient
class AbusedClient extends \SoapClient
{
public static function createFromOptions(ExtSoapOptions $options): PhproAbusedClient
/**
* @var SoapRequest|null
*/
protected $storedRequest;

/**
* @var SoapResponse|null
*/
protected $storedResponse;

// @codingStandardsIgnoreStart
/**
* Internal SoapClient property for storing last request.
*
* @var string
*/
protected $__last_request = '';
// @codingStandardsIgnoreEnd

// @codingStandardsIgnoreStart
/**
* Internal SoapClient property for storing last response.
*
* @var string
*/
protected $__last_response = '';
// @codingStandardsIgnoreEnd

public function __construct($wsdl, array $options = [])
{
$options = ExtSoapOptionsResolverFactory::createForWsdl($wsdl)->resolve($options);
parent::__construct($wsdl, $options);
}

public static function createFromOptions(ExtSoapOptions $options): self
{
return new self($options->getWsdl(), $options->getOptions());
}
Expand All @@ -24,4 +59,34 @@ public function __doRequest($request, $location, $action, $version, $oneWay = 0)

return $this->storedResponse ? $this->storedResponse->getResponse() : '';
}

public function collectRequest(): SoapRequest
{
if (! $this->storedRequest) {
throw new \RuntimeException('No request has been registered yet.');
}

return $this->storedRequest;
}

public function registerResponse(SoapResponse $response)
{
$this->storedResponse = $response;
}

public function cleanUpTemporaryState()
{
$this->storedRequest = null;
$this->storedResponse = null;
}

public function __getLastRequest(): string
{
return $this->__last_request;
}

public function __getLastResponse(): string
{
return $this->__last_response;
}
}
40 changes: 40 additions & 0 deletions src/Driver/ExtSoap/ExtSoapDecoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace CodeDredd\Soap\Driver\ExtSoap;

use Phpro\SoapClient\Soap\Driver\ExtSoap\Generator\DummyMethodArgumentsGenerator;
use Phpro\SoapClient\Soap\Engine\DecoderInterface;
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;

class ExtSoapDecoder implements DecoderInterface
{
/**
* @var AbusedClient
*/
private $client;

/**
* @var DummyMethodArgumentsGenerator
*/
private $argumentsGenerator;

public function __construct(AbusedClient $client, DummyMethodArgumentsGenerator $argumentsGenerator)
{
$this->client = $client;
$this->argumentsGenerator = $argumentsGenerator;
}

public function decode(string $method, SoapResponse $response)
{
$this->client->registerResponse($response);
try {
$decoded = $this->client->__soapCall($method, $this->argumentsGenerator->generateForSoapCall($method));
} finally {
$this->client->cleanUpTemporaryState();
}

return $decoded;
}
}
82 changes: 78 additions & 4 deletions src/Driver/ExtSoap/ExtSoapDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,89 @@

namespace CodeDredd\Soap\Driver\ExtSoap;

use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapDriver as PhproExtSoapDriver;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;
use Phpro\SoapClient\Soap\Driver\ExtSoap\Generator\DummyMethodArgumentsGenerator;
use Phpro\SoapClient\Soap\Engine\DecoderInterface;
use Phpro\SoapClient\Soap\Engine\DriverInterface;
use Phpro\SoapClient\Soap\Engine\EncoderInterface;
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataFactory;
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataInterface;
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;

class ExtSoapDriver extends PhproExtSoapDriver
class ExtSoapDriver implements DriverInterface
{
public static function createFromOptions(ExtSoapOptions $options): PhproExtSoapDriver
/**
* @var AbusedClient
*/
private $client;

/**
* @var EncoderInterface
*/
private $encoder;

/**
* @var DecoderInterface
*/
private $decoder;

/**
* @var MetadataInterface
*/
private $metadata;

public function __construct(
AbusedClient $client,
EncoderInterface $encoder,
DecoderInterface $decoder,
MetadataInterface $metadata
) {
$this->client = $client;
$this->encoder = $encoder;
$this->decoder = $decoder;
$this->metadata = $metadata;
}

public static function createFromOptions(ExtSoapOptions $options): self
{
$client = AbusedClient::createFromOptions($options);

return self::createFromClient($client);
return self::createFromClient(
$client,
MetadataFactory::manipulated(new ExtSoapMetadata($client), $options->getMetadataOptions())
);
}

public static function createFromClient(AbusedClient $client, MetadataInterface $metadata = null): self
{
$metadata = $metadata ?? MetadataFactory::lazy(new ExtSoapMetadata($client));

return new self(
$client,
new ExtSoapEncoder($client),
new ExtSoapDecoder($client, new DummyMethodArgumentsGenerator($metadata)),
$metadata
);
}

public function decode(string $method, SoapResponse $response)
{
return $this->decoder->decode($method, $response);
}

public function encode(string $method, array $arguments): SoapRequest
{
return $this->encoder->encode($method, $arguments);
}

public function getMetadata(): MetadataInterface
{
return $this->metadata;
}

public function getClient(): AbusedClient
{
return $this->client;
}
}
33 changes: 33 additions & 0 deletions src/Driver/ExtSoap/ExtSoapEncoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace CodeDredd\Soap\Driver\ExtSoap;

use Phpro\SoapClient\Soap\Engine\EncoderInterface;
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;

class ExtSoapEncoder implements EncoderInterface
{
/**
* @var AbusedClient
*/
private $client;

public function __construct(AbusedClient $client)
{
$this->client = $client;
}

public function encode(string $method, array $arguments): SoapRequest
{
try {
$this->client->__soapCall($method, $arguments);
$encoded = $this->client->collectRequest();
} finally {
$this->client->cleanUpTemporaryState();
}

return $encoded;
}
}
2 changes: 1 addition & 1 deletion src/Driver/ExtSoap/ExtSoapEngineFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public static function fromOptionsWithHandler(
) {
$driver = ExtSoapDriver::createFromOptions($options);

return $withMocking ? new EngineFaker($driver, $handler, $options->getWsdl()) : new Engine($driver, $handler);
return $withMocking ? new EngineFaker($driver, $handler, $options) : new Engine($driver, $handler);
}
}
50 changes: 50 additions & 0 deletions src/Driver/ExtSoap/ExtSoapMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace CodeDredd\Soap\Driver\ExtSoap;

use CodeDredd\Soap\Driver\ExtSoap\Metadata\MethodsParser;
use CodeDredd\Soap\Driver\ExtSoap\Metadata\TypesParser;
use CodeDredd\Soap\Driver\ExtSoap\Metadata\XsdTypesParser;
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\MethodCollection;
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\TypeCollection;
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\XsdTypeCollection;
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataInterface;

class ExtSoapMetadata implements MetadataInterface
{
/**
* @var AbusedClient
*/
private $abusedClient;

/**
* @var XsdTypeCollection|null
*/
private $xsdTypes;

public function __construct(AbusedClient $abusedClient)
{
$this->abusedClient = $abusedClient;
}

public function getMethods(): MethodCollection
{
return (new MethodsParser($this->getXsdTypes()))->parse($this->abusedClient);
}

public function getTypes(): TypeCollection
{
return (new TypesParser($this->getXsdTypes()))->parse($this->abusedClient);
}

private function getXsdTypes(): XsdTypeCollection
{
if (null === $this->xsdTypes) {
$this->xsdTypes = XsdTypesParser::default()->parse($this->abusedClient);
}

return $this->xsdTypes;
}
}
Loading