Skip to content

Commit ace9c25

Browse files
committed
the dtd actually depends on what request/response/message is about to be generated. So there is a hard dependency between the model and the dtd. Refactored to have it set in CXml/Builder to reflect that.
1 parent e61aee7 commit ace9c25

File tree

3 files changed

+50
-25
lines changed

3 files changed

+50
-25
lines changed

src/CXml/Builder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class Builder
123123

124124
private ?Status $status = null;
125125

126+
private string $dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd';
127+
126128
private function __construct(private ?string $senderUserAgent, private readonly ?string $locale = null, ?PayloadIdentityFactoryInterface $payloadIdentityFactory = null)
127129
{
128130
$this->payloadIdentityFactory = $payloadIdentityFactory ?? new DefaultPayloadIdentityFactory();
@@ -133,6 +135,13 @@ public static function create(string $senderUserAgent = 'cxml-php UserAgent', ?s
133135
return new self($senderUserAgent, $locale, $payloadIdentityFactory);
134136
}
135137

138+
public function dtdUri(string $dtdUri): self
139+
{
140+
$this->dtdUri = $dtdUri;
141+
142+
return $this;
143+
}
144+
136145
public function payload(?PayloadInterface $payload = null): self
137146
{
138147
$this->payload = $payload;
@@ -209,6 +218,7 @@ public function build(?string $deploymentMode = null): CXml
209218
new Request($this->payload, null, $deploymentMode),
210219
$this->buildHeader(),
211220
$this->locale,
221+
$this->dtdUri,
212222
);
213223
break;
214224

@@ -219,6 +229,7 @@ public function build(?string $deploymentMode = null): CXml
219229
new Message($this->payload, $this->status, null, $deploymentMode),
220230
$this->buildHeader(),
221231
$this->locale,
232+
$this->dtdUri,
222233
);
223234
break;
224235

@@ -235,6 +246,7 @@ public function build(?string $deploymentMode = null): CXml
235246
$this->payloadIdentityFactory->newPayloadIdentity(),
236247
new Response($status, $this->payload),
237248
$this->locale,
249+
$this->dtdUri,
238250
);
239251
break;
240252

@@ -245,6 +257,7 @@ public function build(?string $deploymentMode = null): CXml
245257
$this->payloadIdentityFactory->newPayloadIdentity(),
246258
new Response($this->status),
247259
$this->locale,
260+
$this->dtdUri,
248261
);
249262

250263
break;

src/CXml/Model/CXml.php

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#[Serializer\XmlRoot('cXML')]
1616
#[Serializer\AccessorOrder(order: 'custom', custom: ['header', 'message', 'request', 'response'])]
17-
readonly class CXml implements Stringable
17+
class CXml implements Stringable
1818
{
1919
final public const DEPLOYMENT_TEST = 'test';
2020

@@ -23,35 +23,42 @@
2323
protected function __construct(
2424
#[Serializer\XmlAttribute]
2525
#[Serializer\SerializedName('payloadID')]
26-
public string $payloadId,
26+
readonly public string $payloadId,
2727
#[Serializer\XmlAttribute]
28-
public DateTimeInterface $timestamp,
28+
readonly public DateTimeInterface $timestamp,
2929
#[Serializer\SerializedName('Request')]
30-
public ?Request $request = null,
30+
readonly public ?Request $request = null,
3131
#[Serializer\SerializedName('Response')]
32-
public ?Response $response = null,
32+
readonly public ?Response $response = null,
3333
#[Serializer\SerializedName('Message')]
34-
public ?Message $message = null,
34+
readonly public ?Message $message = null,
3535
#[Serializer\SerializedName('Header')]
36-
public ?Header $header = null,
36+
readonly public ?Header $header = null,
3737
#[Serializer\XmlAttribute(namespace: 'http://www.w3.org/XML/1998/namespace')]
38-
public ?string $lang = null,
38+
readonly public ?string $lang = null,
39+
#[Serializer\Exclude]
40+
public string $dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd',
3941
) {
4042
}
4143

42-
public static function forMessage(PayloadIdentity $payloadIdentity, Message $message, Header $header, ?string $lang = null): self
44+
public function setDtdUri(string $dtdUri): void
4345
{
44-
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, null, null, $message, $header, $lang);
46+
$this->dtdUri = $dtdUri;
4547
}
4648

47-
public static function forRequest(PayloadIdentity $payloadIdentity, Request $request, Header $header, ?string $lang = null): self
49+
public static function forMessage(PayloadIdentity $payloadIdentity, Message $message, Header $header, ?string $lang = null, string $dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd'): self
4850
{
49-
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, $request, null, null, $header, $lang);
51+
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, null, null, $message, $header, $lang, $dtdUri);
5052
}
5153

52-
public static function forResponse(PayloadIdentity $payloadIdentity, Response $response, ?string $lang = null): self
54+
public static function forRequest(PayloadIdentity $payloadIdentity, Request $request, Header $header, ?string $lang = null, string $dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd'): self
5355
{
54-
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, null, $response, null, null, $lang);
56+
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, $request, null, null, $header, $lang, $dtdUri);
57+
}
58+
59+
public static function forResponse(PayloadIdentity $payloadIdentity, Response $response, ?string $lang = null, string $dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd'): self
60+
{
61+
return new self($payloadIdentity->payloadId, $payloadIdentity->timestamp, null, $response, null, null, $lang, $dtdUri);
5562
}
5663

5764
public function __toString(): string

src/CXml/Serializer.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,12 @@
2828

2929
readonly class Serializer
3030
{
31-
public const DOC_TYPE_VERSION = '1.2.063';
32-
3331
private function __construct(
3432
private SerializerInterface $jmsSerializer,
35-
private string $dtdUri,
3633
) {
3734
}
3835

39-
public static function create(string $dtdUri = 'http://xml.cxml.org/schemas/cXML/' . self::DOC_TYPE_VERSION . '/cXML.dtd'): self
36+
public static function create(): self
4037
{
4138
$jmsSerializer = SerializerBuilder::create()
4239
->configureListeners(static function (EventDispatcherInterface $dispatcher): void {
@@ -57,27 +54,35 @@ public static function create(string $dtdUri = 'http://xml.cxml.org/schemas/cXML
5754
)
5855
->build();
5956

60-
return new self($jmsSerializer, $dtdUri);
57+
return new self($jmsSerializer);
6158
}
6259

6360
public function deserialize(string $xml): CXml
6461
{
65-
// remove doctype (if exists), as it would throw a JMS\Serializer\Exception\InvalidArgumentException
66-
$xml = preg_replace('/<!doctype[^>]+?>/i', '', $xml);
62+
$dtdUri = 'http://xml.cxml.org/schemas/cXML/1.2.063/cXML.dtd';
63+
if (preg_match('/<!doctype.+"(.+)"[^>]*>/i', $xml, $matches) !== false) {
64+
$dtdUri = $matches[1];
65+
66+
// remove doctype from xml (if exists), as it would throw a JMS\Serializer\Exception\InvalidArgumentException
67+
$xml = preg_replace('/<!doctype[^>]+?>/i', '', $xml);
68+
}
6769

68-
if (null === $xml || '' === trim($xml)) {
70+
if ('' === trim($xml ?? '')) {
6971
throw new RuntimeException('Cannot deserialize empty string');
7072
}
7173

72-
/* @phpstan-ignore-next-line */
73-
return $this->jmsSerializer->deserialize($xml, CXml::class, 'xml');
74+
/** @var CXml $cXml */
75+
$cXml = $this->jmsSerializer->deserialize((string)$xml, CXml::class, 'xml');
76+
$cXml->setDtdUri($dtdUri);
77+
78+
return $cXml;
7479
}
7580

7681
public function serialize(CXml $cxml): string
7782
{
7883
$xml = $this->jmsSerializer->serialize($cxml, 'xml');
7984

80-
$docType = '<!DOCTYPE cXML SYSTEM "' . $this->dtdUri . '">';
85+
$docType = '<!DOCTYPE cXML SYSTEM "' . $cxml->dtdUri . '">';
8186
$xmlPrefix = '<?xml version="1.0" encoding="UTF-8"?>';
8287

8388
// add doctype, as it is mandatory in cXML

0 commit comments

Comments
 (0)