Writing a last.fm plug-in for Wordpress – Part Two: The PHP Application
This is the second post in a three part series on writing last.fm plug-in for Wordpress. In the first part of this series, we explored the last.fm API and wrote some simple PHP scripts to demonstrate two of the last.fm API methods. In this post, we'll create a complete PHP application that creates the last.api widget. This application will be generic enough to use in any web page. In the third post in this series, we'll convert the generic application into a Wordpress plug-in.
Before getting started, we should decide what we want to the widget to look like, and what information it should display. Since we'll be pulling in the weekly Album Chart, it makes sense for our widget to display the top five albums that the user has listened to over the past week - that is, the first five entries in the Album Chart. Once we have the list, we'll pull in additional information about each album. This will allow us to display a little thumbnail image of the album's CD cover if one is available.
The finished widget should look something like this:
At the end of the last post we took a look at the API method to retrieve information about a specific album. Using an object-oriented design, we can create a PHP script that encapsulates information about an album. The script is shown here:
<?php
class Album {
private $artist = "";
private $name = "";
private $apikey = "";
private $albumurl = "";
private $imageurl = "";
public function __construct( $p_artist, $p_name, $p_apikey ) {
$this->artist = $p_artist;
$this->name = $p_name;
$this->apikey = $p_apikey;
$this->fetchAlbum();
}
public function render() {
$ret = "<li>";
if( $this->imageurl != "" ) $ret = $ret .
"<a href=\"" . $this->albumurl . "\">" .
"<img width=\"34\" height=\"34\" src=\"" .
$this->imageurl . "\"></a> ";
$ret = $ret . "<a href=\"" .
$this->albumurl . "\">" .
$this->artist . " - " . $this->name . "</a>";
return $ret;
}
private function fetchAlbum() {
$url = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo" .
"&artist=" . urlencode($this->artist) .
"&album=" . urlencode($this->name) .
"&api_key=" . $this->apikey;
$input = file_get_contents($url)
or die('Could not access file: ' . $url );
$xmlobj = simplexml_load_string($input);
$return_code_array = $xmlobj->xpath("@status");
$return_code = $return_code_array[0];
if( $return_code != "ok" )
die('Last.fm returned an error: ' . $xmlobj->error );
$this->albumurl = $xmlobj->album->url;
$imageurl_array = $xmlobj->xpath("//image[@size='small']");
$this->imageurl = $imageurl_array[0];
}
}
?>
The class Album performs two functions - it fetches the album information using the last.fm API, and it provides a render() method that creates and returns a <li> element for the album. The user of this class only has to provide the artist and album name, along with a valid last.fm API key. The mechanics of fetching and rendering the album information is hidden within the class.
In the fetchAlbum() method, we added some error checking to make sure we found a match for our album. Since last.fm is providing the list of albums to us, we should never encounter an "Album not found" error - however, having the error checking gives you a nice piece of reusable code you can use in other applications. Also in fetchAlbum() we use this statement to fetch the album image URL:
$imageurl_array = $xmlobj->xpath("//image[@size='small']");
Xpath is a standard way of querying XML documents, and is supported in many different programming languages. This query says to find all of the <image> elements that have an attribute of "size" with a value of "small." That is, an element that looks like this:
<image size="small">
Now that we have the code to build an individual album's list item, we need to build the overall Album Chart. We developed some rudimentary code in the last post to accomplish this. Here is a more refined version of that code, implemented an AlbumChart class:
include_once 'Album.php';
class AlbumChart {
private $user = "keithlawless";
private $apikey = "14d5668dc30efbc02489d78dfc32da26";
private $max = 5;
private $albums;
public function __construct( $p_user="", $p_apikey="", $p_max=5 ) {
if( $p_user != "" ) {
$this->user = $p_user;
}
if( $p_apikey != "" ) {
$this->apikey = $p_apikey;
}
if( $p_max != "" ) {
$this->max = $p_max;
}
$this->fetchChart();
}
public function render() {
$ret = "<ul>";
foreach( $this->albums as $album ) {
$ret = $ret . $album->render();
}
$ret = $ret . "</ul>";
return $ret;
}
private function fetchChart() {
$url = "http://ws.audioscrobbler.com/2.0/?method=user.getweeklyalbumchart" .
"&user=" . $this->user .
"&api_key=" . $this->apikey;
$input = file_get_contents($url) or die('Could not access file:' . $url);
$xmlobj = simplexml_load_string($input);
$return_code_array = $xmlobj->xpath("@status");
$return_code = $return_code_array[0];
if( $return_code != "ok" )
die('Last.fm returned an error: ' . $xmlobj->error );
$count = 0;
foreach( $xmlobj->weeklyalbumchart->album as $album ) {
$artist = $album->artist;
$name = $album->name;
$album = new Album( $artist, $name, $this->apikey );
$this->albums[$count] = $album;
// If we've hit the maximum number of albums requested,
// break the loop.
$count++;
if( $count == $this->max ) break;
}
}
}
?>
After getting the AlbumChart from last.fm, we iterate through the array of album elements are returned. For each album, we parse out the artist and title, and create a new Album object, which we store in an array. Once we reach the maximum number of albums we want to display - or run out of albums - we stop the loop. To display the Album chart, we simply create an unordered list, an iterate over the array of Album objects, calling each object's render method.
All that's left now is to create the widget script itself. Here is the code:
<html>
<head>
<title>last.fm Widget Test</title>
<body>
<h2>last.fm Recent Albums</h2>
<?php
include 'AlbumChart.php';
$chart = new AlbumChart();
print $chart->render();
?>
</body>
</html>
We simply create an AlbumChart object, and call it's render() method to display the widget. To customize this widget for your site, you can select a different last.fm username and API key by passing parameters when creating the AlbumChart object - for example:
$chart = new AlbumChart( "YourUserName", "Your API Key" );
This code can be used "as is" in your Wordpress blog - you simply drop the code above into your sidebar.php script for your current template, and make any needed adjustments. In the next post, we'll go one step further, and create a Wordpress plug-in that makes it even easier to use this code for your blog.
