View source
<?php
namespace Drupal\name\Plugin\Field\FieldFormatter;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Url;
use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\name\NameFormatParser;
use Drupal\name\NameGeneratorInterface;
use Drupal\name\Traits\NameAdditionalPreferredTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\name\NameFormatter as NameFormatterService;
class NameFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
use NameAdditionalPreferredTrait;
protected $entityFieldManager;
protected $entityTypeManager;
protected $renderer;
protected $formatter;
protected $parser;
protected $generator;
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityFieldManager $entityFieldManager, EntityTypeManagerInterface $entityTypeManager, RendererInterface $renderer, NameFormatterService $formatter, NameFormatParser $parser, NameGeneratorInterface $generator) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->entityFieldManager = $entityFieldManager;
$this->entityTypeManager = $entityTypeManager;
$this->renderer = $renderer;
$this->formatter = $formatter;
$this->parser = $parser;
$this->generator = $generator;
}
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('entity_type.manager'), $container
->get('renderer'), $container
->get('name.formatter'), $container
->get('name.format_parser'), $container
->get('name.generator'));
}
public static function defaultSettings() {
$settings = parent::defaultSettings();
$settings += [
"format" => "default",
"markup" => "none",
"list_format" => "",
"link_target" => "",
];
$settings += self::getDefaultAdditionalPreferredSettings();
return $settings;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = parent::settingsForm($form, $form_state);
$elements['format'] = [
'#type' => 'select',
'#title' => $this
->t('Name format'),
'#default_value' => $this
->getSetting('format'),
'#options' => name_get_custom_format_options(),
'#required' => TRUE,
];
$elements['list_format'] = [
'#type' => 'select',
'#title' => $this
->t('List format'),
'#default_value' => $this
->getSetting('list_format'),
'#empty_option' => $this
->t('-- individually --'),
'#options' => name_get_custom_list_format_options(),
];
$elements['markup'] = [
'#type' => 'select',
'#title' => $this
->t('Markup'),
'#default_value' => $this
->getSetting('markup'),
'#options' => $this->parser
->getMarkupOptions(),
'#description' => $this
->t('This option wraps the individual components of the name in SPAN elements with corresponding classes to the component.'),
'#required' => TRUE,
];
if (!empty($this->fieldDefinition
->getTargetBundle())) {
$elements['link_target'] = [
'#type' => 'select',
'#title' => $this
->t('Link Target'),
'#default_value' => $this
->getSetting('link_target'),
'#empty_option' => $this
->t('-- no link --'),
'#options' => $this
->getLinkableTargets(),
];
$elements += $this
->getNameAdditionalPreferredSettingsForm($form, $form_state);
}
return $elements;
}
public function settingsSummary() {
$settings = $this
->getSettings();
$summary = [];
$machine_name = isset($settings['format']) ? $settings['format'] : 'default';
$name_format = $this->entityTypeManager
->getStorage('name_format')
->load($machine_name);
if ($name_format) {
$summary[] = $this
->t('Format: @format (@machine_name)', [
'@format' => $name_format
->label(),
'@machine_name' => $name_format
->id(),
]);
}
else {
$summary[] = $this
->t('Format: <strong>Missing format.</strong><br/>This field will be displayed using the Default format.');
}
if (!isset($settings['list_format']) || $settings['list_format'] == '') {
$summary[] = $this
->t('List format: Individually');
}
else {
$machine_name = isset($settings['list_format']) ? $settings['list_format'] : 'default';
$name_format = $this->entityTypeManager
->getStorage('name_list_format')
->load($machine_name);
if ($name_format) {
$summary[] = $this
->t('List format: @format (@machine_name)', [
'@format' => $name_format
->label(),
'@machine_name' => $name_format
->id(),
]);
}
else {
$summary[] = $this
->t('List format: <strong>Missing list format.</strong><br/>This field will be displayed using the Default list format.');
}
}
$markup_options = $this->parser
->getMarkupOptions();
$summary[] = $this
->t('Markup: @type', [
'@type' => $markup_options[$this
->getSetting('markup')],
]);
if (!empty($settings['link_target'])) {
$targets = $this
->getLinkableTargets();
$summary[] = $this
->t('Link: @target', [
'@target' => empty($targets[$settings['link_target']]) ? $this
->t('-- invalid --') : $targets[$settings['link_target']],
]);
}
$this
->settingsNameAdditionalPreferredSummary($summary);
if ($name_format) {
$names = $this->generator
->loadSampleValues(1, $this->fieldDefinition);
if ($name = reset($names)) {
$formatted = $this->parser
->parse($name, $name_format
->get('pattern'));
if (empty($formatted)) {
$summary[] = $this
->t('Example: <em><<empty>></em>');
}
else {
$summary[] = $this
->t('Example: @example', [
'@example' => $formatted,
]);
}
}
}
return $summary;
}
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
if (!$items
->count()) {
return $elements;
}
$settings = $this->settings;
$format = isset($settings['format']) ? $settings['format'] : 'default';
$is_multiple = $this->fieldDefinition
->getFieldStorageDefinition()
->isMultiple() && $items
->count() > 1;
$list_format = $is_multiple && !empty($settings['list_format']) ? $settings['list_format'] : '';
$extra = $this
->parseAdditionalComponents($items);
$extra['url'] = empty($settings['link_target']) ? NULL : $this
->getLinkableTargetUrl($items);
$item_array = [];
foreach ($items as $item) {
$components = $item
->toArray() + $extra;
$item_array[] = $components;
}
$this->formatter
->setSetting('markup', $this
->getSetting('markup'));
if ($list_format) {
$elements[0]['#markup'] = $this->formatter
->formatList($item_array, $format, $list_format, $langcode);
}
else {
foreach ($item_array as $delta => $item) {
$elements[$delta]['#markup'] = $this->formatter
->format($item, $format, $langcode);
}
}
return $elements;
}
protected function useMarkup() {
return $this->settings['markup'];
}
protected function getLinkableTargets() {
$targets = [
'_self' => $this
->t('Entity URL'),
];
$bundle = $this->fieldDefinition
->getTargetBundle();
$entity_type_id = $this->fieldDefinition
->getTargetEntityTypeId();
$fields = $this->entityFieldManager
->getFieldDefinitions($entity_type_id, $bundle);
foreach ($fields as $field) {
if (!$field
->getFieldStorageDefinition()
->isBaseField()) {
switch ($field
->getType()) {
case 'entity_reference':
case 'link':
$targets[$field
->getName()] = $field
->getLabel();
break;
}
}
}
return $targets;
}
protected function getLinkableTargetUrl(FieldItemListInterface $items) {
try {
$parent = $items
->getEntity();
if ($this->settings['link_target'] == '_self') {
if (!$parent
->isNew() && $parent
->access('view')) {
return $parent
->toUrl();
}
}
elseif ($parent
->hasField($this->settings['link_target'])) {
$target_items = $parent
->get($this->settings['link_target']);
if (!$target_items
->isEmpty()) {
$field = $target_items
->getFieldDefinition();
switch ($field
->getType()) {
case 'entity_reference':
foreach ($target_items as $item) {
if (!empty($item->entity) && !$item->entity
->isNew() && $item->entity
->access('view')) {
return $item->entity
->toUrl();
}
}
break;
case 'link':
foreach ($target_items as $item) {
if ($url = $item
->getUrl()) {
return $url;
}
}
break;
}
}
}
} catch (UndefinedLinkTemplateException $e) {
}
return Url::fromRoute('<none>');
}
protected function parseAdditionalComponents(FieldItemListInterface $items) {
$extra = [];
foreach ([
'preferred',
'alternative',
] as $key) {
$key_value = $this
->getSetting($key . '_field_reference');
$sep_value = $this
->getSetting($key . '_field_reference_separator');
if (!$key_value) {
$key_value = $this->fieldDefinition
->getSetting($key . '_field_reference');
$sep_value = $this->fieldDefinition
->getSetting($key . '_field_reference_separator');
}
if ($value = name_get_additional_component($this->entityTypeManager, $this->renderer, $items, $key_value, $sep_value)) {
$extra[$key] = $value;
}
}
return $extra;
}
}