Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_tceforms_inline
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_cli.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2006-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
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.
13 *
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.
18 *
19 *
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.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains base class for TYPO3 cli scripts
29 *
30 * $Id$
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 */
34 /**
35 * [CLASS/FUNCTION INDEX of SCRIPT]
36 *
37 *
38 *
39 * 60: class t3lib_cli
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)
48 *
49 * TOTAL FUNCTIONS: 8
50 * (This index is automatically created/updated by the extension "extdeveval")
51 *
52 */
53
54
55 /**
56 * TYPO3 cli script basis
57 *
58 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
59 * @package TYPO3
60 * @subpackage t3lib
61 */
62 class t3lib_cli {
63
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.'),
69 );
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...',
75 'options' => '',
76 'license' => 'GNU GPL - free software!',
77 'author' => '[Author name]',
78 );
79 var $stdin = NULL;
80
81
82 /**
83 * Constructor
84 * Make sure child classes also call this!
85 *
86 * @return void
87 */
88 function t3lib_cli() {
89 // Loads the cli_args array with command line arguments
90 $this->cli_args = $this->cli_getArgIndex();
91 }
92
93 /**
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!
96 *
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.
100 */
101 function cli_getArgArray($option, $argv) {
102 while (count($argv) && strcmp($argv[0], $option)) {
103 array_shift($argv);
104 }
105
106 if (!strcmp($argv[0], $option)) {
107 array_shift($argv);
108 return count($argv) ? $argv : array('');
109 }
110 }
111
112 /**
113 * Return true if option is found
114 *
115 * @param string Option string, eg. "-s"
116 * @return boolean TRUE if option found
117 */
118 function cli_isArg($option) {
119 return isset($this->cli_args[$option]);
120 }
121
122 /**
123 * Return argument value
124 *
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
128 */
129 function cli_argValue($option, $idx = 0) {
130 return is_array($this->cli_args[$option]) ? $this->cli_args[$option][$idx] : '';
131 }
132
133 /**
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
137 *
138 * @return array
139 */
140 function cli_getArgIndex() {
141 $cli_options = array();
142 $index = '_DEFAULT';
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!' . LF;
148 exit;
149 }
150 $cli_options[$index] = array();
151 if (isset($opt)) {
152 $cli_options[$index][] = $opt;
153 }
154 } else {
155 $cli_options[$index][] = $token;
156 }
157 }
158
159 return $cli_options;
160 }
161
162 /**
163 * 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 */
165 function cli_validateArgs() {
166 $cli_args_copy = $this->cli_args;
167 unset($cli_args_copy['_DEFAULT']);
168 $allOptions = array();
169
170 foreach ($this->cli_options as $cfg) {
171 $allOptions[] = $cfg[0];
172 $argSplit = t3lib_div::trimExplode(' ', $cfg[0], 1);
173 if (isset($cli_args_copy[$argSplit[0]])) {
174
175 foreach ($argSplit as $i => $v) {
176 $ii = $i;
177 if ($i > 0) {
178 if (!isset($cli_args_copy[$argSplit[0]][$i - 1]) && $v{0} != '[') { // Using "[]" around a paramter makes it optional
179 echo 'ERROR: Option "' . $argSplit[0] . '" requires a value ("' . $v . '") on position ' . $i . LF;
180 exit;
181 }
182 }
183 }
184
185 $ii++;
186 if (isset($cli_args_copy[$argSplit[0]][$ii - 1])) {
187 echo 'ERROR: Option "' . $argSplit[0] . '" does not support a value on position ' . $ii . LF;
188 exit;
189 }
190
191 unset($cli_args_copy[$argSplit[0]]);
192 }
193 }
194
195 if (count($cli_args_copy)) {
196 echo wordwrap('ERROR: Option ' . implode(',', array_keys($cli_args_copy)) . ' was unknown to this script!' . LF . '(Options are: ' . implode(', ', $allOptions) . ')' . LF);
197 exit;
198 }
199 }
200
201 /**
202 * Asks stdin for keyboard input and returns the line (after enter is pressed)
203 *
204 * @return string
205 */
206 function cli_keyboardInput() {
207
208 // Have to open the stdin stream only ONCE! otherwise I cannot read multiple lines from it... :
209 if (!$this->stdin) {
210 $this->stdin = fopen('php://stdin', 'r');
211 }
212
213 while (FALSE == ($line = fgets($this->stdin, 1000))) {
214 }
215
216 return trim($line);
217 }
218
219 /**
220 * Asks for Yes/No from shell and returns true if "y" or "yes" is found as input.
221 *
222 * @param string String to ask before...
223 * @return boolean TRUE if "y" or "yes" is the input (case insensitive)
224 */
225 function cli_keyboardInput_yes($msg = '') {
226 echo $msg . ' (Yes/No + return): '; // ONLY makes sense to echo it out since we are awaiting keyboard input - that cannot be silenced...
227
228 return t3lib_div::inList('y,yes', strtolower($this->cli_keyboardInput()));
229 }
230
231 /**
232 * Echos strings to shell, but respective silent-modes
233 *
234 * @param string The string
235 * @param boolean If string should be written even if -s is set (-ss will subdue it!)
236 * @return boolean Returns TRUE if string was outputted.
237 */
238 function cli_echo($string = '', $force = FALSE) {
239 if (isset($this->cli_args['-ss'])) {
240 // Nothing to do...
241 } elseif (isset($this->cli_args['-s']) || isset($this->cli_args['--silent'])) {
242 if ($force) {
243 echo $string;
244 return TRUE;
245 }
246 } else {
247 echo $string;
248 return TRUE;
249 }
250
251 return FALSE;
252 }
253
254 /**
255 * Prints help-output from ->cli_help array
256 *
257 * @return void
258 */
259 function cli_help() {
260 foreach ($this->cli_help as $key => $value) {
261 $this->cli_echo(strtoupper($key) . ":\n");
262 switch ($key) {
263 case 'synopsis':
264 $optStr = '';
265 foreach ($this->cli_options as $v) {
266 $optStr .= ' [' . $v[0] . ']';
267 }
268 $this->cli_echo($this->cli_indent(str_replace('###OPTIONS###', trim($optStr), $value), 4) . "\n\n");
269 break;
270 case 'options':
271 $this->cli_echo($this->cli_indent($value, 4) . LF);
272
273 $maxLen = 0;
274 foreach ($this->cli_options as $v) {
275 if (strlen($v[0]) > $maxLen) {
276 $maxLen = strlen($v[0]);
277 }
278 }
279
280 foreach ($this->cli_options as $v) {
281 $this->cli_echo($v[0] . substr($this->cli_indent(rtrim($v[1] . LF . $v[2]), $maxLen + 4), strlen($v[0])) . LF);
282 }
283 $this->cli_echo(LF);
284 break;
285 default:
286 $this->cli_echo($this->cli_indent($value, 4) . "\n\n");
287 break;
288 }
289 }
290 }
291
292 /**
293 * Indentation function for 75 char wide lines.
294 *
295 * @param string String to break and indent.
296 * @param integer Number of space chars to indent.
297 * @return string Result
298 */
299 function cli_indent($str, $indent) {
300 $lines = explode(LF, wordwrap($str, 75 - $indent));
301 $indentStr = str_pad('', $indent, ' ');
302 foreach ($lines as $k => $v) {
303 $lines[$k] = $indentStr . $lines[$k];
304 }
305
306 return implode(LF, $lines);
307 }
308 }
309
310 ?>