Issues (20)

src/ConsoleApplication.php (4 issues)

1
<?php
2
3
namespace Ballen\Clip;
4
5
use Ballen\Clip\Utilities\ArgumentsParser;
6
use Ballen\Clip\Utilities\CommandRouter;
7
use InvalidArgumentException;
8
9
/**
10
 * Clip
11
 * 
12
 * A package for speeding up development of PHP console (CLI) applications.
13
 *
14
 * @author Bobby Allen <[email protected]>
15
 * @license https://raw.githubusercontent.com/bobsta63/clip/master/LICENSE
16
 * @link https://github.com/allebb/clip
17
 * @link http://www.bobbyallen.me
18
 *
19
 */
20
class ConsoleApplication
21
{
22
23
    /**
24
     * The CLI arguments
25
     * @var ArgumentsParser
26
     */
27
    private $arguments;
28
29
    /**
30
     * Command routing configuration.
31
     * @var CommandRouter 
32
     */
33
    private $router;
34
35
    /**
36
     * Console Application Constructor
37
     * @param ArgumentsParser $argv The PHP $argv array (Pass $argv global if you wish to access the CLI arguments)
38
     */
39 12
    public function __construct(ArgumentsParser $argv)
40
    {
41 12
        $this->arguments = $argv;
42 12
        $this->router = new CommandRouter();
43
    }
44
45
    /**
46
     * Returns the CLI arguments exposed to the CLI application.
47
     * @return ArgumentsParser
48
     */
49 2
    public function arguments()
50
    {
51 2
        return $this->arguments;
52
    }
53
54
    /**
55
     * Returns the router instance.
56
     * @return CommandRouter
57
     */
58 2
    public function router()
59
    {
60 2
        return $this->router;
61
    }
62
63
    /**
64
     * Enforces that the script must be run at the console.
65
     * @param boolean $enforced Enforce execution only through the CLI.
66
     * @param string $error_message Custom error message.
67
     * @return void
68
     */
69
    public function enforceCli($enforced = false, $error_message = 'CLI execution permitted only!')
70
    {
71
        if ($enforced && (php_sapi_name() != "cli")) {
72
            die($error_message);
73
        }
74
    }
75
76
    /**
77
     * Checks that the user is root!
78
     * @return boolean
79
     */
80
    public function isSuperUser()
81
    {
82
        if (!function_exists('posix_getuid')) {
83
            throw new RuntimeException('The isSuperUser() method requires the PHP POSIX extention to be enabled!');
0 ignored issues
show
The type Ballen\Clip\RuntimeException was not found. Did you mean RuntimeException? If so, make sure to prefix the type with \.
Loading history...
84
        }
85
        if (posix_getuid() == 0) {
86
            return true;
87
        }
88
        return false;
89
    }
90
91
    /**
92
     * Executes a system command.
93
     * @param string $command The command to execute.
94
     * @return string
95
     */
96
    public function call($command)
97
    {
98
        return system($command);
99
    }
100
101
    /**
102
     * Write to the console.
103
     * @param string $text The text to output.
104
     * @return \Ballen\Clip\ConsoleApplication
105
     */
106
    public function write($text = '')
107
    {
108
        fwrite(STDOUT, $text);
109
        return $this;
110
    }
111
112
    /**
113
     * Write a line of characters (or an empty line) to the CLI.
114
     * @param string $text The text to output.
115
     * @return \Ballen\Clip\ConsoleApplication
116
     */
117
    public function writeln($text = '')
118
    {
119
        $this->write($text . PHP_EOL);
120
        return $this;
121
    }
122
123
    /**
124
     * Request user input
125
     * @param string $question The input question/text
126
     * @param string $default A default value if one is not selected.
127
     * @param array $options Valid options that are acceptable, these are case insensitive!
128
     * @return string
129
     */
130
    public function input($question, $default = '', $options = [])
131
    {
132
        if (empty($default)) {
133
            $this->write($question . ' ');
134
        } elseif (empty($options)) {
135
            $this->write($question . ' [' . $default . '] ');
136
        } else {
137
            $available_options = [];
138
            foreach (strtolower($options) as $option) {
0 ignored issues
show
$options of type array is incompatible with the type string expected by parameter $string of strtolower(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

138
            foreach (strtolower(/** @scrutinizer ignore-type */ $options) as $option) {
Loading history...
The expression strtolower($options) of type string is not traversable.
Loading history...
139
                if ($option === strtolower($default)) {
140
                    $option = strtoupper($option);
141
                }
142
                $available_options[] = $option;
143
            }
144
            $available_opts = rtrim(implode($available_options, '/'), '/');
145
            $this->write($question . ' [' . $available_opts . '] ');
146
        }
147
        $answer = rtrim(fgets(STDIN), PHP_EOL);
148
        if (empty($answer)) {
149
            return $default;
150
        }
151
        if (count($options) > 0) {
152
            if (!in_array(strtolower($answer), array_map('strtolower', $options))) {
153
                return $this->input($question, $default, $options);
154
            }
155
            return $answer;
156
        }
157
        return $answer;
158
    }
159
160
    /**
161
     * Writes an array to the CLI output
162
     * @param array $array The array of data to write to the console.
163
     * @return \Ballen\Clip\ConsoleApplication
164
     */
165
    public function writearr($array = [])
166
    {
167
        print_r($array);
168
        return $this;
169
    }
170
171
    /**
172
     * Exits with a specific status code.
173
     * @param int $status The status code to exit with.
174
     * @throws InvalidArgumentException
175
     */
176
    public function exitWithStatus($status = 0)
177
    {
178
        if (!is_int($status)) {
179
            throw new InvalidArgumentException('The status code must be an integer value.');
180
        }
181
        exit($status);
182
    }
183
184
    /**
185
     * Exits the CLI with status code 0 (Successful)
186
     * @return void
187
     */
188
    public function exitWithSuccess()
189
    {
190
        $this->exitWithStatus(0);
191
    }
192
193
    /**
194
     * Exits the CLI with statu code 1 (Error)
195
     * @return void
196
     */
197
    public function exitWithError()
198
    {
199
        $this->exitWithStatus(1);
200
    }
201
202
    /**
203
     * Run the current application.
204
     * @return void
205
     */
206
    public function run()
207
    {
208
        $this->router()->dispatch($this->arguments()->getCommand(1));
0 ignored issues
show
It seems like $this->arguments()->getCommand(1) can also be of type false; however, parameter $call of Ballen\Clip\Utilities\CommandRouter::dispatch() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

208
        $this->router()->dispatch(/** @scrutinizer ignore-type */ $this->arguments()->getCommand(1));
Loading history...
209
    }
210
}
211