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('ajax clock '); - $('#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('ajax clock '); + $('#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('ajax clock '); - $('#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('
ajax clock
') + .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('ajax clock ') + .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('ajax clock '); + $('#upload_form_status_info').html('ajax clock '); $('#upload_form_status').css("display", "none");