datafield-1.x-dev/src/Plugin/Field/FieldFormatter/Details.php
src/Plugin/Field/FieldFormatter/Details.php
<?php
namespace Drupal\datafield\Plugin\Field\FieldFormatter;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\datafield\Plugin\DataFieldFormatterPluginManager;
use Drupal\datafield\Plugin\DataFieldTypePluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementations for 'details' formatter.
*/
#[FieldFormatter(
id: 'data_field_details',
label: new TranslatableMarkup('Details'),
field_types: [
'data_field',
],
)]
class Details extends Base {
/**
* Constructs a FormatterDetails object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The definition of the field to which the formatter is associated.
* @param array $settings
* The formatter settings.
* @param string $label
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Any third party settings.
* @param \Drupal\datafield\Plugin\DataFieldTypePluginManager $pluginType
* Plugin data type service.
* @param \Drupal\datafield\Plugin\DataFieldFormatterPluginManager $pluginFormatter
* Plugin data formatter service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DataFieldTypePluginManager $pluginType, DataFieldFormatterPluginManager $pluginFormatter, protected RendererInterface $renderer) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $pluginType, $pluginFormatter);
}
/**
* {@inheritdoc}
*/
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.data_field.type'),
$container->get('plugin.manager.data_field.formatter'),
$container->get('renderer'),
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings(): array {
return [
'open' => TRUE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state): array {
$settings = $this->getSettings();
$element = parent::settingsForm($form, $form_state);
$element['open'] = [
'#type' => 'checkbox',
'#title' => $this->t('Open'),
'#default_value' => $settings['open'],
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary(): array {
$settings = $this->getSettings();
$summary = parent::settingsSummary();
if (!empty($settings['open'])) {
$summary[] = $this->t('Open: @open', ['@open' => $settings['open'] ? $this->t('yes') : $this->t('no')]);
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode): array {
$element = [];
$field_settings = $this->getFieldSettings();
$settings = $this->getSettings();
$subfields = array_keys($field_settings["columns"]);
if (!empty($setting = $settings['formatter_settings'])) {
uasort($setting, [
'Drupal\Component\Utility\SortArray',
'sortByWeightElement',
]);
$subfields = array_keys($setting);
}
// No other way to pass context to the theme.
// @see datafield_theme_suggestions_details_alter()
$attributes = [
'data_field--field-name' => $items->getName(),
'class' => ['data-field-details'],
];
if (!empty($this->getSetting('custom_class'))) {
$attributes['class'][] = $this->getSetting('custom_class');
}
foreach ($items as $delta => $item) {
$values = [];
$labels = [];
foreach ($subfields as $subfield) {
$values[$subfield] = $item->{$subfield};
if (!empty($setting[$subfield]['show_label'])) {
// phpcs:ignore
$labels[$subfield] = new TranslatableMarkup($field_settings['field_settings'][$subfield]["label"] ?? '');
}
}
$firstValues = array_shift($values);
$firstKey = current($subfields);
if (!empty($labels[$firstKey])) {
$firstValues = [
'#theme' => 'data_field_subfield',
'#value' => $firstValues,
'#label' => $labels[$firstKey],
'#field_name' => $firstKey,
'#index' => $firstKey,
];
}
$element[$delta] = [
'#title' => $firstValues,
'#type' => 'details',
'#open' => $settings['open'],
'#attributes' => $attributes,
];
foreach ($values as $subfield => $value) {
if (!empty($setting[$subfield]['hidden'])) {
continue;
}
if (!empty($labels[$subfield])) {
$value = [
'#theme' => 'data_field_subfield',
'#value' => $value,
'#label' => $labels[$subfield],
'#field_name' => $subfield,
'#index' => $subfield,
];
}
$element[$delta]['#value'][$subfield] = [
'#type' => 'container',
'content' => $value,
'#attributes' => [
'class' => [$subfield],
],
];
}
}
if (!empty($this->getSetting('form_format_table'))) {
$entity = $items->getEntity();
$entityId = $entity->id();
$field_definition = $items->getFieldDefinition();
$field_name = $items->getName();
$hasPermission = $this->checkPermissionOperation($entity, $field_name);
if ($entityId && $hasPermission) {
$dialog_width = '80%';
$element[] = [
'#type' => 'container',
'add-button' => [
'#type' => 'link',
'#title' => Markup::create('<i class="bi bi-plus" aria-hidden="true"></i> ' . $this->t('Add')),
'#url' => Url::fromRoute('datafield.add_form', $params = [
'entity_type' => $field_definition->getTargetEntityTypeId(),
'field_name' => $field_name,
'entity' => $entityId,
]),
'#attributes' => [
'class' => [
'btn',
'btn-success',
'use-ajax',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode(['width' => $dialog_width]),
],
],
'edit-button' => [
'#type' => 'link',
'#title' => Markup::create('<i class="bi bi-pencil-square"></i> ' . $this->t('Edit')),
'#url' => Url::fromRoute('datafield.edit_all_form', $params = [
'entity_type' => $field_definition->getTargetEntityTypeId(),
'field_name' => $field_name,
'entity' => $entityId,
]),
'#attributes' => [
'class' => [
'btn',
'btn-info',
'use-ajax',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode(['width' => $dialog_width]),
],
],
];
}
}
return $element;
}
}
