├── README.md ├── config └── autoload.php └── libraries └── Cli.php /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter-CLI 2 | 3 | Interact with the command line by accepting input options, parameters and output text. 4 | 5 | ## History 6 | 7 | This library was originally written in 2009 and was... alright. Now it has been totally rewritten based on the FuelPHP CLI library I wrote, which was based on this. MADNESS! 8 | 9 | ## Requirements 10 | 11 | * CodeIgniter 2.0.x 12 | 13 | ## Examples 14 | 15 | // Output "Hello World" to the CLI 16 | $this->cli->write('Hello World!'); 17 | 18 | // Waits for any key press 19 | $this->cli->prompt(); 20 | 21 | // Takes any input 22 | $color = $this->cli->prompt('What is your favorite color?'); 23 | 24 | // Takes any input, but offers default 25 | $color = $this->cli->prompt('What is your favorite color?', 'white'); 26 | 27 | // Will only accept the options in the array 28 | $ready = $this->cli->prompt('Are you ready?', array('y','n')); 29 | 30 | $this->cli->write('Loading...'); 31 | $this->cli->wait(5, true); -------------------------------------------------------------------------------- /config/autoload.php: -------------------------------------------------------------------------------- 1 | '0;30', 23 | 'dark_gray' => '1;30', 24 | 'blue' => '0;34', 25 | 'light_blue' => '1;34', 26 | 'green' => '0;32', 27 | 'light_green' => '1;32', 28 | 'cyan' => '0;36', 29 | 'light_cyan' => '1;36', 30 | 'red' => '0;31', 31 | 'light_red' => '1;31', 32 | 'purple' => '0;35', 33 | 'light_purple' => '1;35', 34 | 'brown' => '0;33', 35 | 'yellow' => '1;33', 36 | 'light_gray' => '0;37', 37 | 'white' => '1;37', 38 | ); 39 | 40 | protected $background_colors = array( 41 | 'black' => '40', 42 | 'red' => '41', 43 | 'green' => '42', 44 | 'yellow' => '43', 45 | 'blue' => '44', 46 | 'magenta' => '45', 47 | 'cyan' => '46', 48 | 'light_gray' => '47', 49 | ); 50 | 51 | /** 52 | * Constructor. Parses all the CLI params. 53 | */ 54 | public function __construct() 55 | { 56 | for ($i = 1; $i < $_SERVER['argc']; $i++) 57 | { 58 | $arg = explode('=', $_SERVER['argv'][$i]); 59 | 60 | $this->_args[$i] = $arg[0]; 61 | 62 | if (count($arg) > 1 || strncmp($arg[0], '-', 1) === 0) 63 | { 64 | $this->_args[ltrim($arg[0], '-')] = isset($arg[1]) ? $arg[1] : true; 65 | } 66 | } 67 | 68 | // Readline is an extension for PHP that makes interactive with PHP much more bash-like 69 | // http://www.php.net/manual/en/readline.installation.php 70 | $this->readline_support = extension_loaded('readline'); 71 | } 72 | 73 | /** 74 | * Returns the option with the given name. You can also give the option 75 | * number. 76 | * 77 | * Named options must be in the following formats: 78 | * php index.php user -v --v -name=John --name=John 79 | * 80 | * @param string|int $name the name of the option (int if unnamed) 81 | * @return string 82 | */ 83 | public function option($name, $default = null) 84 | { 85 | if ( ! isset($this->_args[$name])) 86 | { 87 | return $default; 88 | } 89 | return $this->_args[$name]; 90 | } 91 | 92 | 93 | /** 94 | * Get input from the shell, using readline or the standard STDIN 95 | * 96 | * Named options must be in the following formats: 97 | * php index.php user -v --v -name=John --name=John 98 | * 99 | * @param string|int $name the name of the option (int if unnamed) 100 | * @return string 101 | */ 102 | public function input($prefix = '') 103 | { 104 | if ($this->readline_support) 105 | { 106 | return readline($prefix); 107 | } 108 | 109 | echo $prefix; 110 | return fgets(STDIN); 111 | } 112 | 113 | 114 | /** 115 | * Asks the user for input. This can have either 1 or 2 arguments. 116 | * 117 | * Usage: 118 | * 119 | * // Waits for any key press 120 | * $this->cli->prompt(); 121 | * 122 | * // Takes any input 123 | * $color = $this->cli->prompt('What is your favorite color?'); 124 | * 125 | * // Takes any input, but offers default 126 | * $color = $this->cli->prompt('What is your favourite color?', 'white'); 127 | * 128 | * // Will only accept the options in the array 129 | * $ready = $this->cli->prompt('Are you ready?', array('y','n')); 130 | * 131 | * @return string the user input 132 | */ 133 | public function prompt() 134 | { 135 | $args = func_get_args(); 136 | 137 | $options = array(); 138 | $output = ''; 139 | $default = null; 140 | 141 | // How many we got 142 | $arg_count = count($args); 143 | 144 | // Is the last argument a boolean? True means required 145 | $required = end($args) === true; 146 | 147 | // Reduce the argument count if required was passed, we don't care about that anymore 148 | $required === true and --$arg_count; 149 | 150 | // This method can take a few crazy combinations of arguments, so lets work it out 151 | switch ($arg_count) 152 | { 153 | case 2: 154 | 155 | // E.g: $ready = $this->cli->prompt('Are you ready?', array('y','n')); 156 | if (is_array($args[1])) 157 | { 158 | list($output, $options)=$args; 159 | } 160 | 161 | // E.g: $color = $this->cli->prompt('What is your favourite color?', 'white'); 162 | elseif (is_string($args[1])) 163 | { 164 | list($output, $default)=$args; 165 | } 166 | 167 | break; 168 | 169 | case 1: 170 | 171 | // No question (probably been asked already) so just show options 172 | // E.g: $ready = $this->cli->prompt(array('y','n')); 173 | if (is_array($args[0])) 174 | { 175 | $options = $args[0]; 176 | } 177 | 178 | // Question without options 179 | // E.g: $ready = $this->cli->prompt('What did you do today?'); 180 | elseif (is_string($args[0])) 181 | { 182 | $output = $args[0]; 183 | } 184 | 185 | break; 186 | } 187 | 188 | // If a question has been asked with the read 189 | if ($output !== '') 190 | { 191 | $extra_output = ''; 192 | 193 | if ($default !== null) 194 | { 195 | $extra_output = ' [ Default: "'.$default.'" ]'; 196 | } 197 | 198 | elseif ($options !== array()) 199 | { 200 | $extra_output = ' [ '.implode(', ', $options).' ]'; 201 | } 202 | 203 | fwrite(STDOUT, $output.$extra_output.': '); 204 | } 205 | 206 | // Read the input from keyboard. 207 | ($input = trim($this->input())) or $input = $default; 208 | 209 | // No input provided and we require one (default will stop this being called) 210 | if (empty($input) and $required === true) 211 | { 212 | $this->write('This is required.'); 213 | $this->new_line(); 214 | 215 | $input = call_user_func(array($this, 'prompt'), $args); 216 | } 217 | 218 | // If options are provided and the choice is not in the array, tell them to try again 219 | if ( ! empty($options) && ! in_array($input, $options)) 220 | { 221 | $this->write('This is not a valid option. Please try again.'); 222 | $this->new_line(); 223 | 224 | $input = call_user_func_array(array($this, 'prompt'), $args); 225 | } 226 | 227 | return $input; 228 | } 229 | 230 | /** 231 | * Outputs a string to the cli. If you send an array it will implode them 232 | * with a line break. 233 | * 234 | * @param string|array $text the text to output, or array of lines 235 | */ 236 | public function write($text = '', $foreground = null, $background = null) 237 | { 238 | if (is_array($text)) 239 | { 240 | $text = implode(PHP_EOL, $text); 241 | } 242 | 243 | if ($foreground OR $background) 244 | { 245 | $text = $this->color($text, $foreground, $background); 246 | } 247 | 248 | fwrite(STDOUT, $text.PHP_EOL); 249 | } 250 | 251 | /** 252 | * Outputs an error to the CLI using STDERR instead of STDOUT 253 | * 254 | * @param string|array $text the text to output, or array of errors 255 | */ 256 | public function error($text = '', $foreground = 'light_red', $background = null) 257 | { 258 | if (is_array($text)) 259 | { 260 | $text = implode(PHP_EOL, $text); 261 | } 262 | 263 | if ($foreground OR $background) 264 | { 265 | $text = $this->color($text, $foreground, $background); 266 | } 267 | 268 | fwrite(STDERR, $text.PHP_EOL); 269 | } 270 | 271 | /** 272 | * Beeps a certain number of times. 273 | * 274 | * @param int $num the number of times to beep 275 | */ 276 | public function beep($num = 1) 277 | { 278 | echo str_repeat("\x07", $num); 279 | } 280 | 281 | /** 282 | * Waits a certain number of seconds, optionally showing a wait message and 283 | * waiting for a key press. 284 | * 285 | * @param int $seconds number of seconds 286 | * @param bool $countdown show a countdown or not 287 | */ 288 | public function wait($seconds = 0, $countdown = false) 289 | { 290 | if ($countdown === true) 291 | { 292 | $time = $seconds; 293 | 294 | while ($time > 0) 295 | { 296 | fwrite(STDOUT, $time.'... '); 297 | sleep(1); 298 | $time--; 299 | } 300 | $this->write(); 301 | } 302 | 303 | else 304 | { 305 | if ($seconds > 0) 306 | { 307 | sleep($seconds); 308 | } 309 | else 310 | { 311 | $this->write($this->wait_msg); 312 | $this->read(); 313 | } 314 | } 315 | } 316 | 317 | 318 | /** 319 | * if oprerating system === windows 320 | */ 321 | public function is_windows() 322 | { 323 | return 'win' === strtolower(substr(php_uname("s"), 0, 3)); 324 | } 325 | 326 | /** 327 | * Enter a number of empty lines 328 | * 329 | * @param integer Number of lines to output 330 | * @return void 331 | */ 332 | function new_line($num = 1) 333 | { 334 | // Do it once or more, write with empty string gives us a new line 335 | for($i = 0; $i < $num; $i++) 336 | { 337 | $this->write(); 338 | } 339 | } 340 | 341 | /** 342 | * Clears the screen of output 343 | * 344 | * @return void 345 | */ 346 | function clear_screen() 347 | { 348 | $this->is_windows() 349 | 350 | // Windows is a bit crap at this, but their terminal is tiny so shove this in 351 | ? $this->new_line(40) 352 | 353 | // Anything with a flair of Unix will handle these magic characters 354 | : fwrite(STDOUT, chr(27)."[H".chr(27)."[2J"); 355 | } 356 | 357 | /** 358 | * Returns the given text with the correct color codes for a foreground and 359 | * optionally a background color. 360 | * 361 | * @param string $text the text to color 362 | * @param atring $foreground the foreground color 363 | * @param string $background the background color 364 | * @return string the color coded string 365 | */ 366 | public function color($text, $foreground, $background = null) 367 | { 368 | if ($this->is_windows()) 369 | { 370 | return $text; 371 | } 372 | 373 | if ( ! array_key_exists($foreground, $this->foreground_colors)) 374 | { 375 | throw new Exception('Invalid CLI foreground color: '.$foreground); 376 | } 377 | 378 | if ( $background !== null and ! array_key_exists($background, $this->background_colors)) 379 | { 380 | throw new Exception('Invalid CLI background color: '.$background); 381 | } 382 | 383 | $string = "\033[".$this->foreground_colors[$foreground]."m"; 384 | 385 | if ($background !== null) 386 | { 387 | $string .= "\033[".$this->background_colors[$background]."m"; 388 | } 389 | 390 | $string .= $text."\033[0m"; 391 | 392 | return $string; 393 | } 394 | 395 | } 396 | 397 | /* End of file cli.php */ --------------------------------------------------------------------------------