Skip to content

Instantly share code, notes, and snippets.

@JordanMagnuson
Created March 18, 2012 22:33
Show Gist options
  • Save JordanMagnuson/2083193 to your computer and use it in GitHub Desktop.
Save JordanMagnuson/2083193 to your computer and use it in GitHub Desktop.
<?php
/**
* @file
* This file contains the various forms used in the node download wizard.
*/
/**
* ctools form wizard builder; Create and display the node download form.
*/
function download_manager_wizard($js = NULL, $nid = NULL, $step = NULL) {
// $user_id is used to create $download_object_id
global $user;
// Check for js
if ($js) {
ctools_include('modal');
ctools_include('ajax');
}
// Set up the ctools wizard
$form_info = array(
'id' => 'download_manager',
'path' => "download-manager/" . ($js ? 'ajax' : 'nojs') . "/download/$nid/%step",
'show trail' => TRUE,
'show back' => TRUE,
'show return' => FALSE,
'next callback' => 'download_manager_wizard_next',
'finish callback' => 'download_manager_wizard_finish',
'cancel callback' => 'download_manager_wizard_cancel',
'order' => array(
'choose-license' => t('Choose License'),
'confirm-spending' => t('Confirm Spending'),
'start-download' => t('Start Download'),
),
'forms' => array(
'choose-license' => array(
'form id' => 'download_manager_wizard_choose_license_form',
),
'confirm-spending' => array(
'form id' => 'download_manager_wizard_confirm_spending_form',
),
'start-download' => array(
'form id' => 'download_manager_wizard_start_download_form',
),
),
);
// Create our unique object id, for caching.
$download_object_id = $nid . '_' . $user->uid;
// TODO: This automatically gets defaults if there wasn't anything saved.
$download_object = download_manager_wizard_cache_get($download_object_id);
if (!isset($download_object)) {
// Create a default object.
$download_object = new stdClass;
$download_object->nid = $nid;
$download_object->license = 'unknown';
$download_object->price = 'unknown';
}
if (empty($step)) {
// We reset the form when $step is NULL because that means they have
// for whatever reason started over.
download_manager_wizard_cache_clear($download_object_id);
$step = 'choose-license';
}
// Set the form state
$form_state = array(
'ajax' => $js,
// Put our download_object and ID into the form state cache so we can easily find it.
'download_object_id' => $download_object_id,
'download_object' => &$download_object,
);
// Send this all off to our form. This is like drupal_get_form only wizardy.
ctools_include('wizard');
$form = ctools_wizard_multistep_form($form_info, $step, $form_state);
$output = drupal_render($form);
// Render the form in modal if js.
if ($js) {
// If javascript is active, we have to use a render array.
$commands = array();
if (!empty($form_state['cancel'])) {
// If cancelling, return to the activity.
$commands[] = ctools_modal_command_dismiss();
}
else {
$commands = ctools_modal_form_render($form_state, $output);
}
print ajax_render($commands);
exit;
}
else {
if (!empty($form_state['cancel'])) {
$original_node_path = 'node/' . $nid;
drupal_goto($original_node_path);
}
else {
return $output;
}
}
}
/**
* Get licenses for a particular node
*/
function download_manager_wizard_get_licenses($nid = NULL) {
// Load the node
$node = node_load($nid);
dsm($node);
// TODO: get this to work if js is true
if (!$node) {
watchdog('download_manager', 'download_manager_wizard_get_licenses failed to retrieve licences because node_load failed', array(), WATCHDOG_ERROR);
drupal_set_message(t('An error has occured while attempting to process your download. Please try again later. If the problem persists, please contact a site administrator.'), 'error');
return;
}
// Get the global tid values for personal and commercial use licenses
$personal_use_license_id = 0;
$commercial_use_license_id = 1;
// Load the licenses from the node in question
$licenses[] = $node->field_license['und']['0']['value'];
if ($node->field_license['und']['1']['value']) {
$licenses[] = $node->field_license['und']['1']['value'];
}
// ---------------------------------------------------------------------------
// Construct our options array for the form wizard
// 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) {
$title = t("Personal Use Unlimited (price: FREE!)");
$config_title = t('Download Starting...');
$next_form = 'download_manager_wizard_start_download_form';
}
else {
$title = t("Personal Use Unlimited (price: @personal_use_price ScrapperDollars)", array('@personal_use_price' => $personal_use_price));
$config_title = t('Confirm Spending');
$next_form = 'download_manager_wizard_confirm_spending_form';
}
$wizard_options['personal-use'] = array(
'title' => $title,
'config title' => $config_title,
'form' => $next_form,
'license_id' => $personal_use_license_id,
'price' => $personal_use_price,
);
}
// Commercial 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) {
$title = t("Commercial Use Unlimited (price: FREE!)");
$config_title = t('Download Starting...');
$next_form = 'download_manager_wizard_start_download_form';
}
else {
$title = t("Commercial Use Unlimited (price: @commercial_use_price ScrapperDollars)", array('@commercial_use_price' => $commercial_use_price));
$config_title = t('Confirm Spending');
$next_form = 'download_manager_wizard_confirm_spending_form';
}
$wizard_options['commercial-use'] = array(
'title' => $title,
'config title' => $config_title,
'form' => $next_form,
'license_id' => $commercial_use_license_id,
'price' => $commercial_use_price,
);
}
return $wizard_options;
}
/**
* Choose license form.
*/
function download_manager_wizard_choose_license_form($form, &$form_state) {
$form_state['title'] = t('Choose license');
// There should never be a 'back' button on this first form.
if (isset($form['buttons']['previous'])) {
unset($form['buttons']['previous']);
}
$nid = $form_state['download_object']->nid;
$licenses = download_manager_wizard_get_licenses($nid);
foreach ($licenses as $id => $license) {
$license_options[$id] = $license['title'];
$license_prices[$id] = $license['price'];
$license_ids[$id] = $license['license_id'];
}
// Set the default value to the index of the first array element, unless the user has clicked 'back',
// in which case we get teh selection from the cache.
$default_value = $form_state['download_object']->license == 'unknown' ? key($license_options) : $form_state['download_object']->license;
$form['license'] = array(
'#title' => t('Choose your license'),
'#type' => 'radios',
'#options' => $license_options,
'#default_value' => $default_value,
'#required' => TRUE,
);
$form['personal_use_price'] = array(
'#type' => 'value',
'#value' => $license_prices['personal-use'],
);
$form['commercial_use_price'] = array(
'#type' => 'value',
'#value' => $license_prices['commercial-use'],
);
$form['personal_use_license_id'] = array(
'#type' => 'value',
'#value' => $license_ids['personal-use'],
);
$form['commercial_use_license_id'] = array(
'#type' => 'value',
'#value' => $license_ids['commercial-use'],
);
return $form;
}
/**
* License has been selected, now update our download_object accordingly.
*/
function download_manager_wizard_choose_license_form_submit(&$form, &$form_state) {
// Set license
$form_state['download_object']->license = $form_state['values']['license'];
// Set price and license_id
if ($form_state['values']['license'] == 'personal-use') {
$form_state['download_object']->price = $form['personal_use_price']['#value'];
$form_state['download_object']->license_id = $form['personal_use_license_id']['#value'];
}
else {
$form_state['download_object']->price = $form['commercial_use_price']['#value'];
$form_state['download_object']->license_id = $form['commercial_use_license_id']['#value'];
}
// Override where to go next based on the price of the selected license.
if ($form_state['download_object']->price > 0) {
$form_state['clicked_button']['#next'] = 'confirm-spending';
}
else {
$form_state['clicked_button']['#next'] = 'start-download';
}
}
/**
* Confirm spending form.
*/
function download_manager_wizard_confirm_spending_form($form, &$form_state) {
$form_state['title'] = t('Confirm Spending');
$price = $form_state['download_object']->price;
// Message
$form['download_confirm_spending_message'] = array(
'#prefix' => '<div id="download-confirm-spending-message">',
'#suffix' => '</div>',
'#markup' => t("This will cost you @price ScrapperDollars... do you wish to proceed?", array('@price' => $price)),
);
return $form;
}
/**
* Start download form.
*/
function download_manager_wizard_start_download_form($form, &$form_state) {
// Form title
$form_state['title'] = t('Start download');
// Construct the process_download callback url
global $user;
global $base_url;
$nid = $form_state['download_object']->nid;
$license_id = $form_state['download_object']->license_id;
$uid = $user->uid;
$price = $form_state['download_object']->price;
$session_token = drupal_get_token($user->uid);
$form_state['process_download_url'] = $base_url . "/download-manager/process-download/$nid/$license_id/$uid/$price/$session_token";
// Remove 'back' button (no going back at this point)
unset($form['buttons']['previous']);
// Create download button
$form['download_button'] = array(
'#type' => 'submit',
'#value' => t('Start File Download'),
'#prefix' => '<div id="download-wizard-download-button">',
'#suffix' => '</div>',
);
if ($form_state['ajax']) {
// Hide the 'return' button
unset($form['buttons']['return']);
// Grab callback using js onClick.
$form['download_button']['#attributes']['onClick'] = 'window.open("' . $form_state['process_download_url'] . '"); return true;'; // Returning true here allows processing to continue, and wizard_finish to be called
// Let the ctools wizard know that this button should be treated as a 'finish' button (so wizard_finish callback is called)
$form['download_button']['#wizard type'] = 'finish';
// Message
$form['download_will_begin_message'] = array(
'#prefix' => '<div id="download-will-begin-message">',
'#suffix' => '</div>',
'#markup' => t('Ajax. Your download will begin when you click on the button.'),
);
}
else {
// Grab callback using regular form redirect.
$form['download_button']['#submit'] = array('download_manager_wizard_nojs_download_button_submit');
// Message
$form['download_will_begin_message'] = array(
'#prefix' => '<div id="download-will-begin-message">',
'#suffix' => '</div>',
'#markup' => t('No ajax. Your download will begin when you click on the button. Click finish when you\'re done.'),
);
}
return $form;
}
function download_manager_wizard_nojs_download_button_submit($form, &$form_state) {
// Ajax uses onClick to the call the process_download callback
if ($form_state['ajax']) {
return;
}
// Call the process_download_url callback to process the actual download
$form_state['redirect'] = array($form_state['process_download_url']);
}
/**
* Handle the 'next' click on the add/edit pane form wizard.
*
* All we need to do is store the updated pane in the cache.
*/
function download_manager_wizard_next(&$form_state) {
download_manager_wizard_cache_set($form_state['download_object_id'], $form_state['download_object']);
}
/**
* Handle the 'finish' click on teh add/edit pane form wizard.
*
* All we need to do is set a flag so the return can handle adding
* the pane.
*/
function download_manager_wizard_finish(&$form_state) {
$form_state['complete'] = TRUE;
// Clear the cache
download_manager_wizard_cache_clear($form_state['download_object_id']);
// Dismiss differently depending on whether js is true
if ($form_state['ajax']) {
$commands = array();
$commands[] = ctools_modal_command_dismiss();
print ajax_render($commands);
exit;
}
else {
$original_node_path = 'node/' . $form_state['download_object']->nid;
drupal_goto($original_node_path);
}
}
/**
* Handle the 'cancel' click on the add/edit pane form wizard.
*/
function download_manager_wizard_cancel(&$form_state) {
$form_state['cancel'] = TRUE;
// Clear the cache
download_manager_wizard_cache_clear($form_state['download_object_id']);
}
/**
* Store our wizard cache so that we can retain data from form to form.
*/
function download_manager_wizard_cache_set($id, $object) {
ctools_include('object-cache');
ctools_object_cache_set('download_manager', $id, $object);
}
/**
* Get the current object from the wizard cache.
*/
function download_manager_wizard_cache_get($id) {
ctools_include('object-cache');
$object = ctools_object_cache_get('download_manager', $id);
// if (!$object) {
// // Create a default object.
// $object = new stdClass;
// $object->nid = '';
// $object->license = 'unknown';
// $object->license_id = '';
// $object->price = '';
// }
return $object;
}
/**
* Clear the wizard cache.
*/
function download_manager_wizard_cache_clear($id) {
ctools_include('object-cache');
ctools_object_cache_clear('download_manager', $id);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment