Skip to content

Commit 2d0f291

Browse files
authored
Merge pull request #76 from abdedarghal111/replaceLaravelPrompts
Replace laravel prompts
2 parents 8eb2cc9 + 11dfefd commit 2d0f291

5 files changed

Lines changed: 131 additions & 10 deletions

File tree

src/Column.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static function askMulti(bool $extension = false): array
9898
label: '¿Desea crear los campos habituales? (No = Default)'
9999
);
100100

101-
if ($prompt === 'Si') {
101+
if ($prompt === 'si') {
102102
$fields[] = new Column([
103103
'display' => 'none',
104104
'nombre' => 'id',
@@ -539,8 +539,8 @@ private function askRequerido(): void
539539
{
540540
do {
541541
$requerido = Utils::promptYesOrNo("¿El campo {$this->nombre} es obligatorio? (No = predeterminado)");
542-
$this->requerido = $requerido === 'Si';
543-
} while ($requerido !== 'Si' && $requerido !== 'No');
542+
$this->requerido = $requerido === 'si';
543+
} while ($requerido !== 'si' && $requerido !== 'no');
544544
}
545545

546546
private function askStep(): void

src/Command/Controller/ControllerCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ private function createController(string $name): void
9393
hint: 'El nombre que se colocará en "$data[\'menu\'] = \'NOMBRE_ELEGIDO\';", por defecto es "admin".'
9494
);
9595

96-
$createView = 'Si' === Utils::promptYesOrNo(
96+
$createView = 'si' === Utils::promptYesOrNo(
9797
label: '¿Desea añadir la vista twig?'
9898
);
9999

src/Command/Model/ModelCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6767
}
6868

6969
Utils::echo("\n");
70-
if (Utils::promptYesOrNo('¿Crear EditController? (No - predeterminado)') === 'Si') {
70+
if (Utils::promptYesOrNo('¿Crear EditController? (No - predeterminado)') === 'si') {
7171
$this->createEditController($name, $fields);
7272
}
7373

7474
Utils::echo("\n");
75-
if (Utils::promptYesOrNo('¿Crear ListController? (No - predeterminado)') === 'Si') {
75+
if (Utils::promptYesOrNo('¿Crear ListController? (No - predeterminado)') === 'si') {
7676
$this->createListController($name, $fields);
7777
}
7878

src/Console/Application.php

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,18 @@
55

66
namespace fsmaker\Console;
77

8+
use Laravel\Prompts\MultiSelectPrompt;
9+
use Laravel\Prompts\Prompt;
10+
use Laravel\Prompts\SelectPrompt;
11+
use Laravel\Prompts\TextPrompt;
812
use Symfony\Component\Console\Application as BaseApplication;
913
use Symfony\Component\Console\Input\InputDefinition;
1014
use Symfony\Component\Console\Input\InputArgument;
1115
use Symfony\Component\Console\Input\InputOption;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Console\Question\ChoiceQuestion;
19+
use Symfony\Component\Console\Style\SymfonyStyle;
1220

1321
class Application extends BaseApplication
1422
{
@@ -18,6 +26,119 @@ public function __construct()
1826
$this->addCommands($this->getCommands());
1927
}
2028

29+
public function doRun(InputInterface $input, OutputInterface $output): int
30+
{
31+
// Fix para windows (la librería prompt no lo soporta)
32+
Prompt::fallbackWhen(PHP_OS_FAMILY === 'Windows');
33+
// Prompt::fallbackWhen(true); // para tests
34+
35+
$io = new SymfonyStyle($input, $output);
36+
37+
TextPrompt::fallbackUsing(function (TextPrompt $prompt) use ($io) {
38+
while (true) {
39+
$value = $io->ask($prompt->label, $prompt->default);
40+
41+
if ($prompt->validate) {
42+
$error = ($prompt->validate)($value ?? '');
43+
if (is_string($error) && strlen($error) > 0) {
44+
$io->writeln("<fg=red>Error: $error</>");
45+
continue;
46+
}
47+
}
48+
return (string)$value;
49+
}
50+
});
51+
52+
SelectPrompt::fallbackUsing(function (SelectPrompt $prompt) use ($io) {
53+
$question = new ChoiceQuestion($prompt->label, $prompt->options, $prompt->default);
54+
// Capturar el validador por defecto
55+
$validator = $question->getValidator();
56+
57+
$question->setValidator(function ($answer) {
58+
return $answer;
59+
});
60+
61+
while (true) {
62+
// Aquí el askQuestion llamará a nuestro validador nulo.
63+
$answer = $io->askQuestion($question);
64+
65+
try {
66+
// Validar manualmente con el validador original.
67+
// El validador original espera el valor tal cual sale del normalizador interno.
68+
$choice = $validator($answer);
69+
70+
// Ensure we return the key if options are associative
71+
if (array_is_list($prompt->options)) {
72+
return $choice;
73+
}
74+
return array_search($choice, $prompt->options) ?: $choice;
75+
} catch (\Exception $e) {
76+
$msg = $e->getMessage();
77+
if (preg_match('/^Value "(.*)" is invalid$/', $msg, $matches)) {
78+
$msg = "El valor \"{$matches[1]}\" es inválido";
79+
}
80+
$io->writeln("<fg=red>Error: $msg</>");
81+
}
82+
}
83+
});
84+
85+
MultiSelectPrompt::fallbackUsing(function (MultiSelectPrompt $prompt) use ($io) {
86+
$default = $prompt->default;
87+
if (is_array($default) && !empty($default)) {
88+
$default = implode(',', $default);
89+
} elseif (empty($default)) {
90+
$default = null;
91+
}
92+
93+
$question = new ChoiceQuestion($prompt->label, $prompt->options, $default);
94+
$question->setMultiselect(true);
95+
96+
// Normalizador para permitir separar por espacios además de comas
97+
$question->setNormalizer(function ($value) {
98+
if ($value === null) {
99+
return $value;
100+
}
101+
// Reemplaza uno o más espacios/comas con una sola coma
102+
return preg_replace('/[\s,]+/', ',', trim($value));
103+
});
104+
105+
// Capturar el validador por defecto
106+
$validator = $question->getValidator();
107+
// Anular el validador en la pregunta
108+
$question->setValidator(function ($answer) {
109+
return $answer;
110+
});
111+
112+
while (true) {
113+
$result = $io->askQuestion($question);
114+
try {
115+
// Validar manualmente
116+
$result = $validator($result);
117+
118+
if (array_is_list($prompt->options)) {
119+
return $result;
120+
}
121+
122+
// Map values back to keys
123+
$mapped = [];
124+
foreach ($result as $val) {
125+
$key = array_search($val, $prompt->options);
126+
$mapped[] = $key !== false ? $key : $val;
127+
}
128+
return $mapped;
129+
} catch (\Exception $e) {
130+
$msg = $e->getMessage();
131+
if (preg_match('/^Value "(.*)" is invalid$/', $msg, $matches)) {
132+
$msg = "El valor \"{$matches[1]}\" es inválido";
133+
}
134+
$io->writeln("<fg=red>Error: $msg</>");
135+
}
136+
}
137+
});
138+
139+
return parent::doRun($input, $output);
140+
}
141+
21142
/**
22143
* Esto es para definir solo las opciones existentes (en fsmaker no existen opciones)
23144
*/

src/Utils.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,17 @@ public static function prompt(string $label, string $placeholder = '', string $d
116116
}
117117

118118
/**
119-
* Muestra un prompt de elegir si o no, devuelve 'Si' o 'No'
119+
* Muestra un prompt de elegir si o no, devuelve 'si' o 'no'
120120
*/
121121
public static function promptYesOrNo(string $label, bool $noPorDefecto = true): string {
122122
return select(
123123
label: $label,
124124
options: [
125125
// 'valor que devuelve' => 'key que se muestra al usuario a elegir'
126-
'Si' => 'Si',
127-
'No' => 'No'
126+
'si' => 'Si',
127+
'no' => 'No'
128128
],
129-
default: $noPorDefecto ? 'No' : 'Si',
129+
default: $noPorDefecto ? 'no' : 'si',
130130
scroll: 2, // cantidad de opciones a mostrar a la vez en pantalla (el resto scroll)
131131
required: true
132132
);

0 commit comments

Comments
 (0)