diff --git a/progressbar.class.php b/progressbar.class.php
index 08be927..451a869 100644
--- a/progressbar.class.php
+++ b/progressbar.class.php
@@ -51,155 +51,199 @@
*/
class ProgressBar {
- private $currentProgress;
- private $endProgress;
- private $currentTime;
-
- /**
- * Constructor. Requires $endProgress param.
- * This param should be Integer value indicating, how many iterations
- * will loop, that this progress bar is used in, contain.
- *
- * @param integer $endProgress end progress
- * @throws InvalidArgumentException
- */
- public function __construct($endProgress)
- {
- if (!is_numeric($endProgress) || $endProgress < 1) {
- throw new InvalidArgumentException('Provided end progress value should be numeric.');
- }
- $this->endProgress = $endProgress;
- $this->currentTime = microtime(true);
+ private $currentProgress;
+ private $endProgress;
+ private $currentTime;
+ private $progressChar;
+ private $progressCharColor;
+ private $progressTrack;
+ private $progressTrackColor;
+
+ /**
+ * Constructor. Requires $endProgress param.
+ * This param should be Integer value indicating, how many iterations
+ * will loop, that this progress bar is used in, contain.
+ *
+ * @param integer $endProgress end progress
+ * @throws InvalidArgumentException
+ */
+ public function __construct(
+ $endProgress,
+ $progressChar = "=",
+ $progressTrack = " ",
+ $progressCharColor = "default",
+ $progressTrackColor = "default"
+ ) {
+ if (!is_numeric($endProgress) || $endProgress < 1) {
+ throw new InvalidArgumentException('Provided end progress value should be numeric.');
}
- /**
- * Returns current progress. $currentProgress
- * parameter is optional. If not provided, current progress
- * will be incremented by one.
- *
- * @param int $currentProgress
- * @return string
- * @throws InvalidArgumentException
- */
- public function drawCurrentProgress($currentProgress = null)
- {
- if ($currentProgress !== null) {
- if ($currentProgress < $this->currentProgress) {
- throw new InvalidArgumentException("Provided current progress is smaller than previous one.");
- } else {
- $this->currentProgress = $currentProgress;
- }
- } else {
- $this->currentProgress++;
- }
-
- $progress = $this->currentPercentage();
- $maxWidth = $this->getTerminalWidth();
- $etaNum = $this->getETA($progress);
-
- return $this->buildBar($progress, $maxWidth, $etaNum);
+ $this->endProgress = $endProgress;
+ $this->currentTime = microtime(true);
+ $this->progressChar = $progressChar;
+ $this->progressTrack = $progressTrack;
+ $this->progressCharColor = $progressCharColor;
+ $this->progressTrackColor = $progressTrackColor;
+ }
+
+ /**
+ * Returns current progress. $currentProgress
+ * parameter is optional. If not provided, current progress
+ * will be incremented by one.
+ *
+ * @param int $currentProgress
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public function drawCurrentProgress($currentProgress = null) {
+ if ($currentProgress !== null) {
+ if ($currentProgress < $this->currentProgress) {
+ throw new InvalidArgumentException("Provided current progress is smaller than previous one.");
+ }
+ else {
+ $this->currentProgress = $currentProgress;
+ }
}
-
- /**
- * Calculates current percentage
- * @return int
- */
- private function currentPercentage()
- {
- $progress = $this->currentProgress / $this->endProgress;
-
- return $progress * 100;
+ else {
+ $this->currentProgress++;
}
- /**
- * Builds progress bar row using provided data
- *
- * @param int $progress
- * @param int $maxWidth
- * @param string $etaNum
- * @return string
- */
- private function buildBar($progress, $maxWidth, $etaNum)
- {
- $eta = $etaNum ? '(ETA: ' . $etaNum . ')' : '';
- $percentage = number_format($progress, 2) . "%";
-
- $widthLeft = $maxWidth - 1 - strlen($eta) - 1 - strlen($percentage) - 2;
-
-
- $prgDone = ceil($widthLeft * ($progress / 100));
- $prgNotDone = $widthLeft - $prgDone;
-
- $out = "[" . str_repeat("=", $prgDone) . str_repeat(" ", $prgNotDone) . '] ' . $percentage . ' ' . $eta;
-
- return "\r" . $out;
+ $progress = $this->currentPercentage();
+ $maxWidth = $this->getTerminalWidth();
+ $etaNum = $this->getETA($progress);
+
+ return $this->buildBar($progress, $maxWidth, $etaNum);
+ }
+
+ private function color(string $color, string $text) {
+ $colors = [
+ "black" => "\033[0;30m",
+ "red" => "\033[0;31m",
+ "light-red" => "\033[1;31m",
+ "green" => "\033[0;32m",
+ "light-green" => "\033[1;32m",
+ "brown" => "\033[0;33m",
+ "orange" => "\033[0;33m",
+ "blue" => "\033[0;34m",
+ "light-blue" => "\033[1;34m",
+ "purple" => "\033[0;35m",
+ "light-purple" => "\033[1;35m",
+ "cyan" => "\033[0;36m",
+ "light-cyan" => "\033[1;36m",
+ "light-gray" => "\033[0;37m",
+ "dark-gray" => "\033[1;30m",
+ "yellow" => "\033[1;33m",
+ "white" => "\033[1;37m",
+ "default" => "\033[0m",
+ ];
+
+ if (!array_key_exists($color, $colors)) $color = $colors["default"];
+
+ return $colors[$color] . "{$text}" . $colors['default'];
+ }
+
+ /**
+ * Calculates current percentage
+ * @return int
+ */
+ private function currentPercentage() {
+ $progress = $this->currentProgress / $this->endProgress;
+
+ return $progress * 100;
+ }
+
+ /**
+ * Builds progress bar row using provided data
+ *
+ * @param int $progress
+ * @param int $maxWidth
+ * @param string $etaNum
+ * @return string
+ */
+ private function buildBar($progress, $maxWidth, $etaNum) {
+ $eta = $etaNum ? '(ETA: ' . $etaNum . ')' : '';
+ $percentage = number_format($progress, 2) . "%";
+ $widthLeft = $maxWidth - 1 - strlen($eta) - 1 - strlen($percentage) - 2;
+ $prgDone = ceil($widthLeft * ($progress / 100));
+ $prgNotDone = $widthLeft - $prgDone;
+ $out = "[" . str_repeat($this->color($this->progressCharColor, $this->progressChar), $prgDone) . str_repeat($this->color($this->progressTrackColor, $this->progressTrack), $prgNotDone) . '] ' . $percentage . ' ' . $eta;
+
+ return "\r{$out}";
+ }
+
+ /**
+ * Returns terminal width
+ *
+ * @return int
+ */
+ private function getTerminalWidth() {
+ switch (PHP_OS_FAMILY) {
+ case "Windows":
+ return (int) exec('%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -Command "$Host.UI.RawUI.WindowSize.Width"');
+ case 'Darwin':
+ return (int) exec('/bin/stty/ size | cut -d" " -f2');
+ case 'Linux':
+ return (int) exec('/usr/bin/env tput cols');
+ default:
+ return 0;
}
-
- /**
- * Returns terminal width
- *
- * @return int
- */
- private function getTerminalWidth()
- {
- return exec('tput cols');
+ }
+
+ /**
+ * Calculates and returns ETA with human timing formatting
+ *
+ * @param int $progress
+ * @return string
+ */
+ private function getETA($progress) {
+ $currTime = microtime(true);
+
+ if (!$progress || $progress <= 0 || $progress === false) {
+ return "";
}
- /**
- * Calculates and returns ETA with human timing formatting
- *
- * @param int $progress
- * @return string
- */
- private function getETA($progress)
- {
-
-
- $currTime = microtime(true);
-
- if (!$progress || $progress <= 0 || $progress === false) {
- return "";
- }
-
- try {
- $etaTime = (($currTime - $this->currentTime) / $progress) * (100 - $progress);
-
- $diff = ceil($etaTime);
-
- $eta = $this->humanTiming($diff);
- } catch (Exception $ex) {
- $eta = '';
- }
-
- return $eta;
+ try {
+ $etaTime = (($currTime - $this->currentTime) / $progress) * (100 - $progress);
+ $diff = ceil($etaTime);
+ $eta = $this->humanTiming($diff);
+ }
+ catch (Exception $ex) {
+ $eta = '';
}
- /**
- * Converts numeric time to human-readable format
- *
- * @param int $time
- * @return string
- */
- private function humanTiming($time)
- {
-
- $tokens = array(
- 31536000 => 'y',
- 2592000 => 'mo',
- 604800 => 'w',
- 86400 => 'd',
- 3600 => 'h',
- 60 => 'm',
- 1 => 's'
- );
-
- foreach ($tokens as $unit => $text) {
- if ($time < $unit) {
- continue;
- }
- $numberOfUnits = floor($time / $unit);
- return $numberOfUnits . '' . $text;
- }
+ return $eta;
+ }
+
+ /**
+ * Converts numeric time to human-readable format
+ *
+ * @param int $time
+ * @return string
+ */
+ private function humanTiming($time) {
+ $tokens = [
+ 31536000 => ['year', 'years'],
+ 2592000 => ['month', 'months'],
+ 604800 => ['week', 'weeks'],
+ 86400 => ['day', 'days'],
+ 3600 => ['hour', 'hours'],
+ 60 => ['minute', 'minutes'],
+ 1 => ['second', 'seconds']
+ ];
+
+ $result = '';
+
+ foreach ($tokens as $unit => $labels) {
+ if ($time < $unit) continue;
+
+ $numberOfUnits = floor($time / $unit);
+ $label = $numberOfUnits === 1 ? $labels[0] : $labels[1];
+
+ $result .= ($result ? ' ' : '') . $numberOfUnits . ' ' . $label;
+ $time -= $numberOfUnits * $unit;
}
+ return $result ?: '0 seconds';
+ }
+
}