diff --git a/Documentation.html b/Documentation.html
index fdd519c9ea..dd08e4438f 100644
--- a/Documentation.html
+++ b/Documentation.html
@@ -3399,11 +3399,16 @@ RewriteRule .* - [F]
2.9 Seeing an upload progress bar
To be able to see a progress bar during your uploads, your server must
-have either the APC extension
- or the uploadprogress
- one. Moreover, the JSON extension has to be enabled in your PHP.
+ have the APC extension,
+ the uploadprogress
+ one, or you must be running PHP 5.4.0 or higher.
+ Moreover, the JSON extension has to be enabled in your PHP.
+
If using APC, you must set apc.rfc1867 to on in your php.ini.
+ If using PHP 5.4.0 or higher, you must set session.upload_progress.enabled
+ to 1 in your php.ini.
+
Known limitations
diff --git a/js/codemirror/mode/mysql/mysql.js b/js/codemirror/mode/mysql/mysql.js
index 94b89a5e27..ca07c26f14 100644
--- a/js/codemirror/mode/mysql/mysql.js
+++ b/js/codemirror/mode/mysql/mysql.js
@@ -25,7 +25,7 @@ CodeMirror.defineMode("mysql", function(config, parserConfig) {
// start of string?
if (ch == '"' || ch == "'" || ch == '`')
return chain(stream, state, tokenString(ch));
- // is it one of the special signs []{}().,;? Seperator?
+ // is it one of the special signs []{}().,;? separator?
else if (/[\[\]{}\(\),;\.]/.test(ch))
return ret(ch, "separator");
// start of a number value?
diff --git a/js/functions.js b/js/functions.js
index 8c3cf665e9..30e5511ce0 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -3644,6 +3644,30 @@ function toggleRowColors($start)
}
}
+/**
+ * Formats a byte number to human-readable form
+ *
+ * @param bytes the bytes to format
+ * @param optional subdecimals the number of digits after the point
+ * @param optional pointchar the char to use as decimal point
+ */
+function formatBytes(bytes, subdecimals, pointchar) {
+ if (!subdecimals) {
+ var subdecimals = 0;
+ }
+ if (!pointchar) {
+ var pointchar = '.';
+ }
+ var units = ['B', 'KiB', 'MiB', 'GiB'];
+ for (var i = 0; bytes > 1024 && i < units.length; i++) {
+ bytes /= 1024;
+ }
+ var factor = Math.pow(10, subdecimals);
+ bytes = Math.round(bytes * factor) / factor;
+ bytes = bytes.toString().split('.').join(pointchar);
+ return bytes + ' ' + units[i];
+}
+
/**
* Opens pma more themes link in themes browser, in new window instead of popup
* This way, we don't break HTML validity
diff --git a/js/import.js b/js/import.js
index ec5fc9b5da..04f5217a4d 100644
--- a/js/import.js
+++ b/js/import.js
@@ -38,7 +38,6 @@ function matchFile(fname)
}
// Only toggle if the format of the file can be imported
if($("select[name='format'] option").filterByValue(fname_array[len - 1]).length == 1) {
- $("#plugins option:selected").removeProp("selected");
$("select[name='format'] option").filterByValue(fname_array[len - 1]).prop('selected', true);
changePluginOpts();
}
@@ -65,7 +64,7 @@ $(document).ready(function() {
* When the "Browse the server" form is clicked or the "Select from the web server upload directory"
* form is clicked, the radio button beside it becomes selected and the other form becomes disabled.
*/
- $("#input_import_file").focus(function() {
+ $("#input_import_file").bind("focus change", function() {
$("#radio_import_file").prop('checked', true);
$("#radio_local_import_file").removeProp('checked');
});
diff --git a/js/jquery/timepicker.js b/js/jquery/timepicker.js
index 41e3ea005d..8425ab5b91 100644
--- a/js/jquery/timepicker.js
+++ b/js/jquery/timepicker.js
@@ -209,7 +209,7 @@ $.extend(Timepicker.prototype, {
// the time should come after x number of characters and a space.
// x = at least the length of text specified by the date format
var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
- // escape special regex characters in the seperator
+ // escape special regex characters in the separator
var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");
regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr;
}
diff --git a/js/messages.php b/js/messages.php
index bc10c3fd53..16a3d51e17 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -69,9 +69,9 @@ $js_messages['strTotal'] = __('Total');
/* l10n: Other, small valued, queries */
$js_messages['strOther'] = __('Other');
/* l10n: Thousands separator */
-$js_messages['strThousandsSeperator'] = __(',');
+$js_messages['strThousandsSeparator'] = __(',');
/* l10n: Decimal separator */
-$js_messages['strDecimalSeperator'] = __('.');
+$js_messages['strDecimalSeparator'] = __('.');
$js_messages['strChartKBSent'] = __('KiB sent since last refresh');
$js_messages['strChartKBReceived'] = __('KiB received since last refresh');
diff --git a/js/server_status.js b/js/server_status.js
index 893fb34d0d..31a9471d81 100644
--- a/js/server_status.js
+++ b/js/server_status.js
@@ -25,8 +25,8 @@ $(function() {
},
format: function(s) {
var num = jQuery.tablesorter.formatFloat(
- s.replace(PMA_messages['strThousandsSeperator'], '')
- .replace(PMA_messages['strDecimalSeperator'], '.')
+ s.replace(PMA_messages['strThousandsSeparator'], '')
+ .replace(PMA_messages['strDecimalSeparator'], '.')
);
var factor = 1;
diff --git a/libraries/common.lib.php b/libraries/common.lib.php
index 5a3ed9d02f..21787b34c1 100644
--- a/libraries/common.lib.php
+++ b/libraries/common.lib.php
@@ -1587,7 +1587,7 @@ function PMA_formatNumber(
$value = round($value / (PMA_pow(1000, $d, 'pow') / $dh)) /$dh;
$unit = $units[$d];
- // If we dont want any zeros after the comma just add the thousand seperator
+ // If we dont want any zeros after the comma just add the thousand separator
if ($noTrailingZero) {
$value = PMA_localizeNumber(
preg_replace('/(?<=\d)(?=(\d{3})+(?!\d))/', ',', $value)
@@ -3515,7 +3515,7 @@ function PMA_createGISData($gis_string)
* that are applicable to the provided geometry type.
* @param bool $binary if set to false functions that take two geometries
* as arguments will not be included.
- * @param bool $display if set to true seperators will be added to the
+ * @param bool $display if set to true separators will be added to the
* output array.
*
* @return array names and details of the functions that can be applied on
@@ -3576,7 +3576,7 @@ function PMA_getGISFunctions($geom_type = null, $binary = true, $display = false
// If we are asked for binary functions as well
if ($binary) {
- // section seperator
+ // section separator
if ($display) {
$funcs[] = array('display' => '--------');
}
diff --git a/libraries/display_import.lib.php b/libraries/display_import.lib.php
index 656f5844a0..080239f651 100644
--- a/libraries/display_import.lib.php
+++ b/libraries/display_import.lib.php
@@ -40,19 +40,14 @@ if (empty($import_list)) {
- $('#upload_form_status').html(''); // add the progress bar
-
var finished = false;
var percent = 0.0;
var total = 0;
var complete = 0;
+ var original_title = parent && parent.document ? parent.document.title : false;
+ var import_start;
- var perform_upload;
- var periodical_upload;
-
- var request_upload = [];
-
- perform_upload = function () {
+ var perform_upload = function () {
new $.getJSON(
'import_status.php?id=&',
{},
@@ -62,40 +57,94 @@ if ($_SESSION[$SESSION_KEY]["handler"]!="noplugin") {
total = response.total;
complete = response.complete;
- if (total==0 && complete==0 && percent==0) {
- $('#upload_form_status_info').html('
');
- $('#upload_form_status').css("display", "none");
- } else {
- $('#upload_form_status_info').html(' '+Math.round(percent)+'%, '+complete+'/'+total);
- $('#status').animate({width: Math.round(percent)*2+'px'},150);
- } // else
+ if (total==0 && complete==0 && percent==0) {
+ $('#upload_form_status_info').html('
');
+ $('#upload_form_status').css("display", "none");
+ } else {
+ var now = new Date();
+ now = Date.UTC(
+ now.getFullYear(), now.getMonth(), now.getDate(),
+ now.getHours(), now.getMinutes(), now.getSeconds())
+ + now.getMilliseconds() - 1000;
+ var statustext =
+ formatBytes(complete, 1, PMA_messages.strDecimalSeparator)
+ + ' '
+ + formatBytes(total, 1, PMA_messages.strDecimalSeparator);
- if (finished==true) {
- $('#importmain').css('display', 'none');
- $('#import_form_status').css('display', 'inline');
- $('#import_form_status').html('
');
- $('#import_form_status').load('import_status.php?message=true&'); // loads the message, either success or mysql error
-
+ if ($('#importmain').is(':visible')) {
+ // show progress UI
+ $('#importmain').hide();
+ $('#import_form_status')
+ .html('')
+ .show();
+ import_start = now;
+ }
+ else if (percent > 9 || complete > 2000000) {
+ // calculate estimated time
+ var used_time = now - import_start;
+ var seconds = parseInt(((total - complete) / complete) * used_time / 1000);
+ var speed = ''
+ .replace('%s', formatBytes(complete / used_time * 1000, 1, PMA_messages.strDecimalSeparator));
- } // if finished
- else {
- window.setTimeout(perform_upload, 1000);
- }
+ var minutes = parseInt(seconds / 60);
+ seconds %= 60;
+ var estimated_time;
+ if (minutes > 0) {
+ estimated_time = ''
+ .replace('%MIN', minutes).replace('%SEC', seconds);
+ }
+ else {
+ estimated_time = ''
+ .replace('%SEC', seconds);
+ }
- }
- );
+ statustext += '
' + speed + '
' + estimated_time;
+ }
- }
- window.setTimeout(perform_upload, 1000);
+ var percent_str = Math.round(percent) + '%';
+ $('#status').animate({width: percent_str}, 150);
+ $('.percentage').text(percent_str);
+
+ // show percent in window title
+ if (original_title !== false) {
+ parent.document.title = percent_str + ' - ' + original_title;
+ }
+ else {
+ document.title = percent_str + ' - ' + original_title;
+ }
+ $('#statustext').html(statustext);
+ } // else
+
+ if (finished == true) {
+ if (original_title !== false) {
+ parent.document.title = original_title;
+ }
+ else {
+ document.title = original_title;
+ }
+ $('#importmain').hide();
+ $('#import_form_status')
+ .html('
')
+ .show();
+ $('#import_form_status').load('import_status.php?message=true&'); // loads the message, either success or mysql error
+
+
+ } // if finished
+ else {
+ setTimeout(perform_upload, 1000);
+ }
+ });
+ }
+ setTimeout(perform_upload, 1000);
- $('#upload_form_status_info').html('
');
+ $('#upload_form_status_info').html('
');
$('#upload_form_status').css("display", "none");