View source
<?php
namespace Drupal\conditional_fields\Form;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\conditional_fields\Conditions;
use Drupal\conditional_fields\DependencyHelper;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ConditionalFieldForm extends FormBase {
protected $editPath = 'conditional_fields.edit_form';
protected $deletePath = 'conditional_fields.delete_form';
protected $uuidGenerator;
protected $entityFieldManager;
protected $entityTypeManager;
protected $list;
protected $form;
protected $form_state;
protected $entity_type;
protected $bundle_name;
public function __construct(Conditions $list, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager, UuidInterface $uuid) {
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeManager = $entity_type_manager;
$this->list = $list;
$this->uuidGenerator = $uuid;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('conditional_fields.conditions'), $container
->get('entity_field.manager'), $container
->get('entity_type.manager'), $container
->get('uuid'));
}
public function getFormId() {
return 'conditional_field_form';
}
public function buildForm(array $form, FormStateInterface $form_state, $entity_type = NULL, $bundle = NULL) {
$this->form = $form;
$this->form_state = $form_state;
$this->entity_type = $entity_type;
$this->bundle_name = $bundle;
$this->form['entity_type'] = [
'#type' => 'hidden',
'#value' => $this->entity_type,
];
$this->form['bundle'] = [
'#type' => 'hidden',
'#value' => $this->bundle_name,
];
$this
->buildTable();
return $this->form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$table = $form_state
->getValue('table');
if (empty($table['add_new_dependency']) || !is_array($table['add_new_dependency'])) {
parent::validateForm($form, $form_state);
}
$conditional_values = $table['add_new_dependency'];
if (array_key_exists('dependee', $conditional_values) && array_key_exists('dependent', $conditional_values)) {
$dependent = $conditional_values['dependent'];
$state = isset($conditional_values['state']) ? $conditional_values['state'] : NULL;
$instances = $this->entityFieldManager
->getFieldDefinitions($form_state
->getValue('entity_type'), $form_state
->getValue('bundle'));
foreach ($dependent as $field) {
if ($conditional_values['dependee'] == $field) {
$form_state
->setErrorByName('dependee', $this
->t('You should select two different fields.'));
$form_state
->setErrorByName('dependent', $this
->t('You should select two different fields.'));
}
if (!empty($instances[$field]) && $this
->requiredFieldIsNotVisible($instances[$field], $state)) {
$field_instance = $instances[$field];
$form_state
->setErrorByName('state', $this
->t('Field %field is required and can not have state %state.', [
'%field' => $field_instance
->getLabel() . ' (' . $field_instance
->getName() . ')',
'%state' => $this->list
->conditionalFieldsStates()[$state],
]));
}
}
}
parent::validateForm($form, $form_state);
}
protected function requiredFieldIsNotVisible(FieldDefinitionInterface $field, $state) : bool {
return method_exists($field, 'isRequired') && $field
->isRequired() && in_array($state, [
'!visible',
'disabled',
'!required',
]);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$table = $form_state
->getValue('table');
if (empty($table['add_new_dependency']) || !is_array($table['add_new_dependency'])) {
parent::submitForm($form, $form_state);
}
$field_names = [];
$form_state
->set('plugin_settings_edit', NULL);
$conditional_values = $table['add_new_dependency'];
$component_value = [];
$settings = $this->list
->conditionalFieldsDependencyDefaultSettings();
foreach ($conditional_values as $key => $value) {
if ($key == 'dependent') {
$field_names = $value;
continue;
}
if (in_array($key, [
'entity_type',
'bundle',
'dependee',
])) {
$component_value[$key] = $value;
continue;
}
$settings[$key] = $value;
}
unset($settings['actions']);
$component_value['settings'] = $settings;
$component_value['entity_type'] = $form_state
->getValue('entity_type');
$component_value['bundle'] = $form_state
->getValue('bundle');
$entity = $this->entityTypeManager
->getStorage('entity_form_display')
->load($component_value['entity_type'] . '.' . $component_value['bundle'] . '.' . 'default');
if (!$entity) {
return;
}
if (count($field_names) == 1) {
$field_name = reset($field_names);
$uuid = $form_state
->getValue('uuid', $this->uuidGenerator
->generate());
$field = $entity
->getComponent($field_name);
$field['third_party_settings']['conditional_fields'][$uuid] = $component_value;
$entity
->setComponent($field_name, $field);
$entity
->save();
$parameters = [
'entity_type' => $component_value['entity_type'],
'bundle' => $component_value['bundle'],
'field_name' => $field_name,
'uuid' => $uuid,
];
$form_state
->setRedirect($this->editPath, $parameters);
return;
}
foreach ($field_names as $field_name) {
$uuid = $this->uuidGenerator
->generate();
$field = $entity
->getComponent($field_name);
$field['third_party_settings']['conditional_fields'][$uuid] = $component_value;
$entity
->setComponent($field_name, $field);
}
$entity
->save();
}
protected function buildTable() {
$table = [
'#type' => 'table',
'#entity_type' => $this->entity_type,
'#bundle_name' => $this->bundle_name,
'#header' => [
$this
->t('Target field'),
$this
->t('Controlled by'),
[
'data' => $this
->t('Description'),
'colspan' => 2,
],
[
'data' => $this
->t('Operations'),
'colspan' => 2,
],
],
];
$fields = $this
->getFieldsList();
$form_display_entity = $this->entityTypeManager
->getStorage('entity_form_display')
->load("{$this->entity_type}.{$this->bundle_name}.default");
if (empty($form_display_entity) && $entity_type == 'taxonomy_term') {
$form_display_entity = $this->entityTypeManager
->getStorage('entity_form_display')
->create([
'targetEntityType' => 'taxonomy_term',
'bundle' => $bundle_name,
'mode' => 'default',
'status' => TRUE,
]);
}
if (!$form_display_entity) {
$this->form['conditional_fields_wrapper']['table'] = $table;
return;
}
foreach ($fields as $field_name => $label) {
$field = $form_display_entity
->getComponent($field_name);
if (empty($field['third_party_settings']['conditional_fields'])) {
continue;
}
foreach ($field['third_party_settings']['conditional_fields'] as $uuid => $condition) {
$parameters = [
'entity_type' => $condition['entity_type'],
'bundle' => $condition['bundle'],
'field_name' => $field_name,
'uuid' => $uuid,
];
$table[] = [
'dependent' => [
'#markup' => $field_name,
],
'dependee' => [
'#markup' => $condition['dependee'],
],
'state' => [
'#markup' => $condition['settings']['state'],
],
'condition' => [
'#markup' => $condition['settings']['condition'],
],
'actions' => [
'#type' => 'operations',
'#links' => [
'edit' => [
'title' => $this
->t('Edit'),
'url' => Url::fromRoute($this->editPath, $parameters),
],
'delete' => [
'title' => $this
->t('Delete'),
'url' => Url::fromRoute($this->deletePath, $parameters),
],
],
],
];
}
}
$states = $this->list
->conditionalFieldsStates();
$conditions = [];
foreach ($this->list
->conditionalFieldsConditions() as $condition => $label) {
$label = (string) $label;
$conditions[$condition] = $condition == 'value' ? $this
->t('has value...') : $this
->t('is @label', [
'@label' => (string) $label,
]);
}
$table['add_new_dependency'] = [
'dependent' => [
'#type' => 'select',
'#multiple' => TRUE,
'#title' => $this
->t('Target field'),
'#title_display' => 'invisible',
'#description' => $this
->t('Target field'),
'#options' => $fields,
'#prefix' => '<div class="add-new-placeholder">' . $this
->t('Add new dependency') . '</div>',
'#required' => TRUE,
'#attributes' => [
'class' => [
'conditional-fields-selector',
],
'style' => [
'resize: both;',
],
],
],
'dependee' => [
'#type' => 'select',
'#title' => $this
->t('Controlled by'),
'#title_display' => 'invisible',
'#description' => $this
->t('Control field'),
'#options' => $fields,
'#prefix' => '<div class="add-new-placeholder"> </div>',
'#required' => TRUE,
'#attributes' => [
'class' => [
'conditional-fields-selector',
],
],
],
'state' => [
'#type' => 'select',
'#title' => $this
->t('State'),
'#title_display' => 'invisible',
'#options' => $states,
'#default_value' => 'visible',
'#prefix' => $this
->t('The target field is'),
],
'condition' => [
'#type' => 'select',
'#title' => $this
->t('Condition'),
'#title_display' => 'invisible',
'#options' => $conditions,
'#default_value' => 'value',
'#prefix' => $this
->t('when the control field'),
],
'actions' => [
'submit' => [
'#type' => 'submit',
'#value' => $this
->t('Add dependency'),
],
],
];
$table['#attached']['library'][] = 'conditional_fields/admin';
$this->form['conditional_fields_wrapper']['table'] = $table;
}
protected function getFieldsList() {
$dependency_helper = new DependencyHelper($this->entity_type, $this->bundle_name);
$fields = [];
foreach ($dependency_helper
->getAvailableConditionalFields() as $name => $label) {
$fields[$name] = $label . ' (' . $name . ')';
}
return $fields;
}
}