forked from php-soap/encoding
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRequestEncoder.php
More file actions
116 lines (101 loc) · 3.87 KB
/
RequestEncoder.php
File metadata and controls
116 lines (101 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php declare(strict_types=1);
namespace Soap\Encoding\Encoder\Method;
use Closure;
use Generator;
use Soap\Encoding\Xml\Node\Element;
use Soap\Encoding\Xml\Reader\OperationReader;
use Soap\Encoding\Xml\Writer\OperationBuilder;
use Soap\Encoding\Xml\Writer\ParameterBuilder;
use Soap\Encoding\Xml\Writer\SoapEnvelopeWriter;
use Soap\Engine\Metadata\Model\Parameter;
use Soap\WsdlReader\Model\Definitions\BindingUse;
use Soap\WsdlReader\Model\Definitions\EncodingStyle;
use Soap\WsdlReader\Model\Definitions\SoapVersion;
use VeeWee\Reflecta\Iso\Iso;
use XMLWriter;
use function Psl\Vec\map_with_key;
use function VeeWee\Reflecta\Lens\index;
/**
* @template-implements SoapMethodEncoder<list<mixed>, non-empty-string>
*/
final class RequestEncoder implements SoapMethodEncoder
{
/**
* @return Iso<list<mixed>, non-empty-string>
*/
public function iso(MethodContext $context): Iso
{
$meta = $context->method->getMeta();
$context = $context->withBindingUse(
$meta->inputBindingUsage()
->map(static fn ($value) => BindingUse::from($value))
->unwrapOr(BindingUse::LITERAL)
);
/** @var Iso<list<mixed>, non-empty-string> */
return new Iso(
/**
* @param list<mixed> $arguments
* @return non-empty-string
*/
fn (array $arguments): string => $this->encode($context, $arguments),
/**
* @param non-empty-string $xml
* @return list<mixed>
*/
fn (string $xml): array => $this->decode($context, $xml),
);
}
/**
* @param list<mixed> $arguments
* @return non-empty-string
*/
private function encode(MethodContext $context, array $arguments): string
{
$method = $context->method;
$meta = $method->getMeta();
$soapVersion = $meta->soapVersion()
->map(static fn ($value) => SoapVersion::from($value))
->unwrapOr(SoapVersion::SOAP_12);
$encodingStyle = $meta->inputEncodingStyle()
->map(static fn ($value) => EncodingStyle::from($value));
$requestParams = map_with_key(
$method->getParameters(),
/**
* @return Closure(XMLWriter): Generator<bool>
*/
static function (int $index, Parameter $parameter) use ($meta, $context, $arguments): Closure {
$type = $parameter->getType();
$typeContext = $context->createXmlEncoderContextForType($type);
/** @var mixed $value */
$value = index($index)->get($arguments);
return (new ParameterBuilder($meta, $typeContext, $value))(...);
}
);
$operation = new OperationBuilder($meta, $context->namespaces, $requestParams);
$writeEnvelope = new SoapEnvelopeWriter($soapVersion, $context->bindingUse, $encodingStyle, $operation(...));
return $writeEnvelope() . PHP_EOL;
}
/**
* @param non-empty-string $xml
* @return list<mixed>
*/
private function decode(MethodContext $context, string $xml): array
{
$method = $context->method;
$meta = $method->getMeta();
$parts = (new OperationReader($meta))($xml)->elements();
return map_with_key(
$method->getParameters(),
static function (int $index, Parameter $parameter) use ($context, $parts) : mixed {
$type = $parameter->getType();
$typeContext = $context->createXmlEncoderContextForType($type);
$decoder = $context->registry->detectEncoderForContext($typeContext);
$iso = $decoder->iso($typeContext);
/** @var Element $value */
$value = index($index)->get($parts);
/** @var mixed */
return $iso->from($value);
}
);
}
}