Created
December 19, 2012 03:56
-
-
Save jnrbsn/4334276 to your computer and use it in GitHub Desktop.
Objected-oriented command line output library for PHP.
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 | |
/** | |
* Objected-oriented command line output library for PHP. | |
* | |
* Dependencies: | |
* - Console_Color PEAR package | |
* - Bash | |
* | |
* PHP version 5 | |
* | |
* @author Jonathan Robson <jnrbsn@gmail.com> | |
* @copyright 2011 Jonathan Robson | |
* @license MIT License http://www.opensource.org/licenses/mit-license.php | |
* @version 0.1-beta | |
* @link N/A | |
*/ | |
/** | |
* The main class for the library. | |
*/ | |
class Outy | |
{ | |
/** | |
* Stores the message of the current task or false if not doing anything. | |
* | |
* @var mixed | |
* @since 0.1 | |
*/ | |
private $_currentTask = false; | |
/** | |
* Creates an instance of the class. | |
* | |
* Sets the error handler to $this->errorHandler(). | |
* | |
* @since 0.1 | |
*/ | |
public function __construct() | |
{ | |
// Turn on all PHP errors. | |
error_reporting(E_ALL); | |
// Set a custom error handler. | |
set_error_handler(array($this, 'errorHandler')); | |
}//end __construct() | |
/** | |
* Prints a status message to the console. | |
* | |
* @param string $message The message to print. | |
* @param boolean $clearLine Whether or not to clear the line before printing. | |
* | |
* @since 0.1 | |
* @return void | |
*/ | |
public function status($message, $clearLine=false) | |
{ | |
if ($clearLine === true) { | |
echo "\033[K\r"; | |
} else if ($this->_currentTask !== false && $this->_currentTask !== $message) { | |
$this->success(); | |
} | |
$this->_currentTask = $message; | |
echo str_pad($message.':', 59); | |
}//end status() | |
/** | |
* Prints "[ OK ]" in green. | |
* | |
* @since 0.1 | |
* @return void | |
*/ | |
public function success() | |
{ | |
if ($this->_currentTask !== false) { | |
$this->_currentTask = false; | |
echo '[ '.Console_Color::convert('%gOK%n').' ]'."\n"; | |
} | |
}//end success() | |
/** | |
* Prints "[FAILED]" in red. | |
* | |
* @since 0.1 | |
* @return void | |
*/ | |
public function failure() | |
{ | |
if ($this->_currentTask !== false) { | |
$this->_currentTask = false; | |
echo '['.Console_Color::convert('%rFAILED%n').']'."\n"; | |
} | |
}//end failure() | |
/** | |
* Prints "[ SKIP ]" in yellow. | |
* | |
* @since 0.1 | |
* @return void | |
*/ | |
public function skip() | |
{ | |
if ($this->_currentTask !== false) { | |
$this->_currentTask = false; | |
echo '[ '.Console_Color::convert('%ySKIP%n').' ]'."\n"; | |
} | |
}//end skip() | |
/** | |
* Prints a percentage of progress. | |
* | |
* Designed to be used while a task is running. | |
* | |
* @param float $decimal A float between 0 and 1. | |
* | |
* @since 0.1 | |
* @return void | |
*/ | |
public function percentProgress($decimal) | |
{ | |
echo str_pad(number_format($decimal * 100, 1).'% ', 8, ' ', STR_PAD_LEFT); | |
echo str_repeat("\010", 8); | |
}//end percentProgress() | |
/** | |
* Ask a question at the CLI and get the answer. | |
* | |
* @param string $question The prompt to display. | |
* @param boolean $pattern A regular expression that answer must match. | |
* @param string $default The default answer if no answer is given. | |
* @param boolean $echo Whether or not to echo the answer as it's typed. | |
* | |
* @since 0.1 | |
* @return string The answer. | |
*/ | |
public function prompt($question, $pattern=null, $default=null, $echo=true) | |
{ | |
if ($default === null) { | |
$default = ''; | |
} | |
if ($pattern === null) { | |
$pattern = '/.*/'; | |
} | |
do { | |
if (isset($answer)) { | |
echo "\n".self::formatText('Invalid answer! Please try again...')."\n"; | |
} | |
$question = rtrim(self::formatText($question), "\r\n").' '; | |
$answer = rtrim( | |
shell_exec( | |
'read -e'.($echo ? '' : 's').' -p '.escapeshellarg($question). | |
' OUTY_PROMPT_ANSWER; echo $OUTY_PROMPT_ANSWER 2>&1' | |
), "\r\n" | |
); | |
if (!$echo) { | |
echo "\n"; | |
} | |
} while (!preg_match($pattern, $answer)); | |
if (empty($answer) && !empty($default)) { | |
$answer = $default; | |
} | |
return $answer; | |
}//end prompt() | |
/** | |
* The error handler. | |
* | |
* Tries to output errors in a consistent way. | |
* | |
* @param integer $level The error level. | |
* @param string $message The error message. | |
* @param string $file The path to the file in which the error occurred. | |
* @param integer $line The line number on which the error occurred. | |
* | |
* @since 0.1 | |
* @return bool Returns true or dies. | |
*/ | |
public function errorHandler($level, $message, $file, $line) | |
{ | |
if (error_reporting() === 0) { | |
// Return early if an error-control operator was used. | |
return true; | |
} | |
$filename_length_max = 50 - strlen($line); | |
$filename_length = strlen($file); | |
if ($filename_length > $filename_length_max) { | |
$file = '...'.substr($file, $filename_length - $filename_length_max); | |
} | |
$formattedMessage = self::formatText( | |
$message."\n".'{'.$file.':'.$line.'}', | |
4, | |
false | |
)."\n"; | |
if ($level == E_ERROR || $level == E_USER_ERROR) { | |
if ($this->_currentTask !== false) { | |
$this->failure(); | |
} | |
fwrite(STDERR, "\n ".Console_Color::convert('%RERROR:%n ').$formattedMessage); | |
exit(2); | |
} else if ($level == E_WARNING || $level == E_USER_WARNING) { | |
if ($this->_currentTask !== false) { | |
$this->failure(); | |
} | |
fwrite(STDERR, "\n ".Console_Color::convert('%YWARNING:%n ').$formattedMessage); | |
} else if ($level == E_NOTICE || $level == E_USER_NOTICE) { | |
return true; | |
} else if ($level == E_STRICT) { | |
return true; | |
} else if (defined('E_DEPRECATED') | |
&& ($level == E_DEPRECATED || $level == E_USER_DEPRECATED) | |
) { | |
return true; | |
} else { | |
if ($this->_currentTask !== false) { | |
$this->failure(); | |
} | |
fwrite( | |
STDERR, | |
"\n ".Console_Color::convert('%RUNKNOWN ERROR ('.$level.'):%n '). | |
$formattedMessage | |
); | |
exit(1); | |
}//end if | |
return true; | |
}//end errorHandler() | |
/** | |
* Formats some arbitary text in preparation for outputing it to the console. | |
* | |
* @param string $text The text to format. | |
* @param integer $indentation The amount of indentation for each level. | |
* @param boolean $indent_first_line Whether or not to indent the very first line. | |
* @param boolean $indent_forced_wraps Whether or not to indent text that gets wrapped an | |
* additional level. | |
* | |
* @since 0.1 | |
* @return string The formatted text. | |
*/ | |
public static function formatText($text, $indentation=4, $indent_first_line=true, | |
$indent_forced_wraps=true | |
) { | |
$padding = str_repeat(' ', $indentation); | |
$line_length = 80; | |
$formatted = ''; | |
foreach (explode("\n", trim($text)) as $line) { | |
if (strlen($line) <= $line_length - $indentation) { | |
$formatted .= $padding.$line."\n"; | |
continue; | |
} | |
$end_of_first_line = strrpos(substr($line, 0, $line_length - $indentation + 1), ' '); | |
$formatted .= $padding.substr($line, 0, $end_of_first_line)."\n"; | |
$formatted .= $indent_forced_wraps === true ? $padding.$padding : $padding; | |
$formatted .= wordwrap( | |
substr($line, $end_of_first_line + 1), | |
$line_length - ($indentation * ($indent_forced_wraps === true ? 2 : 1)), | |
"\n".($indent_forced_wraps === true ? $padding.$padding : $padding) | |
); | |
$formatted .= "\n"; | |
} | |
if ($indent_first_line === false) { | |
$formatted = ltrim($formatted); | |
} | |
return $formatted; | |
}//end formatText() | |
/** | |
* Converts a string to the color blue for console output. | |
* | |
* @param string $string The string to convert. | |
* | |
* @since 0.1 | |
* @return string The colored text. | |
*/ | |
public static function blue($string) | |
{ | |
return Console_Color::convert('%c'.$string.'%n'); | |
}//end blue() | |
/** | |
* Converts a string to the color green for console output. | |
* | |
* @param string $string The string to convert. | |
* | |
* @since 0.1 | |
* @return string The colored text. | |
*/ | |
public static function green($string) | |
{ | |
return Console_Color::convert('%g'.$string.'%n'); | |
}//end green() | |
/** | |
* Converts a string to the color red for console output. | |
* | |
* @param string $string The string to convert. | |
* | |
* @since 0.1 | |
* @return string The colored text. | |
*/ | |
public static function red($string) | |
{ | |
return Console_Color::convert('%r'.$string.'%n'); | |
}//end red() | |
/** | |
* Converts a string to the color yellow for console output. | |
* | |
* @param string $string The string to convert. | |
* | |
* @since 0.1 | |
* @return string The colored text. | |
*/ | |
public static function yellow($string) | |
{ | |
return Console_Color::convert('%y'.$string.'%n'); | |
}//end yellow() | |
}//end class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment