What?
A quick article to stop me running into this issue again. This article serves to address the issue of importing characters from an XML in a different language character set and trying to load it in PHP with the function simplexml_load_string(). The error I get is something similar to:

PHP Warning:
simplexml_load_string(): Entity: line #: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xA0 0x3C 0x2F 0x73 in /home/public_html/my_folder/my_xml_processing_script.php on line 160

Why?
I'm downloading an XML feed to our servers, and then loading the downloaded file into memory with simplexml_load_string(). I get the above error when it is attempting to load an XML feed which is mostly in Spanish and breaks at the following XML node:
<baños>2</baños>

-> yields issue: PHP Warning:  simplexml_load_string():     <baños>2</baños> in /home/public_html/my_folder/my_xml_processing_script.php on line 160

should read

<baños>2</baños>

How?

Applies to:

  • Apimo Webservice 2.0 (apimo.com)
  • PHP v5.5
What?
This is an article on how I connected to the Apimo WebService. The Apimo Webservice is an API provided by apimo.com and requires a server request over HTTPS using the GET method.

Why?
This was quite difficult to connect to and to determine what was wrong with each step of the development as the error messages were somewhat vague. I thought I'd quickly write this article so I don't have to spend so much time on it again.

Note that the below examples, demonstrate a script on a Non-SSL-Enabled host.

How?
Previously, I would have used cURL but for some reason, I couldn't get the configuration right. After several days... I tried the example as per the Apimo documentation and it worked like viagra or cialis! There were a few adjustments to make which I'm documenting here.

Basic Example
Here's a complete PHP script of a basic example of getting the agencies belonging to a company (note you will need to change the keys and relevant IDs to match your own solution):
// specify provider ID
$my_provider_id = 1234;  
$my_timestamp = time();

// specify company ID
$company_id_1 = 1234;
$company_id_2 = 4321;

// specify agency ID
$company_id_1_agency_id = '';
$company_id_1_brand_id = '';

// specify target url and version
$apimo_url = 'https://api.apimo.com/api/call';
$apimo_version = 2;

// specify data output
$apimo_method = 'getAgencies';
$apimo_type = 'xml';

// specify key and encryption
$apimo_key = 'abcd1234abcd1234abcd1234abcd1234abcd1234';  // specify your assigned key here
$apimo_sha = sha1($apimo_key.$my_timestamp);

// receive content
$output = file_get_contents(
        $apimo_url.
        '?provider='.$my_provider_id.
        '×tamp='.$my_timestamp.
        '&sha1='.$apimo_sha.
        '&method='.$apimo_method.
        '&type='.$apimo_type.
        '&version='.$apimo_version.
        '&agency='.$company_id_1_agency_id.
        '&company='.$company_id_1.
        '&brand='.$company_id_1_brand_id
);

// remove XML declaration from results 
$output = substr($output, stripos($output, '?>') + 2 );

// remove leading spaces, carriage returns
$output = trim($output); 

// process if type specified was xml
if($apimo_type=='xml'){

        // send header
        header("Content-Type:text/xml");

        // print result to page
        echo $output;
}
Advanced Example
Here's a complete PHP script of a more complex example of 1) getting the agencies belonging to a company then 2) getting the properties for each agency:
<?php

// intialize a result count
$property_count=0;

// specify provider ID
$my_provider_id = 1234;
$my_timestamp = time();

// specify company IDs
$target_company_ids = array(2345, 3456);

// specify target url and version
$apimo_url = 'https://api.apimo.com/api/call';
$apimo_version = 2;

// specify data output
$apimo_type = 'xml';

// specify key and encryption
$apimo_key = 'abcd1234abcd1234abcd1234abcd1234abcd1234';
$apimo_sha = sha1($apimo_key.$my_timestamp);

// 
for($i=0;$i<count($target_company_ids);$i++){

        // receive content
        $output = file_get_contents(
                $apimo_url.
                '?provider='.$my_provider_id.
                '×tamp='.$my_timestamp.
                '&sha1='.$apimo_sha.
                '&method=getAgencies'.
                '&type='.$apimo_type.
                '&version='.$apimo_version.
                '&agency='.
                '&company='.$target_company_ids[$i].
                '&brand='
        );

        echo '<h1>Company: '.$target_company_ids[$i].'</h1>';

        // remove XML declaration from results 
        $output = substr($output, stripos($output, '?>') + 2 );

        // remove leading spaces, carriage returns
        $output = trim($output); 

        // convert output to XML string type
        $apimo = new SimpleXMLElement($output);

        // loop through each agency and retrieve ID
        foreach($apimo->agencies->agency as $agency){

        echo '<h2>Agency: '.$agency->id.'</h2>';

                // get properties for each agency
                $agency_output = file_get_contents(
                        $apimo_url.
                        '?provider='.$my_provider_id.
                        '×tamp='.$my_timestamp.
                        '&sha1='.$apimo_sha.
                        '&method=getProperties'.
                        '&type='.$apimo_type.
                        '&version='.$apimo_version.
                        '&agency='.$agency->id.
                        '&company='.
                        '&brand='
                );

                // remove XML declaration from results 
                $agency_output = trim(substr($agency_output, stripos($agency_output, '?>') + 2 ));

                // convert output to XML string type
                $properties = new SimpleXMLElement($agency_output);

                foreach($properties->properties->property as $property){
                        echo '<h3>Property: '.$property->id.'</h3>';
                        echo $property->reference.'<br />';
                        echo $property->address.'<br />';
                        foreach($property->pictures->picture as $picture){
                                echo '<img src="'.$picture->url.'" width="150" height="100" />';
                        }
                        $property_count++;
                }

        }

} // end for i=0 i<count i++

// output how many properties were returned
echo '<hr />Returned Properties: '.$property_count;
?>

Other Methods
Here's the cURL I couldn't get working. Instead I used Apimo's documentation with file_get_contents. Just storing this in case.

// cURL With SSL via method GET: FAIL
$header = array(
"Content-Type: text/xml;charset=UTF-8",
"Accept: gzip,deflate",
"User-Agent: WWPC uAPI Test",
"Cache-Control: no-cache",
"Pragma: no-cache",
"Connection: Keep-Alive",
"Host: api.apimo.com",
"Content-length: " . strlen($test_message_url),
);
$ch = curl_init();    
curl_setopt($ch, CURLOPT_URL, $apimo_url.'?'.$apimo_message_xml); // set url
curl_setopt($ch, CURLOPT_VERBOSE, 1);                              // For debugging purposes (read CURL manual for nore info)
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);                      // Timeout options
curl_setopt($ch, CURLOPT_TIMEOUT, 30);                             // Timeout options
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"); // set browser/user agent    
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);       // TLS version to use (1.0)
curl_setopt($ch, CURLOPT_HEADER, 0 );                              // Omit headers (enable these during testing - malformed XML but more info)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );                      // curl_exec function will show the response directly on the page (if set to 0 curl_exec function will return the result)
curl_setopt($ch, CURLOPT_PORT, 443);                               // SSL port to use (443)
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); // get header
$ch_result = curl_exec($ch);

echo $ch_result;

Applies to:

  • TravelPort Universal API
  • PHP 4 or 5
  • cURL
What?
An article on how to resolve errors and setup a standard ping request using the TravelPort Universal API. This is to be achieved using PHP as the server-side programming language and cURL, a sub-component of PHP that allows you to send and receive requests as the server (as opposed to the client device).

Why?
Yes there's documentation online that TravelPort provide you with but it didn't help. The error I'm going to address has to do with getting the latest schemas but as I couldn't find anything using Google regarding these errors or how to set up a basic ping request, I thought I'd write this article.

How?
Using PHP and cURL, here is the full script for a standard ping request. Before you say it doesn't work, it has to be updated every time a new schema is introduced to the system. See my errors section for how you can resolve this.

Previously titled
Fix PHP cURL: parser error: Document labelled UTF-16 but has UTF-8 content

What?
This is an article with notes for me on how to convert some received XML encoded in UTF-16 to some JSON in UTF-8. If it were entirely in UTF-8, I would simply load the received XML with SimpleXML and use the built-in PHP JSON_encode function. I ran into the following errors:

Warning: SimpleXMLElement::__construct() [<a href='simplexmlelement.--construct'>simplexmlelement.--construct</a>]: Entity: line 1: parser error : Document labelled UTF-16 but has UTF-8 content in /public_html/.../.../my_script.php on line ###

Warning: simplexml_load_string() [<a href='function.simplexml-load-string'>function.simplexml-load-string</a>]: Entity: line 1: parser error : Document labelled UTF-16 but has UTF-8 content in /public_html/.../.../my_script.php on line ###
Why?
So I've googled, binged and yahoo'd for this and although there are some solutions that deal with loading UTF16 content into SimpleXMLElement or simplexml_load_string, it doesn't solve my problem. I'm receiving XML data within a cURL result but I get the above error with using either "SimpleXMLElement" or "simplexml_load_string". Returning the XML with cURL isn't a problem, but I want to convert it to JSON and I usually use a PHP function to load the data into an XML array and use the built-in PHP function: "json_encode".

How?