Passed
Pull Request — master (#116)
by Théo
02:04
created

IO   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 33
dl 0
loc 181
rs 9.3999
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A isInteractive() 0 3 1
B checkInteractivity() 0 17 6
A hasColorSupport() 0 3 1
A __construct() 0 8 1
A hasParameter() 0 16 3
C checkColorSupport() 0 32 11
A getVerbosity() 0 3 1
D configureVerbosity() 0 37 9
1
<?php
2
3
/*
4
 * This file is part of the box project.
5
 *
6
 * (c) Kevin Herrera <[email protected]>
7
 *     Théo Fidry <[email protected]>
8
 *
9
 * This source file is subject to the MIT license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace KevinGH\RequirementChecker;
14
15
/**
16
 * The code in this file must be PHP 5.3+ compatible as is used to know if the application can be run.
17
 *
18
 * @private
19
 */
20
final class IO
21
{
22
    const VERBOSITY_QUIET = 16;
23
    const VERBOSITY_NORMAL = 32;
24
    const VERBOSITY_VERBOSE = 64;
25
    const VERBOSITY_VERY_VERBOSE = 128;
26
    const VERBOSITY_DEBUG = 256;
27
28
    private $interactive;
29
    private $verbosity = self::VERBOSITY_NORMAL;
30
    private $colorSupport;
31
    private $options;
32
33
    public function __construct()
34
    {
35
        $this->options = \implode(' ', $_SERVER['argv']);
36
37
        $shellVerbosity = $this->configureVerbosity();
38
39
        $this->interactive = $this->checkInteractivity($shellVerbosity);
40
        $this->colorSupport = $this->checkColorSupport();
41
    }
42
43
    /**
44
     * @return bool
45
     */
46
    public function isInteractive()
47
    {
48
        return $this->interactive;
49
    }
50
51
    /**
52
     * @return int
53
     */
54
    public function getVerbosity()
55
    {
56
        return $this->verbosity;
57
    }
58
59
    /**
60
     * @return bool
61
     */
62
    public function hasColorSupport()
63
    {
64
        return $this->colorSupport;
65
    }
66
67
    /**
68
     * @param mixed
69
     * @param mixed $values
70
     *
71
     * @return bool
72
     */
73
    public function hasParameter($values)
74
    {
75
        $values = (array) $values;
76
77
        foreach ($values as $value) {
78
            $regexp = sprintf(
79
                '/\s%s\b/',
80
                str_replace(' ', '\s+', preg_quote($value, '/'))
81
            );
82
83
            if (1 === preg_match($regexp, $this->options)) {
84
                return true;
85
            }
86
        }
87
88
        return false;
89
    }
90
91
    /**
92
     * @param int $shellVerbosity
93
     *
94
     * @return bool
95
     */
96
    private function checkInteractivity($shellVerbosity)
97
    {
98
        if (-1 === $shellVerbosity) {
99
            return false;
100
        }
101
102
        if (true === $this->hasParameter(array('--no-interaction', '-n'))) {
103
            return false;
104
        }
105
106
        if (function_exists('posix_isatty')) {
107
            if (!@posix_isatty(STDOUT) && false === \getenv('SHELL_INTERACTIVE')) {
108
                return false;
109
            }
110
        }
111
112
        return true;
113
    }
114
115
    /**
116
     * @return int
117
     */
118
    private function configureVerbosity()
119
    {
120
        switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
121
            case -1:
122
                $this->verbosity = self::VERBOSITY_QUIET;
123
                break;
124
            case 1:
125
                $this->verbosity = self::VERBOSITY_VERBOSE;
126
                break;
127
            case 2:
128
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
129
                break;
130
            case 3:
131
                $this->verbosity = self::VERBOSITY_DEBUG;
132
                break;
133
            default:
134
                $shellVerbosity = 0;
135
                break;
136
        }
137
138
        if ($this->hasParameter(array('--quiet', '-q'))) {
139
            $this->verbosity = self::VERBOSITY_QUIET;
140
            $shellVerbosity = -1;
141
        } else {
142
            if ($this->hasParameter(array('-vvv', '--verbose=3', '--verbose 3'))) {
143
                $this->verbosity = self::VERBOSITY_DEBUG;
144
                $shellVerbosity = 3;
145
            } elseif ($this->hasParameter(array('-vv', '--verbose=2', '--verbose 2'))) {
146
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
147
                $shellVerbosity = 2;
148
            } elseif ($this->hasParameter(array('-v', '--verbose=1', '--verbose 1', '--verbose'))) {
149
                $this->verbosity = self::VERBOSITY_VERBOSE;
150
                $shellVerbosity = 1;
151
            }
152
        }
153
154
        return $shellVerbosity;
155
    }
156
157
    /**
158
     * Returns true if the stream supports colorization.
159
     *
160
     * Colorization is disabled if not supported by the stream:
161
     *
162
     *  -  Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
163
     *  -  non tty consoles
164
     *
165
     * @return bool true if the stream supports colorization, false otherwise
166
     *
167
     * @see \Symfony\Component\Console\Output\StreamOutput
168
     */
169
    private function checkColorSupport()
170
    {
171
        if ($this->hasParameter(array('--ansi'))) {
172
            return true;
173
        }
174
175
        if ($this->hasParameter(array('--no-ansi'))) {
176
            return false;
177
        }
178
179
        if (DIRECTORY_SEPARATOR === '\\') {
180
            return (
181
                    function_exists('sapi_windows_vt100_support')
182
                    && sapi_windows_vt100_support(STDOUT)
183
                )
184
                || false !== getenv('ANSICON')
185
                || 'ON' === getenv('ConEmuANSI')
186
                || 'xterm' === getenv('TERM');
187
        }
188
189
        if (function_exists('stream_isatty')) {
190
            return stream_isatty(STDOUT);
191
        }
192
193
        if (function_exists('posix_isatty')) {
194
            return posix_isatty(STDOUT);
195
        }
196
197
        $stat = fstat(STDOUT);
198
199
        // Check if formatted mode is S_IFCHR
200
        return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
201
    }
202
}
203