Skip to content
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
2 changes: 1 addition & 1 deletion src/Encoder/Method/ResponseEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private function decode(MethodContext $context, string $xml): array
// The SoapResponse only contains the payload of the response (with no headers).
// It can be parsed directly as XML.
invariant($xml !== '', 'Expected a non-empty response payload. Received an empty HTTP response');
$parts = (new OperationReader($meta))($xml)->elements();
$parts = (new OperationReader($meta))($xml, $context->registry->decoderLibXmlOptions())->elements();

return map(
$parts,
Expand Down
22 changes: 21 additions & 1 deletion src/EncoderRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ final class EncoderRegistry
/**
* @param MutableMap<string, XmlEncoder<mixed, string>> $simpleTypeMap
* @param MutableMap<string, XmlEncoder<mixed, string>> $complextTypeMap
* @param int $decoderLibXmlOptions - bitmask of LIBXML_* constants https://www.php.net/manual/en/libxml.constants.php
*/
private function __construct(
private MutableMap $simpleTypeMap,
private MutableMap $complextTypeMap
private MutableMap $complextTypeMap,
private int $decoderLibXmlOptions = 0,
) {
}

Expand Down Expand Up @@ -341,4 +343,22 @@ public function detectEncoderForContext(Context $context): XmlEncoder
{
return EncoderDetector::default()($context);
}

/**
* @param int $libXmlOptions - bitmask of LIBXML_* constants https://www.php.net/manual/en/libxml.constants.php
*/
public function setDecoderLibXmlOptions(int $libXmlOptions): self
{
$this->decoderLibXmlOptions = $libXmlOptions;

return $this;
}

/**
* @return int - bitmask of LIBXML_* constants https://www.php.net/manual/en/libxml.constants.php
*/
public function decoderLibXmlOptions(): int
{
return $this->decoderLibXmlOptions;
}
}
5 changes: 3 additions & 2 deletions src/Xml/Reader/OperationReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ public function __construct(
* Reads all operation response message parts:
*
* @param non-empty-string $xml
* @param int $libXmlOptions - bitmask of LIBXML_* constants https://www.php.net/manual/en/libxml.constants.php
*/
public function __invoke(string $xml): ElementList
public function __invoke(string $xml, int $libXmlOptions = 0): ElementList
{
$bindingStyle = BindingStyle::tryFrom($this->meta->bindingStyle()->unwrapOr(BindingStyle::DOCUMENT->value));

// The Response can contain out of multiple response parts.
// Therefore, it is being wrapped by a central root element:
$body = (new SoapEnvelopeReader())($xml);
$body = (new SoapEnvelopeReader())($xml, $libXmlOptions);
$bodyElement = $body->element();

$elements = match($bindingStyle) {
Expand Down
7 changes: 5 additions & 2 deletions src/Xml/Reader/SoapEnvelopeReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
use Soap\Xml\Locator\SoapBodyLocator;
use VeeWee\Xml\Dom\Document;
use function VeeWee\Xml\Dom\Assert\assert_element;
use function VeeWee\Xml\Dom\Configurator\loader;
use function VeeWee\Xml\Dom\Loader\xml_string_loader;

final class SoapEnvelopeReader
{
/**
* @param non-empty-string $xml
* @param int $libXmlOptions - bitmask of LIBXML_* constants https://www.php.net/manual/en/libxml.constants.php
*/
public function __invoke(string $xml): Element
public function __invoke(string $xml, int $libXmlOptions = 0): Element
{
$envelope = Document::fromXmlString($xml);
$envelope = Document::configure(loader(xml_string_loader($xml, $libXmlOptions)));

// Make sure it does not contain a fault response before parsing the body parts.
(new SoapFaultGuard())($envelope);
Expand Down
19 changes: 17 additions & 2 deletions tests/Unit/Xml/Reader/OperationReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
use Soap\Engine\Metadata\Model\MethodMeta;
use Soap\WsdlReader\Model\Definitions\BindingStyle;
use function Psl\Vec\map;
use const LIBXML_NOCDATA;

#[CoversClass(OperationReader::class)]
final class OperationReaderTest extends TestCase
{
#[DataProvider('provideEnvelopeCases')]
public function test_it_can_read_a_soap_envelope(MethodMeta $meta, string $envelope, array $expected): void
public function test_it_can_read_a_soap_envelope(MethodMeta $meta, string $envelope, array $expected, int $libXmlOptions = 0): void
{
$reader = new OperationReader($meta);
$actual = $reader($envelope);
$actual = $reader($envelope, $libXmlOptions);

static::assertSame(
$expected,
Expand Down Expand Up @@ -91,5 +92,19 @@ public static function provideEnvelopeCases()
'<c>c</c>',
],
];

yield 'xml-options' => [
$methodMeta->withBindingStyle(BindingStyle::DOCUMENT->value),
<<<EOXML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<Request><![CDATA[content]]></Request>
</soap:Body>
</soap:Envelope>
EOXML,
['<Request>content</Request>'],
LIBXML_NOCDATA
];

}
}
22 changes: 20 additions & 2 deletions tests/Unit/Xml/Reader/SoapEnvelopeReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@
use Soap\Encoding\Xml\Reader\SoapEnvelopeReader;
use Soap\Encoding\Xml\Writer\SoapEnvelopeWriter;
use Soap\WsdlReader\Model\Definitions\SoapVersion;
use const LIBXML_NOCDATA;

#[CoversClass(SoapEnvelopeWriter::class)]
#[CoversClass(SoapFaultGuard::class)]
final class SoapEnvelopeReaderTest extends TestCase
{
#[DataProvider('provideEnvelopeCases')]
public function test_it_can_read_a_soap_envelope(SoapVersion $version, string $envelope, string $expected): void
public function test_it_can_read_a_soap_envelope(SoapVersion $version, string $envelope, string $expected, int $libXmlOptions = 0): void
{
$reader = new SoapEnvelopeReader();
$actual = $reader($envelope);
$actual = $reader($envelope, $libXmlOptions);

static::assertXmlStringEqualsXmlString($expected, $actual->value());
}
Expand Down Expand Up @@ -83,5 +84,22 @@ public static function provideEnvelopeCases()
</soap:Body>
EOXML,
];

yield 'xml-options' => [
SoapVersion::SOAP_12,
<<<EOXML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/">
<Request><![CDATA[content]]></Request>
</soap:Body>
</soap:Envelope>
EOXML,
<<<EOXML
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/">
<Request>content</Request>
</soap:Body>
EOXML,
LIBXML_NOCDATA
];
}
}