Search code examples
phpweb-servicessoapwsdl

Using a WSDL with abstract types in PHP


I'm working on an integration between our web application and Microsoft Exchange 2007. I am using Exchange Web Services (EWS) to communicate to the Exchange Server. However, I am running into some issues with the WSDL. There are several types defined in the WSDL that have elements of abstract types. For example:

<xs:complexType name="RestrictionType">
  <xs:sequence>
    <xs:element ref="t:SearchExpression"/>
  </xs:sequence>
</xs:complexType>

SearchExpression is an abtract type. There are several types that extend SearchExpression such as ExistsType:

<xs:complexType name="ExistsType"> 
  <xs:complexContent> 
    <xs:extension base="t:SearchExpressionType"> 
      ...
    </xs:extension>
  </xs:complexContent>
</xs:complexType>
<xs:element name="Exists" type="t:ExistsType" substitutionGroup="t:SearchExpression"/>

I would expect to be able to make a valid call that produces the following XML:

<Restriction>
  <Exists>
    ...
  </Exists>
</Restriction>

However, when I attempt to make the call using PHP's SoapClient class I receive the following error:

The request failed schema validation: The element 'http://schemas.microsoft.com/exchange/services/2006/types:SearchExpression' is abstract or its type is abstract.

If I modify the definition of the RestrictionType type to the follow, the call works:

<xs:element name="Exists" type="t:ExistsType"/>

Is PHP's SOAP handling not able to properly handle abstract types in the WSDL, or could there be something wrong with the WSDL itself? The WSDL is stored locally so I can make edits to it if the need arrises.

Thank you for your help in advance.

Edit:
I just wanted to clarify that I am not forming the XML myself. I am using the following code that should be creating the proper XML:

$request->Restriction->IsGreaterThan->FieldURI->FieldURI =
  'item:DateTimeReceived';
$request->Restriction->IsGreaterThan->FieldURIOrConstant
  ->Constant->Value = date('c', $last_checked_time);

Solution

  • I found the answer to my own question. Apparently PHP's SOAP object cannot properly form XML from the object structure I am using when there are abstract types. To combat the issue, I edited the WSDL and replaced references to any abstract types with references to the concrete types that extend them. So for the RestrictionType example above, I changed the schema definition to match the following:

    <xs:complexType name="RestrictionType"> 
      <xs:choice maxOccurs ="unbounded">
        <xs:element ref="t:Exists"/>
        <xs:element ref="t:Excludes"/>
        <xs:element ref="t:IsEqualTo"/>
        <xs:element ref="t:IsNotEqualTo"/>
        <xs:element ref="t:IsGreaterThan"/>
        <xs:element ref="t:IsGreaterThanOrEqualTo"/>
        <xs:element ref="t:IsLessThan"/>
        <xs:element ref="t:IsLessThanOrEqualTo"/>
        <xs:element ref="t:Not"/>
        <xs:element ref="t:And"/>
        <xs:element ref="t:Or"/>
      </xs:choice>
    </xs:complexType>
    

    I hope this helps somebody else out. Thanks to all who took the time to at least read my post.