Complex classes like BaseConsole often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BaseConsole, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class BaseConsole |
||
21 | { |
||
22 | // foreground color control codes |
||
23 | const FG_BLACK = 30; |
||
24 | const FG_RED = 31; |
||
25 | const FG_GREEN = 32; |
||
26 | const FG_YELLOW = 33; |
||
27 | const FG_BLUE = 34; |
||
28 | const FG_PURPLE = 35; |
||
29 | const FG_CYAN = 36; |
||
30 | const FG_GREY = 37; |
||
31 | // background color control codes |
||
32 | const BG_BLACK = 40; |
||
33 | const BG_RED = 41; |
||
34 | const BG_GREEN = 42; |
||
35 | const BG_YELLOW = 43; |
||
36 | const BG_BLUE = 44; |
||
37 | const BG_PURPLE = 45; |
||
38 | const BG_CYAN = 46; |
||
39 | const BG_GREY = 47; |
||
40 | // fonts style control codes |
||
41 | const RESET = 0; |
||
42 | const NORMAL = 0; |
||
43 | const BOLD = 1; |
||
44 | const ITALIC = 3; |
||
45 | const UNDERLINE = 4; |
||
46 | const BLINK = 5; |
||
47 | const NEGATIVE = 7; |
||
48 | const CONCEALED = 8; |
||
49 | const CROSSED_OUT = 9; |
||
50 | const FRAMED = 51; |
||
51 | const ENCIRCLED = 52; |
||
52 | const OVERLINED = 53; |
||
53 | |||
54 | |||
55 | /** |
||
56 | * Moves the terminal cursor up by sending ANSI control code CUU to the terminal. |
||
57 | * If the cursor is already at the edge of the screen, this has no effect. |
||
58 | * @param integer $rows number of rows the cursor should be moved up |
||
59 | */ |
||
60 | 1 | public static function moveCursorUp($rows = 1) |
|
64 | |||
65 | /** |
||
66 | * Moves the terminal cursor down by sending ANSI control code CUD to the terminal. |
||
67 | * If the cursor is already at the edge of the screen, this has no effect. |
||
68 | * @param integer $rows number of rows the cursor should be moved down |
||
69 | */ |
||
70 | 1 | public static function moveCursorDown($rows = 1) |
|
74 | |||
75 | /** |
||
76 | * Moves the terminal cursor forward by sending ANSI control code CUF to the terminal. |
||
77 | * If the cursor is already at the edge of the screen, this has no effect. |
||
78 | * @param integer $steps number of steps the cursor should be moved forward |
||
79 | */ |
||
80 | 1 | public static function moveCursorForward($steps = 1) |
|
84 | |||
85 | /** |
||
86 | * Moves the terminal cursor backward by sending ANSI control code CUB to the terminal. |
||
87 | * If the cursor is already at the edge of the screen, this has no effect. |
||
88 | * @param integer $steps number of steps the cursor should be moved backward |
||
89 | */ |
||
90 | 1 | public static function moveCursorBackward($steps = 1) |
|
94 | |||
95 | /** |
||
96 | * Moves the terminal cursor to the beginning of the next line by sending ANSI control code CNL to the terminal. |
||
97 | * @param integer $lines number of lines the cursor should be moved down |
||
98 | */ |
||
99 | 1 | public static function moveCursorNextLine($lines = 1) |
|
103 | |||
104 | /** |
||
105 | * Moves the terminal cursor to the beginning of the previous line by sending ANSI control code CPL to the terminal. |
||
106 | * @param integer $lines number of lines the cursor should be moved up |
||
107 | */ |
||
108 | 1 | public static function moveCursorPrevLine($lines = 1) |
|
112 | |||
113 | /** |
||
114 | * Moves the cursor to an absolute position given as column and row by sending ANSI control code CUP or CHA to the terminal. |
||
115 | * @param integer $column 1-based column number, 1 is the left edge of the screen. |
||
116 | * @param integer|null $row 1-based row number, 1 is the top edge of the screen. if not set, will move cursor only in current line. |
||
117 | */ |
||
118 | 1 | public static function moveCursorTo($column, $row = null) |
|
126 | |||
127 | /** |
||
128 | * Scrolls whole page up by sending ANSI control code SU to the terminal. |
||
129 | * New lines are added at the bottom. This is not supported by ANSI.SYS used in windows. |
||
130 | * @param integer $lines number of lines to scroll up |
||
131 | */ |
||
132 | 1 | public static function scrollUp($lines = 1) |
|
136 | |||
137 | /** |
||
138 | * Scrolls whole page down by sending ANSI control code SD to the terminal. |
||
139 | * New lines are added at the top. This is not supported by ANSI.SYS used in windows. |
||
140 | * @param integer $lines number of lines to scroll down |
||
141 | */ |
||
142 | 1 | public static function scrollDown($lines = 1) |
|
146 | |||
147 | /** |
||
148 | * Saves the current cursor position by sending ANSI control code SCP to the terminal. |
||
149 | * Position can then be restored with [[restoreCursorPosition()]]. |
||
150 | */ |
||
151 | 1 | public static function saveCursorPosition() |
|
155 | |||
156 | /** |
||
157 | * Restores the cursor position saved with [[saveCursorPosition()]] by sending ANSI control code RCP to the terminal. |
||
158 | */ |
||
159 | 1 | public static function restoreCursorPosition() |
|
163 | |||
164 | /** |
||
165 | * Hides the cursor by sending ANSI DECTCEM code ?25l to the terminal. |
||
166 | * Use [[showCursor()]] to bring it back. |
||
167 | * Do not forget to show cursor when your application exits. Cursor might stay hidden in terminal after exit. |
||
168 | */ |
||
169 | 1 | public static function hideCursor() |
|
173 | |||
174 | /** |
||
175 | * Will show a cursor again when it has been hidden by [[hideCursor()]] by sending ANSI DECTCEM code ?25h to the terminal. |
||
176 | */ |
||
177 | 1 | public static function showCursor() |
|
181 | |||
182 | /** |
||
183 | * Clears entire screen content by sending ANSI control code ED with argument 2 to the terminal. |
||
184 | * Cursor position will not be changed. |
||
185 | * **Note:** ANSI.SYS implementation used in windows will reset cursor position to upper left corner of the screen. |
||
186 | */ |
||
187 | 1 | public static function clearScreen() |
|
191 | |||
192 | /** |
||
193 | * Clears text from cursor to the beginning of the screen by sending ANSI control code ED with argument 1 to the terminal. |
||
194 | * Cursor position will not be changed. |
||
195 | */ |
||
196 | 1 | public static function clearScreenBeforeCursor() |
|
200 | |||
201 | /** |
||
202 | * Clears text from cursor to the end of the screen by sending ANSI control code ED with argument 0 to the terminal. |
||
203 | * Cursor position will not be changed. |
||
204 | */ |
||
205 | 1 | public static function clearScreenAfterCursor() |
|
209 | |||
210 | /** |
||
211 | * Clears the line, the cursor is currently on by sending ANSI control code EL with argument 2 to the terminal. |
||
212 | * Cursor position will not be changed. |
||
213 | */ |
||
214 | 5 | public static function clearLine() |
|
218 | |||
219 | /** |
||
220 | * Clears text from cursor position to the beginning of the line by sending ANSI control code EL with argument 1 to the terminal. |
||
221 | * Cursor position will not be changed. |
||
222 | */ |
||
223 | 1 | public static function clearLineBeforeCursor() |
|
227 | |||
228 | /** |
||
229 | * Clears text from cursor position to the end of the line by sending ANSI control code EL with argument 0 to the terminal. |
||
230 | * Cursor position will not be changed. |
||
231 | */ |
||
232 | 1 | public static function clearLineAfterCursor() |
|
236 | |||
237 | /** |
||
238 | * Returns the ANSI format code. |
||
239 | * |
||
240 | * @param array $format An array containing formatting values. |
||
241 | * You can pass any of the FG_*, BG_* and TEXT_* constants |
||
242 | * and also [[xtermFgColor]] and [[xtermBgColor]] to specify a format. |
||
243 | * @return string The ANSI format code according to the given formatting constants. |
||
244 | */ |
||
245 | public static function ansiFormatCode($format) |
||
249 | |||
250 | /** |
||
251 | * Echoes an ANSI format code that affects the formatting of any text that is printed afterwards. |
||
252 | * |
||
253 | * @param array $format An array containing formatting values. |
||
254 | * You can pass any of the FG_*, BG_* and TEXT_* constants |
||
255 | * and also [[xtermFgColor]] and [[xtermBgColor]] to specify a format. |
||
256 | * @see ansiFormatCode() |
||
257 | * @see endAnsiFormat() |
||
258 | */ |
||
259 | 1 | public static function beginAnsiFormat($format) |
|
263 | |||
264 | /** |
||
265 | * Resets any ANSI format set by previous method [[beginAnsiFormat()]] |
||
266 | * Any output after this will have default text format. |
||
267 | * This is equal to calling |
||
268 | * |
||
269 | * ```php |
||
270 | * echo Console::ansiFormatCode([Console::RESET]) |
||
271 | * ``` |
||
272 | */ |
||
273 | 1 | public static function endAnsiFormat() |
|
277 | |||
278 | /** |
||
279 | * Will return a string formatted with the given ANSI style |
||
280 | * |
||
281 | * @param string $string the string to be formatted |
||
282 | * @param array $format An array containing formatting values. |
||
283 | * You can pass any of the FG_*, BG_* and TEXT_* constants |
||
284 | * and also [[xtermFgColor]] and [[xtermBgColor]] to specify a format. |
||
285 | * @return string |
||
286 | */ |
||
287 | 18 | public static function ansiFormat($string, $format = []) |
|
293 | |||
294 | /** |
||
295 | * Returns the ansi format code for xterm foreground color. |
||
296 | * You can pass the return value of this to one of the formatting methods: |
||
297 | * [[ansiFormat]], [[ansiFormatCode]], [[beginAnsiFormat]] |
||
298 | * |
||
299 | * @param integer $colorCode xterm color code |
||
300 | * @return string |
||
301 | * @see http://en.wikipedia.org/wiki/Talk:ANSI_escape_code#xterm-256colors |
||
302 | */ |
||
303 | 1 | public static function xtermFgColor($colorCode) |
|
307 | |||
308 | /** |
||
309 | * Returns the ansi format code for xterm background color. |
||
310 | * You can pass the return value of this to one of the formatting methods: |
||
311 | * [[ansiFormat]], [[ansiFormatCode]], [[beginAnsiFormat]] |
||
312 | * |
||
313 | * @param integer $colorCode xterm color code |
||
314 | * @return string |
||
315 | * @see http://en.wikipedia.org/wiki/Talk:ANSI_escape_code#xterm-256colors |
||
316 | */ |
||
317 | 1 | public static function xtermBgColor($colorCode) |
|
321 | |||
322 | /** |
||
323 | * Strips ANSI control codes from a string |
||
324 | * |
||
325 | * @param string $string String to strip |
||
326 | * @return string |
||
327 | */ |
||
328 | 5 | public static function stripAnsiFormat($string) |
|
332 | |||
333 | /** |
||
334 | * Returns the length of the string without ANSI color codes. |
||
335 | * @param string $string the string to measure |
||
336 | * @return integer the length of the string not counting ANSI format characters |
||
337 | */ |
||
338 | 4 | public static function ansiStrlen($string) |
|
339 | { |
||
340 | 4 | return mb_strlen(static::stripAnsiFormat($string)); |
|
341 | } |
||
342 | |||
343 | /** |
||
344 | * Converts an ANSI formatted string to HTML |
||
345 | * |
||
346 | * Note: xTerm 256 bit colors are currently not supported. |
||
347 | * |
||
348 | * @param string $string the string to convert. |
||
349 | * @param array $styleMap an optional mapping of ANSI control codes such as |
||
350 | * [[FG_COLOR]] or [[BOLD]] to a set of css style definitions. |
||
351 | * The CSS style definitions are represented as an array where the array keys correspond |
||
352 | * to the css style attribute names and the values are the css values. |
||
353 | * values may be arrays that will be merged and imploded with `' '` when rendered. |
||
354 | * @return string HTML representation of the ANSI formatted string |
||
355 | */ |
||
356 | 15 | public static function ansiToHtml($string, $styleMap = []) |
|
455 | |||
456 | /** |
||
457 | * Converts Markdown to be better readable in console environments by applying some ANSI format |
||
458 | * @param string $markdown |
||
459 | * @return string |
||
460 | */ |
||
461 | public static function markdownToAnsi($markdown) |
||
466 | |||
467 | /** |
||
468 | * Converts a string to ansi formatted by replacing patterns like %y (for yellow) with ansi control codes |
||
469 | * |
||
470 | * Uses almost the same syntax as https://github.com/pear/Console_Color2/blob/master/Console/Color2.php |
||
471 | * The conversion table is: ('bold' meaning 'light' on some |
||
472 | * terminals). It's almost the same conversion table irssi uses. |
||
473 | * <pre> |
||
474 | * text text background |
||
475 | * ------------------------------------------------ |
||
476 | * %k %K %0 black dark grey black |
||
477 | * %r %R %1 red bold red red |
||
478 | * %g %G %2 green bold green green |
||
479 | * %y %Y %3 yellow bold yellow yellow |
||
480 | * %b %B %4 blue bold blue blue |
||
481 | * %m %M %5 magenta bold magenta magenta |
||
482 | * %p %P magenta (think: purple) |
||
483 | * %c %C %6 cyan bold cyan cyan |
||
484 | * %w %W %7 white bold white white |
||
485 | * |
||
486 | * %F Blinking, Flashing |
||
487 | * %U Underline |
||
488 | * %8 Reverse |
||
489 | * %_,%9 Bold |
||
490 | * |
||
491 | * %n Resets the color |
||
492 | * %% A single % |
||
493 | * </pre> |
||
494 | * First param is the string to convert, second is an optional flag if |
||
495 | * colors should be used. It defaults to true, if set to false, the |
||
496 | * color codes will just be removed (And %% will be transformed into %) |
||
497 | * |
||
498 | * @param string $string String to convert |
||
499 | * @param boolean $colored Should the string be colored? |
||
500 | * @return string |
||
501 | */ |
||
502 | public static function renderColoredString($string, $colored = true) |
||
557 | |||
558 | /** |
||
559 | * Escapes % so they don't get interpreted as color codes when |
||
560 | * the string is parsed by [[renderColoredString]] |
||
561 | * |
||
562 | * @param string $string String to escape |
||
563 | * |
||
564 | * @access public |
||
565 | * @return string |
||
566 | */ |
||
567 | public static function escape($string) |
||
572 | |||
573 | /** |
||
574 | * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream. |
||
575 | * |
||
576 | * - windows without ansicon |
||
577 | * - not tty consoles |
||
578 | * |
||
579 | * @param mixed $stream |
||
580 | * @return boolean true if the stream supports ANSI colors, otherwise false. |
||
581 | */ |
||
582 | 4 | public static function streamSupportsAnsiColors($stream) |
|
583 | { |
||
584 | 4 | return DIRECTORY_SEPARATOR === '\\' |
|
585 | 4 | ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON' |
|
586 | 4 | : function_exists('posix_isatty') && @posix_isatty($stream); |
|
587 | } |
||
588 | |||
589 | /** |
||
590 | * Returns true if the console is running on windows |
||
591 | * @return boolean |
||
592 | */ |
||
593 | 4 | public static function isRunningOnWindows() |
|
594 | { |
||
595 | 4 | return DIRECTORY_SEPARATOR === '\\'; |
|
596 | } |
||
597 | |||
598 | /** |
||
599 | * Usage: list($width, $height) = ConsoleHelper::getScreenSize(); |
||
600 | * |
||
601 | * @param boolean $refresh whether to force checking and not re-use cached size value. |
||
602 | * This is useful to detect changing window size while the application is running but may |
||
603 | * not get up to date values on every terminal. |
||
604 | * @return array|boolean An array of ($width, $height) or false when it was not able to determine size. |
||
605 | */ |
||
606 | 4 | public static function getScreenSize($refresh = false) |
|
607 | { |
||
608 | 4 | static $size; |
|
609 | 4 | if ($size !== null && !$refresh) { |
|
610 | return $size; |
||
611 | } |
||
612 | |||
613 | 4 | if (static::isRunningOnWindows()) { |
|
614 | $output = []; |
||
615 | exec('mode con', $output); |
||
616 | if (isset($output, $output[1]) && strpos($output[1], 'CON') !== false) { |
||
617 | return $size = [(int) preg_replace('~\D~', '', $output[3]), (int) preg_replace('~\D~', '', $output[4])]; |
||
618 | } |
||
619 | } else { |
||
620 | // try stty if available |
||
621 | 4 | $stty = []; |
|
622 | 4 | if (exec('stty -a 2>&1', $stty) && preg_match('/rows\s+(\d+);\s*columns\s+(\d+);/mi', implode(' ', $stty), $matches)) { |
|
623 | 4 | return $size = [$matches[2], $matches[1]]; |
|
624 | } |
||
625 | |||
626 | // fallback to tput, which may not be updated on terminal resize |
||
627 | if (($width = (int) exec('tput cols 2>&1')) > 0 && ($height = (int) exec('tput lines 2>&1')) > 0) { |
||
628 | return $size = [$width, $height]; |
||
629 | } |
||
630 | |||
631 | // fallback to ENV variables, which may not be updated on terminal resize |
||
632 | if (($width = (int) getenv('COLUMNS')) > 0 && ($height = (int) getenv('LINES')) > 0) { |
||
633 | return $size = [$width, $height]; |
||
634 | } |
||
635 | } |
||
636 | |||
637 | return $size = false; |
||
638 | } |
||
639 | |||
640 | /** |
||
641 | * Word wrap text with indentation to fit the screen size |
||
642 | * |
||
643 | * If screen size could not be detected, or the indentation is greater than the screen size, the text will not be wrapped. |
||
644 | * |
||
645 | * The first line will **not** be indented, so `Console::wrapText("Lorem ipsum dolor sit amet.", 4)` will result in the |
||
646 | * following output, given the screen width is 16 characters: |
||
647 | * |
||
648 | * ``` |
||
649 | * Lorem ipsum |
||
650 | * dolor sit |
||
651 | * amet. |
||
652 | * ``` |
||
653 | * |
||
654 | * @param string $text the text to be wrapped |
||
655 | * @param integer $indent number of spaces to use for indentation. |
||
656 | * @param boolean $refresh whether to force refresh of screen size. |
||
657 | * This will be passed to [[getScreenSize()]]. |
||
658 | * @return string the wrapped text. |
||
659 | * @since 2.0.4 |
||
660 | */ |
||
661 | public static function wrapText($text, $indent = 0, $refresh = false) |
||
679 | |||
680 | /** |
||
681 | * Gets input from STDIN and returns a string right-trimmed for EOLs. |
||
682 | * |
||
683 | * @param boolean $raw If set to true, returns the raw string without trimming |
||
684 | * @return string the string read from stdin |
||
685 | */ |
||
686 | public static function stdin($raw = false) |
||
690 | |||
691 | /** |
||
692 | * Prints a string to STDOUT. |
||
693 | * |
||
694 | * @param string $string the string to print |
||
695 | * @return integer|boolean Number of bytes printed or false on error |
||
696 | */ |
||
697 | 4 | public static function stdout($string) |
|
698 | { |
||
699 | 4 | return fwrite(\STDOUT, $string); |
|
700 | } |
||
701 | |||
702 | /** |
||
703 | * Prints a string to STDERR. |
||
704 | * |
||
705 | * @param string $string the string to print |
||
706 | * @return integer|boolean Number of bytes printed or false on error |
||
707 | */ |
||
708 | public static function stderr($string) |
||
712 | |||
713 | /** |
||
714 | * Asks the user for input. Ends when the user types a carriage return (PHP_EOL). Optionally, It also provides a |
||
715 | * prompt. |
||
716 | * |
||
717 | * @param string $prompt the prompt to display before waiting for input (optional) |
||
718 | * @return string the user's input |
||
719 | */ |
||
720 | public static function input($prompt = null) |
||
728 | |||
729 | /** |
||
730 | * Prints text to STDOUT appended with a carriage return (PHP_EOL). |
||
731 | * |
||
732 | * @param string $string the text to print |
||
733 | * @return integer|boolean number of bytes printed or false on error. |
||
734 | */ |
||
735 | public static function output($string = null) |
||
739 | |||
740 | /** |
||
741 | * Prints text to STDERR appended with a carriage return (PHP_EOL). |
||
742 | * |
||
743 | * @param string $string the text to print |
||
744 | * @return integer|boolean number of bytes printed or false on error. |
||
745 | */ |
||
746 | public static function error($string = null) |
||
750 | |||
751 | /** |
||
752 | * Prompts the user for input and validates it |
||
753 | * |
||
754 | * @param string $text prompt string |
||
755 | * @param array $options the options to validate the input: |
||
756 | * |
||
757 | * - `required`: whether it is required or not |
||
758 | * - `default`: default value if no input is inserted by the user |
||
759 | * - `pattern`: regular expression pattern to validate user input |
||
760 | * - `validator`: a callable function to validate input. The function must accept two parameters: |
||
761 | * - `input`: the user input to validate |
||
762 | * - `error`: the error value passed by reference if validation failed. |
||
763 | * |
||
764 | * @return string the user input |
||
765 | */ |
||
766 | public static function prompt($text, $options = []) |
||
804 | |||
805 | /** |
||
806 | * Asks user to confirm by typing y or n. |
||
807 | * |
||
808 | * @param string $message to print out before waiting for user input |
||
809 | * @param boolean $default this value is returned if no selection is made. |
||
810 | * @return boolean whether user confirmed |
||
811 | */ |
||
812 | public static function confirm($message, $default = false) |
||
831 | |||
832 | /** |
||
833 | * Gives the user an option to choose from. Giving '?' as an input will show |
||
834 | * a list of options to choose from and their explanations. |
||
835 | * |
||
836 | * @param string $prompt the prompt message |
||
837 | * @param array $options Key-value array of options to choose from |
||
838 | * |
||
839 | * @return string An option character the user chose |
||
840 | */ |
||
841 | public static function select($prompt, $options = []) |
||
858 | |||
859 | private static $_progressStart; |
||
860 | private static $_progressWidth; |
||
861 | private static $_progressPrefix; |
||
862 | private static $_progressEta; |
||
863 | private static $_progressEtaLastDone = 0; |
||
864 | private static $_progressEtaLastUpdate; |
||
865 | |||
866 | /** |
||
867 | * Starts display of a progress bar on screen. |
||
868 | * |
||
869 | * This bar will be updated by [[updateProgress()]] and my be ended by [[endProgress()]]. |
||
870 | * |
||
871 | * The following example shows a simple usage of a progress bar: |
||
872 | * |
||
873 | * ```php |
||
874 | * Console::startProgress(0, 1000); |
||
875 | * for ($n = 1; $n <= 1000; $n++) { |
||
876 | * usleep(1000); |
||
877 | * Console::updateProgress($n, 1000); |
||
878 | * } |
||
879 | * Console::endProgress(); |
||
880 | * ``` |
||
881 | * |
||
882 | * Git clone like progress (showing only status information): |
||
883 | * ```php |
||
884 | * Console::startProgress(0, 1000, 'Counting objects: ', false); |
||
885 | * for ($n = 1; $n <= 1000; $n++) { |
||
886 | * usleep(1000); |
||
887 | * Console::updateProgress($n, 1000); |
||
888 | * } |
||
889 | * Console::endProgress("done." . PHP_EOL); |
||
890 | * ``` |
||
891 | * |
||
892 | * @param integer $done the number of items that are completed. |
||
893 | * @param integer $total the total value of items that are to be done. |
||
894 | * @param string $prefix an optional string to display before the progress bar. |
||
895 | * Default to empty string which results in no prefix to be displayed. |
||
896 | * @param integer|boolean $width optional width of the progressbar. This can be an integer representing |
||
897 | * the number of characters to display for the progress bar or a float between 0 and 1 representing the |
||
898 | * percentage of screen with the progress bar may take. It can also be set to false to disable the |
||
899 | * bar and only show progress information like percent, number of items and ETA. |
||
900 | * If not set, the bar will be as wide as the screen. Screen size will be detected using [[getScreenSize()]]. |
||
901 | * @see startProgress |
||
902 | * @see updateProgress |
||
903 | * @see endProgress |
||
904 | */ |
||
905 | 4 | public static function startProgress($done, $total, $prefix = '', $width = null) |
|
916 | |||
917 | /** |
||
918 | * Updates a progress bar that has been started by [[startProgress()]]. |
||
919 | * |
||
920 | * @param integer $done the number of items that are completed. |
||
921 | * @param integer $total the total value of items that are to be done. |
||
922 | * @param string $prefix an optional string to display before the progress bar. |
||
923 | * Defaults to null meaning the prefix specified by [[startProgress()]] will be used. |
||
924 | * If prefix is specified it will update the prefix that will be used by later calls. |
||
925 | * @see startProgress |
||
926 | * @see endProgress |
||
927 | */ |
||
928 | 4 | public static function updateProgress($done, $total, $prefix = null) |
|
929 | { |
||
930 | 4 | $width = self::$_progressWidth; |
|
931 | 4 | if ($width === false) { |
|
932 | $width = 0; |
||
933 | } else { |
||
934 | 4 | $screenSize = static::getScreenSize(true); |
|
935 | 4 | if ($screenSize === false && $width < 1) { |
|
936 | $width = 0; |
||
937 | 4 | } elseif ($width === null) { |
|
938 | 4 | $width = $screenSize[0]; |
|
939 | 4 | } elseif ($width > 0 && $width < 1) { |
|
940 | $width = floor($screenSize[0] * $width); |
||
941 | } |
||
942 | } |
||
943 | 4 | if ($prefix === null) { |
|
944 | 4 | $prefix = self::$_progressPrefix; |
|
945 | 4 | } else { |
|
946 | 4 | self::$_progressPrefix = $prefix; |
|
947 | } |
||
948 | 4 | $width -= static::ansiStrlen($prefix); |
|
949 | |||
950 | 4 | $percent = ($total == 0) ? 1 : $done / $total; |
|
951 | 4 | $info = sprintf('%d%% (%d/%d)', $percent * 100, $done, $total); |
|
952 | |||
953 | 4 | if ($done > $total || $done == 0) { |
|
954 | 4 | self::$_progressEta = null; |
|
955 | 4 | self::$_progressEtaLastUpdate = time(); |
|
956 | 4 | } elseif ($done < $total) { |
|
957 | // update ETA once per second to avoid flapping |
||
958 | 4 | if (time() - self::$_progressEtaLastUpdate > 1 && $done > self::$_progressEtaLastDone) { |
|
959 | 4 | $rate = (time() - (self::$_progressEtaLastUpdate ?: self::$_progressStart)) / ($done - self::$_progressEtaLastDone); |
|
960 | 4 | self::$_progressEta = $rate * ($total - $done); |
|
961 | 4 | self::$_progressEtaLastUpdate = time(); |
|
962 | 4 | self::$_progressEtaLastDone = $done; |
|
963 | 4 | } |
|
964 | 4 | } |
|
965 | 4 | if (self::$_progressEta === null) { |
|
966 | 4 | $info .= ' ETA: n/a'; |
|
967 | 4 | } else { |
|
968 | 4 | $info .= sprintf(' ETA: %d sec.', self::$_progressEta); |
|
969 | } |
||
970 | |||
971 | 4 | $width -= 3 + static::ansiStrlen($info); |
|
972 | // skipping progress bar on very small display or if forced to skip |
||
973 | 4 | if ($width < 5) { |
|
974 | static::stdout("\r$prefix$info "); |
||
975 | } else { |
||
976 | 4 | if ($percent < 0) { |
|
977 | $percent = 0; |
||
978 | 4 | } elseif ($percent > 1) { |
|
979 | $percent = 1; |
||
980 | } |
||
981 | 4 | $bar = floor($percent * $width); |
|
982 | 4 | $status = str_repeat('=', $bar); |
|
983 | 4 | if ($bar < $width) { |
|
984 | 4 | $status .= '>'; |
|
985 | 4 | $status .= str_repeat(' ', $width - $bar - 1); |
|
986 | 4 | } |
|
987 | 4 | static::stdout("\r$prefix" . "[$status] $info"); |
|
988 | } |
||
989 | 4 | flush(); |
|
990 | 4 | } |
|
991 | |||
992 | /** |
||
993 | * Ends a progress bar that has been started by [[startProgress()]]. |
||
994 | * |
||
995 | * @param string|boolean $remove This can be `false` to leave the progress bar on screen and just print a newline. |
||
996 | * If set to `true`, the line of the progress bar will be cleared. This may also be a string to be displayed instead |
||
997 | * of the progress bar. |
||
998 | * @param boolean $keepPrefix whether to keep the prefix that has been specified for the progressbar when progressbar |
||
999 | * gets removed. Defaults to true. |
||
1000 | * @see startProgress |
||
1001 | * @see updateProgress |
||
1002 | */ |
||
1003 | 4 | public static function endProgress($remove = false, $keepPrefix = true) |
|
1022 | } |
||
1023 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: