summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/batch.inc18
1 files changed, 16 insertions, 2 deletions
diff --git a/includes/batch.inc b/includes/batch.inc
index 7011abfbd..727c62560 100644
--- a/includes/batch.inc
+++ b/includes/batch.inc
@@ -339,6 +339,8 @@ function _batch_process() {
$progress_message = $old_set['progress_message'];
}
+ // Total progress is the number of operations that have fully run plus the
+ // completion level of the current operation.
$current = $total - $remaining + $finished;
$percentage = _batch_api_percentage($total, $current);
$elapsed = isset($current_set['elapsed']) ? $current_set['elapsed'] : 0;
@@ -373,7 +375,10 @@ function _batch_process() {
* @param $total
* The total number of operations.
* @param $current
- * The number of the current operation.
+ * The number of the current operation. This may be a floating point number
+ * rather than an integer in the case of a multi-step operation that is not
+ * yet complete; in that case, the fractional part of $current represents the
+ * fraction of the operation that has been completed.
* @return
* The properly formatted percentage, as a string. We output percentages
* using the correct number of decimal places so that we never print "100%"
@@ -390,7 +395,16 @@ function _batch_api_percentage($total, $current) {
// We add a new digit at 200, 2000, etc. (since, for example, 199/200
// would round up to 100% if we didn't).
$decimal_places = max(0, floor(log10($total / 2.0)) - 1);
- $percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
+ do {
+ // Calculate the percentage to the specified number of decimal places.
+ $percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
+ // When $current is an integer, the above calculation will always be
+ // correct. However, if $current is a floating point number (in the case
+ // of a multi-step batch operation that is not yet complete), $percentage
+ // may be erroneously rounded up to 100%. To prevent that, we add one
+ // more decimal place and try again.
+ $decimal_places++;
+ } while ($percentage == '100');
}
return $percentage;
}