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('There aren\'t any CustomFieldsGroup recorded' . ' Please create at least one.'); } $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('Adding Custom Field of type ' . $cf->getType() . "\t with slug " . $cf->getSlug() . "\t and names : " . implode(', ', $names) . ''); } 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; } }