You are here

facebook_album.module in Facebook Album 7.2

File

facebook_album.module
View source
<?php

/**
 * @file facebook_album.module
 *
 * Creates the block for display and menu items for configuration
 */
DEFINE('API_BASE_URL', 'https://graph.facebook.com/');
DEFINE('API_AUTH_PATH', 'oauth/');

/**
 * Implements menu_hook()
 *
 * Setup routes to their appropriate functions
 */
function facebook_album_menu() {
  $items = array();
  $items['admin/config/services/facebook_album'] = array(
    'title' => 'Facebook Album Settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'facebook_album_admin_form',
      'system_admin_menu_block_page',
    ),
    'access arguments' => array(
      'facebook album',
    ),
    'file' => 'facebook_album.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['facebook_album/get/albums'] = array(
    'title' => 'Fetch Albums',
    'page callback' => 'facebook_album_ajax_get_albums',
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['facebook_album/get/albums/next/%'] = array(
    'title' => 'Fetch Next Albums',
    'page callback' => 'facebook_album_ajax_get_albums_next',
    'access arguments' => array(
      'access content',
    ),
    'page arguments' => array(
      4,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['facebook_album/get/album/%'] = array(
    'title' => 'Fetch Album Photos',
    'page callback' => 'facebook_album_ajax_get_album',
    'access arguments' => array(
      'access content',
    ),
    'page arguments' => array(
      3,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['facebook_album/get/album/%/next/%'] = array(
    'title' => 'Fetch Next Album Photos',
    'page callback' => 'facebook_album_ajax_get_album_next',
    'access arguments' => array(
      'access content',
    ),
    'page arguments' => array(
      3,
      5,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['facebook_album/get/album/%/cover'] = array(
    'title' => 'Fetch Album Cover',
    'page callback' => 'facebook_album_ajax_get_album_cover',
    'access arguments' => array(
      'access content',
    ),
    'page arguments' => array(
      3,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['facebook_album/get/photo/%'] = array(
    'title' => 'Fetch Photo Url',
    'page callback' => 'facebook_album_ajax_get_photo_url',
    'access arguments' => array(
      'access content',
    ),
    'page arguments' => array(
      3,
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_permission()
 */
function facebook_album_permission() {
  return array(
    'facebook album' => array(
      'title' => t('Administer Facebook Album'),
      'description' => t('Change settings for the Facebook Album Module'),
    ),
  );
}

/**
 * Implements hook_block_info().
 */
function facebook_album_block_info() {
  $blocks = array();
  $blocks['facebook_album'] = array(
    'info' => t('Facebook Album Gallery'),
  );
  return $blocks;
}

/**
 * Implements hook_theme()
 */
function facebook_album_theme($existing, $type, $theme, $path) {
  return array(
    'facebook_album_covers' => array(
      'variables' => array(
        'settings' => NULL,
        'photos' => NULL,
      ),
      'template' => 'templates/facebook_album_covers',
    ),
    'facebook_album_photos' => array(
      'variables' => array(
        'settings' => NULL,
        'photos' => NULL,
      ),
      'template' => 'templates/facebook_album_photos',
    ),
  );
}

/**
 * Fetch the first set of photos from the specified album
 *
 * @param $id
 *    The album id to fetch photos from
 * @return mixed
 *    A json object containing html template
 */
function facebook_album_ajax_get_album($id) {
  return facebook_album_ajax_get_album_next($id, null);
}

/**
 * Fetch the next or previous set of photos from the specified album
 *
 * @param $id
 *    The album id to fetch photos from
 * @param $after
 *    The id for fetching the next or previous set of photos
 * @return mixed
 *    A json object containing html template
 */
function facebook_album_ajax_get_album_next($id, $after) {
  $settings = facebook_album_get_settings();
  $url = _facebook_album_build_api_request($id . '/photos', array(
    'access_token' => $settings['appToken'],
    'after' => $after,
    'fields' => 'url',
  ));
  $response = _facebook_album_fetch_api_response($url);
  $module_response['data']['content'] = facebook_album_build_photo_template($settings, $response['data']);
  $module_response['data']['photo_ids'] = $response['data'];
  if (isset($response['paging']) && isset($response['paging']['next'])) {
    $module_response['data']['after'] = $response['paging']['cursors']['after'];
  }
  return drupal_json_output($module_response);
}

/**
 * Fetch first set of albums specified in the settings menu
 *
 * @return mixed
 *    A json object containing html template
 */
function facebook_album_ajax_get_albums() {
  return facebook_album_ajax_get_albums_next(null);
}

/**
 * Fetch the next or previous set of cover photos from the specified page ID
 *
 * @param $after
 *    The id for fetching the next set of albums
 * @return mixed
 *    A json object containing an html template and after id
 */
function facebook_album_ajax_get_albums_next($after) {
  $settings = facebook_album_get_settings();
  $limit = $settings['albumLimit'];
  if ($limit < 1) {
    $limit = null;
  }
  else {

    // ensure that ID's can't be passed in to retrieve albums
    // if limit has been set to a non-zero number
    $after = null;
  }
  $url = _facebook_album_build_api_request($settings['pageID'] . '/albums', array(
    'access_token' => $settings['appToken'],
    'after' => $after,
    'limit' => $limit,
    'fields' => 'location,description,name',
  ));
  $response = _facebook_album_fetch_api_response($url);
  $module_response['data']['content'] = facebook_album_build_cover_template($settings, $response['data']);
  if (isset($response['paging']) && isset($response['paging']['next']) && $limit == null) {
    $module_response['data']['after'] = $response['paging']['cursors']['after'];
  }
  else {
    $module_response['data']['after'] = null;
  }
  return drupal_json_output($module_response);
}

/**
 * Fetch an individual album cover
 *
 * @param $id
 *    The album id to fetch the cover for
 * @return mixed
 *    A json object containing html template
 */
function facebook_album_ajax_get_album_cover($id) {
  $settings = facebook_album_get_settings();
  $module_response = array(
    'data' => null,
  );
  $url = _facebook_album_build_api_request($id . '/picture', array(
    'access_token' => $settings['appToken'],
    'redirect' => 'false',
  ));
  $response = _facebook_album_fetch_api_response($url);
  if (!isset($response['error'])) {
    $module_response = $response;
  }
  return drupal_json_output($module_response);
}

/**
 * Fetch an individual photo url from a Facebook album photo
 *
 * @param $id
 * @return json
 */
function facebook_album_ajax_get_photo_url($id) {
  $settings = facebook_album_get_settings();
  $module_response = array(
    'data' => null,
  );
  $url = _facebook_album_build_api_request($id, array(
    'access_token' => $settings['appToken'],
    'fields' => 'images,name',
  ));
  $response = _facebook_album_fetch_api_response($url);
  if (!isset($response['error'])) {
    $module_response['data']['url'] = $response['images'][0]['source'];
    $module_response['data']['name'] = isset($response['name']) ? $response['name'] : '';
  }
  return drupal_json_output($module_response);
}

/**
 * Implements hook_block_view().
 */
function facebook_album_block_view($delta = '') {
  $block = array();
  $app_token = variable_get('facebook_album_access_token');
  if (!isset($app_token)) {
    return $block;
  }
  switch ($delta) {
    case 'facebook_album':
      $block['content'] = array(
        '#markup' => '<div id="facebook-album"><div id="fb-album-header"></div>' . '<div id="facebook-album-images-container"></div>' . '<div class="fb-loading-icon"></div></div>',
        '#attached' => array(
          'css' => array(
            drupal_get_path('module', 'facebook_album') . '/css/facebook_album.css',
          ),
          'js' => array(
            drupal_get_path('module', 'facebook_album') . '/js/facebook_album.js',
            array(
              'data' => array(
                'facebookAlbum' => array(
                  'colorboxOptions' => variable_get('facebook_album_colorboxOptions', ''),
                ),
              ),
              'type' => 'setting',
            ),
          ),
        ),
      );
      break;
  }
  return $block;
}

/**
 * Build the template for displaying album photos
 *
 * @param $settings
 *    An array of settings
 * @param $placeholders
 * @return mixed
 *    A prebuilt block of html containing all album photos
 */
function facebook_album_build_photo_template($settings, $placeholders) {
  return theme('facebook_album_photos', array(
    'settings' => $settings,
    'photos' => $placeholders,
  ));
}

/**
 * Build the template for displaying albums with a filtered data set
 *
 * @param $settings
 *    An array of settings
 * @param $albums
 *    An array of albums from the facebook API
 * @return mixed
 **    A prebuilt block of html containing all albums
 */
function facebook_album_build_cover_template($settings, $albums) {
  $filtered_content = facebook_album_filter_albums($albums, $settings['albums'], $settings['visibility']);
  return theme('facebook_album_covers', array(
    'settings' => $settings,
    'photos' => $filtered_content,
  ));
}

/**
 * The Facebook API does not allow us to specify which albums to load or
 * exclude so after loading the albums we'll simply filter for any albums
 * we want to display
 *
 * @param $albums
 *    An array of albums from the facebook API
 * @param array $album_ids
 *    Album IDs used to determine a whitelist or blacklist of albums from
 * @param bool $include
 *    A flag, that if true, includes all albums specified in $albumIDs, otherwise
 *    it excludes all albums in $albumIDs
 * @return array
 *    An array of filtered albums
 */
function facebook_album_filter_albums($albums, $album_ids = array(), $include = true) {
  if (isset($album_ids[0]) && ($album_ids[0] != '' || $album_ids[0] == 0)) {
    $include = (bool) $include;
    $albums = array_filter($albums, function ($album) use ($album_ids, $include) {
      return $include === in_array($album['id'], $album_ids);
    });
  }
  return $albums;
}

/**
 * Takes all customized settings and returns them as an array
 *
 * @return array
 *    Settings as specified from the settings menu in facebook_album.admin.inc
 */
function facebook_album_get_settings() {
  return array(
    'pageID' => variable_get('facebook_album_pageID', 'acromediainc'),
    'visibility' => variable_get('facebook_album_visibility', 0),
    'albums' => variable_get('facebook_album_albums', array()),
    'albumLimit' => variable_get('facebook_album_albumLimit', 3),
    'showDescription' => variable_get('facebook_album_showDescription', 1),
    'showLocation' => variable_get('facebook_album_showLocation', 1),
    'albumThumbWidth' => variable_get('facebook_album_albumThumbWidth', 365),
    'albumThumbHeight' => variable_get('facebook_album_albumThumbHeight', 250),
    'photoThumbWidth' => variable_get('facebook_album_photoThumbWidth', 160),
    'photoThumbHeight' => variable_get('facebook_album_photoThumbHeight', 120),
    'appToken' => variable_get('facebook_album_access_token', ''),
    'albumVisibility' => variable_get('facebook_album_visibility'),
  );
}

/**
 * Utility function to build the API call for accessing Facebook's Graph API
 *
 * @param string $call_path
 *    An extra path to be appended to the api's base url i.e. (albums/)
 * @param array $parameters
 *    Query string parameters to be appended to the api's base url
 * @return string
 *    A built url for the facebook api
 */
function _facebook_album_build_api_request($call_path = '', $parameters = array()) {
  $query = http_build_query($parameters);
  return API_BASE_URL . variable_get('facebook_album_api_version', 'v2.3') . '/' . $call_path . '?' . $query;
}

/**
 * Make a curl request to the specified url and return
 * a converted response
 *
 * @param $url
 *    The url to make a request to
 * @return mixed
 *    A response rendered as an array
 */
function _facebook_album_fetch_api_response($url) {
  $cURL = curl_init();
  curl_setopt($cURL, CURLOPT_URL, $url);
  curl_setopt($cURL, CURLOPT_HTTPGET, true);
  curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Accept: application/json',
  ));
  $result = curl_exec($cURL);
  $content_type = curl_getinfo($cURL, CURLINFO_CONTENT_TYPE);
  curl_close($cURL);
  return _facebook_album_api_response_to_array($content_type, $result);
}

/**
 * Convert the API response into an array based on the content type
 * Currently only, json and plain-text responses are supported
 *
 * @param $content_type
 *    The type of content returned in the response. I.e. (json, plain-text, html)
 * @param $response
 *    The actual response to convert
 * @return mixed
 *    A response converted to an array
 */
function _facebook_album_api_response_to_array($content_type, $response) {
  if (strstr($content_type, 'plain')) {
    $a = explode(',', $response);
    foreach ($a as $response) {
      $b = explode('=', $response);
      $array[$b[0]] = $b[1];
    }
    $response = $array;
  }
  else {
    if (strstr($content_type, 'json')) {
      $response = json_decode($response, true);
    }
    else {
      $response['error']['message'] = t("Unrecognized response type. Unable to parse data.");
      $response['error']['code'] = 10000;
    }
  }
  if (!isset($response['data'])) {
    $response['data'] = array();
  }
  return $response;
}

/**
 * Translate API errors into a user friendly error.
 *
 * @param $code
 *    The error code returned from the facebook API or internally
 * @param $message
 *    The corresponding message to that error code, if there is one
 * @return string
 *    A user friendly error message
 */
function _facebook_album_translate_api_error($code, $message) {
  switch ($code) {
    case 1:
      $message = "Unable to retrieve data from Facebook. This could be due to an invalid Application ID/Application Secret or Facebook is temporarily unreachable.";
      break;
    case 10000:
      $message = "Unable to verify data from Facebook at this time. Please try again.";
      break;
    default:
  }
  return t($message);
}

Functions

Namesort descending Description
facebook_album_ajax_get_album Fetch the first set of photos from the specified album
facebook_album_ajax_get_albums Fetch first set of albums specified in the settings menu
facebook_album_ajax_get_albums_next Fetch the next or previous set of cover photos from the specified page ID
facebook_album_ajax_get_album_cover Fetch an individual album cover
facebook_album_ajax_get_album_next Fetch the next or previous set of photos from the specified album
facebook_album_ajax_get_photo_url Fetch an individual photo url from a Facebook album photo
facebook_album_block_info Implements hook_block_info().
facebook_album_block_view Implements hook_block_view().
facebook_album_build_cover_template Build the template for displaying albums with a filtered data set
facebook_album_build_photo_template Build the template for displaying album photos
facebook_album_filter_albums The Facebook API does not allow us to specify which albums to load or exclude so after loading the albums we'll simply filter for any albums we want to display
facebook_album_get_settings Takes all customized settings and returns them as an array
facebook_album_menu Implements menu_hook()
facebook_album_permission Implements hook_permission()
facebook_album_theme Implements hook_theme()
_facebook_album_api_response_to_array Convert the API response into an array based on the content type Currently only, json and plain-text responses are supported
_facebook_album_build_api_request Utility function to build the API call for accessing Facebook's Graph API
_facebook_album_fetch_api_response Make a curl request to the specified url and return a converted response
_facebook_album_translate_api_error Translate API errors into a user friendly error.