RAWS Tutorial 6 : Handling Atom links and pagination with PHP

In the previous tutorial we've shown the different uses of the "atom:link" element. In this tutorial, we will use the PHP client that was introduced in tutorial 2 to show you how to handle this element. We'll also learn how to retrieve partial atom responses. The complete source code for this tutorial is also part of the client download package (samples/raws_links_and_pagination.php). You can try running it yourself, after having edited the named constants on top of the script. For more information on using the PHP client, see tutorial 2.

This tutorial assumes that a directory named "tutorial6" has already been created on the CDN and 15 files have been uploaded to this directory (named "test1.mp4", "test2.mp4" ...). The sample script uses a local file, if which the path needs to be set in the named constant 'LOCAL_FILE', to create these files.

Getting entry links

You can use the properties of an $entry object (= in this case returned by RASS as a response to a POST item request) to directly access each link element and its attributes. The following code loops through all 'atom:link' elements that are part of the entry and displays the relevant attributes.

  foreach($item_entry->link as $link) {
echo "\nType of relation: " . $link->rel;
echo "\nLink URI: " . $link->href;
echo "\nExpected type: " . $link->type . "\n";
}
>> Type of relation: self
>> Link URI: http://rass.cdn03.rambla.be/meta/monty/tutorial6/test15.mp4/
>> Expected type: application/atom+xml
>>
>> Type of relation: edit
>> Link URI: http://rass.cdn03.rambla.be/item/tutorial6/test15.mp4/
>> Expected type: video/mp4
>> ...

The $entry object also has helper methods which you can use to retrieve the 'href' value of a link with a given relation type. Since this entry is returned by the RASS item resource, it will contain an enclosure link that points to CDN location at which the file (attached to this resource) can be downloaded by end-users.

  echo "\nGetting alternate link via helper method: " . $item_entry->get_alternate_url();
>> http://rass.cdn03.rambla.be/meta/monty/tutorial6/test15.mp4/?alt=atom
echo "\nGetting enclosure link via helper method: " . $item_entry->get_enclosure_url() . "\n";
>> http://monty.cdn03.rambla.be/tutorial6/test15.mp4

Getting feed links

In the same way as for an entry, you can use a $feed object's properties (or helper methods) to directly access each link element and its attributes. The following code loops through all 'atom:link' elements that are part of the feed and displays the relevant attributes.

  foreach($feed->link as $link) {
echo "\nType of relation: " . $link->rel;
echo "\nLink URI: " . $link->href;
echo "\nExpected type: " . $link->type . "\n";
}
>> Type of relation: self
>> Link URI: http://rass.cdn03.rambla.be/dir/tutorial6/?kind=file;page=1;paginate_by=...
>> Expected type: application/atom+xml
>> ...

Using pagination

In the previous tutorial, we already learned how the 'atom:link' element is being used by some RAWS resources to return partial collections. These resources will return a feed that may contain an 'atom:link' element with its 'rel' attribute set to "next", to indicate that not all entries could be fitted inside of the response. The next page can then be retrieved by sending a GET request to the URI inside of the link element's 'href' attribute.

Most resources that support pagination also return a 'last' link that points to a URL that can be used to retrieve the last batch of entries from a given collection. You can use the $feed object's helper methods get_next_link() and get_last_link() to retrieve these URLs.

For this tutorial we have created a directory that contains 15 files. By passing the 'paginate_by' as part of the query-string arguments (for details, see the 'pagination' wiki page) and setting it to "10", we instruct RASS to return only 10 entries in each (partial) response. Therefore, the response should also contain a 'next' link that points to an URI that can be used to retrieve the 5 remaining entries.

  $query->setPaginateBy("10");
$feed = $rass->getDirFeed($dir_entry->path, $query);
echo "\nNext link URI: " . $feed->get_next_link() . "\n";
>> Next link URI: http://rass.cdn03.rambla.be/dir/tutorial6/?kind=file;page=2;paginate_by=10;
echo "Last link URI: " . $feed->get_last_link() . "\n";
>> Last link URI: http://rass.cdn03.rambla.be/dir/tutorial6/?kind=file;page=2;paginate_by=10;

Note that in this case the 'next' and 'last' link both point to the same URL. This is normal, since RASS only needs to return 5 item entries in its next response. If instead our 'tutorial6' directory would contain more than 20 files, the 'next' and 'last' link would point to different URLs.

The connection object also has two helper methods - getNextFeed() and getLastFeed() - that automatically return the $feed object for the 'next' or 'last' link (by sending a GET request to the URL inside their 'href' attribute). When calling these methods, you need to pass the original $feed object as their argument.

   $next_feed = $rass->getNextFeed($feed);

Pagination best practices

If you're using a RAWS resource that supports pagination and you want to retrieve all entries from a given collection, you should always check for the presence of a 'next' link inside the 'atom:feed' element. You can automate this behaviour by nesting a call to the connection object's getNextFeed() inside a while-loop that checks on the $feed object returned by this call. If there's no 'next' link present (= no more entries), the $feed variable will be set to null and your code will exit the loop.

  $feed = $rass->getDirFeed($dir_entry->path, $query);
while($feed)
{
foreach ($feed as $entry) {
# process your entries here..
echo "\nFound entry with path = " . $entry->path;
}
# get next feed, by sending a new request to the next link inside this page
$feed = $rass->getNextFeed($feed);
}