You are here

class Instagram in Drupagram 6

Same name and namespace in other branches
  1. 7 drupagram.lib.php \Instagram

Primary Instagram API implementation class Supports the full REST API for drupagram.

Hierarchy

Expanded class hierarchy of Instagram

3 string references to 'Instagram'
drupagram_menu in ./drupagram.module
Implementation hook_menu().
drupagram_views_data in views/drupagram.views.inc
Implements hook_views_data().
drupagram_views_default_views in views/drupagram.views_default.inc
@file Provide views for drupagram

File

./drupagram.lib.php, line 67
Classes to implement the full Instagram API

View source
class Instagram {

  /**
   * The name of the GET param that holds the authentication code
   * @var string
   */
  const RESPONSE_CODE_PARAM = 'code';

  /**
   * @var $format API format to use: can be json or xml
   */
  protected $format = 'json';

  /**
   * @var $source the drupagram api 'source'
   */
  protected $source = 'drupal';

  /**
   * @var $username Instagram username to use for authenticated requests
   */
  protected $username;

  /**
   * @var $password Instagram password to use for authenticated requests
   */
  protected $password;

  /**
   * JSON encoded OAuth token
   * @var string
   */
  protected $oauth_token = null;

  /**
   * Decoded plain access token
   * @var string
   */
  protected $access_token = null;

  /**
   * OAuth user object
   * @var object
   */
  protected $current_user = null;
  protected $endpoints = array(
    'authorize' => 'oauth/authorize/?client_id=!client_id&redirect_uri=!redirect_uri&response_type=!response_type',
    'access_token' => 'oauth/access_token',
    'user' => 'v1/users/!user_id/?access_token=!access_token',
    'user_feed' => 'v1/users/self/feed?access_token=!access_token&min_id=!min_id',
    'user_recent' => 'v1/users/!user_id/media/recent/?access_token=!access_token&max_id=!max_id&min_id=!min_id&max_timestamp=!max_timestamp&min_timestamp=!min_timestamp',
    'user_search' => 'v1/users/search?q=!q&access_token=!access_token',
    'user_follows' => 'v1/users/!user_id/follows?access_token=!access_token',
    'user_followed_by' => 'v1/users/!user_id/followed-by?access_token=!access_token',
    'user_requested_by' => 'v1/users/self/requested-by?access_token=!access_token',
    'user_relationship' => 'v1/users/!user_id/relationship?access_token=!access_token',
    'modify_user_relationship' => 'v1/users/!user_id/relationship?action=%s&access_token=!access_token',
    'media' => 'v1/media/!user_id?access_token=!access_token',
    'media_search' => 'v1/media/search?lat=%s&lng=%s&max_timestamp=%d&min_timestamp=%d&distance=%d&access_token=!access_token',
    'media_popular' => 'v1/media/popular?access_token=!access_token',
    'media_comments' => 'v1/media/%d/comments?access_token=!access_token',
    'post_media_comment' => 'v1/media/%d/comments?access_token=!access_token',
    'delete_media_comment' => 'v1/media/%d/comments?comment_id=%d&access_token=!access_token',
    'likes' => 'v1/media/%d/likes?access_token=!access_token',
    'post_like' => 'v1/media/%d/likes',
    'remove_like' => 'v1/media/%d/likes?access_token=!access_token',
    'tags' => 'v1/tags/%s?access_token=!access_token',
    'tags_recent' => 'v1/tags/!tag_name/media/recent?max_id=%d&min_id=%d&access_token=!access_token',
    'tags_search' => 'v1/tags/search?q=%s&access_token=!access_token',
    'locations' => 'v1/locations/%d?access_token=!access_token',
    'locations_recent' => 'v1/locations/%d/media/recent/?max_id=%d&min_id=%d&max_timestamp=%d&min_timestamp=%d&access_token=!access_token',
    'locations_search' => 'v1/locations/search?lat=%s&lng=%s&foursquare_id=%d&distance=%d&access_token=!access_token',
    'geographies' => 'v1/geographies/%d/media/recent?access_token=!access_token',
  );

  /**
   * Constructor for the Instagram class
   */
  public function __construct($username = NULL, $access_token = NULL) {
    if (!empty($username) && !empty($access_token)) {
      $this
        ->set_auth($username, $access_token);
    }
  }

  /**
   * Set the username and password
   */
  public function set_auth($username, $access_token) {
    $this->username = $username;
    $this->access_token = $access_token;
  }
  protected function create_url($path, $format = NULL) {
    if (is_null($format)) {
      $format = $this->format;
    }
    $conf = InstagramConf::instance();
    $url = $conf
      ->get('apibase') . '/' . $path;
    if (!empty($format)) {
      $url .= '.' . $this->format;
    }
    return $url;
  }

  /**
   * Get an array of Instagram objects from an API endpoint
   */
  protected function fetch($key, $params = array(), $use_auth = TRUE) {
    $results = array();
    if (array_key_exists($key, $this->endpoints)) {
      $path = $this->endpoints[$key];
    }
    else {
      watchdog('drupagram', 'Endpoint key not found: !key', array(
        '!key' => $key,
      ), WATCHDOG_ERROR);
      return FALSE;
    }
    $response = $this
      ->call($path, $params, 'GET', $use_auth);
    switch ($key) {
      case 'user':
      case 'user_search':
      case 'user_follows':
      case 'user_followed_by':
        $class = 'InstagramUser';
        break;
      default:
        $class = 'InstagramMedia';
        break;
    }
    if (isset($response) && is_array($response)) {
      $response = array_filter($response);
    }
    if (!empty($response)) {
      foreach ($response as $key => $item) {
        if ($key != 'data') {
          continue;
        }
        elseif (!empty($item) && isset($item[0])) {
          foreach ($item as $object) {
            $results[] = new $class($object);
          }
        }
        else {
          $results[] = new $class($item);
        }
      }
    }
    return $results;
  }

  /**
   * Perform a request
   *
   * @param string $url
   * @param array $params
   * @param string $method. Can be one of: GET, POST, DELETE or PUT.
   * @param bool $use_auth
   * @return type
   */
  protected function request($url, $params = array(), $method = 'GET', $use_auth = FALSE) {
    $data = '';
    if (!is_array($params)) {
      $params = (array) $params;
    }
    if (count($params) > 0) {
      if ($method == 'GET') {
        if (is_array($params) && !empty($params)) {
          $url = t($url, $params);
        }
        $url = preg_replace('/&?[a-z_]*=![a-z_]*/', '', $url, -1);
      }
      else {
        $data = http_build_query($params, '', '&');
      }
    }
    $headers = array();
    $response = drupal_http_request($url, $headers, $method, $data, 3, 30);
    if (!isset($response->error)) {
      return $response->data;
    }
    else {
      throw new InstagramException($response->error);
    }
  }

  /**
   * Get the most recent media published by a user.
   * GET /users/{user-id}/media/recent
   *
   * PARAMETERS
   * access_token	A valid access token.
   * max_id	Return media earlier than this max_id
   * min_id	Return media later than this min_id
   * count	Count of media to return
   * min_timestamp	Return media after this UNIX timestamp
   * max_timestamp	Return media before this UNIX timestamp
   */
  public function user_recent($id = NULL, $params = array(), $use_auth = TRUE) {
    if (empty($id)) {
      $params['!user_id'] = 'self';
    }
    elseif (is_numeric($id)) {
      $params['!user_id'] = $id;
    }
    else {
      $username = $id;

      // $params['username'] = $username;
      $account = $this
        ->user_lookup($username);
      $params['!user_id'] = $account->id;
    }
    return $this
      ->fetch('user_recent', $params, $use_auth);
  }
  public function user_lookup($username, $params = array(), $use_auth = TRUE) {
    $params['!q'] = $username;
    $result = $this
      ->fetch('user_search', $params, $use_auth);
    return $result;
  }

  /**
   * Search for a user by name.
   * GET /users/search
   *
   * PARAMETERS
   * q	A query string.
   * count	Number of users to return
   *
   */
  public function user_search($q, $params = array(), $use_auth = TRUE) {
    $params['!q'] = $q;
    return $this
      ->fetch('user_search', $params, $use_auth);
  }

  /**
   * See the authenticated user's list of media they've liked. Note that this
   * list is ordered by the order in which the user liked the media. Private
   * media is returned as long as the authenticated user has permission to view
   * that media. Liked media lists are only available for the currently
   * authenticated user.
   * GET /users/self/media/liked
   *
   * PARAMETERS
   * access_token	A valid access token.
   * max_like_id	Return media liked before this id
   * count	Count of media to return
   */
  public function self_liked($params = array(), $use_auth = TRUE) {
    $params['user-id'] = 'self';
    return $this
      ->fetch('users/{user-id}/media/recent', $params, $use_auth);
  }

  /**
   * See the authenticated user's feed.
   * GET /users/self/feed
   *
   * PARAMETERS
   * access_token	A valid access token.
   * max_id	Return media earlier than this max_id
   * min_id	Return media later than this min_id
   * count	Count of media to return
   *
   */
  public function self_feed($params = array(), $use_auth = TRUE) {
    return $this
      ->fetch('user_feed', $params, $use_auth);
  }

  /**
   * Get the most recent hash media published.
   * GET v1/tags/!tag_name/media/recent
   *
   * PARAMETERS
   * access_token	A valid access token.
   * max_id	Return media earlier than this max_id
   * min_id	Return media later than this min_id
   */
  public function tag_recent($hashtag, $oAuth_token) {
    $params = array(
      '!tag_name' => t($hashtag),
      '!access_token' => $oAuth_token,
    );
    return $this
      ->fetch("tags_recent", $params, FALSE);
  }

  /**
   * Method for calling any drupagram api resource
   */
  public function call($path, $params = array(), $method = 'GET', $use_auth = FALSE) {
    $url = $this
      ->create_url($path, '');
    try {
      if ($use_auth) {
        $response = $this
          ->auth_request($url, $params, $method);
      }
      else {
        $response = $this
          ->request($url, $params, $method);
      }
    } catch (InstagramException $e) {
      watchdog('drupagram', '!message', array(
        '!message' => $e
          ->__toString(),
      ), WATCHDOG_ERROR);
      return FALSE;
    }
    if (!$response) {
      return FALSE;
    }
    return $this
      ->parse_response($response);
  }
  protected function parse_response($response, $format = NULL) {
    if (empty($format)) {
      $format = $this->format;
    }
    switch ($format) {
      case 'json':

        // http://drupal.org/node/985544 - json_decode large integer issue
        // $length = strlen(PHP_INT_MAX);
        // $response = preg_replace('/"(id|in_reply_to_status_id)":(\d{' . $length . ',})/', '"\1":"\2"', $response);
        return json_decode($response, TRUE);
    }
  }

  /**
   * Perform an authentication required request.
   */
  protected function auth_request($path, $params = array(), $method = 'GET') {
    $params['!access_token'] = $this->access_token;
    return $this
      ->request($path, $params, $method, TRUE);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Instagram::$access_token protected property Decoded plain access token 1
Instagram::$current_user protected property OAuth user object
Instagram::$endpoints protected property
Instagram::$format protected property
Instagram::$oauth_token protected property JSON encoded OAuth token
Instagram::$password protected property
Instagram::$source protected property
Instagram::$username protected property
Instagram::auth_request protected function Perform an authentication required request. 1
Instagram::call public function Method for calling any drupagram api resource
Instagram::create_url protected function
Instagram::fetch protected function Get an array of Instagram objects from an API endpoint
Instagram::parse_response protected function
Instagram::request protected function Perform a request
Instagram::RESPONSE_CODE_PARAM constant The name of the GET param that holds the authentication code
Instagram::self_feed public function See the authenticated user's feed. GET /users/self/feed
Instagram::self_liked public function See the authenticated user's list of media they've liked. Note that this list is ordered by the order in which the user liked the media. Private media is returned as long as the authenticated user has permission to view that media. Liked…
Instagram::set_auth public function Set the username and password
Instagram::tag_recent public function Get the most recent hash media published. GET v1/tags/!tag_name/media/recent
Instagram::user_lookup public function
Instagram::user_recent public function Get the most recent media published by a user. GET /users/{user-id}/media/recent
Instagram::user_search public function Search for a user by name. GET /users/search
Instagram::__construct public function Constructor for the Instagram class 1