class ConditionalFieldForm in Conditional Fields 8
Same name and namespace in other branches
- 4.x src/Form/ConditionalFieldForm.php \Drupal\conditional_fields\Form\ConditionalFieldForm
Class ConditionalFieldForm.
@package Drupal\conditional_fields\Form
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\conditional_fields\Form\ConditionalFieldForm
Expanded class hierarchy of ConditionalFieldForm
1 string reference to 'ConditionalFieldForm'
File
- src/
Form/ ConditionalFieldForm.php, line 22
Namespace
Drupal\conditional_fields\FormView source
class ConditionalFieldForm extends FormBase {
protected $editPath = 'conditional_fields.edit_form';
protected $deletePath = 'conditional_fields.delete_form';
/**
* Uuid generator.
*
* @var UuidInterface
*/
protected $uuidGenerator;
/**
* Provides an interface for an entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* Provides an interface for entity type managers.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* CF lists builder.
*
* @var Conditions $list
*/
protected $list;
/**
* Form array.
*/
protected $form;
/**
* FormState object.
*/
protected $form_state;
/**
* Name of the entity type being configured.
*/
protected $entity_type;
/**
* Name of the entity bundle being configured.
*/
protected $bundle_name;
/**
* Class constructor.
*
* @param \Drupal\conditional_fields\Conditions $list
* Conditions list provider.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* Provides an interface for an entity field manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Provides an interface for entity type managers.
* @param \Drupal\Component\Uuid\UuidInterface $uuid
* Uuid generator.
*/
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;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
// Instantiates this form class.
return new static($container
->get('conditional_fields.conditions'), $container
->get('entity_field.manager'), $container
->get('entity_type.manager'), $container
->get('uuid'));
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'conditional_field_form';
}
/**
* {@inheritdoc}
*/
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;
}
/**
* {@inheritdoc}
*/
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);
}
/**
* Determine if a field is configured to be required, but not visible.
*
* This is considered an error condition as a user would not be able to fill
* out the field.
*
* @param \Drupal\Core\Field\FieldDefinitionInterface $field
* The field to evaluate.
* @param null|string $state
* The configured state for the field.
*
* @return bool
* TRUE if the field is required but not visible; FALSE otherwise.
*/
protected function requiredFieldIsNotVisible(FieldDefinitionInterface $field, $state) : bool {
return method_exists($field, 'isRequired') && $field
->isRequired() && in_array($state, [
'!visible',
'disabled',
'!required',
]);
}
/**
* {@inheritdoc}
*/
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'];
// Copy values from table for submit.
$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;
}
// @TODO: it seems reasonable
// to only set values allowed by field schema,
// @see conditional_fields.schema.yml
$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');
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity */
$entity = $this->entityTypeManager
->getStorage('entity_form_display')
->load($component_value['entity_type'] . '.' . $component_value['bundle'] . '.' . 'default');
if (!$entity) {
return;
}
// Handle one to one condition creating with redirect to edit form.
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;
}
// Handle many to one, in that case we always need new uuid.
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();
}
/**
* Builds table with conditional fields.
*/
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();
/* Existing conditions. */
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_entity */
$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;
}
// Create row for existing field's conditions.
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),
],
],
],
];
}
}
/* Row for creating new condition. */
// Build list of states.
$states = $this->list
->conditionalFieldsStates();
// Build list of conditions.
$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,
]);
}
// Add new dependency row.
$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;
}
/**
* Build options list of available fields.
*/
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;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ConditionalFieldForm:: |
protected | property | Name of the entity bundle being configured. | |
ConditionalFieldForm:: |
protected | property | 1 | |
ConditionalFieldForm:: |
protected | property | 1 | |
ConditionalFieldForm:: |
protected | property | Provides an interface for an entity field manager. | |
ConditionalFieldForm:: |
protected | property | Provides an interface for entity type managers. | |
ConditionalFieldForm:: |
protected | property | Name of the entity type being configured. | |
ConditionalFieldForm:: |
protected | property | Form array. | |
ConditionalFieldForm:: |
protected | property | FormState object. | |
ConditionalFieldForm:: |
protected | property | CF lists builder. | |
ConditionalFieldForm:: |
protected | property | Uuid generator. | |
ConditionalFieldForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
|
ConditionalFieldForm:: |
protected | function | Builds table with conditional fields. | |
ConditionalFieldForm:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
|
ConditionalFieldForm:: |
protected | function | Build options list of available fields. | |
ConditionalFieldForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
1 |
ConditionalFieldForm:: |
protected | function | Determine if a field is configured to be required, but not visible. | |
ConditionalFieldForm:: |
public | function |
Form submission handler. Overrides FormInterface:: |
|
ConditionalFieldForm:: |
public | function |
Form validation handler. Overrides FormBase:: |
|
ConditionalFieldForm:: |
public | function | Class constructor. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |