diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index f5b5dc7..f246a54 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -5,6 +5,7 @@
\Symfony\Component\Finder\Finder::create()
->in([
__DIR__ . '/src',
+ __DIR__ . '/examples',
__DIR__ . '/tests',
])
->name('*.php')
diff --git a/README.md b/README.md
index d5ef4ff..2b924bb 100644
--- a/README.md
+++ b/README.md
@@ -126,3 +126,6 @@ class MySpecificTypeCEncoder implements XmlEncoder
**Note:** An encoder is considered to be isomorphic : When calling `from` and `to` on the `Iso` object, the data should be the same.
More information about the concept [can be found here](https://github.com/veewee/reflecta/blob/main/docs/isomorphisms.md).
+
+For a full list of available encoders, you can check the [Soap\Encoding\Encoder](src/Encoder) namespace.
+There are also some examples of common problems you can solve with these encoders in the [examples/encoders](examples/encoders) directory.
diff --git a/examples/calc-encode.php b/examples/calc-encode.php
index 5745ba3..33dd555 100644
--- a/examples/calc-encode.php
+++ b/examples/calc-encode.php
@@ -1,13 +1,12 @@
-
+ *
+ *
+ *
+ *
+ *
+ * This encoder will use veewee/xml to encode and decode the whole XML structure so that it can be used by you.
+ *
+ * The result looks like this:
+ *
+ *
+ *
+ *
+ * world
+ *
+ *
+ * <=>
+ *
+ * ^ {#1761
+ * +"customerName": "John Doe"
+ * +"customerEmail": "john@doe.com"
+ * +"customerData": array:3 [
+ * "foo" => ""
+ * "bar" => ""
+ * "hello" => "world"
+ * ]
+ * }
+ */
+
+EncoderRegistry::default()
+ ->addComplexTypeConverter(
+ 'http://yournamespace',
+ 'yourTypeUsingTheAnyType',
+ new class implements XmlEncoder {
+ /**
+ * @return Iso
+ */
+ public function iso(Context $context): Iso
+ {
+ $typeName = $context->type->getName();
+
+ return new Iso(
+ to: static fn (array $data): string => document_encode([$typeName => $data])->stringifyDocumentElement(),
+ from: static fn (Element|string $xml): array => xml_decode(
+ ($xml instanceof Element ? $xml : Element::fromString($xml))->value()
+ )[$typeName],
+ );
+ }
+ }
+ );
diff --git a/examples/encoders/simpleType/anyType-with-xsi-info.php b/examples/encoders/simpleType/anyType-with-xsi-info.php
new file mode 100644
index 0000000..2ca3522
--- /dev/null
+++ b/examples/encoders/simpleType/anyType-with-xsi-info.php
@@ -0,0 +1,57 @@
+
+ *
+ * Will Result in for example:
+ *
+ *
+ * 789
+ *
+ */
+
+EncoderRegistry::default()
+ ->addSimpleTypeConverter(
+ 'http://www.w3.org/2001/XMLSchema',
+ 'anyType',
+ new class implements
+ ElementContextEnhancer,
+ XmlEncoder {
+ public function iso(Context $context): Iso
+ {
+ return (new ScalarTypeEncoder())->iso($context);
+ }
+
+ /**
+ * This method allows to change the context on the wrapping elementEncoder.
+ * By forcing the bindingUse to `ENCODED`, we can make sure the xsi:type attribute is added.
+ * We also make sure the type is not qualified so that the xsi:type prefix xmlns is imported as well.
+ */
+ public function enhanceElementContext(Context $context): Context
+ {
+ return $context
+ ->withBindingUse(BindingUse::ENCODED)
+ ->withType(
+ $context->type->withMeta(
+ static fn (TypeMeta $meta): TypeMeta => $meta->withIsQualified(false)
+ )
+ );
+ }
+ }
+ );
diff --git a/src/Encoder/Context.php b/src/Encoder/Context.php
index 7cc22ae..16bad2b 100644
--- a/src/Encoder/Context.php
+++ b/src/Encoder/Context.php
@@ -30,4 +30,15 @@ public function withType(XsdType $type): self
$this->bindingUse,
);
}
+
+ public function withBindingUse(BindingUse $bindingUse): self
+ {
+ return new self(
+ $this->type,
+ $this->metadata,
+ $this->registry,
+ $this->namespaces,
+ $bindingUse,
+ );
+ }
}
diff --git a/src/Encoder/ElementEncoder.php b/src/Encoder/ElementEncoder.php
index c27b954..c65dcd1 100644
--- a/src/Encoder/ElementEncoder.php
+++ b/src/Encoder/ElementEncoder.php
@@ -28,6 +28,9 @@ public function __construct(
public function iso(Context $context): Iso
{
$typeEncoder = $this->typeEncoder;
+ $context = $this->typeEncoder instanceof Feature\ElementContextEnhancer
+ ? $this->typeEncoder->enhanceElementContext($context)
+ : $context;
return new Iso(
/**
diff --git a/src/Encoder/Feature/ElementContextEnhancer.php b/src/Encoder/Feature/ElementContextEnhancer.php
new file mode 100644
index 0000000..66ebbfc
--- /dev/null
+++ b/src/Encoder/Feature/ElementContextEnhancer.php
@@ -0,0 +1,19 @@
+ '32',
'data' => 32,
];
+ yield 'context-enhancing-child-encoder' => [
+ ...$baseConfig,
+ 'encoder' => $encoder = new ElementEncoder(new class implements ElementContextEnhancer, XmlEncoder {
+ public function iso(Context $context): Iso
+ {
+ return (new IntTypeEncoder())->iso($context);
+ }
+
+ public function enhanceElementContext(Context $context): Context
+ {
+ return $context->withType(
+ $context->type->withXmlTargetNodeName('bonjour')
+ );
+ }
+ }),
+ 'xml' => '32',
+ 'data' => 32,
+ ];
}
public function test_it_can_decode_from_xml_item(): void