See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 401]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * Command line utility functions and classes 20 * 21 * @package core 22 * @subpackage cli 23 * @copyright 2009 Petr Skoda (http://skodak.org) 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 // NOTE: no MOODLE_INTERNAL test here, sometimes we use this before requiring Moodle libs! 28 29 /** 30 * Write a text to the given stream 31 * 32 * @param string $text text to be written 33 * @param resource $stream output stream to be written to, defaults to STDOUT 34 */ 35 function cli_write($text, $stream=STDOUT) { 36 fwrite($stream, $text); 37 } 38 39 /** 40 * Write a text followed by an end of line symbol to the given stream 41 * 42 * @param string $text text to be written 43 * @param resource $stream output stream to be written to, defaults to STDOUT 44 */ 45 function cli_writeln($text, $stream=STDOUT) { 46 cli_write($text.PHP_EOL, $stream); 47 } 48 49 /** 50 * Get input from user 51 * @param string $prompt text prompt, should include possible options 52 * @param string $default default value when enter pressed 53 * @param array $options list of allowed options, empty means any text 54 * @param bool $casesensitive true if options are case sensitive 55 * @return string entered text 56 */ 57 function cli_input($prompt, $default='', array $options=null, $casesensitiveoptions=false) { 58 cli_writeln($prompt); 59 cli_write(': '); 60 $input = fread(STDIN, 2048); 61 $input = trim($input); 62 if ($input === '') { 63 $input = $default; 64 } 65 if ($options) { 66 if (!$casesensitiveoptions) { 67 $input = strtolower($input); 68 } 69 if (!in_array($input, $options)) { 70 cli_writeln(get_string('cliincorrectvalueretry', 'admin')); 71 return cli_input($prompt, $default, $options, $casesensitiveoptions); 72 } 73 } 74 return $input; 75 } 76 77 /** 78 * Returns cli script parameters. 79 * @param array $longoptions array of --style options ex:('verbose'=>false) 80 * @param array $shortmapping array describing mapping of short to long style options ex:('h'=>'help', 'v'=>'verbose') 81 * @return array array of arrays, options, unrecognised as optionlongname=>value 82 */ 83 function cli_get_params(array $longoptions, array $shortmapping=null) { 84 $shortmapping = (array)$shortmapping; 85 $options = array(); 86 $unrecognized = array(); 87 88 if (empty($_SERVER['argv'])) { 89 // bad luck, we can continue in interactive mode ;-) 90 return array($options, $unrecognized); 91 } 92 $rawoptions = $_SERVER['argv']; 93 94 //remove anything after '--', options can not be there 95 if (($key = array_search('--', $rawoptions)) !== false) { 96 $rawoptions = array_slice($rawoptions, 0, $key); 97 } 98 99 //remove script 100 unset($rawoptions[0]); 101 foreach ($rawoptions as $raw) { 102 if (substr($raw, 0, 2) === '--') { 103 $value = substr($raw, 2); 104 $parts = explode('=', $value); 105 if (count($parts) == 1) { 106 $key = reset($parts); 107 $value = true; 108 109 if (substr($key, 0, 3) === 'no-' && !array_key_exists($key, $longoptions) 110 && array_key_exists(substr($key, 3), $longoptions)) { 111 // Support flipping the boolean value. 112 $value = !$value; 113 $key = substr($key, 3); 114 } 115 } else { 116 $key = array_shift($parts); 117 $value = implode('=', $parts); 118 } 119 if (array_key_exists($key, $longoptions)) { 120 $options[$key] = $value; 121 } else { 122 $unrecognized[] = $raw; 123 } 124 125 } else if (substr($raw, 0, 1) === '-') { 126 $value = substr($raw, 1); 127 $parts = explode('=', $value); 128 if (count($parts) == 1) { 129 $key = reset($parts); 130 $value = true; 131 } else { 132 $key = array_shift($parts); 133 $value = implode('=', $parts); 134 } 135 if (array_key_exists($key, $shortmapping)) { 136 $options[$shortmapping[$key]] = $value; 137 } else { 138 $unrecognized[] = $raw; 139 } 140 } else { 141 $unrecognized[] = $raw; 142 continue; 143 } 144 } 145 //apply defaults 146 foreach ($longoptions as $key=>$default) { 147 if (!array_key_exists($key, $options)) { 148 $options[$key] = $default; 149 } 150 } 151 // finished 152 return array($options, $unrecognized); 153 } 154 155 /** 156 * This sets the cli process title suffix 157 * 158 * An example is appending current Task API info so a sysadmin can immediately 159 * see what task a cron process is running at any given moment. 160 * 161 * @param string $suffix process suffix 162 */ 163 function cli_set_process_title_suffix(string $suffix) { 164 if (CLI_SCRIPT && function_exists('cli_set_process_title') && isset($_SERVER['argv'])) { 165 $command = join(' ', $_SERVER['argv']); 166 @cli_set_process_title("php $command ($suffix)"); 167 } 168 } 169 170 /** 171 * Print or return section separator string 172 * @param bool $return false means print, true return as string 173 * @return mixed void or string 174 */ 175 function cli_separator($return=false) { 176 $separator = str_repeat('-', 79).PHP_EOL; 177 if ($return) { 178 return $separator; 179 } else { 180 cli_write($separator); 181 } 182 } 183 184 /** 185 * Print or return section heading string 186 * @param string $string text 187 * @param bool $return false means print, true return as string 188 * @return mixed void or string 189 */ 190 function cli_heading($string, $return=false) { 191 $string = "== $string ==".PHP_EOL; 192 if ($return) { 193 return $string; 194 } else { 195 cli_write($string); 196 } 197 } 198 199 /** 200 * Write error notification 201 * @param $text 202 * @return void 203 */ 204 function cli_problem($text) { 205 cli_writeln($text, STDERR); 206 } 207 208 /** 209 * Write to standard error output and exit with the given code 210 * 211 * @param string $text 212 * @param int $errorcode 213 * @return void (does not return) 214 */ 215 function cli_error($text, $errorcode=1) { 216 cli_writeln($text.PHP_EOL, STDERR); 217 die($errorcode); 218 } 219 220 /** 221 * Print an ASCII version of the Moodle logo. 222 * 223 * @param int $padding left padding of the logo 224 * @param bool $return should we print directly (false) or return the string (true) 225 * @return mixed void or string 226 */ 227 function cli_logo($padding=2, $return=false) { 228 229 $lines = array( 230 ' .-..-. ', 231 ' _____ | || | ', 232 '/____/-.---_ .---. .---. .-.| || | .---. ', 233 '| | _ _ |/ _ \\/ _ \\/ _ || |/ __ \\', 234 '* | | | | | || |_| || |_| || |_| || || |___/', 235 ' |_| |_| |_|\\_____/\\_____/\\_____||_|\\_____)', 236 ); 237 238 $logo = ''; 239 240 foreach ($lines as $line) { 241 $logo .= str_repeat(' ', $padding); 242 $logo .= $line; 243 $logo .= PHP_EOL; 244 } 245 246 if ($return) { 247 return $logo; 248 } else { 249 cli_write($logo); 250 } 251 } 252 253 /** 254 * Substitute cursor, colour, and bell placeholders in a CLI output to ANSI escape characters when ANSI is available. 255 * 256 * @param string $message 257 * @return string 258 */ 259 function cli_ansi_format(string $message): string { 260 global $CFG; 261 262 $replacements = [ 263 "<newline>" => "\n", 264 "<bell>" => "\007", 265 266 // Cursor movement: https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html. 267 "<cursor:save>" => "\033[s", 268 "<cursor:restore>" => "\033[u", 269 "<cursor:up>" => "\033[1A", 270 "<cursor:down>" => "\033[1B", 271 "<cursor:forward>" => "\033[1C", 272 "<cursor:back>" => "\033[1D", 273 ]; 274 275 $colours = [ 276 'normal' => '0;0', 277 'black' => '0;30', 278 'darkGray' => '1;30', 279 'red' => '0;31', 280 'lightRed' => '1;31', 281 'green' => '0;32', 282 'lightGreen' => '1;32', 283 'brown' => '0;33', 284 'yellow' => '1;33', 285 'lightYellow' => '0;93', 286 'blue' => '0;34', 287 'lightBlue' => '1;34', 288 'purple' => '0;35', 289 'lightPurple' => '1;35', 290 'cyan' => '0;36', 291 'lightCyan' => '1;36', 292 'lightGray' => '0;37', 293 'white' => '1;37', 294 ]; 295 $bgcolours = [ 296 'black' => '40', 297 'red' => '41', 298 'green' => '42', 299 'yellow' => '43', 300 'blue' => '44', 301 'magenta' => '45', 302 'cyan' => '46', 303 'white' => '47', 304 ]; 305 306 foreach ($colours as $colour => $code) { 307 $replacements["<colour:{$colour}>"] = "\033[{$code}m"; 308 } 309 foreach ($bgcolours as $colour => $code) { 310 $replacements["<bgcolour:{$colour}>"] = "\033[{$code}m"; 311 } 312 313 // Windows don't support ANSI code by default, but does if ANSICON is available. 314 $isansicon = getenv('ANSICON'); 315 if (($CFG->ostype === 'WINDOWS') && empty($isansicon)) { 316 return str_replace(array_keys($replacements), '', $message); 317 } 318 319 return str_replace(array_keys($replacements), array_values($replacements), $message); 320 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body