Completed
Push — master ( e1c388...7bf58d )
by
unknown
12:55 queued 10:58
created

ShellWord::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 12
rs 9.9666
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PHPSu\ShellCommandBuilder\Literal;
6
7
use PHPSu\ShellCommandBuilder\Exception\ShellBuilderException;
8
use PHPSu\ShellCommandBuilder\ShellInterface;
9
10
/**
11
 * Representing the basic element of a Shell Command, a single literal aka "word"
12
 * @internal
13
 * @psalm-internal PHPSu\ShellCommandBuilder\Literal
14
 * @package PHPSu\ShellCommandBuilder\Literal
15
 */
16
class ShellWord implements ShellInterface
17
{
18
    protected const OPTION_CONTROL = '--';
19
    protected const SHORT_OPTION_CONTROL = '-';
20
    protected const EQUAL_CONTROL = '=';
21
22
    /** @var bool */
23
    protected $isShortOption = false;
24
    /** @var bool */
25
    protected $isOption = false;
26
    /** @var bool */
27
    protected $isArgument = false;
28
    /** @var bool */
29
    protected $isEnvironmentVariable = false;
30
    /** @var bool */
31
    protected $isEscaped = true;
32
    /** @var bool */
33
    protected $spaceAfterValue = true;
34
    /** @var bool */
35
    protected $useAssignOperator = false;
36
    /** @var bool */
37
    protected $nameUpperCase = false;
38
    /** @var string */
39
    protected $prefix = '';
40
    /** @var string */
41
    protected $suffix = ' ';
42
    /** @var string */
43
    protected $delimiter = ' ';
44
    /** @var string */
45
    protected $argument;
46
    /** @var string|ShellInterface */
47
    protected $value;
48
49
    /**
50
     * The constructor is protected, you must choose one of the children
51
     * @param string $argument
52
     * @param string|ShellInterface $value
53
     */
54
    protected function __construct(string $argument, $value = '')
55
    {
56
        $this->argument = $argument;
57
        $this->value = $value;
58
    }
59
60
    public function setEscape(bool $isEscaped): self
61
    {
62
        $this->isEscaped = $isEscaped;
63
        return $this;
64
    }
65
66
    public function setSpaceAfterValue(bool $spaceAfterValue): self
67
    {
68
        $this->spaceAfterValue = $spaceAfterValue;
69
        return $this;
70
    }
71
72
    public function setAssignOperator(bool $useAssignOperator): self
73
    {
74
        $this->useAssignOperator = $useAssignOperator;
75
        return $this;
76
    }
77
78
    public function setNameUppercase(bool $uppercaseName): self
79
    {
80
        $this->nameUpperCase = $uppercaseName;
81
        return $this;
82
    }
83
84
    protected function validate(): void
85
    {
86
        /** @psalm-suppress DocblockTypeContradiction */
87
        if (!(is_string($this->value) || $this->value instanceof ShellInterface)) {
0 ignored issues
show
introduced by
$this->value is always a sub-type of PHPSu\ShellCommandBuilder\ShellInterface.
Loading history...
88
            throw new ShellBuilderException('Value must be an instance of ShellInterface or a string');
89
        }
90
    }
91
92
    private function prepare(): void
93
    {
94
        $this->validate();
95
        if (!$this->spaceAfterValue) {
96
            $this->suffix = '';
97
        }
98
        if ($this->useAssignOperator) {
99
            $this->delimiter = self::EQUAL_CONTROL;
100
        }
101
        if (!empty($this->argument) && $this->nameUpperCase) {
102
            $this->argument = strtoupper($this->argument);
103
        }
104
    }
105
106
    /**
107
     * @param bool $debug
108
     * @return array<mixed>|string
109
     */
110
    private function getValue(bool $debug = false)
111
    {
112
        $word = $this->value;
113
        if ($word instanceof ShellInterface) {
114
            if ($debug) {
115
                return $word->__toArray();
116
            }
117
            $word = (string)$word;
118
        }
119
        if ($this->isEscaped && !empty($word)) {
120
            $word = escapeshellarg($word);
121
        }
122
        return $word;
123
    }
124
125
    /**
126
     * @return array<string, mixed>
127
     */
128
    public function __toArray(): array
129
    {
130
        $this->prepare();
131
        return [
132
            'isArgument' => $this->isArgument,
133
            'isShortOption' => $this->isShortOption,
134
            'isOption' => $this->isOption,
135
            'isEnvironmentVariable' => $this->isEnvironmentVariable,
136
            'escaped' => $this->isEscaped,
137
            'withAssign' => $this->useAssignOperator,
138
            'spaceAfterValue' => $this->spaceAfterValue,
139
            'value' => $this->getValue(true),
140
            'argument' => $this->argument,
141
        ];
142
    }
143
144
    public function __toString(): string
145
    {
146
        $this->prepare();
147
        /** @var string $value */
148
        $value = $this->getValue();
149
        return sprintf(
150
            '%s%s%s%s%s',
151
            $this->prefix,
152
            $this->argument,
153
            $this->delimiter,
154
            $value,
155
            $this->suffix
156
        );
157
    }
158
}
159