Reputation: 5116
I'll be the first to admit I rarely use SOAP, but I generally can make do. I am seriously struggling with something, hopefully someone can shed some light on this.
I have a WSDL, that I am connecting to and getting a sessionToken
that is used for future requests, all well and good.
I am trying to call a VmifCreateVisitor
method now that according to SOAP UI, should look something like the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vmif="http://www.gallagher.co/security/commandcentre/vmifws" xmlns:web="http://www.gallagher.co/security/commandcentre/webservice">
<soapenv:Header/>
<soapenv:Body>
<vmif:VmifCreateVisitor>
<!--Optional:-->
<vmif:sessionToken>
<web:Value>?</web:Value>
</vmif:sessionToken>
<!--Optional:-->
<vmif:vmConfigDivisionId>
<web:Value>?</web:Value>
</vmif:vmConfigDivisionId>
<!--Optional:-->
<vmif:visitor>
<!--Optional:-->
<vmif:DetailFields>
<!--Zero or more repetitions:-->
<web:PdfValue>
<!--Optional:-->
<web:IsUsedForNotification>?</web:IsUsedForNotification>
<web:Name>?</web:Name>
<web:Type>?</web:Type>
</web:PdfValue>
</vmif:DetailFields>
<vmif:FirstName>?</vmif:FirstName>
<vmif:LastName>?</vmif:LastName>
<!--Optional:-->
<vmif:DivisionId>
<web:Value>?</web:Value>
</vmif:DivisionId>
<!--Optional:-->
<vmif:Id>
<web:Value>?</web:Value>
</vmif:Id>
<!--Optional:-->
<vmif:UserCode>?</vmif:UserCode>
<vmif:VisitorTypeIds>
<!--Zero or more repetitions:-->
<vmif:VmifVisitorTypeId>
<web:Value>?</web:Value>
</vmif:VmifVisitorTypeId>
</vmif:VisitorTypeIds>
</vmif:visitor>
</vmif:VmifCreateVisitor>
</soapenv:Body>
</soapenv:Envelope>
I can create a visitor OK if I leave out the DetailFields
section:
<vmif:DetailFields>
<!--Zero or more repetitions:-->
<web:PdfValue>
<!--Optional:-->
<web:IsUsedForNotification>?</web:IsUsedForNotification>
<web:Name>?</web:Name>
<web:Type>?</web:Type>
</web:PdfValue>
</vmif:DetailFields>
But this is not something I can do, I need to send some personal details in the POST request. This is where it gets weird. When I send the following SOAP DetailFields Params, I get "Cannot create abstract class"
// ... (Truncated for Brevity)
$params->visitor->FirstName = $request->firstname;
$params->visitor->LastName = $request->lastname;
# ▼▼ Works if commented out. ▼▼
$mobile = new PdfValue();
$mobile->IsUsedForNotification = null;
$mobile->Name = 'Mobile Number';
$mobile->Type = 'Mobile';
$mobile->Value = $request->mobile;
$address = new PdfValue();
$address->IsUsedForNotification = null;
$address->Name = 'Address';
$address->Type = 'Address';
$address->Value = $request->address;
$params->visitor->DetailFields = [
$address,
$mobile
];
# ▲▲ Works if commented out. ▲▲
$visitorId = new VmifVisitorTypeId();
$visitorId->Value = $request->visitor_type_id;
$params->visitor->VisitorTypeIds = [
$visitorId
];
// ... (Truncated for Brevity)
The Generated PHP WSDL Class created the following PdfValue() Class:
class PdfValue {
public $IsUsedForNotification; // boolean
public $Name; // string
public $Type; // PdfType
}
But I notice its missing Value
parameter, same with SOAP structure from SOAP UI. (Adding it to class makes no difference).
If you're curious, here is the VmifVisitor
class the WSDL generated:
class VmifVisitor {
public $DivisionId; // VmifDivisionId
public $Id; // VmifVisitorId
public $UserCode; // string
public $VisitorTypeIds; // ArrayOfVmifVisitorTypeId
}
As shown above - its missing the DetailFields parameter, even the the SOAP API Docs clearly show its required, (Adding it manually to class still doesn't help)
The Actual documentation shows the following structure for PdfValue
:
As you can see it clearly shows Value
as an object
. What is it expecting me to send it in an object?
For completion, this is the documentation for the Visitor
object:
So we can see its expecting an array of PdfValue
, which I believe I am sending. Any Ideas?
TL;DR I am getting "Cannot create abstract class" when I send an array of PdfValue() in DetailFields for VmifVisitorCreate method. The auto-generated php class for PdfValue is missing Value parameter, and the SOAP API Docs expects a Value parameter and says it should be an object, Adding the Value param to my PdfValue class still yields same error, which confuses me.
Upvotes: 1
Views: 317
Reputation: 5116
I feel silly, this basically boiled down to a namespace issue. The Type was not being found due to my assumption that all types were in the same namespace. Simply changing:
$params->visitor->DetailFields = [
$address,
$mobile
];
to
$params->visitor->DetailFields = [
new \SoapVar($address, SOAP_ENC_OBJECT, 'PdfGeneralValue', 'http://www.domain.co/security/namespacepath/webservice'),
new \SoapVar($mobile, SOAP_ENC_OBJECT, 'PdfGeneralValue', 'http://www.domain.co/security/namespacepath/webservice'),
];
This allowed it to work. Notice I also changed the type_name
to PdfGeneralValue
, this was also key in getting it to work. Thanks all.
Upvotes: 1