diff --git a/core/includes/batch.inc b/core/includes/batch.inc index 2152725..3fe9bb0 100644 --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -14,6 +14,7 @@ * @see batch_get() */ +use Drupal\Core\Batch\Percentage; use \Symfony\Component\HttpFoundation\JsonResponse; /** @@ -329,27 +330,7 @@ function _batch_process() { * @see _batch_process() */ function _batch_api_percentage($total, $current) { - if (!$total || $total == $current) { - // If $total doesn't evaluate as true or is equal to the current set, then - // we're finished, and we can return "100". - $percentage = "100"; - } - else { - // 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); - 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; + return Percentage::format($total, $current); } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/Batch/PercentagesUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Batch/PercentagesUnitTest.php deleted file mode 100644 index 5b92b19..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Batch/PercentagesUnitTest.php +++ /dev/null @@ -1,102 +0,0 @@ - 'Batch percentages', - 'description' => 'Unit tests of progress percentage rounding.', - 'group' => 'Batch API', - ); - } - - function setUp() { - // Set up an array of test cases, where the expected values are the keys, - // and the values are arrays with the keys 'total' and 'current', - // corresponding with the function parameters of _batch_api_percentage(). - $this->testCases = array( - // 1/2 is 50%. - '50' => array('total' => 2, 'current' => 1), - // Though we should never encounter a case where the current set is set - // 0, if we did, we should get 0%. - '0' => array('total' => 3, 'current' => 0), - // 1/3 is closer to 33% than to 34%. - '33' => array('total' => 3, 'current' => 1), - // 2/3 is closer to 67% than to 66%. - '67' => array('total' => 3, 'current' => 2), - // 1/199 should round up to 1%. - '1' => array('total' => 199, 'current' => 1), - // 198/199 should round down to 99%. - '99' => array('total' => 199, 'current' => 198), - // 199/200 would have rounded up to 100%, which would give the false - // impression of being finished, so we add another digit and should get - // 99.5%. - '99.5' => array('total' => 200, 'current' => 199), - // The same logic holds for 1/200: we should get 0.5%. - '0.5' => array('total' => 200, 'current' => 1), - // Numbers that come out evenly, such as 50/200, should be forced to have - // extra digits for consistancy. - '25.0' => array('total' => 200, 'current' => 50), - // Regardless of number of digits we're using, 100% should always just be - // 100%. - '100' => array('total' => 200, 'current' => 200), - // 1998/1999 should similarly round down to 99.9%. - '99.9' => array('total' => 1999, 'current' => 1998), - // 1999/2000 should add another digit and go to 99.95%. - '99.95' => array('total' => 2000, 'current' => 1999), - // 19999/20000 should add yet another digit and go to 99.995%. - '99.995' => array('total' => 20000, 'current' => 19999), - // The next five test cases simulate a batch with a single operation - // ('total' equals 1) that takes several steps to complete. Within the - // operation, we imagine that there are 501 items to process, and 100 are - // completed during each step. The percentages we get back should be - // rounded the usual way for the first few passes (i.e., 20%, 40%, etc.), - // but for the last pass through, when 500 out of 501 items have been - // processed, we do not want to round up to 100%, since that would - // erroneously indicate that the processing is complete. - '20' => array('total' => 1, 'current' => 100/501), - '40' => array('total' => 1, 'current' => 200/501), - '60' => array('total' => 1, 'current' => 300/501), - '80' => array('total' => 1, 'current' => 400/501), - '99.8' => array('total' => 1, 'current' => 500/501), - ); - require_once DRUPAL_ROOT . '/core/includes/batch.inc'; - parent::setUp(); - } - - /** - * Tests the _batch_api_percentage() function. - */ - function testBatchPercentages() { - foreach ($this->testCases as $expected_result => $arguments) { - // PHP sometimes casts numeric strings that are array keys to integers, - // cast them back here. - $expected_result = (string) $expected_result; - $total = $arguments['total']; - $current = $arguments['current']; - $actual_result = _batch_api_percentage($total, $current); - if ($actual_result === $expected_result) { - $this->pass(format_string('Expected the batch api percentage at the state @numerator/@denominator to be @expected%, and got @actual%.', array('@numerator' => $current, '@denominator' => $total, '@expected' => $expected_result, '@actual' => $actual_result))); - } - else { - $this->fail(format_string('Expected the batch api percentage at the state @numerator/@denominator to be @expected%, but got @actual%.', array('@numerator' => $current, '@denominator' => $total, '@expected' => $expected_result, '@actual' => $actual_result))); - } - } - } -}