Create generic command with builder to easily edit entities from console
This commit is contained in:
parent
665f4a376e
commit
941e3cdc9c
@ -2,29 +2,101 @@
|
||||
|
||||
namespace Ardent\UtilBundle\Command;
|
||||
|
||||
use App\Entity\Configuration;
|
||||
use Ardent\UtilBundle\EntityBuilder\Builder;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Exception;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
abstract class AbstractEntityCommand extends Command
|
||||
{
|
||||
abstract function getConfig(): Builder;
|
||||
public function __construct(
|
||||
private EntityManagerInterface $em,
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
abstract function getConfig(Builder $builder): void;
|
||||
|
||||
abstract function getEntityClass(): string;
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->addArgument('id', InputArgument::OPTIONAL, 'Object Id')
|
||||
->addOption('create', 'c', InputOption::VALUE_NONE, 'Create entity')
|
||||
->addOption('edit', 'e', InputOption::VALUE_NONE, 'Edit entity')
|
||||
->addOption('modify', 'm', InputOption::VALUE_NONE, 'Edit entity')
|
||||
->addOption('delete', 'd', InputOption::VALUE_NONE, 'Delete entity')
|
||||
->addOption('show', 's', InputOption::VALUE_NONE, 'Show entity');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$id = $input->getArgument('id');
|
||||
|
||||
$builder = new Builder($io);
|
||||
$this->getConfig($builder);
|
||||
|
||||
if ($input->getOption('create')) {
|
||||
$entity = new ($this->getEntityClass())();
|
||||
$builder->setAll($entity);
|
||||
|
||||
if ($io->askQuestion(new ConfirmationQuestion(sprintf('Are you sure you want to create %s with above properties', $entity)))) {
|
||||
$io->success(sprintf('Object "%s" (id: %s) stored successfully', $entity, $entity->getId()));
|
||||
}
|
||||
} elseif ($input->getOption('modify')) {
|
||||
$entity = $this->select($io, $id);
|
||||
$builder->setByQuestion($entity);
|
||||
} elseif ($input->getOption('delete')) {
|
||||
$entity = $this->select($io, $id);
|
||||
if ($io->askQuestion(new ConfirmationQuestion(sprintf('Are you sure you want to delete %s', $entity)))) {
|
||||
$name = (string)$entity;
|
||||
$this->em->remove($entity);
|
||||
$io->success(sprintf('Config "%s" deleted', $name));
|
||||
}
|
||||
} elseif ($input->getOption('show')) {
|
||||
$entity = $this->select($io, $id);
|
||||
$table = $io->createTable();
|
||||
$table->setHeaders(['property', 'value']);
|
||||
$table->setRows($builder->getAllproperties($entity));
|
||||
$table->setHeaderTitle(sprintf('id: %s', $entity->getId()));
|
||||
$table->render();
|
||||
} else {
|
||||
$io->error('Select at least one of the options');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$this->em->persist($entity);
|
||||
$this->em->flush();
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function select(SymfonyStyle $io, ?int $id): object
|
||||
{
|
||||
$repo = $this->em->getRepository($this->getEntityClass());
|
||||
if ($id) {
|
||||
$object = $repo->find($id);
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
$entities = $repo->findAll();
|
||||
|
||||
if (empty($entities)) {
|
||||
throw new Exception('No objects found');
|
||||
}
|
||||
$question = new ChoiceQuestion('Select configuration to delete', $entities);
|
||||
return $io->askQuestion($question);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ namespace Ardent\UtilBundle\EntityBuilder;
|
||||
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class SimpleElement
|
||||
class BaseElement
|
||||
{
|
||||
public function getQuestion(): Question
|
||||
{
|
||||
@ -23,4 +23,9 @@ class SimpleElement
|
||||
{
|
||||
return $this->property;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->property;
|
||||
}
|
||||
}
|
@ -3,39 +3,69 @@
|
||||
namespace Ardent\UtilBundle\EntityBuilder;
|
||||
|
||||
use Exception;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* @var SimpleElement[]
|
||||
* @var BaseElement[]
|
||||
*/
|
||||
private array $elements = [];
|
||||
|
||||
|
||||
public function __construct(
|
||||
private readonly SymfonyStyle $io,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function add(SimpleElement|string $element): self
|
||||
public function add(BaseElement|string $element): self
|
||||
{
|
||||
if (is_string($element)) {
|
||||
$element = new SimpleElement($element);
|
||||
$element = new BaseElement($element);
|
||||
}
|
||||
$this->elements[] = $element;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setObject(mixed $object): void
|
||||
private function getPopertyNames(): array
|
||||
{
|
||||
return array_map(fn(BaseElement $element) => $element->getProperty(), $this->elements);
|
||||
}
|
||||
|
||||
private function setProperty(object $object, BaseElement $element): void
|
||||
{
|
||||
foreach ($this->elements as $element) {
|
||||
$setter = sprintf('set%s', ucfirst($element->getProperty()));
|
||||
if (!method_exists($object, $setter)) {
|
||||
throw new Exception(sprintf('Object does not have setter "%s"', $setter));
|
||||
}
|
||||
$object->$setter($this->io->askQuestion($element->getQuestion()));
|
||||
}
|
||||
|
||||
public function setAll(object $object): void
|
||||
{
|
||||
foreach ($this->elements as $element) {
|
||||
$this->setProperty($object, $element);
|
||||
}
|
||||
}
|
||||
|
||||
public function setByQuestion(object $object): void
|
||||
{
|
||||
$element = $this->io->askQuestion(new ChoiceQuestion('Select property to modify', $this->elements));
|
||||
$getter = sprintf('get%s', ucfirst($element->getProperty()));
|
||||
$this->io->writeln(sprintf('Current value: %s', $object->$getter()));
|
||||
$this->setProperty($object, $element);
|
||||
}
|
||||
|
||||
public function getAllproperties(object $object): array
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->elements as $element) {
|
||||
$getter = sprintf('get%s', ucfirst($element->getProperty()));
|
||||
$data[] = [$element->getProperty(), $object->$getter()];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user