2 /***************************************************************
5 * (c) 2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
28 * Contains base class for TYPO3 cli scripts
32 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
35 * [CLASS/FUNCTION INDEX of SCRIPT]
40 * 83: function t3lib_cli()
41 * 96: function cli_getArg($option,$argv)
42 * 112: function cli_getArgIndex()
43 * 131: function cli_keyboardInput()
44 * 142: function cli_keyboardInput_yes()
45 * 154: function cli_echo($string='',$force=FALSE)
46 * 169: function cli_help()
47 * 207: function cli_indent($str,$indent)
50 * (This index is automatically created/updated by the extension "extdeveval")
56 * TYPO3 cli script basis
58 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
64 var $cli_args = array(); // Command line arguments, exploded into key => value-array pairs
65 var $cli_options = array(
66 array('-s','Silent operation, will only output errors and important messages.'),
67 array('--silent','Same as -s'),
68 array('-ss','Super silent, will not even output errors or important messages.'),
70 var $cli_help = array(
71 'name' => 'CLI base class (overwrite this...)',
72 'synopsis' => '###OPTIONS###',
73 'description' => 'Class with basic functionality for CLI scripts (overwrite this...)',
74 'examples' => 'Give examples...',
76 'license' => 'GNU GPL - free software!',
77 'author' => '[Author name]',
84 * Make sure child classes also call this!
88 function t3lib_cli() {
89 // Loads the cli_args array with command line arguments
90 $this->cli_args
= $this->cli_getArgIndex();
94 * Finds the arg token (like "-s") in argv and returns the rest of argv from that point on.
95 * This should only be used in special cases since this->cli_args should already be prepared with an index of values!
97 * @param string Option string, eg. "-s"
98 * @param array Input argv array
99 * @return array Output argv array with all options AFTER the found option.
101 function cli_getArgArray($option,$argv) {
102 while (count($argv) && strcmp($argv[0],$option)) {
106 if (!strcmp($argv[0],$option)) {
108 return count($argv) ?
$argv : array('');
113 * Return true if option is found
115 * @param string Option string, eg. "-s"
116 * @return boolean TRUE if option found
118 function cli_isArg($option) {
119 return isset($this->cli_args
[$option]);
123 * Return argument value
125 * @param string Option string, eg. "-s"
126 * @param integer Value index, default is 0 (zero) = the first one...
127 * @return boolean TRUE if option found
129 function cli_argValue($option,$idx=0) {
130 return is_array($this->cli_args
[$option]) ?
$this->cli_args
[$option][$idx] : '';
134 * Will parse "_SERVER[argv]" into an index of options and values
135 * Argument names (eg. "-s") will be keys and values after (eg. "-s value1 value2 ..." or "-s=value1") will be in the array.
136 * Array is empty if no values
140 function cli_getArgIndex() {
141 $cli_options = array();
143 foreach($_SERVER['argv'] as $token) {
144 if ($token{0}==='-' && !t3lib_div
::testInt($token{1})) { // Options starting with a number is invalid - they could be negative values... !
145 list($index,$opt) = explode('=',$token,2);
146 if (isset($cli_options[$index])) {
147 echo 'ERROR: Option '.$index.' was used twice!'.chr(10);
150 $cli_options[$index] = array();
152 $cli_options[$index][] = $opt;
155 $cli_options[$index][] = $token;
162 * Validates if the input arguments in this->cli_args are all listed in this->cli_options and if not, will exit with an error.
164 function cli_validateArgs() {
165 $cli_args_copy = $this->cli_args
;
166 unset($cli_args_copy['_DEFAULT']);
167 $allOptions = array();
169 foreach($this->cli_options
as $cfg) {
170 $allOptions[] = $cfg[0];
171 $argSplit = t3lib_div
::trimExplode(' ',$cfg[0],1);
172 if (isset($cli_args_copy[$argSplit[0]])) {
174 foreach($argSplit as $i => $v) {
177 if (!isset($cli_args_copy[$argSplit[0]][$i-1]) && $v{0}!='[') { // Using "[]" around a paramter makes it optional
178 echo 'ERROR: Option "'.$argSplit[0].'" requires a value ("'.$v.'") on position '.$i.chr(10);
185 if (isset($cli_args_copy[$argSplit[0]][$ii-1])) {
186 echo 'ERROR: Option "'.$argSplit[0].'" does not support a value on position '.$ii.chr(10);
190 unset($cli_args_copy[$argSplit[0]]);
194 if (count($cli_args_copy)) {
195 echo wordwrap('ERROR: Option '.implode(',',array_keys($cli_args_copy)).' was unknown to this script!'.chr(10).'(Options are: '.implode(', ',$allOptions).')'.chr(10));
201 * Asks stdin for keyboard input and returns the line (after enter is pressed)
205 function cli_keyboardInput() {
207 // Have to open the stdin stream only ONCE! otherwise I cannot read multiple lines from it... :
209 $this->stdin
= fopen('php://stdin', 'r');
212 while (FALSE == ($line = fgets($this->stdin
,1000))) {}
218 * Asks for Yes/No from shell and returns true if "y" or "yes" is found as input.
220 * @param string String to ask before...
221 * @return boolean TRUE if "y" or "yes" is the input (case insensitive)
223 function cli_keyboardInput_yes($msg='') {
224 echo $msg.' (Yes/No + return): '; // ONLY makes sense to echo it out since we are awaiting keyboard input - that cannot be silenced...
225 return t3lib_div
::inList('y,yes',strtolower($this->cli_keyboardInput()));
229 * Echos strings to shell, but respective silent-modes
231 * @param string The string
232 * @param boolean If string should be written even if -s is set (-ss will subdue it!)
233 * @return boolean Returns TRUE if string was outputted.
235 function cli_echo($string='',$force=FALSE) {
236 if (isset($this->cli_args
['-ss'])) {
238 } elseif (isset($this->cli_args
['-s']) ||
isset($this->cli_args
['--silent'])) {
239 if ($force) { echo $string; return TRUE; }
240 } else { echo $string; return TRUE; }
246 * Prints help-output from ->cli_help array
250 function cli_help() {
251 foreach($this->cli_help
as $key => $value) {
252 $this->cli_echo(strtoupper($key).":\n");
256 foreach ($this->cli_options
as $v) {
257 $optStr.=' ['.$v[0].']';
259 $this->cli_echo($this->cli_indent(str_replace('###OPTIONS###',trim($optStr),$value),4)."\n\n");
262 $this->cli_echo($this->cli_indent($value,4)."\n");
265 foreach ($this->cli_options
as $v) {
266 if (strlen($v[0])>$maxLen) $maxLen=strlen($v[0]);
269 foreach ($this->cli_options
as $v) {
270 $this->cli_echo($v[0].substr($this->cli_indent(rtrim($v[1].chr(10).$v[2]),$maxLen+
4),strlen($v[0]))."\n");
272 $this->cli_echo("\n");
275 $this->cli_echo($this->cli_indent($value,4)."\n\n");
282 * Indentation function for 75 char wide lines.
284 * @param string String to break and indent.
285 * @param integer Number of space chars to indent.
286 * @return string Result
288 function cli_indent($str,$indent) {
289 $lines = explode(chr(10),wordwrap($str,75-$indent));
290 $indentStr = str_pad('',$indent,' ');
291 foreach($lines as $k => $v) {
292 $lines[$k] = $indentStr.$lines[$k];
294 return implode(chr(10),$lines);