Completed
Push — master ( 838d8d...a6ad7c )
by Aydin
11s
created

InputCharacter::getControls()   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
namespace PhpSchool\Terminal;
4
5
use function in_array;
6
7
/**
8
 * @author Aydin Hassan <[email protected]>
9
 */
10
class InputCharacter
11
{
12
    /**
13
     * @var string
14
     */
15
    private $data;
16
17
    public const UP = 'UP';
18
    public const DOWN = 'DOWN';
19
    public const RIGHT = 'RIGHT';
20
    public const LEFT = 'LEFT';
21
    public const CTRLA = 'CTRLA';
22
    public const CTRLB = 'CTRLB';
23
    public const CTRLE = 'CTRLE';
24
    public const CTRLF = 'CTRLF';
25
    public const BACKSPACE = 'BACKSPACE';
26
    public const CTRLW = 'CTRLW';
27
    public const ENTER = 'ENTER';
28
    public const TAB = 'TAB';
29
30
    private static $controls = [
31
        "\033[A" => self::UP,
32
        "\033[B" => self::DOWN,
33
        "\033[C" => self::RIGHT,
34
        "\033[D" => self::LEFT,
35
        "\001"   => self::CTRLA,
36
        "\002"   => self::CTRLB,
37
        "\005"   => self::CTRLE,
38
        "\006"   => self::CTRLF,
39
        "\010"   => self::BACKSPACE,
40
        "\177"   => self::BACKSPACE,
41
        "\027"   => self::CTRLW,
42
        "\n"     => self::ENTER,
43
        "\t"     => self::TAB,
44
    ];
45
46
    public function __construct(string $data)
47
    {
48
        $this->data = $data;
49
    }
50
51
    public function isHandledControl() : bool
52
    {
53
        return isset(static::$controls[$this->data]);
0 ignored issues
show
Bug introduced by
Since $controls is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $controls to at least protected.
Loading history...
54
    }
55
56
    /**
57
     * Is this character a control sequence?
58
     */
59
    public function isControl() : bool
60
    {
61
        return preg_match('/[\x00-\x1F\x7F]/', $this->data);
0 ignored issues
show
Bug Best Practice introduced by
The expression return preg_match('/[\x0...1F\x7F]/', $this->data) returns the type integer which is incompatible with the type-hinted return boolean.
Loading history...
62
    }
63
64
    /**
65
     * Is this character a normal character?
66
     */
67
    public function isNotControl() : bool
68
    {
69
        return ! $this->isControl();
70
    }
71
72
    /**
73
     * Get the raw character or control sequence
74
     */
75
    public function get() : string
76
    {
77
        return $this->data;
78
    }
79
80
    /**
81
     * Get the actual control name that this sequence represents.
82
     * One of the class constants. Eg. self::UP.
83
     *
84
     * Throws an exception if the character is not actually a control sequence
85
     */
86
    public function getControl() : string
87
    {
88
        if (!isset(static::$controls[$this->data])) {
0 ignored issues
show
Bug introduced by
Since $controls is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $controls to at least protected.
Loading history...
89
            throw new \RuntimeException(sprintf('Character "%s" is not a control', $this->data));
90
        }
91
92
        return static::$controls[$this->data];
93
    }
94
95
    /**
96
     * Get the raw character or control sequence
97
     */
98
    public function __toString() : string
99
    {
100
        return $this->get();
101
    }
102
103
    /**
104
     * Does the given control name exist? eg self::UP.
105
     */
106
    public static function controlExists(string $controlName) : bool
107
    {
108
        return in_array($controlName, static::$controls, true);
0 ignored issues
show
Bug introduced by
Since $controls is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $controls to at least protected.
Loading history...
109
    }
110
111
    /**
112
     * Get all of the available control names
113
     */
114
    public static function getControls() : array
115
    {
116
        return array_values(array_unique(static::$controls));
0 ignored issues
show
Bug introduced by
Since $controls is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $controls to at least protected.
Loading history...
117
    }
118
119
    /**
120
     * Create a instance from a given control name. Throws an exception if the
121
     * control name does not exist.
122
     */
123
    public static function fromControlName(string $controlName) : self
124
    {
125
        if (!static::controlExists($controlName)) {
126
            throw new \InvalidArgumentException(sprintf('Control "%s" does not exist', $controlName));
127
        }
128
129
        return new static(array_search($controlName, static::$controls, true));
0 ignored issues
show
Bug introduced by
It seems like array_search($controlName, static::controls, true) can also be of type false; however, parameter $data of PhpSchool\Terminal\InputCharacter::__construct() 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

129
        return new static(/** @scrutinizer ignore-type */ array_search($controlName, static::$controls, true));
Loading history...
Bug introduced by
Since $controls is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $controls to at least protected.
Loading history...
130
    }
131
}
132