Created
March 18, 2012 22:31
-
-
Save JordanMagnuson/2083179 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Enables counting how many times a node's download link(s) has been clicked. | |
* Also includes a form wizard for downloading. | |
*/ | |
// TODO: Better way to handle this? | |
define('PERSONAL_USE_LICENSE_ID', 0); | |
define('COMMERCIAL_USE_LICENSE_ID', 1); | |
/** | |
* Implements hook_menu(). | |
*/ | |
function download_manager_menu() { | |
$items['download-manager/%ctools_js/download/%'] = array( | |
'title' => 'Go to the download form for a particular node.', | |
'page callback' => 'download_manager_wizard', | |
'page arguments' => array(1, 3), // %ctools_js, %nid | |
'access callback' => TRUE, | |
'type' => MENU_CALLBACK, | |
'file' => 'download_manager_wizard.inc', | |
); | |
$items['download-manager/process-download/%node/%/%user/%/%'] = array( | |
'title' => 'Process a download.', | |
'page callback' => 'download_manager_process_download', | |
'page arguments' => array(2, 3, 4, 5), // %nid, %license_id, %uid, %price | |
'access callback' => 'download_manager_process_download_access', | |
'access arguments' => array(4, 6), // %uid, $session_token | |
'type' => MENU_CALLBACK, | |
); | |
return $items; | |
} | |
/** | |
* Implements hook_node_load(). | |
* TODO: do we really need to implement hook_node_load? | |
*/ | |
function download_manager_node_load($nodes, $types) { | |
// Get the global tid values for personal and commercial use licenses | |
$personal_use_license_id = 0; | |
$commercial_use_license_id = 1; | |
$result = db_query("SELECT downloads_total, downloads_month, downloads_week, downloads_day | |
FROM {download_manager_downloads_counted} | |
WHERE nid IN(:nids) AND license_id = :license_id", | |
array(':nids' => array_keys($nodes), ':license_id' => $personal_use_license_id)); | |
foreach ($result as $record) { | |
$downloads['by_license_id'][$personal_use_license_id]['downloads_total'] = $record->downloads_total; | |
} | |
// $node->download_count = $result->fetchField(); | |
// if ($node->download_count === FALSE) { | |
// $node->download_count = 0; | |
// } | |
} | |
/** | |
* Implements hook_node_delete(). | |
*/ | |
function download_manager_node_delete($node) { | |
db_delete('download_manager_downloads') | |
->condition('nid', $node->nid) | |
->execute(); | |
db_delete('download_manager_downloads_counted') | |
->condition('nid', $node->nid) | |
->execute(); | |
} | |
/** | |
* Implements hook_views_api(). | |
*/ | |
function download_manager_views_api() { | |
return array( | |
'api' => 2.0, | |
); | |
} | |
/** | |
* Choose license form. | |
*/ | |
function download_manager_download_form($form, &$form_state, $nid) { | |
// drupal_add_js('misc/ajax.js'); | |
// ctools_include('ajax'); | |
// ctools_include('modal'); | |
// ctools_modal_add_js(); | |
// // ctools_include('form'); | |
// drupal_add_js('misc/jquery.form.js'); | |
// ctools_add_js('ajax-responder'); | |
$node = node_load($nid); | |
// --------------------------------------------------------------------------- | |
// Get license options | |
$licenses = array(); | |
foreach ($node->field_license['und'] as $l) { | |
$licenses[] = $l['value']; | |
} | |
// Define options array | |
$license_options = array(); | |
// Personal use | |
if (in_array(PERSONAL_USE_LICENSE_ID, $licenses)) { | |
$personal_use_price = $node->field_personal_use_price['und']['0']['value']; | |
if ($personal_use_price == 0) { | |
$personal_use_price_text = '<span>FREE</span>'; | |
} | |
else { | |
$personal_use_price_text = '$' . $personal_use_price; | |
} | |
$license_options[PERSONAL_USE_LICENSE_ID] = $personal_use_price_text . ' | Personal Use Unlimited'; | |
} | |
// Commmercial use | |
if (in_array(COMMERCIAL_USE_LICENSE_ID, $licenses)) { | |
$commercial_use_price = $node->field_commercial_use_price['und']['0']['value']; | |
if ($commercial_use_price == 0) { | |
$commercial_use_price_text = '<span>FREE</span>'; | |
} | |
else { | |
$commercial_use_price_text = '$' . $commercial_use_price; | |
} | |
$license_options[COMMERCIAL_USE_LICENSE_ID] = $commercial_use_price_text . ' | Commercial Use Unlimited'; | |
} | |
// Remove personal use if same price as commercial | |
if ($personal_use_price == $commercial_use_price) { | |
unset($license_options[PERSONAL_USE_LICENSE_ID]); | |
} | |
// Default value | |
$default_value = key($license_options); | |
// --------------------------------------------------------------------------- | |
// Build form | |
$form['license'] = array( | |
'#type' => 'radios', | |
'#options' => $license_options, | |
'#default_value' => $default_value, | |
'#required' => TRUE, | |
); | |
$form['personal_use_price'] = array( | |
'#type' => 'value', | |
'#value' => $personal_use_price, | |
); | |
$form['commercial_use_price'] = array( | |
'#type' => 'value', | |
'#value' => $commercial_use_price, | |
); | |
$form['submit'] = array( | |
'#type' => 'submit', | |
'#value' => t('Download'), | |
'#attributes' => array( | |
'class' => array('ctools-use-modal'), | |
), | |
); | |
$form['#action'] = url('download-manager/nojs/download/122'); | |
// %nid, %license_id, %uid, %price | |
// $form['#action'] = url('download-manager/process-download/' . $node . '/' . $licen/%user/%/%'); | |
return $form; | |
} | |
/** | |
* Implementation of hook_form_alter | |
*/ | |
// function download_manager_form_alter(&$form, &$form_state, $form_id) { | |
// switch($form_id) { | |
// case 'download_manager_download_form': | |
// $form['#action'] = url('download-manager/ajax/download/122'); | |
// break; | |
// } | |
// } | |
/** | |
* License has been selected, now update our download_object accordingly. | |
*/ | |
// function download_manager_download_form_submit(&$form, &$form_state) { | |
// dsm($form_state); | |
// global $user; | |
// $session_token = drupal_get_token($user->uid); | |
// // Construct the process_download callback url | |
// global $user; | |
// $nid = $form_state['build_info']['args']['0']; | |
// $license_id = $form_state['values']['license']; | |
// $uid = $user->uid; | |
// if ($form_state['values']['license'] == '0') { | |
// $price = $form_state['values']['personal_use_price']; | |
// } | |
// else { | |
// $price = $form_state['values']['commercial_use_price']; | |
// } | |
// $session_token = drupal_get_token($user->uid); | |
// $process_download_path = "/download-manager/process-download/$nid/$license_id/$uid/$price/$session_token"; | |
// $form_state['redirect'] = array( | |
// // $path | |
// $process_download_path, | |
// // $options | |
// array('query' => array('key' => 'value')), | |
// // $http_response_code | |
// 302, | |
// ); | |
// } | |
/** | |
* Process download. Callback that handles access control, and the actual file transfer. | |
*/ | |
function download_manager_process_download($node, $license_id, $account, $price) { | |
// --------------------------------------------------------------------------- | |
// Log the download in the database | |
// This is equivalent to INSERT... ON DUPLICATE KEY UPDATE count=count+1 | |
$id = db_merge('download_manager_downloads') | |
->key(array('nid' => $node->nid, 'license_id' => $license_id, 'uid' => $account->uid)) | |
->insertFields(array( // 'insertFields' acts only on insert | |
'nid' => $node->nid, | |
'license_id' => $license_id, | |
'uid' => $account->uid, | |
'price' => $price, | |
'count' => 1, | |
)) | |
->fields(array( // 'fields' acts on insert or update | |
'timestamp' => REQUEST_TIME, | |
)) | |
->expression('count', 'count + :inc', array(':inc' => 1)) | |
->execute(); | |
// Update the downloads_counted table as well (this table is then cleaned of old data on cron run). | |
// TODO: should I do this, or just update this table on cron run? Less expensive... | |
$id = db_merge('download_manager_downloads_counted') | |
->key(array('nid' => $node->nid, 'license_id' => $license_id)) | |
->insertFields(array( | |
'nid' => $node->nid, | |
'license_id' => $license_id, | |
'uid' => $node->uid, | |
'downloads_total' => 1, | |
'downloads_month' => 1, | |
'downloads_week' => 1, | |
'downloads_day' => 1, | |
)) | |
->expression('downloads_total', 'downloads_total + :inc', array(':inc' => 1)) | |
->expression('downloads_month', 'downloads_month + :inc', array(':inc' => 1)) | |
->expression('downloads_week', 'downloads_week + :inc', array(':inc' => 1)) | |
->expression('downloads_day', 'downloads_day + :inc', array(':inc' => 1)) | |
->execute(); | |
// --------------------------------------------------------------------------- | |
// TODO: need a dynamic function to get the uri... check for psd if available, check node type, etc. | |
$download_uri = $node->field_image['und']['0']['uri']; | |
// Start the file transfer, with headers designed to force file transfer | |
// (so images aren't opened by the browser) | |
$content_disposition = 'attachment; filename="' . basename($download_uri) . '"'; | |
$headers = array | |
( | |
'Content-type' => 'application/octet-stream', | |
'Content-Disposition' => $content_disposition, | |
'Content-Transfer-Encoding' => 'binary', | |
); | |
file_transfer($download_uri, $headers); | |
} | |
/** | |
* process_download access control. | |
*/ | |
function download_manager_process_download_access($account, $token = NULL) { | |
// TODO: custom access denied message with contact form. | |
global $user; | |
// Check the validity of the user account. | |
if ($account->uid == 0 || $account->uid != $user->uid) { | |
return FALSE; | |
} | |
// Check the validity of the callback token. | |
if (empty($token) || !drupal_valid_token($token, $account->uid)) { | |
return FALSE; | |
} | |
// TODO: check if the user has paid for this download | |
return TRUE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment