Custom Package Previews with XML (using php5, curl and simpleXML)

In addition to using PandoAPI.js and Javascript to generate custom package previews, you can also use a server-side script to process XML or JSON encoded package info. This following example uses php5 (with the CURL and SimpleXML libraries) to take a package URL from the user and generate "cut and paste"-able HTML for use as a package preview. We'll use the CSS and target HTML from the PandoAPI.js example, with the goal to generate package previews that look like this:

Spring Street Art

Downloaded 56 times
Expires in 7240 days

Getting Package URL from User

In order to generate a preview, first we need a package ID (and, optionally, key) to generate the preview. The handiest source for these data are package URLs, so we'll ask the user for the Package URL in a simple HTML form, where ActionUrl is the URL to the code that will process the URL, generate and display the package preview:

<form action="ActionUrl" method="GET">
Pando package url: <input type="text" name="packageurl"><br />
<input type="submit" value="Get Package Preview">
</form>

Parsing a Package URL with PHP

In order to extract the package ID and key from the URL, we'll need to parse it. The following function takes an URL as an argument and extracts plausible id and key parameters, returning an array of those parameters if it found a plausible id, and returning FALSE otherwise.

<?php
function parse_pando_url($url) {
   
$parts = parse_url($url);
   
$args = split("&", $parts[query]);
   
$packagekey = ''; //key is optional; set to blank so it has some value
   
foreach($args as $arg) {
        if(
ereg('^id=[A-Z0-9]*$', $arg)) $packageid = substr($arg, 3);
        if(
ereg('^key=[A-Z0-9]*$', $arg)) $packagekey = substr($arg, 4);
    }
    if(!empty(
$packageid))
        return array(
'id' => $packageid, 'key' => $packagekey);   
    else
        return
FALSE;
}
?>

Retrieving Package Info XML

Once we have a package ID, we can attempt to retrieve the package info encoded as XML using the package info web services call. PHP provides the handy CURL library to retrieve this content. The following function accepts a package ID and (optionally) package key and desired format as parameters. It returns XML (or JSON, if specified) package info or FALSE if CURL fails or returns a non-xml result.

<?php
   
function get_package_info($packageid, $packagekey = '', $format = 'xml') {

   
//only two allowed formats are json and xml, force xml if something other than json is specified
   
if($format != 'json') $format = xml;

   
//build request URL
   
$url = "http://cache.pando.com/soapservices/SendToWeb?action=info&format="
          
. $format ."&id=". $packageid ."&key=". $packagekey;

   
//fetch package info with CURL
   
$ch = curl_init($url);
   
curl_setopt($ch, CURLOPT_HEADER, false);
   
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
   
$xml = curl_exec($ch);
   
   
//make sure there were no errors and the server claims to have returned XML
   
if(ereg('^text/xml', curl_getinfo($ch, CURLINFO_CONTENT_TYPE)) && curl_error($ch) == '' ) {
        return
$xml;       
    }
    else {
        return
FALSE;
    }
}
?>

Generating the HTML

Now that we can retrieve the XML encoded package info, we can use the SimpleXML library available in php5 to generate the HTML.

<?php
   
function build_package_preview($packageid, $packagekey) {
   
//get XML formatted package info from Pando services
   
if($xml = get_package_info($packageid, $packagekey) ) {
       
//load up a new SimpleXML object from the retrieved XML
       
if($package = new SimpleXMLElement($xml)) {
           
//get number of days to/since expiration, set "expired" status
           
$days = round( ( strtotime($package->expirationDate) - time() ) / (60 * 60 * 24) );
            (
$days < 0)? $expired = TRUE: $expired = FALSE;
           
$days = abs($days);

           
//Only wrap title/thumbnail as links if we have a key and package is not expired
           
if($expired || empty($packagekey) ) {
               
$title = $package->title;
               
$expirestr = "<span style='color: red;'>Expired $days days ago</span><br>";
            }
            else {
               
$title = "<a href='$package->packageURL'>$package->title</a>";
               
$thumb = "<a href='$package->packageURL'><img src='$package->thumbnailURL' alt=''></a>";
               
$expirestr = "<span style='color: green;'>Expires in $days days</span><br>";
            }

           
//generate the entire HTML output
           
$html = <<<HTML
<table class="pandopackage"><tbody><tr>
  <td class="packagethumb" align="center" valign="center">
    <a href="$package
->packageURL"><img src="$package->thumbnailURL" alt=""></a>
  </td>
  <td class="packagemeta" valign="center">
    <span class="ptitle">$title</span>
    <p>
    Downloaded <strong>$package
->downloads</strong> times<br>
    $expirestr
    </p>
  </td>
</tr></tbody></table>
HTML;
            return
$html;
        }
    }
   
//something went wrong
   
return FALSE;
}
?>

Bringing it Together

Using the above functions (collected into pando_package_preview.php) we can generate our package preview HTML and both display it on the page and output it into a textarea block from where it can be cut-and-pasted as static HTML into other locations.

<?php
require_once('pando_package_preview.php');

//see if we have a package URL to parse
if(!empty($_GET['packageurl'])) {
    if(
$package = parse_pando_url($_GET['packageurl'])) {
       
//get HTML package preview
       
if($html = build_package_preview($package['id'], $package['key'])) {
           
//show the package preview
           
print $html;
           
//show a textarea box with cut-and-paste-able HTML
           
print "<form style='clear: both;'><br /><textarea  name='copythis' cols='50' rows='5'
            onclick='javascript:this.form.copythis.select();'>"
. $html ."</textarea></form>";
        }
        else {
           
//problem w/ preview
           
print "<span style='color: red;'>Problem generating package preview.  Please cut and paste a valid Pando
            package URL</span><br />"
;           
        }
    }
    else {
       
//couldn't parse package URL
       
print "<span style='color: red;'>Bad package URL.  Please cut and paste a valid Pando package URL</span><br />";
    }
}
?>

Feel free to use these on your web site as is, or extend them any way you like!

If you have questions, or want to share what you've come up with, post a comment below!