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

IO::hasColorSupport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
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\Box\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->parseInput();
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
     * @param int $verbosity
61
     */
62
    public function setVerbosity($verbosity)
63
    {
64
        $this->verbosity = $verbosity;
65
    }
66
67
    /**
68
     * @return bool
69
     */
70
    public function hasColorSupport()
71
    {
72
        return $this->colorSupport;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function hasParameter($values)
79
    {
80
        $values = (array) $values;
81
82
        foreach ($values as $value) {
83
            $regexp = sprintf(
84
                '/\s%s\b/',
85
                str_replace(' ', '\s+', preg_quote($value, '/'))
86
            );
87
            if (preg_match($regexp, $this->options) === 1) {
88
                return true;
89
            }
90
        }
91
        return false;
92
    }
93
94
    /**
95
     * @return array
96
     */
97
    private function parseInput()
98
    {
99
        $this->options = implode(' ', $_SERVER['argv']);
100
    }
101
102
    /**
103
     * @param int $shellVerbosity
104
     *
105
     * @return bool
106
     */
107
    private function checkInteractivity($shellVerbosity)
108
    {
109
        if (-1 === $shellVerbosity) {
110
            return false;
111
        }
112
113
        if (true === $this->hasParameter(array('--no-interaction', '-n'))) {
114
            return false;
115
        }
116
117
        if (function_exists('posix_isatty')) {
118
            if (!@posix_isatty(STDOUT) && false === getenv('SHELL_INTERACTIVE')) {
119
                return false;
120
            }
121
        }
122
123
        return true;
124
    }
125
126
    /**
127
     * @return int
128
     */
129
    private function configureVerbosity()
130
    {
131
        switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
132
            case -1:
133
                $this->verbosity = self::VERBOSITY_QUIET;
134
                break;
135
            case 1:
136
                $this->verbosity = self::VERBOSITY_VERBOSE;
137
                break;
138
            case 2:
139
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
140
                break;
141
            case 3:
142
                $this->verbosity = self::VERBOSITY_DEBUG;
143
                break;
144
            default:
145
                $shellVerbosity = 0;
146
                break;
147
        }
148
149
        if ($this->hasParameter(array('--quiet', '-q'))) {
150
            $this->verbosity = self::VERBOSITY_QUIET;
151
            $shellVerbosity = -1;
152
        } else {
153
            if ($this->hasParameter(array('-vvv', '--verbose=3', '--verbose 3'))) {
154
                $this->verbosity = self::VERBOSITY_DEBUG;
155
                $shellVerbosity = 3;
156
            } elseif ($this->hasParameter(array('-vv', '--verbose=2', '--verbose 2'))) {
157
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
158
                $shellVerbosity = 2;
159
            } elseif ($this->hasParameter(array('-v', '--verbose=1', '--verbose 1', '--verbose'))) {
160
                $this->verbosity = self::VERBOSITY_VERBOSE;
161
                $shellVerbosity = 1;
162
            }
163
        }
164
165
        return $shellVerbosity;
166
    }
167
168
    /**
169
     * Returns true if the stream supports colorization.
170
     *
171
     * Colorization is disabled if not supported by the stream:
172
     *
173
     *  -  Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
174
     *  -  non tty consoles
175
     *
176
     * @return bool true if the stream supports colorization, false otherwise
177
     *
178
     * @see \Symfony\Component\Console\Output\StreamOutput
179
     */
180
    private function checkColorSupport()
181
    {
182
        if ($this->hasParameter(['--ansi'])) {
183
            return true;
184
        }
185
186
        if (DIRECTORY_SEPARATOR === '\\') {
187
            return
188
                '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR . '.' . PHP_WINDOWS_VERSION_MINOR . '.' . PHP_WINDOWS_VERSION_BUILD
189
                || false !== getenv('ANSICON')
190
                || 'ON' === getenv('ConEmuANSI')
191
                || 'xterm' === getenv('TERM');
192
        }
193
194
        return function_exists('posix_isatty') && @posix_isatty(STDOUT);
195
    }
196
}