/* Decoded by unphp.net */ charset); } public static function ansiColorizedSubstr($string, $start, $length) { if ($start < 0 || $length <= 0) { return ''; } $textItems = preg_split(self::ansiCodesPattern(), (string) $string); preg_match_all(self::ansiCodesPattern(), (string) $string, $colors); $colors = count($colors) ? $colors[0] : array(); array_unshift($colors, ''); $result = ''; $curPos = 0; $inRange = false; foreach ($textItems as $k => $textItem) { $color = $colors[$k]; if ($curPos <= $start && $start < $curPos + Console::ansiStrwidth($textItem)) { $text = mb_substr($textItem, $start - $curPos, null, Yii::$app->charset); $inRange = true; } else { $text = $textItem; } if ($inRange) { $result .= $color . $text; $diff = $length - Console::ansiStrwidth($result); if ($diff <= 0) { if ($diff < 0) { $result = mb_substr($result, 0, $diff, Yii::$app->charset); } $defaultColor = static::renderColoredString("%n"); if ($color && $color != $defaultColor) { $result .= $defaultColor; } break; } } $curPos += mb_strlen($textItem, Yii::$app->charset); } return $result; } private static function ansiCodesPattern() { return "/\033\[[\d;?]*\w/"; } public static function ansiToHtml($string, $styleMap = array()) { $styleMap = array(self::FG_BLACK => array("color" => "black"), self::FG_BLUE => array("color" => "blue"), self::FG_CYAN => array("color" => "aqua"), self::FG_GREEN => array("color" => "lime"), self::FG_GREY => array("color" => "silver"), self::FG_PURPLE => array("color" => "rebeccapurple"), self::FG_RED => array("color" => "red"), self::FG_YELLOW => array("color" => "yellow"), self::BG_BLACK => array("background-color" => "black"), self::BG_BLUE => array("background-color" => "blue"), self::BG_CYAN => array("background-color" => "aqua"), self::BG_GREEN => array("background-color" => "lime"), self::BG_GREY => array("background-color" => "silver"), self::BG_PURPLE => array("background-color" => "rebeccapurple"), self::BG_RED => array("background-color" => "red"), self::BG_YELLOW => array("background-color" => "yellow"), self::BOLD => array("font-weight" => "bold"), self::ITALIC => array("font-style" => "italic"), self::UNDERLINE => array("text-decoration" => array("underline")), self::OVERLINED => array("text-decoration" => array("overline")), self::CROSSED_OUT => array("text-decoration" => array("line-through")), self::BLINK => array("text-decoration" => array("blink")), self::CONCEALED => array("visibility" => "hidden")) + $styleMap; $tags = 0; $result = preg_replace_callback("/\033\[([\d;]+)m/", function ($ansi) use(&$tags, $styleMap) { $style = array(); $reset = false; $negative = false; foreach (explode(";", $ansi[1]) as $controlCode) { if ($controlCode == 0) { $style = array(); $reset = true; } elseif ($controlCode == self::NEGATIVE) { $negative = true; } elseif (isset($styleMap[$controlCode])) { $style[] = $styleMap[$controlCode]; } } $return = ''; while ($reset && $tags > 0) { $return .= ""; $tags--; } if (empty($style)) { return $return; } $currentStyle = array(); foreach ($style as $content) { $currentStyle = ArrayHelper::merge($currentStyle, $content); } if ($negative) { if (isset($currentStyle["color"])) { $fgColor = $currentStyle["color"]; unset($currentStyle["color"]); } if (isset($currentStyle["background-color"])) { $bgColor = $currentStyle["background-color"]; unset($currentStyle["background-color"]); } if (isset($fgColor)) { $currentStyle["background-color"] = $fgColor; } if (isset($bgColor)) { $currentStyle["color"] = $bgColor; } } $styleString = ''; foreach ($currentStyle as $name => $value) { if (is_array($value)) { $value = implode(" ", $value); } $styleString .= "{$name}: {$value};"; } $tags++; return "{$return}"; }, $string); while ($tags > 0) { $result .= ""; $tags--; } return $result; } public static function markdownToAnsi($markdown) { $parser = new ConsoleMarkdown(); return $parser->parse($markdown); } public static function renderColoredString($string, $colored = true) { static $conversions = array("%y" => array(self::FG_YELLOW), "%g" => array(self::FG_GREEN), "%b" => array(self::FG_BLUE), "%r" => array(self::FG_RED), "%p" => array(self::FG_PURPLE), "%m" => array(self::FG_PURPLE), "%c" => array(self::FG_CYAN), "%w" => array(self::FG_GREY), "%k" => array(self::FG_BLACK), "%n" => array(0), "%Y" => array(self::FG_YELLOW, self::BOLD), "%G" => array(self::FG_GREEN, self::BOLD), "%B" => array(self::FG_BLUE, self::BOLD), "%R" => array(self::FG_RED, self::BOLD), "%P" => array(self::FG_PURPLE, self::BOLD), "%M" => array(self::FG_PURPLE, self::BOLD), "%C" => array(self::FG_CYAN, self::BOLD), "%W" => array(self::FG_GREY, self::BOLD), "%K" => array(self::FG_BLACK, self::BOLD), "%N" => array(0, self::BOLD), "%3" => array(self::BG_YELLOW), "%2" => array(self::BG_GREEN), "%4" => array(self::BG_BLUE), "%1" => array(self::BG_RED), "%5" => array(self::BG_PURPLE), "%6" => array(self::BG_CYAN), "%7" => array(self::BG_GREY), "%0" => array(self::BG_BLACK), "%F" => array(self::BLINK), "%U" => array(self::UNDERLINE), "%8" => array(self::NEGATIVE), "%9" => array(self::BOLD), "%_" => array(self::BOLD)); if ($colored) { $string = str_replace("%%", "% ", $string); foreach ($conversions as $key => $value) { $string = str_replace($key, static::ansiFormatCode($value), $string); } $string = str_replace("% ", "%", $string); } else { $string = preg_replace("/%((%)|.)/", "$2", $string); } return $string; } public static function escape($string) { return str_replace("%", "%%", $string); } public static function streamSupportsAnsiColors($stream) { return DIRECTORY_SEPARATOR === "\" ? getenv("ANSICON") !== false || getenv("ConEmuANSI") === "ON" : function_exists("posix_isatty") && @posix_isatty($stream); } public static function isRunningOnWindows() { return DIRECTORY_SEPARATOR === "\"; } public static function getScreenSize($refresh = false) { static $size; static $execDisabled; if ($size !== null && ($execDisabled || !$refresh)) { return $size; } if ($execDisabled === null) { $execDisabled = !function_exists("ini_get") || preg_match("/(\bexec\b)/i", ini_get("disable_functions")); if ($execDisabled) { return $size = false; } } if (static::isRunningOnWindows()) { $output = array(); exec("mode con", $output); if (isset($output[1]) && strpos($output[1], "CON") !== false) { return $size = array((int) preg_replace("~\D~", '', $output[4]), (int) preg_replace("~\D~", '', $output[3])); } } else { $stty = array(); if (exec("stty -a 2>&1", $stty)) { $stty = implode(" ", $stty); if (preg_match("/rows\s+(\d+);\s*columns\s+(\d+);/mi", $stty, $matches)) { return $size = array((int) $matches[2], (int) $matches[1]); } if (preg_match("/(\d+)\s+rows;\s*(\d+)\s+columns;/mi", $stty, $matches)) { return $size = array((int) $matches[2], (int) $matches[1]); } } if (($width = (int) exec("tput cols 2>&1")) > 0 && ($height = (int) exec("tput lines 2>&1")) > 0) { return $size = array($width, $height); } if (($width = (int) getenv("COLUMNS")) > 0 && ($height = (int) getenv("LINES")) > 0) { return $size = array($width, $height); } } return $size = false; } public static function wrapText($text, $indent = 0, $refresh = false) { $size = static::getScreenSize($refresh); if ($size === false || $size[0] <= $indent) { return $text; } $pad = str_repeat(" ", $indent); $lines = explode("\xa", wordwrap($text, $size[0] - $indent, " ")); $first = true; foreach ($lines as $i => $line) { if ($first) { $first = false; continue; } $lines[$i] = $pad . $line; } return implode(" ", $lines); } public static function stdin($raw = false) { return $raw ? fgets(\STDIN) : rtrim(fgets(\STDIN), PHP_EOL); } public static function stdout($string) { return fwrite(\STDOUT, $string); } public static function stderr($string) { return fwrite(\STDERR, $string); } public static function input($prompt = null) { if (isset($prompt)) { static::stdout($prompt); } return static::stdin(); } public static function output($string = null) { return static::stdout($string . PHP_EOL); } public static function error($string = null) { return static::stderr($string . PHP_EOL); } public static function prompt($text, $options = array()) { $options = ArrayHelper::merge(array("required" => false, "default" => null, "pattern" => null, "validator" => null, "error" => "Invalid input."), $options); $error = null; top: $input = $options["default"] ? static::input("{$text} [" . $options["default"] . "] ") : static::input("{$text} "); if ($input === '') { if (isset($options["default"])) { $input = $options["default"]; } elseif ($options["required"]) { static::output($options["error"]); goto top; } } elseif ($options["pattern"] && !preg_match($options["pattern"], $input)) { static::output($options["error"]); goto top; } elseif ($options["validator"] && !call_user_func_array($options["validator"], array($input, &$error))) { static::output(isset($error) ? $error : $options["error"]); goto top; } return $input; } public static function confirm($message, $default = false) { while (true) { static::stdout($message . " (yes|no) [" . ($default ? "yes" : "no") . "]:"); $input = trim(static::stdin()); if (empty($input)) { return $default; } if (!strcasecmp($input, "y") || !strcasecmp($input, "yes")) { return true; } if (!strcasecmp($input, "n") || !strcasecmp($input, "no")) { return false; } } } public static function select($prompt, $options = array(), $default = null) { top: static::stdout("{$prompt} (" . implode(",", array_keys($options)) . ",?)" . ($default !== null ? "[" . $default . "]" : '') . ": "); $input = static::stdin(); if ($input === "?") { foreach ($options as $key => $value) { static::output(" {$key} - {$value}"); } static::output(" ? - Show help"); goto top; } elseif ($default !== null && $input === '') { return $default; } elseif (!array_key_exists($input, $options)) { goto top; } return $input; } private static $_progressStart; private static $_progressWidth; private static $_progressPrefix; private static $_progressEta; private static $_progressEtaLastDone = 0; private static $_progressEtaLastUpdate; public static function startProgress($done, $total, $prefix = '', $width = null) { self::$_progressStart = time(); self::$_progressWidth = $width; self::$_progressPrefix = $prefix; self::$_progressEta = null; self::$_progressEtaLastDone = 0; self::$_progressEtaLastUpdate = time(); static::updateProgress($done, $total); } public static function updateProgress($done, $total, $prefix = null) { if ($prefix === null) { $prefix = self::$_progressPrefix; } else { self::$_progressPrefix = $prefix; } $width = static::getProgressbarWidth($prefix); $percent = $total == 0 ? 1 : $done / $total; $info = sprintf("%d%% (%d/%d)", $percent * 100, $done, $total); self::setETA($done, $total); $info .= self::$_progressEta === null ? " ETA: n/a" : sprintf(" ETA: %d sec.", self::$_progressEta); $extraChars = static::isRunningOnWindows() ? 4 : 3; $width -= $extraChars + static::ansiStrlen($info); if ($width < 5) { static::stdout(" {$prefix}{$info} "); } else { if ($percent < 0) { $percent = 0; } elseif ($percent > 1) { $percent = 1; } $bar = floor($percent * $width); $status = str_repeat("=", $bar); if ($bar < $width) { $status .= ">"; $status .= str_repeat(" ", $width - $bar - 1); } static::stdout("\xd{$prefix}" . "[{$status}] {$info}"); } flush(); } 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; } 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; } } public static function endProgress($remove = false, $keepPrefix = true) { if ($remove === false) { static::stdout(PHP_EOL); } else { if (static::streamSupportsAnsiColors(STDOUT)) { static::clearLine(); } static::stdout(" " . ($keepPrefix ? self::$_progressPrefix : '') . (is_string($remove) ? $remove : '')); } flush(); self::$_progressStart = null; self::$_progressWidth = null; self::$_progressPrefix = ''; self::$_progressEta = null; self::$_progressEtaLastDone = 0; self::$_progressEtaLastUpdate = null; } public static function errorSummary($models, $options = array()) { $showAllErrors = ArrayHelper::remove($options, "showAllErrors", false); $lines = self::collectErrors($models, $showAllErrors); return implode(PHP_EOL, $lines); } private static function collectErrors($models, $showAllErrors) { $lines = array(); if (!is_array($models)) { $models = array($models); } foreach ($models as $model) { $lines = array_unique(array_merge($lines, $model->getErrorSummary($showAllErrors))); } return $lines; } } ?>