class ViewsFieldFormatter in Views field formatter 8.2
Same name and namespace in other branches
- 8 src/Plugin/Field/FieldFormatter/ViewsFieldFormatter.php \Drupal\views_field_formatter\Plugin\Field\FieldFormatter\ViewsFieldFormatter
Class ViewsFieldFormatter.
Plugin annotation
@FieldFormatter(
id = "views_field_formatter",
label = @Translation("View"),
description = @Translation("Todo"),
weight = 100,
field_types = {
"boolean",
"changed",
"comment",
"computed",
"created",
"datetime",
"decimal",
"email",
"entity_reference",
"entity_reference_revisions",
"expression_field",
"file",
"float",
"image",
"integer",
"language",
"link",
"list_float",
"list_integer",
"list_string",
"map",
"path",
"string",
"string_long",
"taxonomy_term_reference",
"text",
"text_long",
"text_with_summary",
"timestamp",
"uri",
"uuid"
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\Core\Field\PluginSettingsBase implements DependentPluginInterface, PluginSettingsInterface
- class \Drupal\Core\Field\FormatterBase implements FormatterInterface, ContainerFactoryPluginInterface
- class \Drupal\views_field_formatter\Plugin\Field\FieldFormatter\ViewsFieldFormatter
- class \Drupal\Core\Field\FormatterBase implements FormatterInterface, ContainerFactoryPluginInterface
- class \Drupal\Core\Field\PluginSettingsBase implements DependentPluginInterface, PluginSettingsInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of ViewsFieldFormatter
File
- src/
Plugin/ Field/ FieldFormatter/ ViewsFieldFormatter.php, line 58
Namespace
Drupal\views_field_formatter\Plugin\Field\FieldFormatterView source
class ViewsFieldFormatter extends FormatterBase {
/**
* Custom ajax callback.
*
* @param array $form
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The form element.
*/
public function ajaxAddRow(array &$form, FormStateInterface $form_state) : array {
/** @var \Drupal\field\FieldConfigInterface $fieldConfig */
$fieldConfig = $this->fieldDefinition;
return $form['fields'][$fieldConfig
->getName()]['plugin']['settings_edit_form']['settings']['arguments'];
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = parent::calculateDependencies();
list($view_id) = \explode('::', $this
->getSetting('view'), 2);
// Don't call the current view, as it would result into an
// infinite recursion.
// TODO: Check for infinite loop here.
if ($view_id !== NULL && ($view = View::load($view_id))) {
$dependencies[$view
->getConfigDependencyKey()][] = $view
->getConfigDependencyName();
}
return $dependencies;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'view' => '',
'arguments' => [],
'hide_empty' => FALSE,
'multiple' => FALSE,
'implode_character' => '',
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element = parent::settingsForm($form, $form_state);
$settings = $this
->getSettings();
// Get all views select options.
$options = [];
foreach (Views::getAllViews() as $view) {
foreach ($view
->get('display') as $display) {
$label = $view
->get('label');
$options[$label][$view
->get('id') . '::' . $display['id']] = \sprintf('%s - %s', $label, $display['display_title']);
}
}
// Early return if there is no views.
if ([] === $options) {
$element['help'] = [
'#markup' => '<p>' . $this
->t('No available Views were found.') . '</p>',
];
return $element;
}
$checked_arguments = \array_filter((array) $settings['arguments'], function ($argument) {
return $argument['checked'];
});
// Make sure we only save arguments that are enabled.
$settings['arguments'] = \array_values($checked_arguments);
$this
->setSettings($settings);
$ajax_arguments_count = 'ajax_arguments_count_' . $this->fieldDefinition
->getName();
if ($form_state
->get($ajax_arguments_count) === NULL) {
$form_state
->set($ajax_arguments_count, \count($checked_arguments));
}
// Ensure we clicked the Ajax button.
// @todo Is there a better way to detect this ?
$trigger = $form_state
->getTriggeringElement();
if (\is_array($trigger['#array_parents']) && \end($trigger['#array_parents']) === 'addRow') {
$form_state
->set($ajax_arguments_count, $form_state
->get($ajax_arguments_count) + 1);
}
$element['view'] = [
'#title' => $this
->t('View'),
'#description' => $this
->t("Select the view that will be displayed instead of the field's value."),
'#type' => 'select',
'#default_value' => $this
->getSetting('view'),
'#options' => $options,
];
$element['arguments'] = [
'#prefix' => '<div id="ajax_form_table_arguments">',
'#suffix' => '</div>',
'#type' => 'table',
'#header' => [
'',
$this
->t('Weight'),
$this
->t('Argument index'),
$this
->t('String or token'),
],
'#tabledrag' => [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => 'arguments-order-weight',
],
],
'#caption' => $this
->t('Select,add and reorder the arguments that will be used by the selected
view as contextual filters.
To remove some rows, uncheck the checkbox and save.'),
];
for ($i = 0; $i < $form_state
->get($ajax_arguments_count); $i++) {
$element['arguments'][] = [
'checked' => [
'#type' => 'checkbox',
'#title' => '',
'#default_value' => $this
->getSettings()['arguments'][$i]['checked'],
],
'weight' => [
'#type' => 'weight',
'#title' => $this
->t('Weight for @title', [
'@title' => 'token',
]),
'#title_display' => 'invisible',
'#attributes' => [
'class' => [
'arguments-order-weight',
],
],
],
'argument_index' => [
'#markup' => $i,
],
'token' => [
'#type' => 'textfield',
'#title' => 'Argument',
'#description' => $this
->t('Use a static string or a Drupal token - You can temporary use <em>%value%</em> until a proper token is found.'),
'#default_value' => $this
->getSettings()['arguments'][$i]['token'],
],
'#attributes' => [
'class' => [
'draggable',
],
],
];
}
$element['addRow'] = [
'#type' => 'button',
'#button_type' => 'secondary',
'#value' => t('Add a new argument'),
'#ajax' => [
'callback' => [
$this,
'ajaxAddRow',
],
'event' => 'click',
'wrapper' => 'ajax_form_table_arguments',
],
];
$types = [
'site',
'user',
'entity',
'field',
'date',
];
switch ($this->fieldDefinition
->getTargetEntityTypeId()) {
case 'taxonomy_term':
$types[] = 'term';
$types[] = 'vocabulary';
break;
default:
$types[] = $this->fieldDefinition
->getTargetEntityTypeId();
break;
}
$token = \Drupal::token();
$info = $token
->getInfo();
$available_token = \array_intersect_key($info['tokens'], \array_flip($types));
$token_items = [];
foreach ($available_token as $type => $tokens) {
$item = [
'#markup' => $this
->t('@type tokens', [
'@type' => \ucfirst($type),
]),
'children' => [],
];
foreach ($tokens as $name => $info) {
$info += [
'description' => $this
->t('No description available'),
];
$item['children'][$name] = \sprintf('[%s:%s] - %s: %s', $type, $name, $info['name'], $info['description']);
}
$token_items[$type] = $item;
}
$element['token_tree_link'] = [
'#type' => 'details',
'#title' => $this
->t('Available token replacements'),
'description' => [
'#markup' => $this
->t('To have more tokens, please install the <a href="@token">Token contrib module</a>.', [
'@token' => 'https://drupal.org/project/token',
]),
],
];
$element['token_tree_link']['list'] = [
'#theme' => 'item_list',
'#items' => $token_items,
'#attributes' => [
'class' => [
'global-tokens',
],
],
];
if (\Drupal::moduleHandler()
->moduleExists('token')) {
$element['token_tree_link'] = [
'#theme' => 'token_tree_link',
'#token_types' => $types,
];
}
$element['hide_empty'] = [
'#title' => $this
->t('Hide empty views'),
'#description' => $this
->t('Do not display the field if the view is empty.'),
'#type' => 'checkbox',
'#default_value' => (bool) $this
->getSetting('hide_empty'),
];
$element['multiple'] = [
'#title' => $this
->t('Multiple'),
'#description' => $this
->t('If the field is configured as multiple (<em>greater than one</em>),
should we display a view per item ? If selected, there will be one view per item.'),
'#type' => 'checkbox',
'#default_value' => (bool) $this
->getSetting('multiple'),
];
$element['implode_character'] = [
'#title' => $this
->t('Concatenate arguments'),
'#description' => $this
->t('If it is set, all arguments will be concatenated with the chosen character (<em>ex: a simple comma</em>)
and sent as one argument. Empty to disable.'),
'#type' => 'textfield',
'#default_value' => $this
->getSetting('implode_character'),
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
$settings = $this
->getSettings();
// For default settings, don't show a summary.
if ($settings['view'] === '') {
return [
$this
->t('Not configured yet.'),
];
}
list($view, $view_display) = \explode('::', $settings['view'], 2);
$multiple = (bool) $settings['multiple'] === TRUE ? 'Enabled' : 'Disabled';
$hide_empty = (bool) $settings['hide_empty'] === TRUE ? 'Hide' : 'Display';
$arguments = \array_map(function ($argument) {
return 'Token';
}, \array_keys(\array_filter((array) $settings['arguments'], function ($argument) {
return $argument['checked'];
})));
if ([] === $arguments) {
$arguments[] = $this
->t('None');
}
if ($view !== NULL) {
$summary[] = t('View: @view', [
'@view' => $view,
]);
$summary[] = t('Display: @display', [
'@display' => $view_display,
]);
$summary[] = t('Argument(s): @arguments', [
'@arguments' => \implode(', ', $arguments),
]);
$summary[] = t('Empty views: @hide_empty empty views', [
'@hide_empty' => $hide_empty,
]);
$summary[] = t('Multiple: @multiple', [
'@multiple' => $multiple,
]);
}
if ((bool) $settings['multiple'] === TRUE && $settings['implode_character'] !== '') {
$summary[] = t('Implode character: @character', [
'@character' => $settings['implode_character'],
]);
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
$settings = $this
->getSettings();
if (isset($settings['view']) && !empty($settings['view']) && \strpos($settings['view'], '::') !== FALSE) {
list($view_id, $view_display) = \explode('::', $settings['view'], 2);
}
else {
return $elements;
}
// First check the availability of the view.
$view = Views::getView($view_id);
if (!$view || !$view
->access($view_display)) {
return $elements;
}
$user_arguments = \array_filter((array) $this
->getSetting('arguments'), function ($argument) {
return $argument['checked'];
});
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $items
->getParent()
->getValue();
$token = \Drupal::token();
$arguments = [];
foreach ($user_arguments as $delta_argument => $item_argument) {
foreach ($items as $delta_item => $item) {
// This is temporary until we find a solution to get that same value
// using a tokens.
if ($item_argument['token'] === '%value%') {
$columns = array_keys($items
->getFieldDefinition()
->getFieldStorageDefinition()
->getSchema()['columns']);
$column = array_shift($columns);
$arguments[$delta_argument][] = !empty($column) && isset($item
->getValue()[$column]) ? $item
->getValue()[$column] : NULL;
continue;
}
$replacements = [
$entity
->getEntityTypeId() => $entity,
'entity' => $entity,
'views_field_formatter' => [
'delta' => $delta_item,
'item' => $item,
'items' => $items,
],
];
switch ($this->fieldDefinition
->getTargetEntityTypeId()) {
case 'taxonomy_term':
$replacements['term'] = $entity;
$replacements['vocabulary'] = Vocabulary::load($entity
->getVocabularyId());
break;
}
$arguments[$delta_argument][] = $token
->replace($item_argument['token'], $replacements);
}
}
if ((bool) $settings['multiple'] === TRUE) {
foreach ($items as $delta => $item) {
$viewArray = $this
->getViewArray($view, $view_display, \array_column($arguments, $delta), $settings);
if ([] !== $viewArray) {
$elements[$delta] = $viewArray;
}
}
}
else {
foreach ($arguments as $delta_argument => $item_argument) {
$arguments[$delta_argument] = \implode($settings['implode_character'], $arguments[$delta_argument]);
}
$viewArray = $this
->getViewArray($view, $view_display, $arguments, $settings);
if ([] !== $viewArray) {
$elements[0] = $viewArray;
}
}
return $elements;
}
/**
* Custom function to generate a view render array.
*
* @param \Drupal\views\ViewExecutable $view
* The view.
* @param string $view_display
* The view display.
* @param array $arguments
* The arguments to pass to the view.
* @param array $settings
* The field formatter settings.
*
* @return array
* A render array.
*/
private function getViewArray(ViewExecutable $view, $view_display, array $arguments, array $settings) : array {
if ((bool) $settings['hide_empty'] === TRUE) {
$view
->setArguments($arguments);
$view
->setDisplay($view_display);
$view
->preExecute();
$view
->execute();
if (empty($view->result)) {
return [];
}
}
return [
'#type' => 'view',
'#name' => $view
->id(),
'#display_id' => $view_display,
'#arguments' => $arguments,
];
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormatterBase:: |
protected | property | The field definition. | |
FormatterBase:: |
protected | property | The label display setting. | |
FormatterBase:: |
protected | property |
The formatter settings. Overrides PluginSettingsBase:: |
|
FormatterBase:: |
protected | property | The view mode. | |
FormatterBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
11 |
FormatterBase:: |
protected | function | Returns the value of a field setting. | |
FormatterBase:: |
protected | function | Returns the array of field settings. | |
FormatterBase:: |
public static | function |
Returns if the formatter can be used for the provided field. Overrides FormatterInterface:: |
14 |
FormatterBase:: |
public | function |
Allows formatters to load information for field values being displayed. Overrides FormatterInterface:: |
2 |
FormatterBase:: |
public | function |
Builds a renderable array for a fully themed field. Overrides FormatterInterface:: |
1 |
FormatterBase:: |
public | function |
Constructs a FormatterBase object. Overrides PluginBase:: |
11 |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginSettingsBase:: |
protected | property | Whether default settings have been merged into the current $settings. | |
PluginSettingsBase:: |
protected | property | The plugin settings injected by third party modules. | |
PluginSettingsBase:: |
public | function |
Returns the value of a setting, or its default value if absent. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Returns the array of settings, including defaults for missing settings. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
protected | function | Merges default settings values into $settings. | |
PluginSettingsBase:: |
public | function |
Informs the plugin that some configuration it depends on will be deleted. Overrides PluginSettingsInterface:: |
3 |
PluginSettingsBase:: |
public | function |
Sets the value of a setting for the plugin. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Sets the settings for the plugin. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Unsets a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
ViewsFieldFormatter:: |
public | function | Custom ajax callback. | |
ViewsFieldFormatter:: |
public | function |
Calculates dependencies for the configured plugin. Overrides PluginSettingsBase:: |
|
ViewsFieldFormatter:: |
public static | function |
Defines the default settings for this plugin. Overrides PluginSettingsBase:: |
|
ViewsFieldFormatter:: |
private | function | Custom function to generate a view render array. | |
ViewsFieldFormatter:: |
public | function |
Returns a form to configure settings for the formatter. Overrides FormatterBase:: |
|
ViewsFieldFormatter:: |
public | function |
Returns a short summary for the current formatter settings. Overrides FormatterBase:: |
|
ViewsFieldFormatter:: |
public | function |
Builds a renderable array for a field value. Overrides FormatterInterface:: |