mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
264 lines
8.0 KiB
PHP
264 lines
8.0 KiB
PHP
<?php
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\CustomFieldsBundle\Command;
|
|
|
|
use Chill\CustomFieldsBundle\Entity\CustomField;
|
|
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
|
|
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
|
|
use Doctrine\ORM\EntityManager;
|
|
use RuntimeException;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Helper\Table;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\Console\Question\Question;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
use Symfony\Component\Yaml\Exception\ParseException;
|
|
use Symfony\Component\Yaml\Parser;
|
|
|
|
use function count;
|
|
|
|
/**
|
|
* Class for the command 'chill:custom_fields:populate_group' that
|
|
* Create custom fields from a yml file.
|
|
*/
|
|
class CreateFieldsOnGroupCommand extends Command
|
|
{
|
|
public const ARG_DELETE = 'delete';
|
|
|
|
public const ARG_PATH = 'path';
|
|
|
|
private $availableLanguages;
|
|
|
|
/**
|
|
* @var CustomFieldProvider
|
|
*/
|
|
private $customFieldProvider;
|
|
|
|
private $customizablesEntities;
|
|
|
|
/**
|
|
* @var EntityManager
|
|
*/
|
|
private $entityManager;
|
|
|
|
/**
|
|
* @var ValidatorInterface
|
|
*/
|
|
private $validator;
|
|
|
|
/**
|
|
* CreateFieldsOnGroupCommand constructor.
|
|
*
|
|
* @param $availableLanguages
|
|
* @param $customizablesEntities
|
|
*/
|
|
public function __construct(
|
|
CustomFieldProvider $customFieldProvider,
|
|
EntityManager $entityManager,
|
|
ValidatorInterface $validator,
|
|
$availableLanguages,
|
|
$customizablesEntities
|
|
) {
|
|
$this->customFieldProvider = $customFieldProvider;
|
|
$this->entityManager = $entityManager;
|
|
$this->validator = $validator;
|
|
$this->availableLanguages = $availableLanguages;
|
|
$this->customizablesEntities = $customizablesEntities;
|
|
parent::__construct();
|
|
}
|
|
|
|
protected function configure()
|
|
{
|
|
$this->setName('chill:custom_fields:populate_group')
|
|
->setDescription('Create custom fields from a yml file')
|
|
->addArgument(
|
|
self::ARG_PATH,
|
|
InputOption::VALUE_REQUIRED,
|
|
'Path to description file'
|
|
)
|
|
->addOption(
|
|
self::ARG_DELETE,
|
|
null,
|
|
InputOption::VALUE_NONE,
|
|
'If set, delete existing fields'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete the existing custom fields for a given customFieldGroup.
|
|
*
|
|
* @param CustomFieldsGroup $customFieldsGroup : The custom field group
|
|
*/
|
|
protected function deleteFieldsForCFGroup($customFieldsGroup)
|
|
{
|
|
$em = $this->entityManager;
|
|
|
|
foreach ($customFieldsGroup->getCustomFields() as $field) {
|
|
$em->remove($field);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return int|void|null
|
|
*/
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
{
|
|
$helper = $this->getHelperSet()->get('question');
|
|
|
|
$em = $this->entityManager;
|
|
|
|
$customFieldsGroups = $em
|
|
->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class)
|
|
->findAll();
|
|
|
|
if (count($customFieldsGroups) === 0) {
|
|
$output->writeln('<error>There aren\'t any CustomFieldsGroup recorded'
|
|
. ' Please create at least one.</error>');
|
|
}
|
|
|
|
$table = new Table($output);
|
|
$table
|
|
->setHeaders(array_merge(
|
|
['id', 'entity'],
|
|
$this->availableLanguages
|
|
))
|
|
->setRows($this->_prepareRows($customFieldsGroups))
|
|
->render();
|
|
|
|
$question = new Question(
|
|
"Enter the customfieldGroup's id on which the custom fields should be added: "
|
|
);
|
|
$question->setNormalizer(
|
|
static function ($answer) use ($customFieldsGroups) {
|
|
foreach ($customFieldsGroups as $customFieldsGroup) {
|
|
if ($customFieldsGroup->getId() === $answer) {
|
|
return $customFieldsGroup;
|
|
}
|
|
}
|
|
|
|
throw new RuntimeException('The id does not match an existing CustomFieldsGroup');
|
|
}
|
|
);
|
|
$customFieldsGroup = $helper->ask($input, $output, $question);
|
|
|
|
if ($input->getOption(self::ARG_DELETE)) {
|
|
$this->deleteFieldsForCFGroup($customFieldsGroup);
|
|
}
|
|
|
|
$fieldsInput = $this->_parse(
|
|
$input->getArgument(self::ARG_PATH),
|
|
$output
|
|
);
|
|
|
|
$fields = $this->_addFields($customFieldsGroup, $fieldsInput, $output);
|
|
}
|
|
|
|
private function _addFields(CustomFieldsGroup $group, $values, OutputInterface $output)
|
|
{
|
|
$em = $this->entityManager;
|
|
|
|
$languages = $this->availableLanguages;
|
|
|
|
foreach ($values['fields'] as $slug => $field) {
|
|
//check the cf type exists
|
|
$cfType = $this->customFieldProvider->getCustomFieldByType($field['type']);
|
|
|
|
if (null === $cfType) {
|
|
throw new RuntimeException('the type ' . $field['type'] . ' '
|
|
. 'does not exists');
|
|
}
|
|
|
|
$cf = new CustomField();
|
|
$cf->setSlug($slug)
|
|
->setName($field['name'])
|
|
->setOptions($field['options'] ?? [])
|
|
->setOrdering($field['ordering'])
|
|
->setType($field['type'])
|
|
->setCustomFieldsGroup($group);
|
|
|
|
//add to table
|
|
$names = [];
|
|
|
|
foreach ($languages as $lang) {
|
|
//todo replace with service to find lang when available
|
|
$names[] = (isset($cf->getName()[$lang])) ?
|
|
$cf->getName()[$lang] :
|
|
'Not available in this language';
|
|
}
|
|
|
|
if ($this->validator->validate($cf)) {
|
|
$em->persist($cf);
|
|
$output->writeln('<info>Adding Custom Field of type '
|
|
. $cf->getType() . "\t with slug " . $cf->getSlug() .
|
|
"\t and names : " . implode(', ', $names) . '</info>');
|
|
} else {
|
|
throw new RuntimeException('Error in field ' . $slug);
|
|
}
|
|
}
|
|
|
|
$em->flush();
|
|
}
|
|
|
|
private function _parse($path, OutputInterface $output)
|
|
{
|
|
$parser = new Parser();
|
|
|
|
if (!file_exists($path)) {
|
|
throw new RuntimeException('file does not exist');
|
|
}
|
|
|
|
try {
|
|
$values = $parser->parse(file_get_contents($path));
|
|
} catch (ParseException $ex) {
|
|
throw new RuntimeException('The yaml file is not valid', 0, $ex);
|
|
}
|
|
|
|
return $values;
|
|
}
|
|
|
|
private function _prepareRows($customFieldsGroups)
|
|
{
|
|
$rows = [];
|
|
$languages = $this->availableLanguages;
|
|
//gather entitites and create an array to access them easily
|
|
$customizableEntities = [];
|
|
|
|
foreach ($this->customizablesEntities as $entry) {
|
|
$customizableEntities[$entry['class']] = $entry['name'];
|
|
}
|
|
|
|
array_walk(
|
|
$customFieldsGroups,
|
|
static function (CustomFieldsGroup $customFieldGroup, $key) use ($languages, &$rows, $customizableEntities) {
|
|
//set id and entity
|
|
$row = [
|
|
$customFieldGroup->getId(),
|
|
$customizableEntities[$customFieldGroup->getEntity()],
|
|
];
|
|
|
|
foreach ($languages as $lang) {
|
|
//todo replace with service to find lang when available
|
|
$row[] = (isset($customFieldGroup->getName()[$lang])) ?
|
|
$customFieldGroup->getName()[$lang] :
|
|
'Not available in this language';
|
|
}
|
|
$rows[] = $row;
|
|
}
|
|
);
|
|
|
|
return $rows;
|
|
}
|
|
}
|