View source
<?php
namespace Drupal\custom_formatters\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Field\FormatterPluginManager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\custom_formatters\FormatterExtrasManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
class FormatterForm extends EntityForm {
protected $entity;
protected $formatterExtrasManager;
protected $fieldFormatterManager;
protected $fieldTypeManager;
public function __construct(FormatterExtrasManager $formatter_extras_manager, FormatterPluginManager $field_formatter_manager, FieldTypePluginManagerInterface $field_type_manager) {
$this->formatterExtrasManager = $formatter_extras_manager;
$this->fieldTypeManager = $field_type_manager;
$this->fieldFormatterManager = $field_formatter_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.custom_formatters.formatter_extras'), $container
->get('plugin.manager.field.formatter'), $container
->get('plugin.manager.field.field_type'));
}
public function form(array $form, FormStateInterface $form_state) {
$formatter_type = $this->entity
->getFormatterType();
$form = parent::form($form, $form_state);
$dependent_entities = $this->entity
->getDependentEntities();
if ($dependent_entities) {
$form['warning'] = [
'#theme' => 'status_messages',
'#message_list' => [
'warning' => [
$this
->t("Changing the field type(s) are currently disabled as this formatter is required by the following configuration(s): @config", [
'@config' => $this
->getDependentEntitiesList($dependent_entities),
]),
],
],
'#status_headings' => [
'warning' => t('Warning message'),
],
];
}
$form['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Formatter name'),
'#description' => $this
->t('This will appear in the administrative interface to easily identify it.'),
'#required' => TRUE,
'#default_value' => $this->entity
->label(),
];
$form['id'] = [
'#type' => 'machine_name',
'#machine_name' => [
'exists' => '\\Drupal\\custom_formatters\\Entity\\Formatter::load',
'source' => [
'label',
],
'replace_pattern' => '[^a-z0-9_]+',
'replace' => '_',
],
'#default_value' => $this->entity
->isNew() ? NULL : $this->entity
->id(),
'#disabled' => !$this->entity
->isNew(),
'#maxlength' => 255,
];
$form['type'] = [
'#type' => 'value',
'#value' => $this->entity
->get('type'),
];
$form['status'] = [
'#type' => 'value',
'#value' => TRUE,
];
$form['description'] = [
'#type' => 'textarea',
'#title' => $this
->t('Description'),
'#default_value' => $this->entity
->get('description'),
];
$form['field_types'] = [
'#type' => 'select',
'#title' => $this
->t('Field type(s)'),
'#options' => $this
->getFieldTypes(),
'#default_value' => $this->entity
->get('field_types'),
'#required' => TRUE,
'#multiple' => $formatter_type
->getPluginDefinition()['multipleFields'],
'#ajax' => [
'callback' => '::formAjax',
'wrapper' => 'plugin-wrapper',
],
'#disabled' => $dependent_entities,
];
$plugin_form = [];
$form['plugin'] = $formatter_type
->settingsForm($plugin_form, $form_state);
$form['plugin']['#type'] = 'container';
$form['plugin']['#prefix'] = "<div id='plugin-wrapper'>";
$form['plugin']['#suffix'] = "</div>";
$extras = $this
->getFormatterExtrasForm();
if ($extras && is_array($extras)) {
$form['vertical_tabs'] = [
'#type' => 'vertical_tabs',
'#title' => $this
->t('Extras'),
'#parents' => [
'extras',
],
];
$form['extras'] = $extras;
$form['extras']['#tree'] = TRUE;
}
return $form;
}
public function getFormatterExtrasForm() {
$form = [];
$definitions = $this->formatterExtrasManager
->getDefinitions();
if (is_array($definitions) && !empty($definitions)) {
foreach ($definitions as $definition) {
$extras_form = $this->formatterExtrasManager
->invoke($definition['id'], 'settingsForm', $this->entity);
if (is_array($extras_form) && !empty($extras_form)) {
$form[$definition['id']] = $extras_form;
$form[$definition['id']]['#type'] = 'details';
$form[$definition['id']]['#title'] = $definition['label'];
$form[$definition['id']]['#description'] = $definition['description'];
$form[$definition['id']]['#group'] = 'extras';
}
}
}
return $form;
}
public function formAjax(array $form, FormStateInterface $form_state) {
return $form['plugin'];
}
public function save(array $form, FormStateInterface $form_state) {
$this->entity
->getFormatterType()
->submitForm($form, $form_state);
$entity = $this->entity;
$is_new = !$entity
->getOriginalId();
$this->formatterExtrasManager
->invokeAll('settingsSave', $entity, $form, $form_state);
$entity
->save();
$this->fieldFormatterManager
->clearCachedDefinitions();
if ($is_new) {
$this
->messenger()
->addStatus($this
->t('Added formatter %formatter.', [
'%formatter' => $entity
->label(),
]));
}
else {
$this
->messenger()
->addStatus($this
->t('Updated formatter %formatter.', [
'%formatter' => $entity
->label(),
]));
}
$form_state
->setRedirectUrl(new Url('entity.formatter.collection'));
}
protected function getDependentEntitiesList(array $entities = []) {
$list = [];
foreach ($entities as $entity) {
$entity_type_id = $entity
->getEntityTypeId();
if (!isset($list[$entity_type_id])) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$label = $entity_type
->getLabel();
$list[$entity_type_id] = [
'#theme' => 'item_list',
'#title' => $label,
'#items' => [],
];
}
$list[$entity_type_id]['#items'][$entity
->id()] = $entity
->label() ?: $entity
->id();
}
return render($list);
}
protected function getFieldTypes() {
$options = [];
$field_types = $this->fieldTypeManager
->getDefinitions();
$this->moduleHandler
->alter('custom_formatters_fields', $field_types);
ksort($field_types);
foreach ($field_types as $field_type) {
$options[$field_type['provider']][$field_type['id']] = $field_type['label']
->render();
}
ksort($options);
return $options;
}
}