Completed
Push — 4.9 ( 33aa8a...e292e7 )
by Mikhail
02:18 queued 26s
created

Terminal::echo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace terminal;
4
5
/**
6
 * class for terminal/cli/bash output
7
 */
8
final class Terminal {
9
    private $argv;
10
    private $argc;
11
    private $arguments = [];
12
13
    public function __construct()
14
    {
15
        global $argv;
16
        global $argc;
17
18
        $this->argv = $argv;
19
        $this->argc = $argc;
20
21
        $this->parseArguments();
22
    }
23
24
    public function echo(string $string)
25
    {
26
        echo $string . PHP_EOL;
27
    }
28
29
    public function diff(string $string)
30
    {
31
        $result_string = '';
32
        $separator = "\r\n";
33
        $line = strtok($string, $separator);
34
35
        while ($line !== false) {
36
            if (strpos($line, '-') === 0) {
37
                $result_string .= $this->error($line, false, true);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->error($line, false, true) targeting terminal\Terminal::error() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to terminal\Terminal::error() has too many arguments starting with false. ( Ignorable by Annotation )

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

37
                $result_string .= $this->/** @scrutinizer ignore-call */ error($line, false, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
38
            } else if (strpos($line, '+') === 0) {
39
                $result_string .= $this->success($line, false, true);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->success($line, false, true) targeting terminal\Terminal::success() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to terminal\Terminal::success() has too many arguments starting with false. ( Ignorable by Annotation )

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

39
                $result_string .= $this->/** @scrutinizer ignore-call */ success($line, false, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
40
            } else {
41
                $result_string .= $line;
42
            }
43
44
            $result_string .= PHP_EOL;
45
46
            $line = strtok($separator);
47
        }
48
49
        $this->echo($result_string);
50
    }
51
52
    public function info(string $string)
53
    {
54
        $this->echo("\e[46m" . $string . "\e[0m");    
55
    }
56
57
    public function success(string $string)
58
    {
59
        $this->echo("\e[32m" . $string . "\e[0m");
60
    }
61
62
    public function warning(string $string)
63
    {
64
        $this->echo("\e[43m" . $string . "\e[0m");
65
    }
66
67
    public function error(string $string)
68
    {
69
        $this->echo("\e[1;31m" . $string . "\e[0m");
70
    }
71
72
    /**
73
     * Requests user for confirm his action
74
     * 
75
     * @param callable $success_action
76
     * @param callable $cancel_action
77
     * @param string $question
78
     * @param string $confirmation_word
79
     */
80
    public function confirm(
81
        callable    $success_action,
82
        callable    $cancel_action     = null,
83
        string      $question          = "Are you sure?\n Type 'Y' to continue: ",
84
        string      $confirmation_word = 'Y'
85
    ): void
86
    {
87
        $this->warning($question);
88
        $handle = fopen('php://stdin', 'r');
89
        $line   = fgets($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of fgets() does only seem to accept resource, 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

89
        $line   = fgets(/** @scrutinizer ignore-type */ $handle);
Loading history...
90
91
        if(trim($line) != $confirmation_word) {
92
            $this->warning('ABORTING');
93
            call_user_func($cancel_action);
94
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
95
        }
96
97
        fclose($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, 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

97
        fclose(/** @scrutinizer ignore-type */ $handle);
Loading history...
98
        call_user_func($success_action);
99
    }
100
101
    /**
102
     * Requests config item from user 
103
     */
104
    public function requestSetting(
105
        string $name,
106
        callable $result_action,
107
        $default = ''
108
    ): void
109
    {
110
        $this->echo("Please, set up $name");
111
        $handle = fopen('php://stdin', 'r');
112
        $line   = fgets($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of fgets() does only seem to accept resource, 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

112
        $line   = fgets(/** @scrutinizer ignore-type */ $handle);
Loading history...
113
        $result = trim($line);
114
115
        call_user_func($result_action, $result ?: $default);
116
        fclose($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, 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

116
        fclose(/** @scrutinizer ignore-type */ $handle);
Loading history...
117
    }
118
119
    /**
120
     * Set arguments
121
     * 
122
     * @param array  $arguments
123
     * 
124
     * @return void
125
     */
126
    public function setArguments(array $arguments): void
127
    {
128
        $this->arguments = $arguments;
129
    }
130
131
    /**
132
     * Get arguments
133
     * 
134
     * @return array
135
     */
136
    public function getArguments(): array
137
    {
138
        return $this->arguments;
139
    }
140
141
    /**
142
     * Parse arguments from terminal to array
143
     * 
144
     * @return void
145
     */
146
    private function parseArguments(): void
147
    {
148
        $arguments = arguments(implode(' ', $this->argv));
149
        $controller = @$this->argv[1] ?: '';
150
        list($generator, $command) = array_pad(explode('/', $controller), 2, '');
151
        $generator = (1 === preg_match('/^[\w]+/ui', $generator)) ? $generator : '';
152
153
        $arguments['generator'] = to_camel_case($generator);
154
        $arguments['command'] = $command;
155
        $this->setArguments($arguments);
156
    }
157
158
    /**
159
     * Cheks is terminal at autocomplete mode
160
     * 
161
     * @return bool
162
     */
163
    public function isAutocomplete()
164
    {
165
        return (
166
            isset($this->arguments['autocomplete'])
167
            && $this->arguments['autocomplete'] === 'y'
168
        );
169
    }
170
171
    /**
172
     * Echo autocompletes to terminal
173
     * 
174
     * @param array
175
     * 
176
     * @return Terminal
177
     */
178
    public function autocomplete(array $variants)
179
    {
180
        echo implode(' ', $variants) . ' ';
181
182
        return $this;
183
    }
184
185
    /**
186
     * Closes program execution
187
     * @codeCoverageIgnore
188
     */
189
    public function exit()
190
    {
191
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
192
    }
193
}
194