Integrating ListHub with Joomla

Lately, we spent a lot of time working on a project integrating ListHub, the famous MLS platform, on an existing Joomla website. The project consisted of finding “special” listings (those listings with special criteria) within ListHub‘s listings and then displaying them on the site. Despite the fact that it was our third project that consisted of integrating ListHub with Joomla so far this year, we still had quite a few challenges particularly when it came to grabbing the data from ListHub and then parsing that data.

Before delving into the challenges, let us briefly explain what we did in the project:

  • We created a Joomla component called com_realestate (we were going to call it com_listhub, but we then changed our minds because it was possible that our client would then switch to another MLS provider).
  • We created a hash-protected view that was responsible for grabbing the data (e.g. downloading the XML file from ListHub‘s site).

  • We then created another view, which was also hash-protected, that was responsible for parsing the XML file downloaded in the previous step and then storing the selected entries (and information) in the database. (Note that these two views can be merged into one view – but we chose to separate them into two).

  • We created a paginated view that displayed a listing of all the entries that were stored in the database (with sorting options).

  • We created a search plugin that scanned all the entries for the searched text, eventually feeding the search results to the view created in the previous step.

  • We then created a search module which made use of the search plugin above.

  • Finally, we created a view that listed the details of a single real estate entry in the database.

Of course, the project was much, much more than the above but the above information is essentially what we can share with the public…

So, as you can see, the project is pretty much a straightforward MVC Joomla extension, with the exception of the first couple of steps (which are always a challenge). So, in order to make things easier for those who would like to do a similar project, we decided to share the main code for the first two steps!

In order to grab the data the XML file from ListHub, we used the following code (note that we are using cURL, so make sure that you have the cURL PHP module installed on your environment):

$jinput = JFactory::getApplication()->input;
$hash = $jinput->get('hash', '');
if ($hash != '[the_secret_hash]')
	die('Unauthorized...');

error_reporting(E_ALL);
set_time_limit(0);
define('XMLNS_COMMON', 'http://rets.org/xsd/RETSCommons');


//The following 5 variables are typically stored in the extension's settings and not hardcoded into the code.
$url = 'https://feeds.listhub.com/pickup/[ourclient]/[ourclient].xml.gz';
$username = '[ListHub username]';
$password = '[ListHub password]';
$filePath = JPATH_SITE.'/xmldata/listhub.xml.gz';
$xmlFilePath = str_replace('.gz', '', $filePath); 


//Get the gzipped file from ListHub
$downloadedFile = fopen ($filePath, 'w+');
$curlHandler = curl_init();
curl_setopt($curlHandler, CURLOPT_URL, $url);
curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandler, CURLOPT_USERPWD, "$username:$password");
curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curlHandler, CURLOPT_FILE, $downloadedFile);
$result = curl_exec($curlHandler);
$info = curl_getinfo($curlHandler);
curl_close($curlHandler);
fclose($downloadedFile);

//Now that we have the gzipped file, we will need to extract it.
$bufferSize = 4096;
$gzippedFile = gzopen($filePath, 'rb');
$xmlDownloadFile = fopen($xmlFilePath, 'wb'); 
while(!gzeof($gzippedFile)) {
  fwrite($xmlDownloadFile, gzread($gzippedFile, $bufferSize));
}  
fclose($xmlDownloadFile);
gzclose($gzippedFile);

The above code will download the zipped XML file (from ListHub‘s server) containing all the data that ListHub has made available for a particular account. Once the zipped XML file is downloaded, the last part of the code will extract it and we will have a pure, unzipped XML file containing all the listings.

Now that we have downloaded and unzipped the XML file, then we need to parse it. Typically, parsing an XML file is not that hard, but if you want some buried values from within a complex XML file, then it’ll be hard enough.

Here’s how we parsed the XML file:

//Get the XML data from the XML file
$xmlListHubListings=simplexml_load_file($xmlFilePath) or die("Error: Cannot create object");
$allListHubListings = $xmlListHubListings->Listing;

//Loop through all the XML listings
for ($i = 0; $i < count($allListHubListings); $i++){
	$singleListing = $allListHubListings[$i];
	$listingNumber = addslashes($singleListing->MlsNumber);
	$listPrice = addslashes($singleListing->ListPrice);
	$listingKey = addslashes($singleListing->ListingKey);
	$listingUrl = addslashes($singleListing->ListingURL);
	$bedrooms =  addslashes($singleListing->Bedrooms);
	$bathrooms =  addslashes($singleListing->Bathrooms);
	if (isset($singleListing->Photos) && isset($singleListing->Photos->Photo)){
		$imageUrl = addslashes($singleListing->Photos->Photo[0]->MediaURL);
		$numberPhotos = count($singleListing->Photos->Photo);
	}
	else{
		$imageUrl = '';
		$numberPhotos = 0;
	}
	$address = $singleListing->Address->children(XMLNS_COMMON);
	$addressStreet = addslashes($address->FullStreetAddress);
	$addressCity = addslashes($address->City);
	$addressState = addslashes($address->StateOrProvince);
	$addressPostalCode = addslashes($address->PostalCode);
	$longitude = '';
	$latitude = '';
	if (isset($singleListing->Location)){
		$longitude = addslashes($singleListing->Location->Longitude);
		$latitude =  addslashes($singleListing->Location->Latitude);
	}
}

The above code will loop through the extracted XML file that was created in the previous step. It will loop through all the listings and retrieve the main values in each listing (of course, there are many more values that can be retrieved from the XML file, so it's really up to your requirements). An important note here is that ListHub requires a minimum amount of information to be displayed on the site (for example, they require that you include the name of the Real Estate agent/company, which is not retrieved in the above code).

By the way, if you want to refresh the ListHub data on your website daily, then you will need to include a call to the above views in your cron. That's how we do it anyway... Of course, you can hire a person who will refresh those views every day, but that would be completely inefficient! (OK - that was a joke...)

Now, in this post, we have tried to make things much, much easier for those trying to integrate ListHub with Joomla (we honestly think that the above code, with just one little exception, can be used in any other CMS, including WordPress and Drupal). We hope we helped! In case you need more help or in case the above code did not work for you for one reason or the other, then we're here for you! Just contact us and we'll integrate ListHub for you on your Joomla website quickly, professionally, and for a very affordable fee!

No comments yet.

Leave a comment