Index: filefield.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.module,v
retrieving revision 1.176
diff -u -r1.176 filefield.module
--- filefield.module 19 Mar 2009 03:43:37 -0000 1.176
+++ filefield.module 20 Mar 2009 04:51:22 -0000
@@ -33,6 +33,12 @@
'access arguments' => array(3),
'type' => MENU_CALLBACK,
);
+ $items['filefield/progress'] = array(
+ 'page callback' => 'filefield_progress',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
return $items;
}
@@ -492,6 +498,70 @@
}
/**
+ * Menu callback for upload progress.
+ */
+function filefield_progress($key) {
+ $progress = array(
+ 'message' => t('Starting upload...'),
+ 'percentage' => -1,
+ );
+
+ $implementation = filefield_progress_implementation();
+ if ($implementation == 'uploadprogress') {
+ $status = uploadprogress_get_info($key);
+ if (isset($status['bytes_uploaded']) && !empty($status['bytes_total'])) {
+ $progress['message'] = t('Uploading... (@current of @total)', array('@current' => filefield_bytes($status['bytes_uploaded']), '@total' => filefield_bytes($status['bytes_total'])));
+ $progress['percentage'] = round(100 * $status['bytes_uploaded'] / $status['bytes_total']);
+ }
+ }
+ elseif ($implementation == 'apc') {
+ $status = apc_fetch('upload_' . $key);
+ if (isset($status['current']) && !empty($status['total'])) {
+ $progress['message'] = t('Uploading... (@current of @total)', array('@current' => filefield_bytes($status['current']), '@total' => filefield_bytes($status['total'])));
+ $progress['percentage'] = round(100 * $status['current'] / $status['total']);
+ }
+ }
+
+ drupal_json($progress);
+}
+
+/**
+ * Determine which upload progress implementation to use, if any available.
+ */
+function filefield_progress_implementation() {
+ static $implementation;
+ if (!isset($implementation)) {
+ $implementation = FALSE;
+
+ // We prefer the PECL extension uploadprogress because it supports multiple
+ // simultaneous uploads. APC only supports one at a time.
+ if (extension_loaded('uploadprogress')) {
+ $implementation = 'uploadprogress';
+ }
+ elseif (extension_loaded('apc') && ini_get('apc.rfc1867')) {
+ $implementation = 'apc';
+ }
+ }
+ return $implementation;
+}
+
+/**
+ * Pretty-print a MB/KB value.
+ */
+function filefield_bytes($bytes) {
+ if ($bytes > 1073741824) {
+ return t('@size GB', array('@size' => round($bytes / 1073741824, 2)));
+ }
+ elseif ($bytes > 1048576) {
+ return t('@size MB', array('@size' => round($bytes / 1048576, 1)));
+ }
+ else {
+ return t('@size KB', array('@size' => round($bytes / 1024, 0)));
+ }
+}
+
+
+/**
* Implementation of hook_file_references().
*/
function filefield_file_references($file) {
Index: filefield.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.install,v
retrieving revision 1.26
diff -u -r1.26 filefield.install
--- filefield.install 20 Mar 2009 01:02:28 -0000 1.26
+++ filefield.install 20 Mar 2009 04:51:22 -0000
@@ -43,6 +43,56 @@
}
/**
+ * Implementation of hook_requirements().
+ *
+ * Display information about getting upload progress bars working.
+ */
+function filefield_requirements($phase) {
+ $requirements = array();
+ // Ensure translations don't break at install time
+ $t = get_t();
+
+ // Report Drupal version
+ if ($phase == 'runtime') {
+ $implementation = filefield_progress_implementation();
+ $apache = strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') !== FALSE;
+ $php_52 = version_compare(phpversion(), '5.2.0', '>');
+ if (!$apache || !$php_52) {
+ $value = $t('Not enabled');
+ $description = $t('Your server is not capable of displaying file upload progress. File upload progress requires PHP 5.2 and an Apache server.');
+ $severity = REQUIREMENT_INFO;
+ }
+ elseif (!$implementation && extension_loaded('apc')) {
+ $value = $t('Not enabled');
+ $description = $t('Your server is capable of displaying file upload progress through APC, but it is not enabled. Add apc.rfc1867 = 1
to your php.ini configuration. Alternatively, it is recommended to use PECL uploadprogress, which supports more than one simultaneous upload.');
+ $severity = REQUIREMENT_WARNING;
+ }
+ elseif (!$implementation) {
+ $value = $t('Not enabled');
+ $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library (prefered) or to install APC.');
+ $severity = REQUIREMENT_WARNING;
+ }
+ elseif ($implementation == 'apc') {
+ $value = $t('Enabled (APC RFC1867)');
+ $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommneded to use the PECL uploadprogress library if possible.');
+ $severity = REQUIREMENT_OK;
+ }
+ elseif ($implementation == 'uploadprogress') {
+ $value = $t('Enabled (PECL uploadprogress)');
+ $severity = REQUIREMENT_OK;
+ }
+ $requirements['filefield_progress'] = array(
+ 'title' => $t('Upload progress'),
+ 'value' => $value,
+ 'severity' => $severity,
+ 'description' => $description,
+ );
+ }
+
+ return $requirements;
+}
+
+/**
* Implementation of hook_update_last_removed().
*/
function filefield_update_last_removed() {
Index: filefield.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.css,v
retrieving revision 1.19
diff -u -r1.19 filefield.css
--- filefield.css 12 Mar 2009 22:22:25 -0000 1.19
+++ filefield.css 20 Mar 2009 04:51:21 -0000
@@ -61,7 +61,11 @@
padding: 1px 13px 2px 3px; /* RTL */
}
-
+.filefield-element div.ahah-progress-bar {
+ display: none;
+ margin-top: 4px;
+ width: 28em;
+}
/* End general widget form styles. */
Index: filefield.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.js,v
retrieving revision 1.16
diff -u -r1.16 filefield.js
--- filefield.js 9 Mar 2009 05:07:35 -0000 1.16
+++ filefield.js 20 Mar 2009 04:51:22 -0000
@@ -37,7 +37,9 @@
* Prevent FileField uploads when using buttons not intended to upload.
*/
Drupal.behaviors.filefieldButtons = function(context) {
- $('input.form-submit').bind('mousedown', Drupal.filefield.disableFields);
+ $('input.form-submit')
+ .bind('mousedown', Drupal.filefield.disableFields)
+ .bind('mousedown', Drupal.filefield.progressBar);
};
/**
@@ -87,5 +89,26 @@
setTimeout(function(){
$disabledFields.attr('disabled', '');
}, 1000);
+ },
+ progressBar: function(event) {
+ var clickedButton = this;
+ var $progressId = $(clickedButton).parents('div.filefield-element').find('input.filefield-progress');
+ if ($progressId.size()) {
+ var originalName = $progressId.attr('name');
+
+ // Replace the name with the required identifier.
+ $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
+
+ // Restore the original name after the upload begins.
+ setTimeout(function() {
+ $progressId.attr('name', originalName);
+ }, 1000);
+
+ // Show the progress bar if the upload takes longer than 3 seconds.
+ setTimeout(function() {
+ $(clickedButton).parents('div.filefield-element').find('div.ahah-progress-bar').slideDown();
+ }, 500);
+
+ }
}
};
Index: filefield_widget.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield_widget.inc,v
retrieving revision 1.65
diff -u -r1.65 filefield_widget.inc
--- filefield_widget.inc 19 Mar 2009 03:43:37 -0000 1.65
+++ filefield_widget.inc 20 Mar 2009 04:51:22 -0000
@@ -237,6 +237,30 @@
$element['filefield_upload']['#access'] = empty($item['fid']);
$element['filefield_remove']['#access'] = !empty($item['fid']);
+ // Add progress bar support to the upload if possible.
+ if ($implementation = filefield_progress_implementation()) {
+ $upload_progress_key = md5(mt_rand());
+
+ if ($implementation == 'uploadprogress') {
+ $element['UPLOAD_IDENTIFIER'] = array(
+ '#type' => 'hidden',
+ '#value' => $upload_progress_key,
+ '#attributes' => array('class' => 'filefield-progress'),
+ );
+ }
+ elseif ($implementation == 'apc') {
+ $element['APC_UPLOAD_PROGRESS'] = array(
+ '#type' => 'hidden',
+ '#value' => $upload_progress_key,
+ '#attributes' => array('class' => 'filefield-progress'),
+ );
+ }
+
+ // Add the upload progress callback.
+ $element['filefield_upload']['#ahah']['progress']['type'] = 'bar';
+ $element['filefield_upload']['#ahah']['progress']['path'] = 'filefield/progress/' . $upload_progress_key;
+ }
+
// Figure out our fid...
$element['fid'] = array('#type' => 'hidden', '#value' => $item['fid']);