1

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:

SOAP API Documentation 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:

Visitor object API Documentation

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.