xml search


As a simpler alternative to the https://www.pond5.com/document/api.html and that doesn't require a user setup in the database, you can use https://www.pond5.com/index.php?page=xml_search_setup. To make things less confusing, it uses JSON by default instead of XML. xml_search uses the API underneath so neither should be more stable/unstable to use than the other. It is even recommended to use the https://www.pond5.com/files/api_client.zip with xml_search.

The examples and code are written in php 5.2. If you are using some other web stack it should be no problem to port the code. You do however need to have the ability to run something on your side to generate the dynamic page.

That was not entirely true. There is a https://www.pond5.com/examples/xml_search_ajax.php https://www.pond5.com/files/xml_search_ajax.txt version you can use. In this case all files on your side are static, but you are more limited in how you can present the clips.


A barebone example https://www.pond5.com/examples/xml_search.php and its https://www.pond5.com/files/xml_search.txt.
mouseover play example https://www.pond5.com/examples/xml_search_video.php and its https://www.pond5.com/files/xml_search_video.txt. https://www.pond5.com/document/xml_search.html.
ajax example https://www.pond5.com/examples/xml_search_ajax.php and its https://www.pond5.com/files/xml_search_ajax.txt.
ajax example, submit to https://www.pond5.com/examples/xml_search_ajax_other.php https://www.pond5.com/files/xml_search_ajax_other.txt.


This is the https://www.pond5.com/examples/xml_search_video.php https://www.pond5.com/files/xml_search_video.txt. Do not use this as a template, try to use the source link instead to make sure you use the latest version. This document might not be updated 100% in line with that file. Let's walk through the essential parts:

error_reporting(E_ALL); // set to 0 on deployment!

header("Pragma: no-cache");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

// Adjust to wherever you unpacked the P5 API client stuff.
// It's not strictly needed, but simplifies things
require_once ('../p5api_client/p5api_client_v1.php');

On the top of the page, before anything at all is echoed
(If you do not have buffering on PHP (the "normal" case) you cannot send http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/ after you've sent any HTML. It's enough with a space before <?php for this to happen.)
it is recommended that you turn on full warning (at least while testing out the code) and that you send the two header lines to make sure the page is not cached.

Here we also include the API library. It is not strictly necessary to use it but it simplifies things. You might need to change the "../" to "" depending on where you put it.

Let's move on to the CSS
<style type="text/css">

#sresults {
	background-color: #eeeeee;
	border-top: 1px solid #aaa;
	border-bottom: 1px solid #aaa;
	padding: 16px;

#sresults div.srbox {
	float: left;
	margin-right: 8px;
	margin-bottom: 8px;
	background-color: #dddddd;

#sresults div.srbox div.srinner {
	padding: 11px;
	width: 120px;
	height: 90px; /* 135 */

#sresults div.srbox div.srinner img.srimg {
	border-style: none;

#P5popUp {
	position: absolute;
	top: 1000px;
	left: 200px;
	text-align: center;
	padding: 5px;
	border: 1px solid black;
	background: white;


Naturally, on your site, you should put this in your site CSS file so it can be cached in the browser. Keeping it in the html file prevents it from being cached but is convenient when testing and for pedagogical purposes. Also, this block is so small it will do little difference putting it somewhere else. The design is a first start, we encourage you to tweak it to fit your page best.

The layout of the search results would be like
<div id="sresults">
    <div class="srbox">
        <div class="srinner">
            <a href="http://www.pond5.com/stock-footage/80647/dog-waits-for-owner-6.html">
                <img src="http://ec.pond5.com/s3/000080647_icon.jpeg" 
                     style="width: 120px; height: 68px;" 
                     alt="item 80647" 
<div style="clear: both;"><!-- --></div>

* The Icon is loaded from the same http://en.wikipedia.org/wiki/Content_Delivery_Network www.pond5.com uses.
* You'll have a referral flag on your links, most likely.

Moving on to the Javascript section
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">

var P5C = {};
P5C._l = {};
P5C._username = "yourP5Username";
P5C._idcounter = 0;

P5C.genId = function()
    return "p5id" + P5C._idcounter

P5C.vidon_ = function()
    var filetype = (100 > P5C._vs) ? 'flv' : 'mp3';
    var aId = P5C.genId();
    var str = "<div style=\"width:416px; height:234px;\"><div id=\"" + aId + "\"><\/div><\/div>";

    P5C._l.moContent = str;

    P5C._l.runMo = function () {

        var el = P5C._el;
        var co = el.cumulativeOffset();
        var elpos = {};
        elpos.left = co[0];
        elpos.top = co[1];
        elpos.right = co[0] + el.getWidth();
        elpos.bottom = co[1] + el.getHeight();
        var tt = $("P5popUp");
        var vp = document.viewport.getDimensions();
        if (Prototype.Browser.Opera) {
            if (screen.width < vp.width) {
                vp.width = screen.width;
            if (screen.height < vp.height) {
                vp.height = screen.height;

        var ttdim = tt.getDimensions();
        var so = document.viewport.getScrollOffsets();

        var py;
        if ((elpos.top - 10 - ttdim.height) < so.top) {
            py = elpos.bottom + 10;
        } else {
            py = elpos.top - 10 - ttdim.height;

        var px = Math.round ((elpos.left + elpos.right) / 2 - ttdim.width / 2);
        if ((px + ttdim.width) > (so.left + vp.width))
            px = so.left + vp.width - ttdim.width;
        if (0 > px) {
            px = 0;

        tt.style.left = px + "px";
        tt.style.top = py + "px";

        P5C._l.moStartFunToId = setTimeout (P5C._l.runMo2, 2);

    P5C._l.runMo2 = function () {
        P5C._l.moObject = swfobject.createSWF(P5C._l.moatt, P5C._l.mopar, P5C._l.moid);
        P5C._timer = undefined;

    P5C._l.moatt = {data:"http://www.pond5.com/pond5FlashPlayer2.swf", width:416, height:234};
    P5C._l.mopar = {wmode:"opaque", allowScriptAccess:"always", allowfullscreen:"true", bgcolor:"#FFFFFF",
         flashvars:"itemid=" + P5C._itemid + 
         "&orgClipWidth=" + P5C._ox + "&orgClipHeight=" + P5C._oy +
         "&hideController=yes" +
         "&debug=no" + "&filetype=" + filetype + "&server=prod&hqFLV=no"};
    P5C._l.moid = aId;
    P5C._timer = setTimeout(P5C._l.runMo, 120);

P5C.vidon = function (in_evt, itemid, ox, oy, vs)
    var ev = in_evt || window.event;
    P5C._el = Event.element (ev);
    P5C._itemid = itemid;
    P5C._ox = ox;
    P5C._oy = oy;
    P5C._vs = vs;
    P5C._timer = setTimeout(P5C.vidon_, 200);

P5C.vidoff = function ()
    var tt = $("P5popUp");
    tt.style.left = "-1000px";
    if ('undefined' != typeof P5C._timer) {
        P5C._timer = undefined;


More or less everyone nowadays use some lib to leverage the behavior of different browsers. It's more a matter of taste rather than one being better than others. Pond5 uses http://www.prototypejs.org/ but http://jquery.com/ should also be mentioned here. Here prototype.js is loaded from google so if the user has been on another page that includes this file, it will be cached.

The second include, http://code.google.com/p/swfobject/, is for helping embedding flash on a web page.

Then we're moving on to inline Javascript code. As in the CSS case, when you're done testing this "should" also be put in a separate js file so it can be cached. As in the CSS case, this is not a massive chunk of code and if you do not want to bother putting it in a separate file, no-one will be very upset.

var P5C = {};
This creates an empty object. Then we put functions and variables inside it. This way, only "P5C" is in your global variables space and the risk of conflict with other javascript libs or code is pretty slim.

Moving forward, the <head> closes and <body> begins. We're activating the php interpreter again:

// You might have caching on PHP level too. Then look at ob_flush();
// By doing this, client can start fetching js and css and process these
// while server side builds the page.

function print_set (&$command)
    $client = new p5api_client();

    $items = $command["items"];

    echo '<div id="sresults">';
    foreach ($items as $v)
        list($icon_url, $xsize, $ysize) = $client->get_icon($command, $v, 120, 90);
        $item_url = $client->get_canonical_url($command, $v);

        // if you want referral, uncomment and change to your username
        // $item_url .= '?ref=username';

        echo '<div class="srbox">' .
             '<div class="srinner">' .
             '<a href="' . $item_url . '">' .
             '<img  onmouseout="P5C.vidoff();" onmouseover="P5C.vidon(event,' . $v["id"] . ',' . $xsize . ',' . $ysize . ',' . $v['vs'] . ');" class="srimg" alt="item ' . $v["id"] . '" style="width:' . $xsize . 'px;height:' . $ysize . 'px;" src="' . $icon_url . '" />' .
             '</a>' .
             '</div>' .

    echo '<div style="clear:both;"><!-- --></div>';
    echo '</div>';

The function print_set() uses the API library. Apart from that it's pretty straight forward. It iterates the result set and prints it. This is where you customize the behavior you want (apart from CSS tweaks). You might for example want to have the title below the clip or something like that.

function dostuff($search)
    // Go to http://www.pond5.com/index.php?page=xml_search_setup and
    // create a link with the settings you want. Make sure it's using json
    // and that you leave the query field blank and that "name" is checked.
    // http://www.pond5.com/index.php?page=xml_search&bm=15&format=json&p=0&col=1

    // If you want to search only your clips, add this and set the username
    // $search .= ' artist:username';

    $url = 'http://www.pond5.com/index.php?page=xml_search&bm=15&format=json&p=0&col=1' .
           '&q=' . urlencode($search);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $mydata = curl_exec ($ch);
    if (curl_errno($ch))
        echo 'Error: ' . "curl error [" . curl_error($ch) . "]";
        return -1;

    $json = json_decode ($mydata, true);

    if (false === $json)
        echo 'Error: ' . 'Failed to decode JSON response.';
        return -1;
    // We know we only have one command_response
    if (isset ($json['e']) && true === $json['e'])
        echo 'Error: there was an error searching: ' . $json['s'];
        return -1;

    return 0;

This is the part that calls Pond5. Change this line...
// $search .= ' artist:username';
...to limit the search to your clips. Ie remove the // and change username to your username. To limit to several users, use artist:username1:username2 etc.

On to the last bit of PHP code
$search = false;
if (isset ($_POST) && isset ($_POST["qsearch"]))
    $search = $_POST["qsearch"];

echo '<form method="post" action="' . $_SERVER["SCRIPT_URL"] . '">';
echo '<div style="vertical-align: middle; height:36px; padding:8px 0 0 0;">';
echo '<input type="text" class="text" value="' .
     ((false === $search) ? '' : htmlspecialchars($search)) .
     '" id="qsearch" name="qsearch" style="float:left;margin: 2px 5px 0 0;">';
echo '<input type="image" style="float:left;" alt="Search" src="http://ec.pond5.com/www/images/button-search.gif">';
echo '</div>';
echo '</form>';

if (false !== $search)


If the form was submitted, the qsearch was posted. Then we render the search form (again, feel free to make it pretty) and last the dostuff() function is called if the form was submitted.

<div id="P5popUp"><!-- --></div>

The P5popUp is a container for the mouseover preview. I find it simpler to update an existing container than adding and removing an element from the page all the time.