Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static function askMulti(bool $extension = false): array
label: '¿Desea crear los campos habituales? (No = Default)'
);

if ($prompt === 'Si') {
if ($prompt === 'si') {
$fields[] = new Column([
'display' => 'none',
'nombre' => 'id',
Expand Down Expand Up @@ -539,8 +539,8 @@ private function askRequerido(): void
{
do {
$requerido = Utils::promptYesOrNo("¿El campo {$this->nombre} es obligatorio? (No = predeterminado)");
$this->requerido = $requerido === 'Si';
} while ($requerido !== 'Si' && $requerido !== 'No');
$this->requerido = $requerido === 'si';
} while ($requerido !== 'si' && $requerido !== 'no');
}

private function askStep(): void
Expand Down
2 changes: 1 addition & 1 deletion src/Command/Controller/ControllerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private function createController(string $name): void
hint: 'El nombre que se colocará en "$data[\'menu\'] = \'NOMBRE_ELEGIDO\';", por defecto es "admin".'
);

$createView = 'Si' === Utils::promptYesOrNo(
$createView = 'si' === Utils::promptYesOrNo(
label: '¿Desea añadir la vista twig?'
);

Expand Down
4 changes: 2 additions & 2 deletions src/Command/Model/ModelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

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

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

Expand Down
121 changes: 121 additions & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@

namespace fsmaker\Console;

use Laravel\Prompts\MultiSelectPrompt;
use Laravel\Prompts\Prompt;
use Laravel\Prompts\SelectPrompt;
use Laravel\Prompts\TextPrompt;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;

class Application extends BaseApplication
{
Expand All @@ -18,6 +26,119 @@ public function __construct()
$this->addCommands($this->getCommands());
}

public function doRun(InputInterface $input, OutputInterface $output): int
{
// Fix para windows (la librería prompt no lo soporta)
Prompt::fallbackWhen(PHP_OS_FAMILY === 'Windows');
// Prompt::fallbackWhen(true); // para tests

$io = new SymfonyStyle($input, $output);

TextPrompt::fallbackUsing(function (TextPrompt $prompt) use ($io) {
while (true) {
$value = $io->ask($prompt->label, $prompt->default);

if ($prompt->validate) {
$error = ($prompt->validate)($value ?? '');
if (is_string($error) && strlen($error) > 0) {
$io->writeln("<fg=red>Error: $error</>");
continue;
}
}
return (string)$value;
}
});

SelectPrompt::fallbackUsing(function (SelectPrompt $prompt) use ($io) {
$question = new ChoiceQuestion($prompt->label, $prompt->options, $prompt->default);
// Capturar el validador por defecto
$validator = $question->getValidator();

$question->setValidator(function ($answer) {
return $answer;
});

while (true) {
// Aquí el askQuestion llamará a nuestro validador nulo.
$answer = $io->askQuestion($question);

try {
// Validar manualmente con el validador original.
// El validador original espera el valor tal cual sale del normalizador interno.
$choice = $validator($answer);

// Ensure we return the key if options are associative
if (array_is_list($prompt->options)) {
return $choice;
}
return array_search($choice, $prompt->options) ?: $choice;
} catch (\Exception $e) {
$msg = $e->getMessage();
if (preg_match('/^Value "(.*)" is invalid$/', $msg, $matches)) {
$msg = "El valor \"{$matches[1]}\" es inválido";
}
$io->writeln("<fg=red>Error: $msg</>");
}
}
});

MultiSelectPrompt::fallbackUsing(function (MultiSelectPrompt $prompt) use ($io) {
$default = $prompt->default;
if (is_array($default) && !empty($default)) {
$default = implode(',', $default);
} elseif (empty($default)) {
$default = null;
}

$question = new ChoiceQuestion($prompt->label, $prompt->options, $default);
$question->setMultiselect(true);

// Normalizador para permitir separar por espacios además de comas
$question->setNormalizer(function ($value) {
if ($value === null) {
return $value;
}
// Reemplaza uno o más espacios/comas con una sola coma
return preg_replace('/[\s,]+/', ',', trim($value));
});

// Capturar el validador por defecto
$validator = $question->getValidator();
// Anular el validador en la pregunta
$question->setValidator(function ($answer) {
return $answer;
});

while (true) {
$result = $io->askQuestion($question);
try {
// Validar manualmente
$result = $validator($result);

if (array_is_list($prompt->options)) {
return $result;
}

// Map values back to keys
$mapped = [];
foreach ($result as $val) {
$key = array_search($val, $prompt->options);
$mapped[] = $key !== false ? $key : $val;
}
return $mapped;
} catch (\Exception $e) {
$msg = $e->getMessage();
if (preg_match('/^Value "(.*)" is invalid$/', $msg, $matches)) {
$msg = "El valor \"{$matches[1]}\" es inválido";
}
$io->writeln("<fg=red>Error: $msg</>");
}
}
});

return parent::doRun($input, $output);
}

/**
* Esto es para definir solo las opciones existentes (en fsmaker no existen opciones)
*/
Expand Down
8 changes: 4 additions & 4 deletions src/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@ public static function prompt(string $label, string $placeholder = '', string $d
}

/**
* Muestra un prompt de elegir si o no, devuelve 'Si' o 'No'
* Muestra un prompt de elegir si o no, devuelve 'si' o 'no'
*/
public static function promptYesOrNo(string $label, bool $noPorDefecto = true): string {
return select(
label: $label,
options: [
// 'valor que devuelve' => 'key que se muestra al usuario a elegir'
'Si' => 'Si',
'No' => 'No'
'si' => 'Si',
'no' => 'No'
],
default: $noPorDefecto ? 'No' : 'Si',
default: $noPorDefecto ? 'no' : 'si',
scroll: 2, // cantidad de opciones a mostrar a la vez en pantalla (el resto scroll)
required: true
);
Expand Down