Skip to content

Commit 069a451

Browse files
authored
47 hidden prompt (#48)
47 hidden prompt
2 parents 11a741d + 568bc79 commit 069a451

File tree

4 files changed

+72
-4
lines changed

4 files changed

+72
-4
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ $interactor->greenBold("Anything is: $any", true);
317317
```php
318318
$nameValidator = function ($value) {
319319
if (\strlen($value) < 5) {
320-
throw new \Exception('Name should be atleast 5 chars');
320+
throw new \InvalidArgumentException('Name should be atleast 5 chars');
321321
}
322322

323323
return $value;
@@ -328,6 +328,22 @@ $name = $interactor->prompt('Name', null, $nameValidator, 5);
328328
$interactor->greenBold("The name is: $name", true);
329329
```
330330

331+
#### Prompt hidden
332+
333+
> Currently not supported in windows platform, but maybe supported in future.
334+
335+
```php
336+
$passValidator = function ($pass) {
337+
if (\strlen($pass) < 6) {
338+
throw new \InvalidArgumentException('Password too short');
339+
}
340+
341+
return $pass;
342+
};
343+
344+
$pass = $interactor->promptHidden('Password', $passValidator, 2);
345+
```
346+
331347
![Interactive Preview](https://i.imgur.com/qYBNd29.gif "Interactive Preview")
332348

333349
## IO Components

src/IO/Interactor.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,25 +280,50 @@ public function choices(string $text, array $choices, $default = null, bool $cas
280280
*/
281281
public function prompt(string $text, $default = null, callable $fn = null, int $retry = 3)
282282
{
283-
$error = 'Invalid value. Please try again!';
283+
$error = 'Invalid value. Please try again!';
284+
$hidden = \func_get_args()[4] ?? false;
285+
$readFn = $hidden ? 'readHidden' : 'read';
284286

285287
$this->writer->yellow($text)->comment(null !== $default ? " [$default]: " : ': ');
286288

287289
try {
288-
$input = $this->reader->read($default, $fn);
290+
$input = $this->reader->{$readFn}($default, $fn);
289291
} catch (\Exception $e) {
290292
$error = $e->getMessage();
291293
}
292294

293295
if ($retry > 0 && (isset($e) || \strlen($input ?? '') === 0)) {
294296
$this->writer->bgRed($error, true);
295297

296-
return $this->prompt($text, $default, $fn, $retry - 1);
298+
return $this->prompt($text, $default, $fn, $retry - 1, $hidden);
297299
}
298300

299301
return $input ?? $default;
300302
}
301303

304+
/**
305+
* Prompt user for secret input like password. Currently for unix only.
306+
*
307+
* @param string $text Prompt text.
308+
* @param callable|null $fn The sanitizer/validator for user input
309+
* Any exception message is printed as error.
310+
* @param int $retry How many more times to retry on failure.
311+
*
312+
* @return mixed
313+
*/
314+
public function promptHidden(string $text, callable $fn = null, int $retry = 3)
315+
{
316+
$winOS = '\\' === \DIRECTORY_SEPARATOR;
317+
318+
// @codeCoverageIgnoreStart
319+
if ($winOS) {
320+
$this->writer->error('Hidden input not supported, Press Ctrl+C if you would like to abort', true);
321+
}
322+
// @codeCoverageIgnoreEnd
323+
324+
return $this->prompt($text, null, $fn, $retry, !$winOS);
325+
}
326+
302327
/**
303328
* Show choices list.
304329
*

src/Input/Reader.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,22 @@ public function read($default = null, callable $fn = null)
5252

5353
return $fn ? $fn($in) : $in;
5454
}
55+
56+
/**
57+
* Read a line from configured stream (or terminal) but don't echo it back.
58+
*
59+
* @param callable|null $fn The validator/sanitizer callback.
60+
*
61+
* @return mixed
62+
*/
63+
public function readHidden($default = null, callable $fn = null)
64+
{
65+
\shell_exec('stty -echo');
66+
$in = $this->read($default, $fn);
67+
\shell_exec('stty echo');
68+
69+
echo \PHP_EOL;
70+
71+
return $in;
72+
}
5573
}

tests/IO/InteractorTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ public function test_prompt_filter()
130130
$this->assertContains('gte 5', file_get_contents(static::$ou));
131131
}
132132

133+
public function test_prompt_hidden()
134+
{
135+
$i = $this->newInteractor('abcde');
136+
137+
$this->assertSame('abcde', $i->promptHidden('pass'));
138+
139+
$this->assertNotContains('abcde', file_get_contents(static::$ou));
140+
}
141+
133142
public function test_call()
134143
{
135144
$i = $this->newInteractor('');

0 commit comments

Comments
 (0)