* CakePHP, a PHP framework for rapid application development. The current version as of this writing is 1.1.13.
* phpFlickr, a PHP class that facilitates interaction with the Flickr API.
* Flickr Component, a CakePHP component developed by Miguel Ros (rossoft) that ties the phpFlickr class into the controller and view of our application.
Setting Up the Files
With CakePHP installed, you'll need to create a phpflickr folder at /app/vendors/phpflickr/ and drop phpFlickr into it. Next, place the Flickr Component into the /app/controllers/components/ folder. In the flickr.php component file, you'll need to specify your API key in the $_api_key variable, like this:
var $_api_key='PLACEKEYHERE';
If you don't already have an API key, you'll need to apply for one.
phpFlickr can cache the data it receives from the Flickr API to speed up subsequent calls. If you're using a file cache, you'll need to make sure the Flickr cache folder has been created and has write permissions. To set or change the cache folder, change the constant declared at the top of the Flickr component file as follows:
define('FLICKR_CACHE_DIR', CACHE . 'flickr/');
You now need to set up your controller to handle the gallery. I'm feeling pretty wild and crazy, so I'm going to call the controller GalleryController, and save it to /app/controllers/gallery_controller.php:
class GalleryController extends AppController{
var $name = 'Gallery';
var $components = array('Flickr');
var $uses = null;
}
The $name attribute is required if you're using PHP4, but can be omitted if you're using PHP5. The components array will automatically load our Flickr component. Finally, we set $uses to null to prevent the controller from auto-loading a model.
Routing
The next thing we need to do is modify our routes to handle the gallery calls. Add the following to your /app/config/routes.php file:
$Route->connect('/gallery/*',
array('controller' => 'gallery', 'action'=>'index'));
This routes all URLs that start with /gallery/ to run the index method of our gallery controller.
The Gallery Controller
Brace yourself! There really isn't much to this magic, but I'll explain what's happening line by line in a moment. Add the following block to the gallery_controller.php file:
function index($id = null)
{
$photosets = $this->flickr->photosets_getList('USER_ID');
$this->set('sets', $photosets);
$currset = $id == null ? $photosets['photoset'][0]['id'] : $id;
$this->set('currset', $this->flickr->photosets_getInfo($currset));
$this->set('thumbs', $this->flickr->photosets_getPhotos($currset));
}
The first thing we see here is that the index function is expecting an $id. This is a photoset ID that we can pass in to pull out a specific photoset.
The next line uses the Flickr API to retrieve all the photosets for a particular user. Authentication is not necessary for this task, unlike other aspects of the API. You'll need to know your user ID, also called an NSID. If you're not sure what it is, try using the API explorer with the flickr.people.findByEmail or .findByUsername calls:
$photosets = $this->flickr->photosets_getList('USER_ID');
Remember to replace USER_ID with your user ID, which you retrieved from the Flickr site.
Next up, we assign the photosets data to a sets variable for use in the view:
$this->set('sets', $photosets);
Next, we determine which is the current photoset ID. If the ID is null, we grab the ID of the first photoset in the list. Otherwise, we use the ID that was passed in:
$currset = $id == null ? $photosets['photoset'][0]['id'] : $id;
After that, we get the title and description of the current photoset, and assign it to a currset variable for use within the view:
$this->set('currset', $this->flickr->photosets_getInfo($currset));
Finally, we grab a list of all the photos and assign it to the thumbs variable for use within the view:
$this->set('thumbs', $this->flickr->photosets_getPhotos($currset));
Just like that, we're almost done. The last thing on our plate is to figure out how to lay this gallery out.
The View
You'll need to create a new folder in /app/views/ called gallery, if you haven't already. And in that folder, you'll need to create an index.thtml file.
I've decided to break my gallery into three main parts:
* the title and description of the current photoset (presented much like a blog post)
* the list of links to all the available photosets
* the thumbnails, one of which will be shown at a larger size
Title and Description
To show the title and description for the current photoset, we tap into the $currset variable we declared in our gallery controller:
Photosets
To display the list of links to photosets, we loop through each of the photosets in our $sets variable, using the title for the link text and creating a link to our gallery controller using the photoset ID as the parameter:
- link($item['title'], '/gallery/' . $item['id']);?>
Clicking on any of the links will load that particular photoset.
If you'd like to change the order in which the photosets appear in the list, you'll need to go into Flickr and use the Organize feature.
Photos
I want to output a reasonably large image before getting into my thumbnails. Here's how I do it:
This code grabs the first thumbnail from the $thumbs array that we set in our controller and uses the phpFlickr library method buildPhotoURL to build the source URL for the image tag. In this case, I'm grabbing a medium-sized version of the photo, which is 500 pixels long on its longest side, but you can choose one of the following versions of the image:
* square, which has dimensions of 75x75px
* thumbnail, which is 100px on longest side
* small, which is 240px on longest side
* medium, which is 500px on its longest side
* large, which is 1024px on longest side
* original, which is the original image file
Last but not least, I loop through each of the photos in the $thumbs array to build the thumbnail display. I request the thumbnail-sized version from the buildPhotoURL method for the image source URLs and link each thumbnail to its medium version on the Flickr server:
A Sprig of JavaScript
To make this gallery a little more interesting, let's add just a touch of JavaScript: