Fixes #15358: Refactored BaseConsole::updateProgress()

This commit is contained in:
Elvira Sheina
2017-12-18 07:43:03 +00:00
committed by Alexander Makarov
parent 0bec2b462c
commit 717d0e80d3
2 changed files with 58 additions and 33 deletions

View File

@ -35,6 +35,7 @@ Yii Framework 2 Change Log
- Enh #15332: Always check for availability of `openssl_pseudo_random_bytes`, even if LibreSSL is available (sammousa)
- Enh #15335: Added `FileHelper::unlink()` that works well under all OSes (samdark)
- Enh #15340: Test CHANGELOG.md for valid format (sammousa)
- Enh #15358: Refactored `BaseConsole::updateProgress()` (developeruz)
- Bug #15317: Regenerate CSRF token if an empty value is given (sammousa)

View File

@ -957,46 +957,16 @@ class BaseConsole
*/
public static function updateProgress($done, $total, $prefix = null)
{
$width = self::$_progressWidth;
if ($width === false) {
$width = 0;
} else {
$screenSize = static::getScreenSize(true);
if ($screenSize === false && $width < 1) {
$width = 0;
} elseif ($width === null) {
$width = $screenSize[0];
} elseif ($width > 0 && $width < 1) {
$width = floor($screenSize[0] * $width);
}
}
if ($prefix === null) {
$prefix = self::$_progressPrefix;
} else {
self::$_progressPrefix = $prefix;
}
$width -= static::ansiStrlen($prefix);
$width = static::getProgressbarWidth($prefix);
$percent = ($total == 0) ? 1 : $done / $total;
$info = sprintf('%d%% (%d/%d)', $percent * 100, $done, $total);
if ($done > $total || $done == 0) {
self::$_progressEta = null;
self::$_progressEtaLastUpdate = time();
} elseif ($done < $total) {
// update ETA once per second to avoid flapping
if (time() - self::$_progressEtaLastUpdate > 1 && $done > self::$_progressEtaLastDone) {
$rate = (time() - (self::$_progressEtaLastUpdate ?: self::$_progressStart)) / ($done - self::$_progressEtaLastDone);
self::$_progressEta = $rate * ($total - $done);
self::$_progressEtaLastUpdate = time();
self::$_progressEtaLastDone = $done;
}
}
if (self::$_progressEta === null) {
$info .= ' ETA: n/a';
} else {
$info .= sprintf(' ETA: %d sec.', self::$_progressEta);
}
self::setETA($done, $total);
$info .= self::$_progressEta === null ? ' ETA: n/a' : sprintf(' ETA: %d sec.', self::$_progressEta);
// Number extra characters outputted. These are opening [, closing ], and space before info
// Since Windows uses \r\n\ for line endings, there's one more in the case
@ -1022,6 +992,60 @@ class BaseConsole
flush();
}
/**
* Return width of the progressbar
* @param string $prefix an optional string to display before the progress bar.
* @see updateProgress
* @return int screen width
* @since 2.0.14
*/
private static function getProgressbarWidth($prefix)
{
$width = self::$_progressWidth;
if ($width === false) {
return 0;
}
$screenSize = static::getScreenSize(true);
if ($screenSize === false && $width < 1) {
return 0;
}
if ($width === null) {
$width = $screenSize[0];
} elseif ($width > 0 && $width < 1) {
$width = floor($screenSize[0] * $width);
}
$width -= static::ansiStrlen($prefix);
return $width;
}
/**
* Calculate $_progressEta, $_progressEtaLastUpdate and $_progressEtaLastDone
* @param int $done the number of items that are completed.
* @param int $total the total value of items that are to be done.
* @see updateProgress
* @since 2.0.14
*/
private static function setETA($done, $total)
{
if ($done > $total || $done == 0) {
self::$_progressEta = null;
self::$_progressEtaLastUpdate = time();
return;
}
if ($done < $total && (time() - self::$_progressEtaLastUpdate > 1 && $done > self::$_progressEtaLastDone)) {
$rate = (time() - (self::$_progressEtaLastUpdate ?: self::$_progressStart)) / ($done - self::$_progressEtaLastDone);
self::$_progressEta = $rate * ($total - $done);
self::$_progressEtaLastUpdate = time();
self::$_progressEtaLastDone = $done;
}
}
/**
* Ends a progress bar that has been started by [[startProgress()]].
*