View source
<?php
namespace Drupal\field_formatter\Plugin\Field\FieldFormatter;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Field\FormatterInterface;
use Drupal\Core\Field\FormatterPluginManager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Utility\NestedArray;
class FieldFormatterWithInlineSettings extends FieldFormatterBase implements ContainerFactoryPluginInterface {
protected $entityFieldManager;
protected $formatterPluginManager;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], $container
->get('entity_field.manager'), $container
->get('plugin.manager.field.formatter'), $container
->get('entity_type.manager'));
}
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityFieldManager $entity_field_manager, FormatterPluginManager $formatter_plugin_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->entityFieldManager = $entity_field_manager;
$this->formatterPluginManager = $formatter_plugin_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function defaultSettings() {
return parent::defaultSettings() + [
'field_name' => '',
'type' => '',
'settings' => [],
'label' => 'above',
];
}
protected function getFieldDefinition(FieldStorageDefinitionInterface $field_storage_definition) {
return BaseFieldDefinition::createFromFieldStorageDefinition($field_storage_definition);
}
protected function getAvailableFormatterOptions(FieldStorageDefinitionInterface $field_storage_definition) {
$field_definition = $this
->getFieldDefinition($field_storage_definition);
$formatters = $this->formatterPluginManager
->getOptions($field_storage_definition
->getType());
$formatter_instances = array_map(function ($formatter_id) use ($field_definition) {
$configuration = [
'field_definition' => $field_definition,
'settings' => [],
'label' => '',
'view_mode' => '',
'third_party_settings' => [],
];
return $this->formatterPluginManager
->createInstance($formatter_id, $configuration);
}, array_combine(array_keys($formatters), array_keys($formatters)));
$filtered_formatter_instances = array_filter($formatter_instances, function (FormatterInterface $formatter) use ($field_definition) {
return $formatter
->isApplicable($field_definition);
});
$options = array_map(function (FormatterInterface $formatter) {
return $formatter
->getPluginDefinition()['label'];
}, $filtered_formatter_instances);
return $options;
}
public static function onFieldNameChange(array $form, FormStateInterface $form_state) {
$triggeringElement = $form_state
->getTriggeringElement();
if (!empty($triggeringElement['#array_parents'])) {
$subformKeys = $triggeringElement['#array_parents'];
array_pop($subformKeys);
return NestedArray::getValue($form, $subformKeys);
}
}
public static function onFormatterTypeChange(array $form, FormStateInterface $form_state) {
$triggeringElement = $form_state
->getTriggeringElement();
if (!empty($triggeringElement['#array_parents'])) {
$subformKeys = $triggeringElement['#array_parents'];
array_pop($subformKeys);
$subformKeys[] = 'settings';
return NestedArray::getValue($form, $subformKeys);
}
}
public static function rebuildSubmit(array $form, FormStateInterface $form_state) {
$form_state
->setRebuild(TRUE);
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$target_entity_type_id = $this->fieldDefinition
->getSetting('target_type');
$field_storage_definitions = $this->entityFieldManager
->getFieldStorageDefinitions($target_entity_type_id);
$formatted_field_name = $this
->getSettingFromFormState($form_state, 'field_name');
if (isset($field_storage_definitions[$formatted_field_name])) {
$field_storage = $field_storage_definitions[$formatted_field_name];
$formatter_options = $this
->getAvailableFormatterOptions($field_storage);
}
$form['#prefix'] = '<div id="field-formatter-ajax">';
$form['#suffix'] = '</div>';
$form['field_name'] = [
'#type' => 'select',
'#title' => $this
->t('Field name'),
'#default_value' => $formatted_field_name,
'#options' => $this
->getAvailableFieldNames(),
'#ajax' => [
'callback' => [
get_class(),
'onFieldNameChange',
],
'wrapper' => 'field-formatter-ajax',
'method' => 'replace',
],
'#submit' => [
[
get_class(),
'rebuildSubmit',
],
],
'#executes_submit_callback' => TRUE,
];
$form['label'] = [
'#type' => 'select',
'#title' => $this
->t('Label'),
'#options' => [
'above' => $this
->t('Above'),
'inline' => $this
->t('Inline'),
'hidden' => '- ' . $this
->t('Hidden') . ' -',
'visually_hidden' => '- ' . $this
->t('Visually Hidden') . ' -',
],
'#default_value' => $this
->getSettingFromFormState($form_state, 'label'),
];
if ($formatted_field_name && !empty($formatter_options)) {
$formatter_type = $this
->getSettingFromFormState($form_state, 'type');
$settings = $this
->getSettingFromFormState($form_state, 'settings');
if (!isset($formatter_options[$formatter_type])) {
$formatter_type = key($formatter_options);
$settings = [];
}
$form['type'] = [
'#type' => 'select',
'#title' => $this
->t('Formatter'),
'#options' => $formatter_options,
'#default_value' => $formatter_type,
'#ajax' => [
'callback' => [
get_class(),
'onFormatterTypeChange',
],
'wrapper' => 'field-formatter-settings-ajax',
'method' => 'replace',
],
'#submit' => [
[
get_class(),
'rebuildSubmit',
],
],
'#executes_submit_callback' => TRUE,
];
$options = [
'field_definition' => $this
->getFieldDefinition($field_storage),
'configuration' => [
'type' => $formatter_type,
'settings' => $settings,
'label' => '',
'weight' => 0,
],
'view_mode' => '_custom',
];
$settings_form = [
'#value' => [],
];
if ($formatter = $this->formatterPluginManager
->getInstance($options)) {
$settings_form = $formatter
->settingsForm([], $form_state);
}
$form['settings'] = $settings_form;
$form['settings']['#prefix'] = '<div id="field-formatter-settings-ajax">';
$form['settings']['#suffix'] = '</div>';
}
return $form;
}
protected function getViewDisplay($bundle_id) {
if (!isset($this->viewDisplay[$bundle_id])) {
$display = EntityViewDisplay::create([
'targetEntityType' => $this->fieldDefinition
->getSetting('target_type'),
'bundle' => $bundle_id,
'status' => TRUE,
]);
$display
->setComponent($this
->getSetting('field_name'), [
'type' => $this
->getSetting('type'),
'settings' => $this
->getSetting('settings'),
'label' => $this
->getSetting('label'),
]);
$this->viewDisplay[$bundle_id] = $display;
}
return $this->viewDisplay[$bundle_id];
}
public function settingsSummary() {
$summary = parent::settingsSummary();
if ($type = $this
->getSetting('type')) {
$summary[] = $this
->t('Formatter %type used.', [
'%type' => $type,
]);
}
else {
$summary[] = $this
->t('Formatter not configured.');
}
return $summary;
}
}