Last active
May 26, 2020 07:24
-
-
Save anon5r/6f4db87cb03272ffff957718f16044c1 to your computer and use it in GitHub Desktop.
Progressbar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Progressbar | |
{ | |
//private $cursor = ['|', '/', '-', '\\']; | |
private $cursor = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏']; | |
private $spacer = '░'; | |
private $indicator = "\033[7m \033[0m"; | |
private $total = 0; | |
private $fulfilled = 100; | |
private $width = 0; | |
private $_callCount = 0; | |
private $progressUnit = ''; | |
private $processLabel = 'Process'; | |
private $msgStart = null; | |
private $msgProcessing = null; | |
private $msgComplete = null; | |
private $taskComplete = null; | |
private $useTaskByBytes = false; | |
private $useCursor = false; | |
private $_format = null; | |
/** | |
* Progressbar constructor. | |
* @param int $total Total value | |
* @param int $width Progress bar width | |
* @param int $fulfilled progress fulfilled value like 100% | |
* @param string $progressUnit with unit label likes '%' | |
*/ | |
public function __construct($total, $width, $fulfilled, $progressUnit = '') | |
{ | |
$this->total = $total; | |
$this->width = $width; | |
$this->fulfilled = $fulfilled; | |
$this->progressUnit = $progressUnit; | |
} | |
/** | |
* set process message | |
* Default: | |
* - when starting, label with "start" | |
* - when processing, label with "ing..." | |
* - when complete, label with " complete!" | |
* @param string $label processing label message | |
* @return $this | |
*/ | |
public function setProcessingLabel(string $label) | |
{ | |
$this->processLabel = $label; | |
return $this; | |
} | |
/** | |
* @param string $unit | |
* @return $this | |
*/ | |
public function setProgressUnit(string $unit) | |
{ | |
$this->progressUnit = $unit; | |
return $this; | |
} | |
/** | |
* | |
* @param string $label | |
* @return $this | |
*/ | |
public function setLabelStart(string $label) | |
{ | |
$this->msgStart = $label; | |
return $this; | |
} | |
/** | |
* @param string $label | |
* @return $this | |
*/ | |
public function setLabelProcessing(string $label) | |
{ | |
$this->msgProcessing = $label; | |
return $this; | |
} | |
/** | |
* @param string $label | |
* @return $this | |
*/ | |
public function setLabelComplete(string $label) | |
{ | |
$this->msgComplete = $label; | |
return $this; | |
} | |
/** | |
* @param string $complete | |
* @return $this | |
*/ | |
public function setTaskComplete($complete) | |
{ | |
$this->taskComplete = $complete; | |
return $this; | |
} | |
/** | |
* @param bool $bool | |
* @return $this | |
*/ | |
public function setUseTasksByBytes(bool $bool) | |
{ | |
$this->useTaskByBytes = (bool)$bool; | |
return $this; | |
} | |
/** | |
* @param bool $bool | |
* @return $this | |
*/ | |
public function setUseCursor(bool $bool) | |
{ | |
$this->useCursor = (bool)$bool; | |
return $this; | |
} | |
/** | |
* Default cursor is ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ | |
* @param array $cursor ['|', '/', '-', '\\'] | |
* @return $this | |
*/ | |
public function setCustomCursors(array $cursor) | |
{ | |
$this->cursor = $cursor; | |
return $this; | |
} | |
private function _generateFormat() | |
{ | |
if (!$this->processLabel) | |
$this->processLabel = 'Process'; | |
$this->msgStart = $this->msgStart ?? $this->processLabel . ' start'; | |
$this->msgProcessing = $this->msgProcessing ?? $this->processLabel . 'ing...'; | |
$this->msgComplete = $this->msgComplete ?? $this->processLabel . ' complete!'; | |
$labelLength = strlen($this->processLabel); | |
$labelLength = $labelLength < strlen($this->msgStart) ? strlen($this->msgStart) : $labelLength; | |
$labelLength = $labelLength < strlen($this->msgProcessing) ? strlen($this->msgProcessing) : $labelLength; | |
$labelLength = $labelLength < strlen($this->msgComplete) ? strlen($this->msgComplete) : $labelLength; | |
$labelLength += 1; | |
$maxMargin = strlen($this->fulfilled) + 1; | |
$this->progressUnit = str_replace('%', '%%', $this->progressUnit); | |
// Label | |
$format = '%-' . $labelLength . 's '; | |
// Cursor | |
if ($this->useCursor) | |
$format .= '%s '; | |
// Indicator with process | |
//$format .= '[%-' . $this->width . 's]%' . $maxMargin . 'd' . $this->progressUnit; | |
$format .= '[%s%s]%' . $maxMargin . 'd' . $this->progressUnit; | |
// Task | |
if ($this->taskComplete != null) { | |
$taskMargin = $this->useTaskByBytes ? 7 : strlen($this->taskComplete); | |
$format .= ' (%' . $taskMargin . 's/%' . $taskMargin . 's)'; | |
} | |
$this->_format = $format; | |
} | |
/** | |
* @param int $current value like progress percentage | |
* @param int $currentTask task complete of current | |
*/ | |
public function drawProgressBar($current = null, $currentTask = null) | |
{ | |
if ($this->_format == null) | |
$this->_generateFormat(); | |
$progress = (floor(($current / $this->fulfilled) * $this->width)); | |
$indicator = str_repeat($this->indicator, $progress); | |
$spacer = str_repeat($this->spacer, ($this->width - $progress)); | |
$params = []; | |
// Label | |
if ($current < 1) | |
$params[] = $this->msgStart; | |
elseif ($this->fulfilled <= $current) | |
$params[] = $this->msgComplete; | |
else | |
$params[] = $this->msgProcessing; | |
// Cursor | |
if ($this->useCursor) { | |
$cNum = count($this->cursor); | |
$params[] = $this->cursor[$this->_callCount % $cNum]; | |
$this->_callCount++; | |
} | |
// Indicator with progress | |
$params[] = $indicator; | |
// Spacer | |
$params[] = $spacer; | |
$params[] = $current; | |
// Task | |
if ($this->taskComplete !== null && $currentTask !== null) { | |
$params[] = $this->useTaskByBytes ? self::convertBytesToHumanReadable($currentTask) : $currentTask; | |
$params[] = $this->useTaskByBytes ? self::convertBytesToHumanReadable($this->taskComplete) : $this->taskComplete; | |
} | |
echo "\r"; // Return the drawing cursor to the line head | |
vprintf($this->_format, $params); | |
flush(); | |
} | |
/** | |
* Convert string of byte size to bytes integer. | |
* @param string $val | |
* @return int|string | |
*/ | |
public static function convertToBytes($val) | |
{ | |
$val = trim($val); | |
$last = strtolower($val[strlen($val) - 1]); | |
$val = intval(substr($val, 0, -1)); | |
switch ($last) { | |
case 't': | |
$val *= 1024; | |
// no break | |
case 'g': | |
$val *= 1024; | |
// no break | |
case 'm': | |
$val *= 1024; | |
// no break | |
case 'k': | |
$val *= 1024; | |
} | |
return $val; | |
} | |
/** | |
* @param int $size | |
* @param int $precision | |
* @return string | |
*/ | |
public static function convertBytesToHumanReadable($size, $precision = 2) { | |
for($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {} | |
return round($size, $precision).['B','kB','MB','GB','TB','PB','EB','ZB','YB'][$i]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$total = 3000; | |
$barWidth = 50; | |
$max = 100; | |
$unit = '%'; | |
$progress = new Progressbar($total, $barWidth, $max, $unit); | |
$progress | |
->setLabelStart('Start!') | |
->setLabelProcessing('Loading...') | |
->setLabelComplete('Complete!') | |
->setProgressUnit('%') | |
->setUseCursor(true) | |
->setUseTasksByBytes(false) | |
->setTaskComplete($total) | |
; | |
$progress->drawProgressBar(0, 0); | |
// Start! ⠋ [ ] 0% ( 0/128) | |
for ($i = 0; $i < $total; $i++) { | |
$progress->drawProgressBar(floor(($i / $total) * 100), $i); | |
usleep(1000); | |
} | |
// Loading... ⠹ [ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 24% ( 31/128) | |
$progress->drawProgressBar(100, $i); | |
// Complete! ⠏ [ ] 100% (128/128) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment