You are here

class ViewsFieldFormatter in Views field formatter 8

Same name and namespace in other branches
  1. 8.2 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"),
    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

Expanded class hierarchy of ViewsFieldFormatter

File

src/Plugin/Field/FieldFormatter/ViewsFieldFormatter.php, line 55

Namespace

Drupal\views_field_formatter\Plugin\Field\FieldFormatter
View source
class ViewsFieldFormatter extends FormatterBase {

  /**
   * {@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' => [
        'field_value' => [
          'checked' => TRUE,
        ],
        'entity_id' => [
          'checked' => TRUE,
        ],
        'delta' => [
          'checked' => TRUE,
        ],
        'entity_revision_id' => [
          'checked' => TRUE,
        ],
      ],
      'hide_empty' => FALSE,
      'multiple' => FALSE,
      'implode_character' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $element = parent::settingsForm($form, $form_state);
    $options = [];
    foreach (Views::getAllViews() as $view) {
      foreach ($view
        ->get('display') as $display) {
        $options[$view
          ->get('label')][$view
          ->get('id') . '::' . $display['id']] = \sprintf('%s - %s', $view
          ->get('label'), $display['display_title']);
      }
    }
    if ([] === $options) {
      $element['help'] = [
        '#markup' => '<p>' . $this
          ->t('No available Views were found.') . '</p>',
      ];
      return $element;
    }
    $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'] = [
      '#type' => 'table',
      '#header' => [
        $this
          ->t('View Arguments'),
        $this
          ->t('Weight'),
      ],
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'arguments-order-weight',
        ],
      ],
      '#caption' => $this
        ->t('Select the arguments to send to the views, you can reorder them.
                          These arguments can be used as contextual filters in the selected View.'),
    ];
    $default_arguments = \array_keys(\array_filter($this
      ->getSetting('arguments'), static function ($argument) {
      return $argument['checked'];
    }));
    $arguments = \array_combine($default_arguments, $default_arguments);
    foreach ($this
      ->getDefaultArguments() as $argument_id => $argument_name) {
      $arguments[$argument_id] = $argument_name;
    }
    foreach ($arguments as $argument_id => $argument_name) {
      $element['arguments'][$argument_id] = [
        'checked' => [
          '#type' => 'checkbox',
          '#title' => $argument_name,
          '#default_value' => \in_array($argument_id, $default_arguments, TRUE),
        ],
        'weight' => [
          '#type' => 'weight',
          '#title' => $this
            ->t('Weight for @title', [
            '@title' => $argument_name,
          ]),
          '#title_display' => 'invisible',
          '#attributes' => [
            'class' => [
              'arguments-order-weight',
            ],
          ],
        ],
        '#attributes' => [
          'class' => [
            'draggable',
          ],
        ],
      ];
    }
    $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('Implode with this character'),
      '#description' => $this
        ->t('If it is set, all field values are imploded with this character (<em>ex: a simple comma</em>)
                          and sent as one views argument. Empty to disable.'),
      '#type' => 'textfield',
      '#default_value' => $this
        ->getSetting('implode_character'),
      '#states' => [
        'visible' => [
          ':input[name="fields[' . $this->fieldDefinition
            ->getName() . '][settings_edit_form][settings][multiple]"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    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_filter($settings['arguments'], static function ($argument) {
      return $argument['checked'];
    });
    $all_arguments = $this
      ->getDefaultArguments();
    $arguments = \array_map(static function ($argument) use ($all_arguments) {
      return $all_arguments[$argument];
    }, \array_keys($arguments));
    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();
    $cardinality = $items
      ->getFieldDefinition()
      ->getFieldStorageDefinition()
      ->getCardinality();
    if (isset($settings['view']) && !empty($settings['view']) && \mb_strpos($settings['view'], '::') !== FALSE) {
      list($view_id, $view_display) = \explode('::', $settings['view'], 2);
    }
    else {
      return $elements;
    }
    $arguments = $this
      ->getArguments($items, $items[0], 0);

    // If empty views are hidden, execute view to count result.
    if (!empty($settings['hide_empty'])) {
      $view = Views::getView($view_id);
      if (!$view || !$view
        ->access($view_display)) {
        return $elements;
      }

      // We try to reproduce the arguments which will be used below. We cannot
      // just use $this->getArguments($items, $items[0], 0) as this might return
      // items, which for example no longer exist, still you want to show the
      // view when there are more possible entries.
      if ((bool) $settings['multiple'] === TRUE && $cardinality !== 1) {
        if (!empty($settings['implode_character'])) {
          $arguments = $this
            ->getArguments($items, NULL, 0);
        }
      }
      $view
        ->setArguments($arguments);
      $view
        ->setDisplay($view_display);
      $view
        ->preExecute();
      $view
        ->execute();
      if (empty($view->result)) {
        return $elements;
      }
    }
    $elements = [
      '#cache' => [
        'max-age' => 0,
      ],
      [
        '#type' => 'view',
        '#name' => $view_id,
        '#display_id' => $view_display,
        '#arguments' => $arguments,
      ],
    ];
    if ($cardinality !== 1 && (bool) $settings['multiple'] === TRUE) {
      if (empty($settings['implode_character'])) {
        foreach ($items as $delta => $item) {
          $elements[$delta] = [
            '#type' => 'view',
            '#name' => $view_id,
            '#display_id' => $view_display,
            '#arguments' => $this
              ->getArguments($items, $items[$delta], $delta),
          ];
        }
      }
    }
    return $elements;
  }

  /**
   * Helper function. Returns the arguments to send to the views.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $items
   *   The items.
   * @param mixed $item
   *   The current item.
   * @param mixed $delta
   *   The item delta.
   *
   * @return array
   *   The arguments array.
   */
  protected function getArguments(FieldItemListInterface $items, $item, $delta) {
    $settings = $this
      ->getSettings();
    $user_arguments = \array_keys(\array_filter($settings['arguments'], static function ($argument) {
      return $argument['checked'];
    }));
    $arguments = [];
    foreach ($user_arguments as $argument) {
      switch ($argument) {
        case 'field_value':
          $columns = \array_keys($items
            ->getFieldDefinition()
            ->getFieldStorageDefinition()
            ->getSchema()['columns']);
          $column = \array_shift($columns);
          $cardinality = $items
            ->getFieldDefinition()
            ->getFieldStorageDefinition()
            ->getCardinality();

          /** @var FieldItemInterface $item */
          if ($item) {
            $arguments[$argument] = !empty($column) && isset($item
              ->getValue()[$column]) ? $item
              ->getValue()[$column] : NULL;
          }
          if ((bool) $settings['multiple'] === TRUE && $cardinality !== 1) {
            if (!empty($settings['implode_character'])) {
              $values = [];

              /** @var FieldItemInterface $item */
              foreach ($items as $item) {
                $values[] = !empty($column) && isset($item
                  ->getValue()[$column]) ? $item
                  ->getValue()[$column] : NULL;
              }
              if (!empty($values)) {
                $arguments[$argument] = \implode($settings['implode_character'], \array_filter($values));
              }
            }
          }
          break;
        case 'entity_id':
          $arguments[$argument] = $items
            ->getParent()
            ->getValue()
            ->id();
          break;
        case 'entity_revision_id':
          $arguments[$argument] = $items
            ->getParent()
            ->getValue()
            ->getRevisionId();
          break;
        case 'delta':
          $arguments[$argument] = isset($delta) ? $delta : NULL;
          break;
      }
    }
    return \array_values($arguments);
  }

  /**
   * Get the default Arguments.
   *
   * @return string[]
   *   The default arguments.
   */
  protected function getDefaultArguments() : array {
    return [
      'field_value' => $this
        ->t('Field value'),
      'entity_id' => $this
        ->t('Entity ID'),
      'delta' => $this
        ->t('Delta'),
      'entity_revision_id' => $this
        ->t('Entity revision ID'),
    ];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormatterBase::$fieldDefinition protected property The field definition.
FormatterBase::$label protected property The label display setting.
FormatterBase::$settings protected property The formatter settings. Overrides PluginSettingsBase::$settings
FormatterBase::$viewMode protected property The view mode.
FormatterBase::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create 11
FormatterBase::getFieldSetting protected function Returns the value of a field setting.
FormatterBase::getFieldSettings protected function Returns the array of field settings.
FormatterBase::isApplicable public static function Returns if the formatter can be used for the provided field. Overrides FormatterInterface::isApplicable 14
FormatterBase::prepareView public function Allows formatters to load information for field values being displayed. Overrides FormatterInterface::prepareView 2
FormatterBase::view public function Builds a renderable array for a fully themed field. Overrides FormatterInterface::view 1
FormatterBase::__construct public function Constructs a FormatterBase object. Overrides PluginBase::__construct 11
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginSettingsBase::$defaultSettingsMerged protected property Whether default settings have been merged into the current $settings.
PluginSettingsBase::$thirdPartySettings protected property The plugin settings injected by third party modules.
PluginSettingsBase::getSetting public function Returns the value of a setting, or its default value if absent. Overrides PluginSettingsInterface::getSetting
PluginSettingsBase::getSettings public function Returns the array of settings, including defaults for missing settings. Overrides PluginSettingsInterface::getSettings
PluginSettingsBase::getThirdPartyProviders public function Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface::getThirdPartyProviders
PluginSettingsBase::getThirdPartySetting public function Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface::getThirdPartySetting
PluginSettingsBase::getThirdPartySettings public function Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface::getThirdPartySettings
PluginSettingsBase::mergeDefaults protected function Merges default settings values into $settings.
PluginSettingsBase::onDependencyRemoval public function Informs the plugin that some configuration it depends on will be deleted. Overrides PluginSettingsInterface::onDependencyRemoval 3
PluginSettingsBase::setSetting public function Sets the value of a setting for the plugin. Overrides PluginSettingsInterface::setSetting
PluginSettingsBase::setSettings public function Sets the settings for the plugin. Overrides PluginSettingsInterface::setSettings
PluginSettingsBase::setThirdPartySetting public function Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface::setThirdPartySetting
PluginSettingsBase::unsetThirdPartySetting public function Unsets a third-party setting. Overrides ThirdPartySettingsInterface::unsetThirdPartySetting
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
ViewsFieldFormatter::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides PluginSettingsBase::calculateDependencies
ViewsFieldFormatter::defaultSettings public static function Defines the default settings for this plugin. Overrides PluginSettingsBase::defaultSettings
ViewsFieldFormatter::getArguments protected function Helper function. Returns the arguments to send to the views.
ViewsFieldFormatter::getDefaultArguments protected function Get the default Arguments.
ViewsFieldFormatter::settingsForm public function Returns a form to configure settings for the formatter. Overrides FormatterBase::settingsForm
ViewsFieldFormatter::settingsSummary public function Returns a short summary for the current formatter settings. Overrides FormatterBase::settingsSummary
ViewsFieldFormatter::viewElements public function Builds a renderable array for a field value. Overrides FormatterInterface::viewElements