Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}