public function GeneralUserReferenceFormatter::viewElements in Formatter Suite 8
Builds a renderable array for a field value.
Parameters
\Drupal\Core\Field\FieldItemListInterface $items: The field values to be rendered.
string $langcode: The language that should be used to render the field.
Return value
array A renderable array for $items, as an array of child elements keyed by consecutive numeric indexes starting from 0.
Overrides FormatterInterface::viewElements
File
- src/
Plugin/ Field/ FieldFormatter/ GeneralUserReferenceFormatter.php, line 784
Class
- GeneralUserReferenceFormatter
- Formats a user entity reference as one or more links.
Namespace
Drupal\formatter_suite\Plugin\Field\FieldFormatterCode
public function viewElements(FieldItemListInterface $items, $langcode) {
$this
->sanitizeSettings();
//
// Get entities.
// -------------
// From the item list, get the entities to process. If there aren't
// any, return nothing.
$elements = [];
$entities = $this
->getEntitiesToView($items, $langcode);
if (empty($entities) === TRUE) {
return [];
}
// Prepare custom classes.
// -----------------------
// If the admin entered custom classes, add them.
$classes = $this
->getSetting('classes');
if (empty($classes) === TRUE) {
$classes = [];
}
else {
// Security: Class names are entered by an administrator.
// They may not include anything but CSS-compatible words, and
// certainly no HTML.
//
// Here, the class text is stripped of HTML tags as a start.
// A regex tosses unacceptable characters in a CSS class name.
$classes = strip_tags($classes);
$classes = mb_ereg_replace('[^_a-zA-Z0-9- ]', '', $classes);
if ($classes === FALSE) {
$classes = [];
}
$classes = explode(' ', $classes);
}
//
// Prepare token pattern.
// ----------------------
// Get the pattern and pre-process it. If the admin entered a custom
// pattern, clean it of dangerous HTML. Otherwise get a well-known
// pattern.
$userReferenceStyle = $this
->getSetting('userReferenceStyle');
if ($userReferenceStyle === 'custom') {
// Custom token pattern.
$pattern = $this
->getSetting('titleCustomText');
if (empty($pattern) === TRUE) {
// If the custom pattern is empty, revert to the ID.
$pattern = '[user:uid]';
}
else {
// Security: A custom pattern is entered by an administrator.
// It may legitimately include HTML entities and minor HTML, but
// it should not include dangerous HTML.
$pattern = Xss::filterAdmin($this
->getSetting('titleCustomText'));
}
}
else {
// User a pre-defined token pattern.
$userReferencePatterns = self::getUserReferenceTokenPatterns();
$pattern = $userReferencePatterns[$userReferenceStyle];
}
//
// Replace tokens.
// ---------------
// Loop through the entities and do token replacement for each one.
foreach ($entities as $delta => &$entity) {
$url = NULL;
if ($entity
->isAnonymous() === FALSE) {
$url = $entity
->toUrl();
$urlOptions = $url
->getOptions();
}
$title = '';
if ($entity
->isAnonymous() === TRUE) {
// For anonymous users, some tokens cannot be replaced because the
// user entity has no account name, display name, etc. Fill those in.
$updatedPattern = $this
->replaceTokensForAnonymous($pattern);
}
else {
$updatedPattern = $pattern;
}
// Replace tokens in the pattern.
$title = $this->tokenService
->replace($updatedPattern, [
'user' => $entity,
], [
'langcode' => $langcode,
'clear' => TRUE,
]);
// Because replaced text may include HTML, we cannot pass it directly as
// the '#title' on a link, which will escape the HTML. Instead we
// use FormattableMarkup.
$title = new FormattableMarkup($title, []);
// If the link is disabled, show the title text within a <span>.
// Otherwise, build a URL and create a link.
if ($this
->getSetting('showLink') === FALSE || $url === NULL) {
$elements[$delta] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#value' => $title,
'#attributes' => [
'class' => $classes,
],
'#cache' => [
'tags' => $entity
->getCacheTags(),
],
];
}
else {
$rel = '';
$target = '';
$download = FALSE;
switch ($this
->getSetting('openLinkIn')) {
case '_self':
$target = '_self';
break;
case '_blank':
$target = '_blank';
break;
case 'download':
$download = TRUE;
break;
}
$topic = $this
->getSetting('linkTopic');
if ($topic !== 'any') {
$rel .= $topic;
}
if (empty($rel) === FALSE) {
$urlOptions['attributes']['rel'] = $rel;
}
if (empty($target) === FALSE) {
$urlOptions['attributes']['target'] = $target;
}
if ($download === TRUE) {
$urlOptions['attributes']['download'] = '';
}
$url
->setOptions($urlOptions);
$elements[$delta] = [
'#type' => 'link',
'#title' => $title,
'#options' => $url
->getOptions(),
'#url' => $url,
'#attributes' => [
'class' => $classes,
],
'#cache' => [
'tags' => $entity
->getCacheTags(),
],
];
if (empty($items[$delta]->_attributes) === FALSE) {
// There are item attributes. Add them to the link's options.
$elements[$delta]['#options'] += [
'attributes' => $items[$delta]->_attributes,
];
// And remove them from the item since they are now included
// on the link.
unset($items[$delta]->_attributes);
}
}
}
if (empty($elements) === TRUE) {
return [];
}
//
// Add multi-value field processing.
// ---------------------------------
// If the field has multiple values, redirect to a theme and pass
// the list style and separator.
$isMultiple = $this->fieldDefinition
->getFieldStorageDefinition()
->isMultiple();
if ($isMultiple === TRUE) {
// Replace the 'field' theme with ours, which supports lists.
$elements['#theme'] = 'formatter_suite_field_list';
// Set the list style.
$elements['#list_style'] = $this
->getSetting('listStyle');
// Set the list separator.
//
// Security: The list separator is entered by an administrator.
// It may legitimately include HTML entities and minor HTML, but
// it should not include dangerous HTML.
//
// Because it may include HTML, we cannot pass it as-is and let a TWIG
// template use {{ }}, which will process the text and corrupt any
// entered HTML or HTML entities.
//
// We therefore use an Xss admin filter to remove any egreggious HTML
// (such as scripts and styles), and then FormattableMarkup() to mark the
// resulting text as safe.
$listSeparator = Xss::filterAdmin($this
->getSetting('listSeparator'));
$elements['#list_separator'] = new FormattableMarkup($listSeparator, []);
}
return $elements;
}