Example 3 – building a library such as the Flickr API wrapper

The flickr.com website by Yahoo! provides API access to the Flickr repository of public photos uploaded to the community. The API is extremely rich, and its documentation is available at http://www.flickr.com/services/api/, and is called App Garden.

The API is enabled for various programming languages and access methods. We will build a solution of a wrapper that can be expanded to get any Flickr API service, using the PHP REST access method.

This example will be constructed from the following library, controller, and view:

  • application/libraries/flickr_wrapper.php: The is the CI wrapper library that enables smooth Flickr API access via CI. This basic services library can be expanded to support the entire Flickr App Garden.
  • application/controllers/flickr_recent.php: This is the controller that uses the flickr_wrapper library that we wrote and pulls the recent public photos uploaded with the EXIF photo info and the photographer-related information.
  • application/views/flickr_recent_view.php: This is the view that shows the collected information of recent photos and photographers.

Let us assume the URI to the project root is http://mydomain.com/myproject. Hence, the URI to execute the auto controller for logging in will be http://mydomain.com/myproject/flickr_recent.

The flickr_wrapper.php library file

The application/libraries/flickr_wrapper.php library file contains the library flickr_wrapper class library that we are building and using to access the Flickr App Garden API. It is mandatory to load this library with a valid Flickr api_key that you can get by following the Flickr App Garden documentation. The library will use the PHP REST API access, so that we can later expand any of the Flickr API services to be supported with our library. Each of the library methods returns a multidimensional keyed array of the resultant data.

The following is the code:

/**
* CodeIgniter Flickr API wrapper Library Class
*
* Enable Simple Flickr API usage 
*
* @package        CodeIgniter
* @category    Libraries
* @author        Eli Orr
* Usage:
* Via CI controller: 
* $this->load->library( 'flickr_wrapper',
* array(   'api_key'     => '<YOUR_FLICKR_API_KEY>',
* 'DEFAULT_RES' => '3000',
// filter 3000 pix 
* 'GPS_ENABLED' => FALSE ));
* $this->flickr_wrapper->set_params ( $keyed_array );
* $recent_photos = 
* $this->flickr_wrapper->flickrPhotosGetRecent ();
* $filter_photos = 
* $this->flickr_handler->
* filter_photos ($photos_to_filter);
* $user_info        = 
* $this->flickr_wrapper->flickrUserInfo ($uid);
* // $uid e.g. 72095130@N00
//.PRIVATE 
//We will use the following private functions:
private function _file_get_contents_curl($url);
private function _flickrRestAPI ($params);
private function _is_filtered_photo ($photo_rec );
*/

The following is the Flickr_wrapper class that we are building:

class Flickr_wrapper {
  // parameters as part of the library instance
  private $DEFAULT_RES = 2000;
  // Width in Pixels 
  private $GPS_ENABLED = TRUE;
  // total shown photos 
  private $RECENT_PHOTOS = 500;
  // how many photos in each poll ?
  // CI instance 
  private $CI;
  // Flickr api_key to use 
  private $api_key = "" ;
  function __construct( $params = array())
  {
    // Make sure we got the api_key – otherwise exit!
    if (!isset ($params['api_key']))
    exit ('FATAL - must be constructed with api_key!'),
    $this->set_params ($params);
    // Just for debugging needs, we may drop those later
    error_reporting(E_ALL);
    ini_set('display_errors', '1'),
  }
  // change settings on the fly
  function set_params ( $key_array ) {
    // sets array of instance parameters 
    foreach ($key_array as $key => $val ){ 
      switch ($key) {
        case 'DEFAULT_RES': $this->DEFAULT_RES 	= $val; break;
        case 'GPS_ENABLED': $this->GPS_ENABLED 	= $val; break;
        case 'RECENT_PHOTOS': $this->RECENT_PHOTOS = $val; break;
       case 'api_key' : $this->api_key = $val; break;
       // We can add many more here.
       default: exit ("FATAL! - set_params invalid param: $key");
     }
  }
}

The class code continues while shifting our focus on accessing the recent public photos.

// Pulls recent public photos as multi-dimensional array
function flickrPhotosGetRecent () {
  #
  # build the Params for API
  #
  $params = array(
    'api_key' => $this->api_key,
    'method' => 'flickr.photos.getRecent',
    'extras' => 'o_dims,owner_name,date_taken,media,
    path_alias,url_sq,geo',
    'per_page' => $this->RECENT_PHOTOS,
    'format' => 'php_serial'
  );
  $rsp_obj = $this->_flickrRestAPI ($params);
  #
  # check if ok or successful result :
  #
  if ($rsp_obj['stat'] == 'ok') {
    # Get the array of all the photo records in this cycle 
    return $recent_photos = $rsp_obj['photos']['photo'];
  }
  else 
  # Query failed we shall return NULL to the caller 
  return NULL;
}
// Get the Photo EXIF that has a lot of info related to the// photo for a given photo id

The class code continues, where we will see how to access additional information related to the image.

function GetPhotoExif ($photo_id) {
  #
  # build the API URL to call
  #
  $params = array(
    'api_key' => $this->api_key,
    'method' => 'flickr.photos.getExif',
    'photo_id' => $photo_id,
    'format' => 'php_serial',
  );
  $rsp_obj = $this->_flickrRestAPI ($params);
  #
  # display the photo title (or an error if it failed)
  #
  if ($rsp_obj['stat'] == 'ok') {
    /*
    Array ([photo] => Array ([id] => 8002716747 [secret] => 559f87aea0
    [server] => 8030
    [farm] => 9
    [camera] => Casio EX-H20G
    [exif] => ... A LOT OF EXTRA INFO
    */
    
    $photo_camera = $rsp_obj['photo']['camera'];
    // We can add more interesting items for our app here
    $params = array
    ( 'camera'    => $photo_camera,
    'full_exif' => $rsp_obj
    // All EXIF info for the photo_id
  );
  return $params;
  }
  else // Request Failed We shall return error:
  return NULL;
}

Let's see how we can apply photo filtering with the following code:

// apply photos filtering on a provided photos array
// based on the current settings
function filter_photos ($photos) {
  $filtered_photos = array();
  foreach ($photos  as $photo) {
    if ($this->_is_filtered_photo ($photo) )
    $filtered_photos[] = $photo;
  }
  return $filtered_photos;
}
function flickrUserInfo ($uid) {
  // UID e.g. : 72095130@N00
  // find info for this User
  #
  # build the API URL to call
  #
  $params = array(
    'api_key'	=> $this->api_key,
    'method'	=> 'flickr.people.getInfo',
    'user_id' 	=> $uid,
    'extras'  	=> 'contact,friend,family',
    'format'	=> 'php_serial',
  );
  $rsp_obj = $this-> _flickrRestAPI ($params);
  #
  # Check if response is OK
  #
  if ($rsp_obj['stat'] == 'ok'){ 
    // Yes! We have a good result .. let's load it to the // keyed array structure
    $real_name = @urlencode($rsp_obj['person']['realname']['_content']);
    $location = @urlencode (strtolower ($rsp_obj['person']['location']['_content']));
    $photos = @$rsp_obj['person']['photos']['count']['_content'];
    // more can be added

The class code continues as follows:

    $params = array ( 
      'name' => $real_name,
      'uid' => $uid,
      'photos' => $photos,
      'location' => $location,
      'full_info' => $rsp_obj
    );
    return $params;
  }
  else // Response failed return NULL
  return NULL;
}
// PRIVATE SECTION OF ALL PRIVATE LIBRARY METHODS 
// THAT CANNOT BE CALLED DIRECTLY FROM THE LIBRARY USER 
// This is the heart of our wrapper library that makes it easy to get 
// The Flickr API access via simple keyed array based calls and response
private function _flickrRestAPI ($params) {
  $encoded_params = array();
  foreach ($params as $k => $v){
    $encoded_params[] = urlencode($k).'='.urlencode($v);
  }
  #
  # call the API and decode the response
  #
  $url = "http://api.flickr.com/services/rest/?".implode('&', $encoded_params);
  // This will create get query URI …?param1=val1&param2=val2// and so on
  $rsp = $this->_file_get_contents_curl($url);
  return $rsp_obj = unserialize($rsp);
}

The class code continues as follows:

// This function assure we can get a url content into a buffer// it requires that a PHP curl library is installed!
private function _file_get_contents_curl($url) {
  if (! function_exists('curl_init') )
  exit ('PHP curl library is not enabled please fix!'),
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}
private function _is_filtered_photo ($photo_rec ) {
  /*
  [o_width]   => 4416
  [latitude] => 0
  //More can be added 
  */
  // Photo width  shall be larger than  $this->DEFAULT_RES ?
  if ( 	(int) (@$photo_rec['o_width'] )  <
  (int)  $this->DEFAULT_RES  )	 return FALSE;
  // GPS info required & Found ?
  if (( $this->GPS_ENABLED && ! @$photo_rec['latitude'] ))
  return FALSE;
  // if we are here the filtered photo passed successfully
  return TRUE;
  }
}

The flickr_recent.php controller file

The application/controllers/flickr_recent.php controller file will load the flickr_wrapper API, call its services for newly uploaded public photos and photographers, and render a view to show the results.

In order to execute the controller, you should point your browser to the following URI: http://mydomain.com/myproject/flickr_recent.

The following is the controller code:

<?php
/**
 * Flickr Recent Controller
 *
 * Provide recent uploaded public photos in flickr community
 * Enable to apply several settings and filtering
 * Enable to get photographer user profile for each photo
 * 
 * @author Eli Orr
*/
class Flickr_recent extends CI_Controller{
  function __construct()
  {
    parent::__construct();
    /* 
    Standard Libraries, database, & helper url are included in theconfigs/autoload.php
    */
    // This lines are only for debugging needs we may drop them// if things are going good
    error_reporting(E_ALL);
    ini_set('display_errors', '1'),
    /* ------Loading User Defined Library------------ */
    $this->load->library
    ( 'flickr_wrapper',
    array('api_key' => '<YOUR_FLICKR_API>',
    'DEFAULT_RES' => '3000',
    // filter 3000 pix
    'GPS_ENABLED' => FALSE
  )
  );
}

The class code continues as follows:

function index () {
  $settings = array(
    'DEFAULT_RES' => '4000',  // Only 4000 pix and better
    'GPS_ENABLED' => FALSE,  // GPS Info is not mandatory
    'RECENT_PHOTOS' => 50,  // Latest 100 photo uploads
  );
  $this->flickr_wrapper->set_params ( $settings );
  $photos_to_filter = 
  $this->flickr_wrapper->flickrPhotosGetRecent ();
  $filter_photos = 
  $this->flickr_wrapper->filter_photos ($photos_to_filter);
  $data = Array();
  $data['photos'] = $filter_photos;
  $data['settings'] = $settings;
  $this->load->view('flickr_recent_view.php',$data );
  }
}

The flickr_recent_view.php view file

The flickr_recent_view.php view file is rendered by our controller named Flickr_recent defined previously. This controller uses our developed flickr_wrapper library in order to get the recent Flickr uploaded photos with their associated information.

The view file is located at application/views/flickr_recent_view.php. This view uses the CI parser for the PHP inserted parameters using the <?=$param ?> notation.

The following is the code:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<div>
<H1>Flickr Recent Uploads</H1>
<p>
<!--  Show the applied filter settings first -->
<table border="1" style='background-color:#b0c4de;' >
<tr>
  <td>Photos in Poll</td><td><?=$settings['RECENT_PHOTOS'];?></td>
</tr>
<tr>
  <td>Min. Width Filter</td><td><?=$settings['DEFAULT_RES'];?>Px</td>
</tr>
<tr>
  <td>GPS Filter</td><td><?=$settings['GPS_ENABLED'] ? "With GPS" : "With/Without GPS"; ?></td>
</tr>
</p>
<!--  For each photo show the User name, how many photos they took till now, the original size in MP (Mega Pixels) of the photos and the Time stamp when the photo was taken by the camera (mostly loaded days or even weeks/months later)
<table border="1"  style='background-color:#009900;'  >
<tr>
  <th>User Uploaded</th><th>User photos Count</th>
  <th>Photo ID</th><th>Original Size MP</th><th>Was Taken</th>
</tr>

The class code continues as follows:

<?PHP foreach($photos as $photo )
{
  // get the owner id
  $uid = $photo['owner'];
  // Get User Info
  $user_info = $this->flickr_wrapper->flickrUserInfo ($uid);
  $photos = number_format ($user_info["photos"]);
  $mp_res = (int) ((( $photo['o_width' ] * $photo['o_height'] )/ 1000000)  +  1);
  ?> 
  <tr>
    <td> <?=$photo['ownername'] ?></td>
    <td> <?=$photos ?></td>
    <td> <?=$photo['id'] ?></td>
    <td> <?=$mp_res ?></td>
    <td> <?=$photo['datetaken'] ?></td>
  </tr>
  <?PHP      } ?>
  </table>
</div>
</body>
</html>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.202.209