mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-04 03:08:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			227 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			7.2 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 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;
 | 
						|
 | 
						|
/**
 | 
						|
 * Class for the command 'chill:custom_fields:populate_group' that
 | 
						|
 * Create custom fields from a yml file.
 | 
						|
 */
 | 
						|
class CreateFieldsOnGroupCommand extends Command
 | 
						|
{
 | 
						|
    protected static $defaultDescription = 'Create custom fields from a yml file';
 | 
						|
    final public const ARG_DELETE = 'delete';
 | 
						|
 | 
						|
    final public const ARG_PATH = 'path';
 | 
						|
 | 
						|
    /**
 | 
						|
     * CreateFieldsOnGroupCommand constructor.
 | 
						|
     */
 | 
						|
    public function __construct(
 | 
						|
        private readonly CustomFieldProvider $customFieldProvider,
 | 
						|
        private readonly EntityManager $entityManager,
 | 
						|
        private readonly ValidatorInterface $validator,
 | 
						|
        private $availableLanguages,
 | 
						|
        private $customizablesEntities
 | 
						|
    ) {
 | 
						|
        parent::__construct();
 | 
						|
    }
 | 
						|
 | 
						|
    protected function configure()
 | 
						|
    {
 | 
						|
        $this->setName('chill:custom_fields:populate_group')
 | 
						|
            ->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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    protected function execute(InputInterface $input, OutputInterface $output): int
 | 
						|
    {
 | 
						|
        $helper = $this->getHelperSet()->get('question');
 | 
						|
 | 
						|
        $em = $this->entityManager;
 | 
						|
 | 
						|
        $customFieldsGroups = $em
 | 
						|
            ->getRepository(CustomFieldsGroup::class)
 | 
						|
            ->findAll();
 | 
						|
 | 
						|
        if (0 === \count($customFieldsGroups)) {
 | 
						|
            $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);
 | 
						|
 | 
						|
        return Command::SUCCESS;
 | 
						|
    }
 | 
						|
 | 
						|
    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[] = $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[] = $customFieldGroup->getName()[$lang] ?? 'Not available in this language';
 | 
						|
                }
 | 
						|
                $rows[] = $row;
 | 
						|
            }
 | 
						|
        );
 | 
						|
 | 
						|
        return $rows;
 | 
						|
    }
 | 
						|
}
 |