peanut
5 years ago

simplexml_load_string(): namespace error : Namespace prefix S on Fault is not defined

Posted 5 years ago by peanut

So I'm using ChromeData for my project to pull data based on make/model/year. This is my code for my helper I'm using:

<?php namespace Duplicolor\Helpers;

use Duplicolor\Traits\ErrorTrait;

    /*

    This PHP implementation cannot use the built-in 'SoapClient' object, due
    to a bug in how it interprets the WSDL.  So instead, we build the requests
    as XML strings, using the curl library to transact with the service, and
    the responses are parsed using the SimpleXML API (the older 'DOMDocument'
    interface may not be compiled into your version of PHP).

    Apparently the bug is that, when there is a "choice" element in the WSDL
    and anything other than the first element in that choice is supplied,
    'SoapClient' will throw an error, expecting the first element to be there.
    Here are some references:

    https://bugs.php.net/bug.php?id=50997
    https://bugs.php.net/bug.php?id=53234

    */
class ChromeData {

    protected $soapURL = 'http://services.chromedata.com/Description/7a';
    use ErrorTrait; // enable error logging

    protected $request; // Request build
    protected $xml; // Passed to soap request

    public function requestParam( $name )
    {
        return (array_key_exists($name, $_REQUEST) ? $_REQUEST[$name] : "");
    }

    public function setCurl()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->soapURL);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->xml);
        $header[] = "SOAPAction: ". "";
        $header[] = "MIME-Version: 1.0";
        $header[] = "Content-type: text/xml; charset=utf-8";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        return curl_exec($ch);
    }

    public function callSoap()
    {
        $result = $this->setCurl();
        $start = strpos($result, "<S:Body>") + 8;
        $end = strrpos($result, "</S:Body>");

        if (($start <= 0) || ($end <= 0))
        {
            $this->setError("Response returned from " . $this->soapURL . " doesn't appear to be a SOAP document.");
            return false;
        }

        $result = substr($result, $start, $end - $start);
        $doc = \simplexml_load_string($result);

        if($doc->responseStatus["responseCode"] != "Successful")
        {
            $this->setError($doc->responseStatus["responseCode"]);
            return false;
        }

        return $doc;
    }

    public function moneyFormat( $dollarValue )
    {
        return "$" . $dollarValue;
    }

    public function getRequestHeader()
    {
        return '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:description7a.services.chrome.com">
           <soapenv:Header/>
           <soapenv:Body>
              <urn:VehicleDescriptionRequest>
                 <urn:accountInfo number="299544" secret="e9c4aec0fa734a50" country="US" language="en" behalfOf="?"/>';
    }

    public function getRequestFooter()
    {
        return '</urn:VehicleDescriptionRequest>
               </soapenv:Body>
            </soapenv:Envelope>';
    }

    public function getVehicleInfoByVin( $vin )
    {
        $this->request = '<urn:vin>' . $vin . '</urn:vin>';

        return $this->getRequest();
    }

    public function getRequest()
    {
        $this->xml = $this->getRequestHeader();
        $this->xml .= $this->request;
        $this->xml .= $this->getRequestFooter();

        return $this->callSoap();
    }

}

And it's throwing this error: simplexml_load_string(): namespace error : Namespace prefix S on Fault is not defined

I tried putting a '\' in front of simplexml_load_string() and that didn't solve the issue.

Can someone help me figure out why this is happening and how to solve it? Thanks!

Please sign in or create an account to participate in this conversation.