bpn_flickr_private.module in Bulk File Nodes 7
Hooks and functions for the bpn_flickr_private module.
File
modules/bpn_flickr_private/bpn_flickr_private.moduleView source
<?php
/**
* @file
* Hooks and functions for the bpn_flickr_private module.
*/
/**
* Implements hook_menu().
*/
function bpn_flickr_private_menu() {
$items = array();
$items['bulk_photo_nodes/auth'] = array(
'title' => 'Authenticate Flickr Credentials',
'page callback' => 'bpn_flickr_private_oauth_authenticate',
'access arguments' => array(
'create bulk photo nodes',
),
);
return $items;
}
/**
* Implements hook_bpn_upload().
*
* Defines a multi-step form to use with bulk_photo_nodes.
*/
function bpn_flickr_private_bulk_photo_nodes_method() {
return 'bpn_flickr_private_form';
}
/**
* Form constructor for the private flickr form.
*
* @see bpn_flickr_private_form_step_1()
* @see bpn_flickr_private_form_step_2()
* @see bpn_flickr_private_form_step_3()
* @ingroup forms
*/
function bpn_flickr_private_form($form, &$form_state, $node_type) {
if (empty($form_state['step'])) {
$form_state['step'] = 1;
}
$form_state['node_type'] = $node_type;
$form_callback = 'bpn_flickr_private_form_step_' . $form_state['step'];
if (function_exists($form_callback)) {
return call_user_func($form_callback, $form, $form_state);
}
}
/**
* Form constructor for Step 1: Select flickr user.
*
* @see bpn_flickr_private_disconnect()
* @see bpn_flickr_private_form_step_1_submit()
* @ingroup forms
*/
function bpn_flickr_private_form_step_1($form, &$form_state) {
// Check if the flickrapi module is authenticated.
module_load_include('module', 'flickrapi');
$authenticated = _flickrapi_is_authenticated();
if (!$authenticated) {
drupal_set_message(t('The Flickr settings have not been established yet.'));
}
$form['flickr_private'] = array(
'#prefix' => '<div class="bpn-upload-option">' . t('OR') . '</div><div class="bpn-flickr bpn-flickr-private">',
'#suffix' => '</div>',
);
$form['flickr_private']['header'] = array(
'#markup' => '<h3>' . t('Upload Images from your Flickr Account') . '</h3>',
);
if ($authenticated) {
$flickr_user = bpn_flickr_private_get_api();
if (!$flickr_user) {
$form['flickr_private']['username'] = array(
'#markup' => '<div class="description">' . t('Authenticate with your Flickr account.') . '</div>',
);
}
$value = bpn_flickr_private_get_api() ? t('Next') : t('Authenticate');
$form['flickr_private']['next'] = array(
'#type' => 'submit',
'#value' => $value,
);
if (bpn_flickr_private_get_api()) {
$flickr_username = bpn_flickr_private_test_login();
if (!empty($flickr_username['username'])) {
$form['flickr_private']['username'] = array(
'#markup' => '<div class="description">' . t('Authenticated as ') . $flickr_username['username'] . t('. Select image(s) on next page') . '</div>',
);
}
$form['flickr_private']['remove'] = array(
'#type' => 'submit',
'#value' => 'Authenticate as a new user',
'#submit' => array(
'bpn_flickr_private_disconnect',
),
);
}
$form['#submit'][] = 'bpn_flickr_private_form_step_1_submit';
}
return $form;
}
/**
* Form submission handler for bpn_flickr_private_form_step_1().
*
* De-authenticates a user's Flickr account.
*
* @see bpn_flickr_private_form_step_1_submit()
*/
function bpn_flickr_private_disconnect($form, &$form_state) {
bpn_flickr_private_oauth_new();
$form_state['step'] = 2;
$form_state['rebuild'] = TRUE;
}
/**
* Form submission handler for bpn_flickr_private_form_step_1().
*
* Redirects the user to Flickr for authentication.
*
* @see bpn_flickr_private_disconnect()
*/
function bpn_flickr_private_form_step_1_submit($form, &$form_state) {
if (bpn_flickr_private_get_api()) {
// If the user has already authenticated.
$form_state['step'] = 2;
$form_state['rebuild'] = TRUE;
}
else {
bpn_flickr_private_oauth_new();
}
}
/**
* Authenticates a flickr user.
*/
function bpn_flickr_private_oauth_new() {
global $user;
module_load_include('module', 'oauth_common');
$callback = url('bulk_photo_nodes/auth', array(
'absolute' => TRUE,
));
// Set up a new OAuth Consumer and Client if it cannot be loaded.
$consumer = DrupalOAuthConsumer::load(variable_get('flickrapi_api_key', ''), FALSE);
if (!$consumer) {
$consumer = new DrupalOAuthConsumer(variable_get('flickrapi_api_key', ''), variable_get('flickrapi_api_secret', ''));
$consumer
->write();
}
$sig_method = DrupalOAuthClient::signatureMethod();
$client = new DrupalOAuthClient($consumer, NULL, $sig_method);
try {
if ($request_token = $client
->getRequestToken('http://www.flickr.com/services/oauth/request_token', array(
'callback' => $callback,
))) {
$request_token->uid = $user->uid;
$request_token
->write();
}
} catch (Exception $e) {
drupal_set_message(t('You API key and secret do not seem to match.'), 'error');
variable_del('flickrapi_api_key');
variable_del('flickrapi_api_secret');
drupal_goto('admin/config/media/flickrapi');
}
// Save current address.
$_SESSION['bulk_photo_node_url'] = implode('/', arg());
$auth_url = $client
->getAuthorizationUrl('http://www.flickr.com/services/oauth/authorize', array(
'callback' => $callback,
'params' => array(
'perms' => variable_get('flickrapi_access_permissions', array(
'read',
)),
),
));
// Send the user to the Flickr page which redirects
// back to the Drupal site after accepting.
drupal_goto($auth_url);
}
/**
* Handle OAuth authentication after step 1.
*/
function bpn_flickr_private_oauth_authenticate() {
$access_token = bpn_flickr_private_get_token();
drupal_set_message(t('Succesfully verified'));
drupal_goto($_SESSION['bulk_photo_node_url'], array(
'query' => array(
'bpn_flickr_private' => 1,
),
));
}
/**
* Form constructor for Step 2: Pick what images to load.
*/
function bpn_flickr_private_form_step_2($form, &$form_state) {
module_load_include('module', 'oauth_common');
$form['#bpn_chosen_form'] = array(
'#type' => 'value',
'#value' => TRUE,
);
$form['photo_container_selector'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#weight' => -2,
);
// Get photosets.
$sets = bpn_flickr_private_get_sets();
$photosets = array();
if (!empty($sets)) {
foreach ($sets['photoset'] as $photoset) {
if ($photoset['photos'] > 0) {
$photosets[$photoset['id']] = $photoset['title'];
}
}
}
asort($photosets);
$form['photo_container_selector']['photo_container_type'] = array(
'#type' => 'select',
'#options' => array(
t('Photos') => array(
'photostream' => 'Photostream',
),
t('Sets') => $photosets,
),
'#title' => t('View flickr photos from:'),
);
$count = isset($form_state['num_photos_checked']) ? intval($form_state['num_photos_checked']) : 0;
$form['photo_container_selector']['stats'] = array(
'#markup' => '<div class="bpn-flickr-selected-count">' . t('Photos selected:') . ' <span class="bpn-flickr-count">' . $count . '</span></div>',
'#attached' => array(
'js' => array(
drupal_get_path('module', 'bpn_flickr') . '/js/bpn_flickr.js',
),
),
);
$form['photo_container_selector']['update'] = array(
'#type' => 'submit',
'#value' => 'Update',
'#submit' => array(
'bpn_flickr_private_photos_state',
'bpn_flickr_private_update_photos',
),
);
$form['photo_container_photos']['photostream'] = array(
'#attributes' => array(
'class' => array(
'clearfix',
),
),
'#type' => 'container',
'#tree' => TRUE,
);
$page = empty($form_state['flickr_page']) ? 1 : $form_state['flickr_page'];
$photo_set = empty($form_state['photo_set']) ? 'photostream' : $form_state['photo_set'];
if ($photo_set == 'photostream') {
$photos_response = bpn_flickr_private_get_photos($page);
$pages = $photos_response['photos']['pages'];
$photos = $photos_response['photos']['photo'];
}
else {
$photos_response = bpn_flickr_private_get_set($photo_set, $page);
$photos = $photos_response['photoset']['photo'];
$pages = $photos_response['photoset']['pages'];
}
if (!empty($photos)) {
if ($pages > 1) {
$form['flickr_pager'] = array(
'#type' => 'container',
'#tree' => TRUE,
'#weight' => -1,
);
if ($page != 1) {
$form['flickr_pager']['flickr_prev'] = array(
'#type' => 'submit',
'#value' => 'Previous Page',
'#submit' => array(
'bpn_flickr_private_photos_state',
'bpn_flickr_private_pager_prev',
),
);
}
$form['flickr_pager']['pager_text'] = array(
'#preix' => '<span>',
'#markup' => "Page {$page} of " . $pages,
'#suffix' => '</span>',
);
$form['flickr_pager']['flickr_page'] = array(
'#type' => 'value',
'#value' => $page,
);
if ($page != $pages) {
$form['flickr_pager']['flickr_next'] = array(
'#type' => 'submit',
'#value' => 'Next Page',
'#submit' => array(
'bpn_flickr_private_photos_state',
'bpn_flickr_private_pager_next',
),
);
}
}
foreach ($photos as $key => $photo) {
$id = $photo['id'];
$has_values = !empty($form_state['checked_photos']);
$default_value = $has_values && in_array($id, $form_state['checked_photos']);
$form['photo_container_photos']['photostream'][$id] = array(
'#type' => 'checkbox',
'#default_value' => $default_value,
'#prefix' => '<div class="bpn-flickr-thumbnail"><div class="inner">' . theme('image', array(
'path' => $photo['url_q'],
)),
'#title' => empty($photo['title']) ? t('Untitled') : $photo['title'],
'#suffix' => '</div></div>',
);
}
}
$form['submit'] = array(
'#prefix' => '<div class="bpn-continue">',
'#type' => 'submit',
'#value' => t('Done Adding Photos - Continue'),
'#suffix' => '</div>',
);
$form['#submit'] = array(
'bpn_flickr_private_photos_state',
'bpn_flickr_private_form_step_2_submit',
);
$form['#attributes'] = array(
'class' => array(
'clearfix',
),
);
return $form;
}
/**
* Form submission handler for bpn_flickr_private_form_step_2().
*/
function bpn_flickr_private_form_step_2_submit($form, &$form_state) {
$operations = array();
foreach ($form_state['checked_photos'] as $key => $flickr_id) {
$operations[] = array(
'bpn_flickr_download_photos',
array(
$flickr_id,
),
);
}
$batch = array(
'title' => t('Importing photos from flickr.'),
'finished' => 'bpn_flickr_private_batch_finished',
'operations' => $operations,
);
batch_set($batch);
$form_state['step'] = 3;
$form_state['rebuild'] = TRUE;
}
/**
* Batch finished callback used by bpn_flickr_private_form_step_2_submit().
*/
function bpn_flickr_private_batch_finished($success, $results, $operations) {
if ($success) {
drupal_set_message(t('@count Photos imported.', array(
'@count' => count($results),
)));
}
else {
$error_operation = reset($operations);
drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array(
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[0], TRUE),
)));
}
$_SESSION['saved_files'] = $results;
}
/**
* Batch operation: Downloads a single image from flickr.
*
* Downloads the largest image size available to the public files directory.
* Also fetches extra information about the image, such as size, date taken,
* etc.
*
* @param string $flickr_id
* The flickr id of the image.
*/
function bpn_flickr_private_download_photos($flickr_id, &$context) {
// Set batch message.
$context['message'] = t('Importing image with flickr id: "@id"', array(
'@id' => $flickr_id,
));
$flickr_sizes = bpn_flickr_private_get_photo($flickr_id);
$extra_info = bpn_flickr_private_get_info($flickr_id);
$largest_size = count($flickr_sizes) - 1;
$extra_info['photo']['exif_width'] = $flickr_sizes[$largest_size]['width'];
$extra_info['photo']['exif_height'] = $flickr_sizes[$largest_size]['height'];
// Get URL to download image from.
$parsed_url = parse_url($flickr_sizes[$largest_size]['source']);
$filename = substr($parsed_url['path'], strrpos($parsed_url['path'], '/') + 1);
// Request and save the image.
$downloaded_file = drupal_http_request($flickr_sizes[$largest_size]['source']);
$destination_uri = file_stream_wrapper_uri_normalize('public://' . $filename);
$file_uri = file_unmanaged_save_data($downloaded_file->data, $destination_uri);
// Convert the saved file to a file object.
$file_object = bpn_flickr_file_uri_to_object($file_uri);
file_save($file_object);
$context['results'][] = array(
'extra_info' => $extra_info['photo'],
'file_object' => $file_object,
);
}
/**
* Step 3 of the Flickr Private form.
*/
function bpn_flickr_private_form_step_3($form, &$form_state) {
return bulk_photo_nodes_add_form($form, $form_state, $form_state['node_type']);
}
/**
* Flickr submit handler.
*/
function bpn_flickr_private_form_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
if (isset($form_state['values']['username']) && !empty($form_state['values']['username'])) {
$form_state['flickr_username'] = $form_state['values']['username'];
$form_state['step'] = 2;
}
}
/**
* Sets a custom POST URL to make private calls.
*/
function _bpn_flickr_private_custom_post($url, $data) {
global $user;
$query = db_select('oauth_common_token', 't')
->fields('t');
$query
->join('oauth_common_consumer', 'c', 'c.csid = t.csid');
$query
->condition('c.consumer_key', variable_get('flickrapi_api_key', ''));
$query
->condition('c.secret', variable_get('flickrapi_api_secret', ''));
$query
->condition('t.uid', $user->uid);
$result = $query
->execute();
$token = DrupalOAuthToken::fromResult($result);
$consumer = DrupalOAuthConsumer::load(variable_get('flickrapi_api_key', ''), FALSE);
$sig_method = FlickrApiOAuthClient::signatureMethod();
$client = new FlickrApiOAuthClient($consumer, $token, $sig_method);
$response = $client
->get($url, array(
'token' => TRUE,
'params' => $data,
));
return $response;
}
/**
* Gets the photosets for a user.
*/
function bpn_flickr_private_get_sets() {
$flickr = bpn_flickr_private_get_api();
return $flickr
->photosets_getList();
}
/**
* Wraps PHPFlickr::people_findByUsername.
*/
function bpn_flickr_private_get_user($username) {
$flickr = bpn_flickr_private_get_api();
return $flickr
->people_findByUsername($username);
}
/**
* Form submission handler for bpn_flickr_private_form_step_2().
*/
function bpn_flickr_private_photos_state($form, &$form_state) {
if (empty($form_state['checked_photos'])) {
$form_state['checked_photos'] = array_keys($form_state['values']['photostream'], 1);
}
else {
$currently_checked = array_keys($form_state['values']['photostream'], 1);
$unique_merged = array_unique(array_merge($form_state['checked_photos'], $currently_checked));
$form_state['checked_photos'] = $unique_merged;
}
$form_state['num_photos_checked'] = count($form_state['checked_photos']);
$form_state['rebuild'] = TRUE;
}
/**
* Form submission handler for bpn_flickr_private_form_step_2().
*/
function bpn_flickr_private_pager_next($form, &$form_state) {
$form_state['flickr_page'] = $form_state['values']['flickr_pager']['flickr_page'] + 1;
}
/**
* Form submission handler for bpn_flickr_private_form_step_2().
*/
function bpn_flickr_private_pager_prev($form, &$form_state) {
$form_state['flickr_page'] = $form_state['values']['flickr_pager']['flickr_page'] - 1;
}
/**
* Form submission handler for bpn_flickr_private_form_step_2().
*/
function bpn_flickr_private_update_photos($form, &$form_state) {
$form_state['photo_set'] = $form_state['values']['photo_container_selector']['photo_container_type'];
$form_state['flickr_page'] = 1;
$form_state['rebuild'] = TRUE;
}
/**
* Returns a file object which can be passed to file_save().
*
* @param string $uri
* a string containing the uri, path, or filename.
*
* @return mixed
* a file object, or false on error.
*
* @todo replace with calls to this function with file_uri_to_object() when
* http://drupal.org/node/685818 is fixed in core.
*/
function bpn_flickr_private_file_uri_to_object($uri) {
global $user;
$uri = file_stream_wrapper_uri_normalize($uri);
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
$file = new stdClass();
$file->uid = $user->uid;
$file->filename = basename($uri);
$file->uri = $uri;
$file->filemime = file_get_mimetype($uri);
// This is gagged because some uris will not support it.
$file->filesize = @filesize($uri);
$file->timestamp = REQUEST_TIME;
$file->status = 1;
return $file;
}
/**
* Gets the Flickr API object for use in API calls.
*
* @return object
* The PHP Flickr object
*/
function bpn_flickr_private_get_api() {
global $user;
$flickr =& drupal_static(__FUNCTION__);
if (!isset($flickr)) {
$query = db_select('oauth_common_token', 't')
->fields('t');
$query
->join('oauth_common_consumer', 'c', 'c.csid = t.csid');
$query
->condition('c.consumer_key', variable_get('flickrapi_api_key', ''));
$query
->condition('c.secret', variable_get('flickrapi_api_secret', ''));
$query
->condition('t.uid', $user->uid);
$result = $query
->execute();
$token = DrupalOAuthToken::fromResult($result);
if (!$token) {
return FALSE;
}
$flickr = new phpFlickr($token->key, $token->secret);
$flickr
->setCustomPost('_bpn_flickr_private_custom_post');
}
return $flickr;
}
/**
* Gets the flickr token.
*
* @return string
* The user's access token to make flickr API calls with.
*/
function bpn_flickr_private_get_token() {
global $user;
module_load_include('module', 'oauth_common');
$oauth_token = NULL;
$oauth_verifier = NULL;
if (isset($_GET['oauth_token'])) {
$oauth_token = $_GET['oauth_token'];
}
if (isset($_GET['oauth_verifier'])) {
$oauth_verifier = $_GET['oauth_verifier'];
}
$consumer = DrupalOAuthConsumer::load(variable_get('flickrapi_api_key', ''), FALSE);
$request_token = DrupalOAuthToken::loadByKey($oauth_token, $consumer, OAUTH_COMMON_TOKEN_TYPE_REQUEST);
$client = new DrupalOAuthClient($consumer, $request_token);
$num_deleted = db_delete('oauth_common_token')
->condition('uid', $user->uid)
->execute();
$access_token = $client
->getAccessToken('http://www.flickr.com/services/oauth/access_token', array(
'verifier' => $oauth_verifier,
));
$request_token
->delete();
$access_token->uid = $user->uid;
$access_token
->write();
return $access_token;
}
/**
* Get photos from a user's photostream.
*/
function bpn_flickr_private_get_set($set_id, $page = 1) {
$flickr = bpn_flickr_private_get_api();
$options = array(
'photoset_id' => $set_id,
'extras' => 'url_q',
'privacy_filter' => NULL,
'per_page' => 9,
'page' => $page,
'media' => 'photos',
);
extract($options);
return $flickr
->photosets_getPhotos($photoset_id, $extras, $privacy_filter, $per_page, $page, $media);
}
/**
* Get photos from a user's photostream.
*/
function bpn_flickr_private_get_photos($page = 1) {
$flickr = bpn_flickr_private_get_api();
$options = array(
'user_id' => 'me',
'safe_search' => NULL,
'extras' => 'url_q',
'per_page' => 9,
'page' => $page,
);
extract($options);
return $flickr
->people_getPhotos('me', $options);
}
/**
* Get information from a photo on flickr.
*/
function bpn_flickr_private_get_info($photo_id) {
$flickr = bpn_flickr_private_get_api();
return $flickr
->photos_getInfo($photo_id);
}
/**
* Get information for the authenticated user.
*/
function bpn_flickr_private_test_login() {
$flickr = bpn_flickr_private_get_api();
return $flickr
->test_login();
}
/**
* Get sizes of a photo on flickr.
*/
function bpn_flickr_private_get_photo($photo_id) {
$flickr = bpn_flickr_private_get_api();
return $flickr
->photos_getSizes($photo_id);
}