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\FieldItemListInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FormatterBase;
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\Component\Utility\NestedArray;
abstract class FieldWrapperBase extends FormatterBase implements ContainerFactoryPluginInterface {
protected $viewDisplay;
protected $entityFieldManager;
protected $formatterPluginManager;
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, FormatterPluginManager $formatter_plugin_manager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->formatterPluginManager = $formatter_plugin_manager;
}
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('plugin.manager.field.formatter'));
}
public static function defaultSettings() {
return [
'type' => '',
'settings' => [],
];
}
protected function getFieldDefinition(FieldStorageDefinitionInterface $field_storage_definition) {
return BaseFieldDefinition::createFromFieldStorageDefinition($field_storage_definition);
}
protected function getAvailableFormatterOptions(FieldStorageDefinitionInterface $field_storage_definition) {
$formatters = $this->formatterPluginManager
->getOptions($field_storage_definition
->getType());
$formatter_instances = array_map(function ($formatter_id) {
$configuration = [
'field_definition' => $this->fieldDefinition,
'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) {
return $formatter
->isApplicable($this->fieldDefinition);
});
$options = array_map(function (FormatterInterface $formatter) {
return $formatter
->getPluginDefinition()['label'];
}, $filtered_formatter_instances);
unset($options['field_link']);
return $options;
}
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 function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$field_storage = $this->fieldDefinition
->getFieldStorageDefinition();
$formatter_options = $this
->getAvailableFormatterOptions($field_storage);
if (!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',
],
];
$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;
}
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;
}
protected function getViewDisplay($bundle_id) {
if (!isset($this->viewDisplay[$bundle_id])) {
$display = EntityViewDisplay::create([
'targetEntityType' => $this->fieldDefinition
->getTargetEntityTypeId(),
'bundle' => $bundle_id,
'status' => TRUE,
]);
$display
->setComponent($this->fieldDefinition
->getName(), [
'type' => $this
->getSetting('type'),
'settings' => $this
->getSetting('settings'),
]);
$this->viewDisplay[$bundle_id] = $display;
}
return $this->viewDisplay[$bundle_id];
}
protected function getFieldOutput(FieldItemListInterface $items, $langcode) {
$entity = $items
->getEntity();
$build = $this
->getViewDisplay($entity
->bundle())
->build($entity);
return isset($build[$this->fieldDefinition
->getName()]) ? $build[$this->fieldDefinition
->getName()] : [];
}
protected function getSettingFromFormState(FormStateInterface $form_state, $setting) {
$field_name = $this->fieldDefinition
->getName();
if ($form_state
->hasValue([
'fields',
$field_name,
'settings_edit_form',
'settings',
$setting,
])) {
return $form_state
->getValue([
'fields',
$field_name,
'settings_edit_form',
'settings',
$setting,
]);
}
return $this
->getSetting($setting);
}
}