-
-
Notifications
You must be signed in to change notification settings - Fork 177
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
Using classes that extends another #536
Comments
Translated chunk of documentation of service:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AddPersonIdentifier
xmlns="http://parsec.ru/ParsecIntergationService">
<personEditSessionID>a0c8c558-0893-4fb6-b2ea528d2f08edd2</personEditSessionID>
<identifier xsi:type="Identifier">
<CODE>11111112</CODE>
<PERSON_ID>be4d3ce8-d830-4796-9197-7fa65c78d13f</PERSON_ID>
<IS_PRIMARY>false</IS_PRIMARY>
<ACCGROUP_ID>111111111-2222-3333-4444-555555555555</ACCGROUP_ID>
</identifier>
</AddPersonIdentifier>
</soap:Body>
</soap:Envelope> |
In comparison to simple types, complex types are in direct control of the element wrapping it's data. Maybe this would work for you? use Soap\Encoding\Encoder\Context;
use Soap\Encoding\Encoder\ObjectEncoder;
use Soap\Encoding\Encoder\XmlEncoder;
use Soap\WsdlReader\Model\Definitions\BindingUse;
use VeeWee\Reflecta\Iso\Iso;
$registry->addComplexTypeConverter(
'http://parsec.ru/Parsec3IntergationService',
'BaseIdentifier',
new class implements XmlEncoder
{
public function iso(Context $context): Iso
{
return (new ObjectEncoder(Identifier::class))->iso(
$context
->withBindingUse(BindingUse::ENCODED)
->withType($context->type->copy('Identifier'))
);
}
}
); (ℹ️ Note that I hardcoded it to the On data input: $encoded = $driver->encode('AddPersonIdentifier', [
[
'personEditSessionID' => '962bf124-2b58-4ed3-b63f-adaa73a29e91',
'identifier' => [
'CODE' => '11111112',
'PERSON_ID' => 'be4d3ce8-d830-4796-9197-7fa65c78d13f',
'IS_PRIMARY' => false,
'ACCGROUP_ID' => '111111111-2222-3333-4444-555555555555',
'PRIVILEGE_MASK' => 0,
'IDENTIFTYPE' => 0,
'NAME' => '',
]
]
]); Resulting in this XML: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<tns:AddPersonIdentifier xmlns:tns="http://parsec.ru/Parsec3IntergationService">
<tns:personEditSessionID xmlns:tns="http://parsec.ru/Parsec3IntergationService">
962bf124-2b58-4ed3-b63f-adaa73a29e91
</tns:personEditSessionID>
<tns:identifier xsi:type="tns:Identifier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">
<tns:CODE xmlns:s="http://www.w3.org/2001/XMLSchema" xsi:type="s:string"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">11111112
</tns:CODE>
<tns:PERSON_ID xmlns:s1="http://microsoft.com/wsdl/types/" xsi:type="s1:guid"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">
be4d3ce8-d830-4796-9197-7fa65c78d13f
</tns:PERSON_ID>
<tns:IS_PRIMARY xmlns:s="http://www.w3.org/2001/XMLSchema" xsi:type="s:boolean"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">false
</tns:IS_PRIMARY>
<tns:ACCGROUP_ID xmlns:s1="http://microsoft.com/wsdl/types/" xsi:type="s1:guid"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">
111111111-2222-3333-4444-555555555555
</tns:ACCGROUP_ID>
<tns:PRIVILEGE_MASK xmlns:s="http://www.w3.org/2001/XMLSchema" xsi:type="s:long"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">0
</tns:PRIVILEGE_MASK>
<tns:IDENTIFTYPE xmlns:s="http://www.w3.org/2001/XMLSchema" xsi:type="s:int"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService">0
</tns:IDENTIFTYPE>
<tns:NAME xmlns:s="http://www.w3.org/2001/XMLSchema" xsi:type="s:string"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://parsec.ru/Parsec3IntergationService"></tns:NAME>
</tns:identifier>
</tns:AddPersonIdentifier>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> (ℹ️ Note that it also adds xsi:type on all it's children. Normally, that shouldn't be a big problem since they are the same as in the WSDL) |
Well, I have come up with a more intelligent solution based on what you suggested. ParsecInvertedClassmap for mapping PHP classes to XSD Types: use Soap\Engine\Metadata\Model\XsdType;
class ParsecInvertedClassmap
{
/**
* @var array<string, XsdType>|null
*/
private static ?array $collection = null;
/**
* @return array<string, XsdType>
*/
public static function getCollection(): array
{
if (self::$collection === null) {
self::$collection = [];
foreach (ParsecClassmap::getCollection() as $classmap) {
self::$collection[$classmap->getPhpClassName()] = XsdType::create($classmap->getXmlType())
->withXmlNamespace($classmap->getXmlNamespace())
->withXmlTypeName($classmap->getXmlType());
}
}
return self::$collection;
}
} ComplexContextEnhancer: use LazyTechwork\Parsec\ParsecInvertedClassmap;
use Soap\Encoding\Encoder\Context;
use Soap\Encoding\Encoder\ObjectEncoder;
use Soap\Encoding\Encoder\XmlEncoder;
use Soap\Encoding\Xml\Node\Element;
use Soap\WsdlReader\Model\Definitions\BindingUse;
use VeeWee\Reflecta\Iso\Iso;
class ComplexContextEnhancer implements XmlEncoder
{
public function __construct(private readonly string $baseClass)
{
}
public function iso(Context $context): Iso
{
return new Iso(
fn (object|array $value): string => $this->getEncoder($context, $value)->to($value),
fn (string|Element $value): object => (new ObjectEncoder($this->baseClass))->iso($context)->from($value)
);
}
private function getEncoder(Context $context, mixed $value): Iso
{
if (is_a($value, $this->baseClass)) {
return (new ObjectEncoder($this->baseClass))->iso($context
->withBindingUse(BindingUse::ENCODED)
->withType($context->type->copy(ParsecInvertedClassmap::getCollection()[get_class($value)]->getName())));
}
return (new ObjectEncoder($this->baseClass))->iso($context);
}
} And complex type converter in Client Factory: use LazyTechwork\Parsec\Types\BaseIdentifier;
use LazyTechwork\Parsec\Encoders\ComplexContextEnhancer;
->addComplexTypeConverter(
'http://parsec.ru/Parsec3IntergationService',
'BaseIdentifier',
new ComplexContextEnhancer(BaseIdentifier::class)
) @veewee Thank you very much! |
Hello! I have another problem with types, as in #534. The
BaseIdentifier
class is extended byIdentifier
, and the documentation for my WSDL states that I need to explicitly specify the type of the object that is being extended. So, when making a request, I useIdentifier
, but when passing arguments, method signature usingBaseIdentifier
. How can I add thexsi:type
attribute to the extended class?Chunk of types in WSDL:
I tried to do something like this:
But I still get an instance of
BaseIdentifier
in the request:The text was updated successfully, but these errors were encountered: