Custom photo gallery with phpFlickr

phpFlickr is a PHP library for use with flickr's powerful API. Recently I had a need for a very simple photo gallery with a minimal budget, so we decided to go with hosting all the images on flickr and accessing them remotely.

The biggest problem with this idea was what we wanted to do with the photos. Flickr allows you a decent range of size options to display. None of these sizes where exactly what we wanted. In order to resize these server side we needed to first download the images, and resize them. This is where caching came into play. By creating a wrapper for phpFlickr and caching the images and requests, we can dramatically speed up the time it takes to get the data from flickr, and to process the images.

In this example we will be using phpFlickr 2.3.1.

First lets make a very basic local cache class. You can easily modify this class to work with a database rather than flat file.

class myCache {
  public function __construct($params) {
    // the directory to store the cache files
    if (isset($params['dir'])) {
      $this->dir = $params['dir'];
    }
    // expiration duration
    if (isset($params['expire'])) {
      $this->expire = $params['expire'];
    }
  }

  public function cached($fileName, $expire = null) {
    // get the valid state of the file
    if (file_exists($this->dir.sha1($fileName).'.cache') && filemtime($this->dir.sha1($fileName).'.cache') expire)) {
      return true;
    } else {
      return false;
    }
  }

  public function read($fileName)  {
    return unserialize(file_get_contents($this->dir.sha1($fileName).'.cache'));
  }

  public function write($fileName, $file)  {
    return file_put_contents($this->dir.sha1($fileName).'.cache', serialize($file));
  }
}

Next we to create an object that extends the flickr library. We will create the cache object instance for reference inside our flickr object.

class myFlickr extends phpFlickr {
  public function __construct($params = array()) {
    $this->cache = new myCache(array(
      'dir' => './cache_dir'
    ));
    if (isset($params['flickrId']) {
      $this->flickrId = $params['flickrId'];
    }
    if (isset($params['apiKey']) {
      $this-> apiKey = $params['apiKey'];
    }
    // use the api key generated from your flickr account
    parent::__construct($this->apiKey);
  }
}

Now for the caching. We need to access the photosets_getList and photosets_getPhotos methods of the flickr library and cache their output.

public function sets() {
  // check the cache status
  $file = 'flickr-portfolio-all-data';
  if ($this->cache->cached($file)) {
    $setpics = $this->cache->read($file);
  } else {

    $setpics = array();
    // get a list of photo sets from a specific user id
    $sets = $this->photosets_getList($this->flickrId);
    foreach ($sets['photoset'] as $set) {
      // get the photos in each set
      $pics = $this->photosets_getPhotos($set['id']);
      $setpics[$set['id']] = $set;
      $setpics[$set['id']]['pics'] = $pics['photoset']['photo'];
    }

    // write the cache
    $this->cache->write($file, $setpics);
  }

  return $setpics;
}

Now that we are all set up, lets use it! For this example we will only display a specific photoset.

// set up our object
$flickr = new myFlickr(array(
  'flickrId' => '48882192@N03',
  'apiKey' => 'my_api_key'
));
// get all the sets
$sets = $flickr->sets();
// loop through only a specific set
foreach ($sets['72157624072392212'] as $set) {
  print_r($set);
}