Skip to content

Commit 55bb4b1

Browse files
committed
Merge branch 'develop'
2 parents 7b042ff + a59d266 commit 55bb4b1

File tree

9 files changed

+595
-162
lines changed

9 files changed

+595
-162
lines changed

Ansi.php

Lines changed: 430 additions & 55 deletions
Large diffs are not rendered by default.

Command.php

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
namespace MaplePHP\Prompts;
44

5+
use Exception;
6+
use MaplePHP\Http\Interfaces\StreamInterface;
57
use MaplePHP\Http\Stream;
6-
//use MaplePHP\Prompts\SttyWrapper;
7-
//use MaplePHP\Prompts\Ansi;
8-
//use MaplePHP\Prompts\Navigation;
98
use InvalidArgumentException;
109

1110
/**
@@ -14,30 +13,31 @@
1413
*/
1514
class Command
1615
{
17-
private Stream $stream;
16+
private StreamInterface $stream;
1817
private SttyWrapper $stty;
1918
private Ansi $ansi;
2019

21-
public function __construct()
20+
public function __construct(?StreamInterface $stream = null)
2221
{
23-
$this->stream = new Stream(Stream::STDOUT);
22+
// This is the stream we want to use, 9/10 times
23+
$this->stream = is_null($stream) ? new Stream(Stream::STDOUT) : $stream;
2424
$this->stty = new SttyWrapper();
2525
$this->ansi = new Ansi();
2626
}
2727

2828
/**
2929
* Get stream
30-
*
31-
* @return Stream
30+
*
31+
* @return StreamInterface
3232
*/
33-
public function getStream(): Stream
33+
public function getStream(): StreamInterface
3434
{
3535
return $this->stream;
3636
}
3737

3838
/**
3939
* Get SttyWrapper
40-
*
40+
*
4141
* @return SttyWrapper
4242
*/
4343
public function getStty(): SttyWrapper
@@ -47,7 +47,7 @@ public function getStty(): SttyWrapper
4747

4848
/**
4949
* Get Ansi
50-
*
50+
*
5151
* @return Ansi
5252
*/
5353
public function getAnsi(): Ansi
@@ -57,7 +57,7 @@ public function getAnsi(): Ansi
5757

5858
/**
5959
* Read line
60-
*
60+
*
6161
* @param string $message
6262
* @return string
6363
*/
@@ -68,12 +68,12 @@ public function readline(string $message): string
6868
}
6969

7070
$this->stream->write("$message: ");
71-
return $this->stream->getLine();
71+
return (string)$this->stream->getLine();
7272
}
7373

7474
/**
7575
* Display a message
76-
*
76+
*
7777
* @param string $message
7878
* @param bool $getLine Stop and get line
7979
* @return string|false
@@ -146,24 +146,25 @@ public function error(string $message, bool $break = true): string|false
146146
*/
147147
public function list(string $message): array
148148
{
149-
$line = $this->message("$message (comma separate)", true);
149+
$line = (string)$this->message("$message (comma separate)", true);
150150
return array_map("trim", explode(",", $line));
151151
}
152152

153153
/**
154154
* Display an interactive prompt with multiple options
155155
* If interactive prompt is not supported, use "inputSelect"
156-
*
156+
*
157157
* @param string $message
158158
* @param array $items
159159
* @return int|string
160+
* @throws Exception
160161
*/
161162
public function select(string $message, array $items): int|string
162163
{
163164
if ($this->stty->hasSttySupport()) {
164165
$command = new Navigation($this);
165166
$command->setHelperText($command::HELPER_TEXT);
166-
$command->navigation($message, $items, function ($index, $items) {
167+
$command->navigation($message, $items, function (int $index, array $items) {
167168
$this->showMenu($index, $items);
168169
});
169170
return $command->getValue();
@@ -173,7 +174,7 @@ public function select(string $message, array $items): int|string
173174

174175
/**
175176
* Display a non-interactive prompt with multiple options
176-
*
177+
*
177178
* @param string $message
178179
* @param array $choices
179180
* @return int|string
@@ -191,7 +192,7 @@ public function inputSelect(string $message, array $choices): int|string
191192
$this->message($this->getAnsi()->style(["blue", "bold"], "$int:") . " $value");
192193
$int++;
193194
}
194-
$line = $this->message("Input your answer", true);
195+
$line = (int)$this->message("Input your answer", true);
195196
if ($line > 0 && $line <= $length) {
196197
$index = $line - 1;
197198
$values = array_keys($choices);
@@ -202,17 +203,18 @@ public function inputSelect(string $message, array $choices): int|string
202203

203204
/**
204205
* Interactive prompt, choose between yes or no
205-
*
206+
*
206207
* @param string $message
207208
* @return int|string
209+
* @throws Exception
208210
*/
209211
public function toggle(string $message): int|string
210212
{
211213
if ($this->stty->hasSttySupport()) {
212214
$items = [1 => "Yes", 0 => "No"];
213215
$command = new Navigation($this);
214216
$command->setHelperText(Navigation::HELPER_TEXT);
215-
$command->navigation($message, $items, function ($index, $items) {
217+
$command->navigation($message, $items, function (int $index, array $items) {
216218
$this->showMenu($index, $items);
217219
});
218220
return $command->getValue();
@@ -222,14 +224,15 @@ public function toggle(string $message): int|string
222224

223225
/**
224226
* Non-interactive prompt, choose between yes or no
225-
*
227+
*
226228
* @param string $message
227-
* @return string
229+
* @return int|string
230+
* @throws Exception
228231
*/
229-
public function inputToggle(string $message): string
232+
public function inputToggle(string $message): int|string
230233
{
231234
$this->message($this->getAnsi()->bold($message));
232-
$line = strtolower($this->message("Type 'yes' or 'no'", true));
235+
$line = strtolower((string)$this->message("Type 'yes' or 'no'", true));
233236

234237
if ($line === "yes" || $line === "no") {
235238
return (int)($line === "yes");
@@ -239,7 +242,7 @@ public function inputToggle(string $message): string
239242

240243
/**
241244
* Get a masked input if supported, otherwise get unmasked input
242-
*
245+
*
243246
* @param string $message
244247
* @return string
245248
*/
@@ -252,26 +255,26 @@ public function mask(string $message): string
252255
// Not yet tested. But should work if my research is right
253256
$input = rtrim((string)exec("powershell -Command \$input = Read-Host -AsSecureString; [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR(\$input))"));
254257
} else {
255-
$input = rtrim(exec($this->stty->maskInput()));
258+
$input = rtrim((string)exec((string)$this->stty->maskInput()));
256259
}
257260
$this->stream->write("\n");
258261
//ob_get_clean();
259262
return $input;
260263
}
261264
$this->message("Warning: The input will not be masked. The PHP function \"system\" is disabled.");
262-
return $this->message($message, true);
265+
return (string)$this->message($message, true);
263266
}
264267

265268
/**
266269
* Display a confirmation prompt
267-
*
270+
*
268271
* @param string $message
269272
* @return bool
270273
*/
271274
public function confirm(string $message): bool
272275
{
273276
$this->message($this->getAnsi()->style(["yellow", "bold"], $message));
274-
$line = trim(strtolower($this->message("Type 'yes' to continue and 'no' to abort'", true)));
277+
$line = trim(strtolower((string)$this->message("Type 'yes' to continue and 'no' to abort'", true)));
275278

276279
if ($line === "yes") {
277280
return true;
@@ -280,10 +283,10 @@ public function confirm(string $message): bool
280283
}
281284
return $this->confirm($message);
282285
}
283-
286+
284287
/**
285288
* Create a progress bar
286-
*
289+
*
287290
* @param int $expectedRows The maximum expected rows
288291
* @param int $maxLength The maximum bar length
289292
* @param int|callable|null $sleep int for sleep in milliseconds (3000 ms = 1 second) or callback with returned int for sleep in milliseconds
@@ -300,7 +303,7 @@ public function progress(int $expectedRows, int $maxLength = 100, null|int|calla
300303
if (is_callable($sleep)) {
301304
$sleep = $sleep($i, $length);
302305
}
303-
if (is_int($sleep)) {
306+
if (is_int($sleep) && $sleep >= 0) {
304307
usleep($sleep * 1000);
305308
}
306309
$this->stream->write($this->progAppear($char, $i, $length));
@@ -311,7 +314,7 @@ public function progress(int $expectedRows, int $maxLength = 100, null|int|calla
311314

312315
/**
313316
* Progress appearance
314-
*
317+
*
315318
* @param string $char
316319
* @param float $i
317320
* @param float $length
@@ -330,16 +333,17 @@ private function progAppear(string $char, float $i, float $length): string
330333

331334
/**
332335
* Show interactive menu
333-
*
336+
*
334337
* @param int $selIndex
335338
* @param array $items
336339
* @return void
340+
* @throws Exception
337341
*/
338342
protected function showMenu(int $selIndex, array $items): void
339343
{
340344
foreach ($items as $index => $item) {
341345
if ($index === $selIndex) {
342-
$this->stream->write("[" . $this->ansi->style(["blue"], $this->ansi->checkbox()) . "] " . $this->ansi->selectedItem($item) . "\n");
346+
$this->stream->write("[" . $this->ansi->style(["blue"], $this->ansi->checkbox()) . "] " . $this->ansi->selectedItem((string)$item) . "\n");
343347
} else {
344348
$this->stream->write("[ ] $item\n");
345349
}

0 commit comments

Comments
 (0)