filefield_nginx_progress.module in FileField Nginx Progress 7
Same filename and directory in other branches
Adds upload progress functionality to FileFields on the nginx webserver.
File
filefield_nginx_progress.moduleView source
<?php
/**
* @file
* Adds upload progress functionality to FileFields on the nginx webserver.
*/
/**
* Implementation of hook_menu().
*/
function filefield_nginx_progress_menu() {
$items = array();
$items['filefield_nginx_progress'] = array(
'page callback' => 'filefield_nginx_progress_ajax',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Menu callback for nginx upload progress.
*/
function filefield_nginx_progress_ajax($key) {
$progress = array(
'message' => t('Starting upload...'),
'percentage' => -1,
);
$status = nginx_progress_fetch($key);
if ($status['state'] == 'uploading') {
$progress['message'] = t('Uploading... (@current of @total)', array(
'@current' => format_size($status['received']),
'@total' => format_size($status['size']),
));
$progress['percentage'] = round(100 * $status['received'] / $status['size']);
}
drupal_json_output($progress);
}
/**
* Implementation of hook_element_info().
*/
function filefield_nginx_progress_element_info() {
$elements = array();
foreach (module_invoke_all('filefield_nginx_progress_widgets') as $widget) {
$elements[$widget]['#process'] = array(
'filefield_nginx_progress_element_process',
);
}
return $elements;
}
/**
* Implementation of hook_filefield_nginx_progress_widgets().
*
* This returns a list of widgets that are compatible with FileField Nginx Progress.
*/
function filefield_nginx_progress_filefield_nginx_progress_widgets() {
return array(
'managed_file',
);
}
/**
* A #process callback to extend the file_widget element type.
*
* To get the field working with nginx upload progress, we need to enable the progress bar
* and modify the ahah paths to work with the nginx redirection.
*/
function filefield_nginx_progress_element_process($element, &$form_state, $form) {
// Generate upload progress key
$upload_progress_key = mt_rand();
// Nginx really wants us to send a get value, but form_expand_ahah doesn't
// allow query strings in paths. The work around is to add the progress id
// into the path and to rewrite at the nginx level to the required url.
$element['upload_button']['#ajax']['path'] .= '/x-progress-id:' . $upload_progress_key;
// Add the upload key to the form, in a manner compatible with the existing
// javascript
$element['UPLOAD_IDENTIFIER'] = array(
'#type' => 'hidden',
'#value' => $upload_progress_key,
'#attributes' => array(
'class' => array(
'file-progress',
),
),
);
// Unset this as a precaution in the unlikely event that apc upload progress
// is enabled in php.ini
unset($element['APC_UPLOAD_PROGRESS']);
// Enable the progress bar
$element['upload_button']['#ajax']['progress']['type'] = 'bar';
// Modify the upload progress callback to use our own menu callback.
$element['upload_button']['#ajax']['progress']['path'] = 'filefield_nginx_progress/' . $upload_progress_key;
return $element;
}
/**
* Fetch the upload progress from nginx using the X-Progress-ID parameter
*
* Since the javascript returned by the progress tracking in nginx is not
* compatible with the ahah progress bar, we need to get drupal to issue an
* http request and then parse the response.
*
*/
function nginx_progress_fetch($key) {
// Find root url of server
$domain = $_SERVER['HTTP_HOST'];
$proto = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
$base_url = $proto . $domain;
$url = url($base_url . '/progress', array(
'query' => array(
'X-Progress-ID' => $key,
),
'absolute' => TRUE,
'external' => TRUE,
));
$response = drupal_http_request($url);
$status = array();
// strip the extraneous parts out leaving a comma delimited list.
if (preg_match("/\\{(.*)\\}/", $response->data, $matches)) {
$items = explode(',', $matches[1]);
foreach ($items as $item) {
$array = explode(':', $item);
// strip quotes and spaces from key & value pair
$key = trim($array[0], "' ");
$value = trim($array[1], "' ");
$status[$key] = $value;
}
}
return $status;
}
Functions
Name![]() |
Description |
---|---|
filefield_nginx_progress_ajax | Menu callback for nginx upload progress. |
filefield_nginx_progress_element_info | Implementation of hook_element_info(). |
filefield_nginx_progress_element_process | A #process callback to extend the file_widget element type. |
filefield_nginx_progress_filefield_nginx_progress_widgets | Implementation of hook_filefield_nginx_progress_widgets(). |
filefield_nginx_progress_menu | Implementation of hook_menu(). |
nginx_progress_fetch | Fetch the upload progress from nginx using the X-Progress-ID parameter |