Skip to content

Instantly share code, notes, and snippets.

@JordanMagnuson
Created March 18, 2012 22:31
Show Gist options
  • Save JordanMagnuson/2083179 to your computer and use it in GitHub Desktop.
Save JordanMagnuson/2083179 to your computer and use it in GitHub Desktop.
<?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