You are here

class ParagraphsTableFormatter in Paragraphs table 8

Plugin implementation of the 'paragraphs_table_formatter' formatter.

Plugin annotation


@FieldFormatter(
  id = "paragraphs_table_formatter",
  module = "paragraphs_table",
  label = @Translation("Paragraphs table"),
  field_types = {
    "entity_reference_revisions"
  }
)

Hierarchy

Expanded class hierarchy of ParagraphsTableFormatter

1 file declares its use of ParagraphsTableFormatter
AjaxController.php in src/Controller/AjaxController.php

File

src/Plugin/Field/FieldFormatter/ParagraphsTableFormatter.php, line 31

Namespace

Drupal\paragraphs_table\Plugin\Field\FieldFormatter
View source
class ParagraphsTableFormatter extends EntityReferenceFormatterBase {

  /**
   * The entity display repository.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
   */
  protected $entityDisplayRepository;

  /**
   * Constructs a FormatterBase 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\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
   *   The entity display repository.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityDisplayRepositoryInterface $entity_display_repository) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
    $this->entityDisplayRepository = $entity_display_repository;
  }

  /**
   * {@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('entity_display.repository'));
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      // Implement default settings.
      'view_mode' => 'default',
      'vertical' => FALSE,
      'caption' => '',
      'mode' => '',
      'chart_type' => '',
      'chart_width' => 900,
      'chart_height' => 300,
      'import' => '',
      'empty_cell_value' => FALSE,
      'empty' => FALSE,
      'ajax' => FALSE,
      'custom_class' => '',
      'hide_line_operations' => FALSE,
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $settingForm = [
      'view_mode' => [
        '#type' => 'select',
        '#options' => $this->entityDisplayRepository
          ->getViewModeOptions($this
          ->getFieldSetting('target_type')),
        '#title' => $this
          ->t('View mode'),
        '#default_value' => $this
          ->getSetting('view_mode'),
        '#required' => TRUE,
      ],
      'caption' => [
        '#title' => $this
          ->t('Caption'),
        '#description' => $this
          ->t('Caption of table'),
        '#type' => 'textfield',
        '#default_value' => $this
          ->getSettings()['caption'],
      ],
      'vertical' => [
        '#title' => $this
          ->t('Table vertical'),
        '#description' => $this
          ->t('If checked, table data will show in vertical mode'),
        '#type' => 'checkbox',
        '#default_value' => $this
          ->getSettings()['vertical'],
      ],
      'mode' => [
        '#title' => $this
          ->t('Table Mode'),
        '#description' => $this
          ->t('Select the table extension.'),
        '#type' => 'select',
        '#default_value' => $this
          ->getSettings()['mode'],
        '#options' => $this
          ->getConfigurableViewModes(),
        '#empty_option' => $this
          ->t('Default'),
        '#states' => [
          'visible' => [
            'input[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][vertical]"]' => [
              'checked' => FALSE,
            ],
          ],
        ],
      ],
      'chart_type' => [
        '#title' => $this
          ->t('Chart type'),
        '#description' => '<a href="https://developers-dot-devsite-v2-prod.appspot.com/chart/interactive/docs/gallery" target="_blank">Google charts</a>',
        '#type' => 'select',
        '#default_value' => $this
          ->getSettings()['chart_type'],
        '#options' => $this
          ->googleChartsOption(),
        '#empty_option' => $this
          ->t('Default'),
        '#states' => [
          'visible' => [
            'select[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][mode]"]' => [
              'value' => 'googleCharts',
            ],
          ],
        ],
      ],
      'chart_width' => [
        '#title' => $this
          ->t('Chart width'),
        '#type' => 'number',
        '#default_value' => $this
          ->getSettings()['chart_width'],
        '#states' => [
          'visible' => [
            'select[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][mode]"]' => [
              'value' => 'googleCharts',
            ],
          ],
        ],
      ],
      'chart_height' => [
        '#title' => $this
          ->t('Chart height'),
        '#type' => 'number',
        '#default_value' => $this
          ->getSettings()['chart_height'],
        '#states' => [
          'visible' => [
            'select[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][mode]"]' => [
              'value' => 'googleCharts',
            ],
          ],
        ],
      ],
      'empty_cell_value' => [
        '#title' => $this
          ->t('Fill Blank Cells in table'),
        '#description' => $this
          ->t('The string which should be displayed in empty cells. Defaults to an empty string.'),
        '#type' => 'textfield',
        '#default_value' => $this
          ->getSettings()['empty_cell_value'],
      ],
      'empty' => [
        '#title' => $this
          ->t('Hide empty columns'),
        '#description' => $this
          ->t('If enabled, hide empty paragraphs table columns'),
        '#type' => 'checkbox',
        '#default_value' => $this
          ->getSettings()['empty'],
        '#states' => [
          'visible' => [
            'input[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][vertical]"]' => [
              'checked' => FALSE,
            ],
          ],
        ],
      ],
      'ajax' => [
        '#title' => $this
          ->t('Load table with ajax'),
        '#description' => $this
          ->t('User for big data, ajax will load table data'),
        '#type' => 'checkbox',
        '#default_value' => $this
          ->getSettings()['ajax'],
        '#states' => [
          'visible' => [
            'input[name="fields[' . $this->fieldDefinition
              ->getName() . '][settings_edit_form][settings][vertical]"]' => [
              'checked' => FALSE,
            ],
          ],
        ],
      ],
      'custom_class' => [
        '#title' => $this
          ->t('Set table class'),
        '#type' => 'textfield',
        '#default_value' => $this
          ->getSettings()['custom_class'],
      ],
      'hide_line_operations' => [
        '#title' => $this
          ->t('Hide line operations'),
        '#type' => 'checkbox',
        '#default_value' => $this
          ->getSettings()['hide_line_operations'],
      ],
    ];
    if (\Drupal::service('module_handler')
      ->moduleExists('quick_data')) {
      $settingForm['import'] = [
        '#title' => $this
          ->t('Import link title'),
        '#description' => $this
          ->t("Leave it blank if you don't want to import csv data"),
        '#type' => 'textfield',
        '#default_value' => $this
          ->getSettings()['import'],
      ];
    }
    return $settingForm + parent::settingsForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];

    // Implement settings summary.
    $view_modes = $this->entityDisplayRepository
      ->getViewModeOptions($this
      ->getFieldSetting('target_type'));
    $view_mode = $this
      ->getSetting('view_mode');
    $summary[] = $this
      ->t('Rendered as @view_mode', [
      '@view_mode' => isset($view_modes[$view_mode]) ? $view_modes[$view_mode] : $view_mode,
    ]);
    if (!empty($this
      ->getSetting('caption'))) {
      $summary[] = $this
        ->t('Caption: @caption', [
        '@caption' => $this
          ->getSetting('caption'),
      ]);
    }
    if (!empty($this
      ->getSetting('vertical'))) {
      $summary[] = $this
        ->t('Table mode vertical');
    }
    if (!empty($this
      ->getSetting('mode'))) {
      $summary[] = $this
        ->t('Mode: @mode', [
        '@mode' => $this
          ->getSetting('mode'),
      ]);
    }
    if (!empty($this
      ->getSetting('chart_type'))) {
      $summary[] = $this
        ->t('Chart type: @type', [
        '@type' => $this
          ->getSetting('chart_type'),
      ]);
    }
    if (!empty($this
      ->getSetting('import'))) {
      $summary[] = $this
        ->t('Label import csv: @import', [
        '@import' => $this
          ->getSetting('import'),
      ]);
    }
    if (!empty($this
      ->getSetting('empty_cell_value'))) {
      $summary[] = $this
        ->t('Replace empty cells with: @replace', [
        '@replace' => $this
          ->getSetting('empty_cell_value'),
      ]);
    }
    if (!empty($this
      ->getSetting('empty'))) {
      $summary[] = $this
        ->t('Hide empty columns');
    }
    if (!empty($this
      ->getSetting('ajax'))) {
      $summary[] = $this
        ->t('Load ajax');
    }
    if (!empty($this
      ->getSetting('custom_class'))) {
      $summary[] = $this
        ->t('Custom class: @class', [
        '@class' => $this
          ->getSetting('custom_class'),
      ]);
    }
    if (!empty($this
      ->getSetting('hide_line_operations'))) {
      $summary[] = $this
        ->t('Hide line operations.');
    }
    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $setting = $this
      ->getSettings();
    $targetType = $this
      ->getFieldSetting('target_type');
    $field_definition = $items
      ->getFieldDefinition();
    $entity = $items
      ->getEntity();
    $entityId = $entity
      ->id();

    // In edit Mode if entity have multiple paragraphs table
    // we will have 1st paragraphs field.
    $field_name_current = $field_definition
      ->getName();
    $request = \Drupal::request()->request;
    if ($field_name_current != ($trigger_name = $request
      ->get('_triggering_add_paragraphs'))) {
      if ($entity
        ->hasField($trigger_name) && empty($request
        ->get('edit_' . $trigger_name))) {
        $items = $entity
          ->get($trigger_name);
        $field_definition = $items
          ->getFieldDefinition();
      }
    }
    $targetBundle = array_key_first($field_definition
      ->getSetting("handler_settings")["target_bundles"]);

    /** @var \Drupal\paragraphs\ParagraphInterface $paragraphs_entity */
    $paragraphs_entity = \Drupal::entityTypeManager()
      ->getStorage($targetType)
      ->create([
      'type' => $targetBundle,
    ]);
    $field_definitions = $paragraphs_entity
      ->getFieldDefinitions();
    $view_mode = $setting['view_mode'];
    $viewDisplay = \Drupal::service('entity_display.repository')
      ->getViewDisplay($targetType, $targetBundle, $view_mode);
    $components = $viewDisplay
      ->getComponents();
    uasort($components, 'Drupal\\Component\\Utility\\SortArray::sortByWeightElement');
    $table = $table_header = $fields = [];
    foreach ($components as $field_name => $component) {
      if (!empty($field_definitions[$field_name]) && $field_definitions[$field_name] instanceof FieldConfigInterface) {
        $fields[$field_name] = $field_definitions[$field_name];
        $table_header[$field_name] = $this
          ->t((string) $field_definitions[$field_name]
          ->getLabel());
      }
    }
    $fieldName = $field_definition
      ->getName();
    $hasPermission = $this
      ->checkPermissionOperation($entity, $fieldName);
    if (!empty($setting['hide_line_operations'])) {
      $hasPermission = FALSE;
    }
    if ($hasPermission) {
      $table_header['operation'] = '';
    }
    $entities = $this
      ->getEntitiesToView($items, $langcode);
    $table_rows = $notEmptyColumn = [];
    if (in_array($setting['mode'], [
      'datatables',
      'bootstrapTable',
    ]) || empty($setting['mode'])) {
      if (empty($setting["ajax"]) && !empty($entities)) {
        $table_rows = $this
          ->getPreparedRenderedEntities($targetType, $targetBundle, $entities, $fields, $notEmptyColumn, $view_mode, $hasPermission);

        // Remove empty columns.
        if (!empty($setting["empty"]) && !empty($notEmptyColumn)) {
          foreach ($table_header as $field_name => $label_column) {
            if (empty($notEmptyColumn[$field_name])) {
              unset($table_header[$field_name]);
              foreach ($table_rows as $delta => &$row) {
                unset($row[$field_name]);
              }
            }
          }
        }
      }
      if (!empty($setting["vertical"])) {
        $table = $this
          ->getTableVertical($table_header, $table_rows, $entities);
      }
      else {
        $table = $this
          ->getTable($table_header, $table_rows, $entities);
        if (empty($table_rows) && $setting['empty']) {
          unset($table["#header"]);
        }
      }
    }
    $table_id = implode('-', [
      $targetType,
      $targetBundle,
    ]);
    $table['#attributes']['id'] = $table_id;
    $table['#attributes']['class'][] = 'paragraphs-table';
    if (!empty($setting['caption'])) {
      $table['#caption'] = $this
        ->t((string) $setting['caption']);
    }
    if (!empty($setting['custom_class'])) {
      $table['#attributes']['class'][] = $setting['custom_class'];
    }
    switch ($setting['mode']) {
      case 'datatables':
        $datatable_options = $this
          ->datatablesOption($table_header, $components, $langcode);
        if (!empty($setting["ajax"]) && $entityId) {
          $url = Url::fromRoute('paragraphs_item.json', [
            'field_name' => $fieldName,
            'host_type' => $field_definition
              ->getTargetEntityTypeId(),
            'host_id' => $entityId,
          ]);
          $datatable_options["ajax"] = $url
            ->toString();
        }
        $table['#attributes']['width'] = '100%';
        $table['#attached']['library'][] = 'paragraphs_table/datatables_core';
        $table['#attached']['drupalSettings']['datatables']['#' . $table_id] = $datatable_options;
        $table['#attached']['library'][] = 'paragraphs_table/datatables';
        break;
      case 'bootstrapTable':
        $bootstrapTable_options = $this
          ->bootstrapTableOption($table_header, $components, $langcode);
        foreach ($bootstrapTable_options as $dataTable => $valueData) {
          $table['#attributes']["data-{$dataTable}"] = $valueData;
        }
        if (!empty($setting["ajax"]) && $entityId) {
          $url = Url::fromRoute('paragraphs_item.json', [
            'field_name' => $fieldName,
            'host_type' => $field_definition
              ->getTargetEntityTypeId(),
            'host_id' => $entityId,
          ], [
            'query' => [
              'type' => 'rows',
            ],
          ]);
          $table['#attributes']["data-url"] = $url
            ->toString();
        }
        foreach ($table_header as $field_name => $field_label) {
          $table_header[$field_name] = [
            'data' => $field_label,
            'data-field' => $field_name,
            'data-sortable' => "true",
          ];
        }
        $table['#header'] = $table_header;
        $table['#attached']['library'][] = 'paragraphs_table/bootstrapTable';
        if (!\Drupal::moduleHandler()
          ->moduleExists('fontawesome')) {
          $table['#attached']['library'][] = 'paragraphs_table/bootstrapTable_fontawesome';
        }
        break;
      case 'googleCharts':
        $options = $this
          ->googleChartsOption($setting['chart_type']);
        $options['url'] = FALSE;
        if (!empty($setting['caption'])) {
          $options['title'] = $setting['caption'];
        }
        if (is_numeric($setting['chart_width'])) {
          $setting['chart_width'] .= 'px';
        }
        if (is_numeric($setting['chart_height'])) {
          $setting['chart_height'] .= 'px';
        }
        if (empty($setting['chart_width'])) {
          $setting['chart_width'] = '100%';
        }
        $table = [
          '#theme' => 'paragraphs_table_chart',
          '#settings' => $setting,
          '#id_field_name' => $table_id,
        ];
        $table['#attached']['drupalSettings']['googleCharts']['#' . $table_id] = [
          'id' => $table_id,
          'type' => !empty($setting['chart_type']) ? $setting['chart_type'] : 'BarChart',
          'options' => $options,
        ];
        if (empty($setting["ajax"])) {
          $data = $this
            ->getData($targetType, $targetBundle, $entities, $fields, $notEmptyColumn, $view_mode);
          if (isset($table_header["operation"])) {
            unset($table_header["operation"]);
          }
          if (empty($options['notHeader'])) {
            $data = array_merge([
              array_values($table_header),
            ], $data);
          }
          $table['#attached']['drupalSettings']['googleCharts']['#' . $table_id]['data'] = $data;
        }
        else {
          $url = Url::fromRoute('paragraphs_item.jsonData', [
            'field_name' => $fieldName,
            'host_type' => $field_definition
              ->getTargetEntityTypeId(),
            'host_id' => $entityId,
          ]);
          $table['#attached']['drupalSettings']['googleCharts']['#' . $table_id]['options']['url'] = $url
            ->toString();
        }
        $table['#attached']['library'][] = 'paragraphs_table/googleCharts';
        break;
      default:
        if (!empty($setting["ajax"])) {
          $url = Url::fromRoute('paragraphs_item.ajax', [
            'field_name' => $fieldName,
            'host_type' => $field_definition
              ->getTargetEntityTypeId(),
            'host_id' => $entityId,
          ]);
          $table['#attached']['drupalSettings']['paragraphsTable']['#' . $table_id] = [
            'id' => $table_id,
            'view_mode' => $view_mode,
            'url' => $url
              ->toString(),
          ];
          $table['#attached']['library'][] = 'paragraphs_table/paragraphsTable';
        }
        break;
    }

    // Alter table results.
    \Drupal::moduleHandler()
      ->alter('paragraphs_table_formatter', $table, $table_id);
    $form = NULL;
    if ($hasPermission) {
      $arrInfo = [
        $entity,
        $field_definition
          ->getName(),
        $targetBundle,
      ];
      $form_state = (new FormState())
        ->set('langcode', $langcode)
        ->disableRedirect()
        ->addBuildInfo('args', $arrInfo);
      $edit_btn = 'edit_' . $fieldName;
      if ($fieldName == $field_name_current) {
        $load_form = 'Drupal\\paragraphs_table\\Form\\ActionButtonForm';
        $is_edit_mode = FALSE;
        if (!empty($_POST[$edit_btn])) {
          $load_form = 'Drupal\\paragraphs_table\\Form\\ActionEditFieldForm';
          $table['#access'] = FALSE;
          $is_edit_mode = TRUE;
        }
        $form = \Drupal::formBuilder()
          ->buildForm($load_form, $form_state);
        if ($is_edit_mode) {
          $form[$edit_btn] = [
            '#type' => 'hidden',
            '#value' => $fieldName,
            '#name' => $edit_btn,
          ];
        }
      }
      if (!empty($redirect = $form_state
        ->getRedirect())) {
        return new RedirectResponse($redirect
          ->toString());
      }
      $triggering_input = $form_state
        ->getUserInput();
      if (!empty($triggering_input)) {
        $triggering_element = $form_state
          ->getTriggeringElement();
        $temp = !empty($triggering_element["#name"]) ? explode("_", $triggering_element["#name"]) : [];
        $trigger_mode = end($temp);
        if (!empty($triggering_input[$edit_btn]) || in_array($trigger_mode, [
          'remove',
          'duplicate',
        ])) {
          $table['#attributes']['class'][] = 'hidden';
          $table['#access'] = FALSE;
        }
      }
    }
    return [
      $table,
      $form,
    ];
  }

  /**
   * Generate the output appropriate for one field item.
   *
   * @param \Drupal\Core\Field\FieldItemInterface $item
   *   One field item.
   *
   * @return string
   *   The textual output generated.
   */
  protected function viewValue(FieldItemInterface $item) {

    // The text value has no text format assigned to it, so the user input
    // should equal the output, including newlines.
    return nl2br(Html::escape($item->value));
  }

  /**
   * Get the entities which will make up the table.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $items
   *   The field items.
   *
   * @return array
   *   An array of loaded entities.
   */
  protected function getEntities(FieldItemListInterface $items) {
    $entity_type = $this->fieldDefinition
      ->getFieldStorageDefinition()
      ->getSetting('target_type');
    $entity_storage = \Drupal::entityTypeManager()
      ->getStorage($entity_type);
    $entities = [];
    foreach ($items as $item) {
      $entity_id = $item
        ->getValue()['target_id'];
      if ($entity_id) {
        $entity = $entity_storage
          ->load($entity_id);
        if ($entity && $entity
          ->access('view')) {
          $entities[] = $entity;
        }
      }
    }
    return $entities;
  }

  /**
   * {@inheritdoc}
   */
  public function getTable($table_columns, $table_rows, $entities) {
    $table = [
      '#theme' => 'table',
      '#rows' => $table_rows,
      '#header' => $table_columns,
    ];
    $this
      ->cacheMetadata($entities, $table);
    return $table;
  }

  /**
   * {@inheritdoc}
   */
  public function getData($type, $bundle, $entities, $fields, &$notEmptyColumn, $view_mode = 'default') {
    $storage = \Drupal::entityTypeManager()
      ->getStorage('entity_view_display');

    // When a display renderer doesn't exist, fall back to the default.
    $renderer = $storage
      ->load(implode('.', [
      $type,
      $bundle,
      $view_mode,
    ]));
    $setting = $this
      ->getSettings();
    $data = [];
    foreach ($entities as $delta => $entitie) {
      $table_entity = $renderer
        ->build($entitie);
      foreach ($fields as $field_name => $field) {
        $table_entity[$field_name]['#label_display'] = 'hidden';
        $value = trim(strip_tags(render($table_entity[$field_name])));
        if (in_array($field
          ->getType(), [
          'integer',
          'list_integer',
          'number_integer',
        ])) {
          $value = (int) $value;
        }
        if (in_array($field
          ->getType(), [
          'boolean',
        ])) {
          $list_value = $table_entity[$field_name]["#items"]
            ->getValue();
          $value = (int) $list_value[0]['value'];
        }
        if (in_array($field
          ->getType(), [
          'decimal',
          'list_decimal',
          'number_decimal',
          'float',
          'list_float',
          'number_float',
        ])) {
          $value = (double) $value;
        }
        if (!empty($value)) {
          $notEmptyColumn[$field_name] = TRUE;
        }
        elseif (!empty($setting["empty_cell_value"])) {
          $value = $setting["empty_cell_value"];
        }
        $data[$delta][] = $value;
      }
    }
    return $data;
  }

  /**
   * {@inheritdoc}
   */
  public function getTableVertical($table_columns, $table_rows, $entities) {
    $rows = [];
    foreach ($table_rows as $delta => $row) {
      if (count($table_rows) > 1) {
        $operation = !empty($row['data']['operation']) ? $row['data']['operation'] : '';
        $rows[] = [
          'data' => [
            [
              'data' => $operation,
              'colspan' => 2,
            ],
          ],
          'class' => [
            'paragraphs-item',
            'action',
          ],
          'data-quickedit-entity-id' => $row['data-quickedit-entity-id'],
          'data-id' => $row['data-id'],
          'data-type' => $row['data-type'],
        ];
      }
      foreach ($row['data'] as $field_name => $value) {
        if (!empty($table_columns[$field_name])) {
          $rows[] = [
            'data' => [
              'label' => [
                'data' => $this
                  ->t((string) $table_columns[$field_name]),
                'class' => [
                  'field__label',
                  $field_name,
                ],
              ],
              'item' => [
                'data' => $value,
                'class' => [
                  'field__item',
                  $field_name,
                ],
              ],
            ],
            'class' => [
              'field-paragraphs-item',
            ],
            'id' => 'item-' . $delta,
          ];
        }
      }
    }
    $table = [
      '#theme' => 'table',
      '#rows' => $rows,
    ];
    $this
      ->cacheMetadata($entities, $table);
    return $table;
  }

  /**
   * Cache.
   */
  protected function cacheMetadata($entities, &$table) {
    $cache_metadata = new CacheableMetadata();
    foreach ($entities as $entity) {
      $cache_metadata
        ->addCacheableDependency($entity);
      $cache_metadata
        ->addCacheableDependency($entity
        ->access('view', NULL, TRUE));
    }
    $cache_metadata
      ->applyTo($table);
  }

  /**
   * Prepare all of the given entities for rendering with applicable fields.
   */
  protected function getPreparedRenderedEntities($type, $bundle, $entities, $fields, &$notEmptyColumn, $view_mode = 'default', $show_operation = FALSE) {
    $storage = \Drupal::entityTypeManager()
      ->getStorage('entity_view_display');

    // When a display renderer doesn't exist, fall back to the default.
    $renderer = $storage
      ->load(implode('.', [
      $type,
      $bundle,
      $view_mode,
    ]));
    if (empty($renderer)) {
      $renderer = $storage
        ->load(implode('.', [
        $type,
        $bundle,
        'default',
      ]));
    }
    $setting = $this
      ->getSettings();
    $rows = [];
    foreach ($entities as $delta => $entity) {
      $entity_bundle = $entity
        ->bundle();
      if ($bundle != $entity_bundle) {
        continue;
      }
      $table_entity = $renderer
        ->build($entity);
      $paragraphs_id = $entity
        ->get('id')->value;
      foreach ($fields as $field_name => $field) {
        $table_entity[$field_name]['#label_display'] = 'hidden';
        $value = render($table_entity[$field_name]);
        if (!empty($value)) {
          $notEmptyColumn[$field_name] = TRUE;
        }
        elseif (!empty($setting["empty_cell_value"])) {
          $value = $setting["empty_cell_value"];
        }
        $rows[$delta]['data'][$field_name] = $value;
        $field_type = $field
          ->getType();

        // Add data order for sort.
        if ($setting['mode'] == 'datatables' && in_array($field_type, [
          'timestamp',
          'datetime',
          'daterange',
          'datestamp',
          'smartdate',
          'number_decimal',
          'decimal',
          'number_float',
          'list_float',
        ]) && !empty($table_entity[$field_name]["#items"])) {
          $list_value = $table_entity[$field_name]["#items"]
            ->getValue();
          $value_order = $list_value[0]['value'];
          if (!is_numeric($value_order)) {
            $value_order = strtotime($value_order);
          }
          $rows[$delta]['data'][$field_name] = [
            'data' => $value,
            'data-order' => $value_order,
          ];
        }
      }
      if ($show_operation) {
        $parent = $entity
          ->getParentEntity();
        $destination = implode('/', [
          $parent
            ->getEntityTypeId(),
          $parent
            ->id(),
        ]);
        $operation = $this
          ->paragraphsTableLinksAction($paragraphs_id, $destination);
        $rows[$delta]['data']['operation'] = $operation;
      }
      $rows[$delta]['data-quickedit-entity-id'] = "{$type}/{$paragraphs_id}";
      $rows[$delta]["data-id"] = $paragraphs_id;
      $rows[$delta]["data-type"] = $type;
    }
    return $rows;
  }

  /**
   * Support Datatable https://datatables.net/ https://bootstrap-table.com/.
   */
  public function getConfigurableViewModes() {
    return [
      'datatables' => $this
        ->t('Datatables'),
      'bootstrapTable' => $this
        ->t('Bootstrap Table'),
      'googleCharts' => $this
        ->t('Google Charts'),
    ];
  }

  /**
   * Links action.
   */
  private function paragraphsTableLinksAction($paragraphsId = FALSE, $destination = '') {
    $route_params = [
      'paragraph' => $paragraphsId,
    ];
    if (!empty($destination)) {
      $route_params['destination'] = $destination;
    }
    $operation = [
      '#type' => 'dropbutton',
      '#links' => [
        'view' => [
          'title' => $this
            ->t('View'),
          'url' => Url::fromRoute('entity.paragraphs_item.canonical', $route_params),
        ],
        'edit' => [
          'title' => $this
            ->t('Edit'),
          'url' => Url::fromRoute('entity.paragraphs_item.edit_form', $route_params),
        ],
        'duplicate' => [
          'title' => $this
            ->t('Duplicate'),
          'url' => Url::fromRoute('entity.paragraphs_item.clone_form', $route_params),
        ],
        'delete' => [
          'title' => $this
            ->t('Remove'),
          'url' => Url::fromRoute('entity.paragraphs_item.delete_form', $route_params),
        ],
      ],
    ];

    // Alter row operation.
    \Drupal::moduleHandler()
      ->alter('paragraphs_table_operations', $operation, $paragraphsId);
    return render($operation);
  }

  /**
   * Support Bootstrap Table.
   */
  public function bootstrapTableOption($header, $components, $langcode = 'en') {
    $data_option = [
      'toggle' => 'table',
      'search' => "true",
      'show-search-clear-button' => "true",
      'show-refresh' => "true",
      'show-toggle' => "true",
      'show-fullscreen' => "true",
      'show-columns' => "true",
      'show-columns-toggle-all' => "true",
      'show-export' => "true",
      'sortable' => "true",
      'click-to-select' => "true",
      'minimum-count-columns' => "2",
      'show-pagination-switch' => "true",
      'pagination' => "true",
      'page-list' => "[10, 25, 50, 100, all]",
      'show-footer' => "false",
    ];
    $languages = [
      'af' => 'af-ZA',
      'am' => 'am-ET',
      'ar' => 'ar-AE',
      'az' => 'az-Latn-AZ',
      'be' => 'be-BY',
      'bg' => 'bg-BG',
      'ca' => 'ca-ES',
      'cs' => 'cs-CZ',
      'cy' => 'cy-GB',
      'da' => 'da-DK',
      'de' => 'de-DE',
      'el' => 'el-GR',
      'eo' => 'eo-EO',
      'es' => 'es-ES',
      'et' => 'et-EE',
      'eu' => 'eu-EU',
      'fa' => 'fa-IR',
      'fi' => 'fi-fi',
      'fr' => 'fr-FR',
      'ga' => 'ga-IE',
      'gl' => 'gl-ES',
      'gu' => 'gu-IN',
      'he' => 'he-IL',
      'hi' => 'hi-IN',
      'hr' => 'hr-HR',
      'hu' => 'hu-HU',
      'hy' => 'hy-AM',
      'id' => 'id-ID',
      'is' => 'is-IS',
      'it' => 'it-CH',
      'ja' => 'ja-JP',
      'ka' => 'ka-GE',
      'kk' => 'kk-KZ',
      'km' => 'km-KH',
      'ko' => 'ko-KR',
      'ky' => 'ky-KG',
      'lo' => 'lo-LA',
      'lt' => 'lt-LT',
      'lv' => 'lv-LV',
      'mk' => 'mk-MK',
      'ml' => 'ml-IN',
      'mn' => 'mn-MN',
      'ne' => 'ne-NP',
      'nl' => 'nl-NL',
      'nb' => 'nb-NO',
      'nn' => 'nn-NO',
      'pa' => 'pa-IN',
      'pl' => 'pl-PL',
      'pt' => 'pt-PT',
      'ro' => 'ro-RO',
      'ru' => 'ru-RU',
      'si' => 'si-LK',
      'sk' => 'sk-SK',
      'sl' => 'sl-SI',
      'sq' => 'sq-AL',
      'sr' => 'sr-Latn-RS',
      'sv' => 'sv-SE',
      'sw' => 'sw-KE',
      'ta' => 'ta-IN',
      'te' => 'te-IN',
      'th' => 'th-TH',
      'tr' => 'tr-TR',
      'uk' => 'uk-UA',
      'ur' => 'ur-PK',
      'vi' => 'vn-VN',
      'fil' => 'fi-FI',
      'zh-hans' => 'zh-CN',
      'zh-hant' => 'zh-TW',
    ];
    if (!empty($languages[$langcode])) {
      $data_option['locale'] = $languages[$langcode];
    }
    return $data_option;
  }

  /**
   * Datatable Options.
   */
  public function datatablesOption($header, $components, $langcode = 'en') {
    $datatable_options = [
      'bExpandable' => TRUE,
      'bInfo' => TRUE,
      'dom' => 'Bfrtip',
      "scrollX" => TRUE,
      'bStateSave' => FALSE,
      "ordering" => TRUE,
      'searching' => TRUE,
      'bMultiFilter' => FALSE,
      'bMultiFilter_position' => "header",
    ];
    foreach ($header as $field_name => $field_label) {
      $datatable_options['aoColumnHeaders'][] = $field_label;
      $column_options = [
        'name' => $field_name,
        'data' => $field_name,
        'orderable' => TRUE,
        'type' => 'html',
      ];

      // Attempt to autodetect the type of field
      // in order to handle sorting correctly.
      if (!empty($components[$field_name]) && in_array($components[$field_name]['type'], [
        'number_decimal',
        'number_integer',
        'number_float',
        'list_float',
        'list_integer',
      ])) {
        $column_options['type'] = 'html-num';
      }
      if (!empty($components[$field_name]) && in_array($components[$field_name]['type'], [
        'datetime',
        'date',
        'datestamp',
      ])) {
        $column_options['type'] = 'date-fr';
      }
      $datatable_options['columns'][] = $column_options;
    }
    $languages = [
      'af' => 'Afrikaans',
      'am' => 'Amharic',
      'ar' => 'Arabic',
      'az' => 'Azerbaijan',
      'be' => 'Belarusian',
      'bg' => 'Bulgarian',
      'ca' => 'Catalan',
      'cs' => 'Czech',
      'cy' => 'Welsh',
      'da' => 'Danish',
      'de' => 'German',
      'el' => 'Greek',
      'eo' => 'Esperanto',
      'es' => 'Spanish',
      'et' => 'Estonian',
      'eu' => 'Basque',
      'fa' => 'Persian',
      'fi' => 'Finnish',
      'fr' => 'French',
      'ga' => 'Irish',
      'gl' => 'Galician',
      'gu' => 'Gujarati',
      'he' => 'Hebrew',
      'hi' => 'Hindi',
      'hr' => 'Croatian',
      'hu' => 'Hungarian',
      'hy' => 'Armenian',
      'id' => 'Indonesian',
      'is' => 'Icelandic',
      'it' => 'Italian',
      'ja' => 'Japanese',
      'ka' => 'Georgian',
      'kk' => 'Kazakh',
      'km' => 'Khmer',
      'ko' => 'Korean',
      'ku' => 'Kurdish',
      'ky' => 'Kyrgyz',
      'lo' => 'Lao',
      'lt' => 'Lithuanian',
      'lv' => 'Latvian',
      'mk' => 'Macedonian',
      'ml' => 'Malay',
      'mn' => 'Mongolian',
      'ne' => 'Nepali',
      'nl' => 'Dutch',
      'nb' => 'Norwegian-Bokmal',
      'nn' => 'Norwegian-Nynorsk',
      'pa' => 'Punjabi',
      'pl' => 'Polish',
      'pt' => 'Portuguese',
      'ro' => 'Romanian',
      'ru' => 'Russian',
      'si' => 'Sinhala',
      'sk' => 'Slovak',
      'sl' => 'Slovenian',
      'sq' => 'Albanian',
      'sr' => 'Serbian',
      'sv' => 'Swedish',
      'sw' => 'Swahili',
      'ta' => 'Tamil',
      'te' => 'telugu',
      'th' => 'Thai',
      'tr' => 'Turkish',
      'uk' => 'Ukrainian',
      'ur' => 'Urdu',
      'vi' => 'Vietnamese',
      'fil' => 'Filipino',
      'zh-hans' => 'Chinese',
      'zh-hant' => 'Chinese',
    ];
    if (!empty($languages[$langcode])) {
      $cdn_lang = '//cdn.datatables.net/plug-ins/';
      $version = '1.10.21';
      $language_url = $cdn_lang . $version . '/i18n/' . $languages[$langcode] . '.json';
      $datatable_options['language']['url'] = $language_url;
    }
    return $datatable_options;
  }

  /**
   * Support google chart.
   */
  private function googleChartsOption($option = FALSE) {
    $options = [
      'BarChart' => [
        'title' => $this
          ->t('Bar'),
        'option' => [
          'bar' => [
            'groupWidth' => "95%",
          ],
          'legend' => [
            'position' => "none",
          ],
        ],
      ],
      'BubbleChart' => [
        'title' => $this
          ->t('Bubble'),
        'option' => [
          'bubble' => [
            'textStyle' => [
              'fontSize' => 11,
            ],
          ],
        ],
      ],
      'LineChart' => [
        'title' => $this
          ->t('Line'),
        'option' => [
          'legend' => [
            'position' => "bottom",
          ],
          'curveType' => 'function',
        ],
      ],
      'ColumnChart' => [
        'title' => $this
          ->t('Column'),
        'option' => [
          'bar' => [
            'groupWidth' => "95%",
          ],
          'legend' => [
            'position' => "none",
          ],
        ],
      ],
      'ComboChart' => [
        'title' => $this
          ->t('Combo'),
        'option' => [
          'seriesType' => 'bars',
        ],
      ],
      'PieChart' => [
        'title' => $this
          ->t('Pie'),
        'option' => [
          'is3D' => TRUE,
        ],
      ],
      'ScatterChart' => [
        'title' => $this
          ->t('Scatter'),
        'option' => [
          'legend' => [
            'position' => "none",
          ],
        ],
      ],
      'SteppedAreaChart' => [
        'title' => $this
          ->t('Stepped Area'),
        'option' => [
          'isStacked' => TRUE,
        ],
      ],
      'AreaChart' => [
        'title' => $this
          ->t('Area'),
        'option' => [
          'legend' => [
            'position' => "top",
            'maxLines' => 3,
          ],
          'isStacked' => 'relative',
        ],
      ],
      'Histogram' => [
        'title' => $this
          ->t('Histogram'),
        'option' => [
          'legend' => [
            'position' => "top",
            'maxLines' => 3,
          ],
          'interpolateNulls' => FALSE,
        ],
      ],
      'CandlestickChart' => [
        'title' => $this
          ->t('Candlestick'),
        'option' => [
          'notHeader' => TRUE,
          'legend' => 'none',
          'bar' => [
            'groupWidth' => '100%',
          ],
        ],
      ],
    ];
    if ($option) {
      return $options[$option]['option'];
    }
    $titleOptions = [];
    foreach ($options as $type => $option) {
      $titleOptions[$type] = $option['title'];
    }
    return $titleOptions;
  }

  /**
   * Check permission Operation.
   */
  public function checkPermissionOperation($entity, $fieldName) {
    $hasPermission = FALSE;
    $user = \Drupal::currentUser();
    $permissions = [
      'bypass node access',
      'administer nodes',
      'administer paragraphs_item fields',
      'create ' . $fieldName,
      'edit ' . $fieldName,
      'edit own ' . $fieldName,
    ];
    foreach ($permissions as $permission) {
      if ($user
        ->hasPermission($permission)) {
        $hasPermission = TRUE;
        break;
      }
    }
    $entityType = $entity
      ->getEntityTypeId();
    if (!$hasPermission && $entityType != 'user') {
      $uid = $entity
        ->getOwnerId();
      if ($user
        ->hasPermission($permission) && $uid && $uid == $user
        ->id()) {
        $hasPermission = TRUE;
      }
    }
    return $hasPermission;
  }

}

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
EntityReferenceFormatterBase::checkAccess protected function Checks access to the given entity. 3
EntityReferenceFormatterBase::getEntitiesToView protected function Returns the referenced entities for display. 1
EntityReferenceFormatterBase::needsEntityLoad protected function Returns whether the entity referenced by an item needs to be loaded. 1
EntityReferenceFormatterBase::prepareView public function Loads the entities referenced in that field across all the entities being viewed. Overrides FormatterBase::prepareView
EntityReferenceFormatterBase::view public function Overrides FormatterBase::view
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::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
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
ParagraphsTableFormatter::$entityDisplayRepository protected property The entity display repository.
ParagraphsTableFormatter::bootstrapTableOption public function Support Bootstrap Table.
ParagraphsTableFormatter::cacheMetadata protected function Cache.
ParagraphsTableFormatter::checkPermissionOperation public function Check permission Operation.
ParagraphsTableFormatter::create public static function Creates an instance of the plugin. Overrides FormatterBase::create
ParagraphsTableFormatter::datatablesOption public function Datatable Options.
ParagraphsTableFormatter::defaultSettings public static function Defines the default settings for this plugin. Overrides PluginSettingsBase::defaultSettings
ParagraphsTableFormatter::getConfigurableViewModes public function Support Datatable https://datatables.net/ https://bootstrap-table.com/.
ParagraphsTableFormatter::getData public function
ParagraphsTableFormatter::getEntities protected function Get the entities which will make up the table.
ParagraphsTableFormatter::getPreparedRenderedEntities protected function Prepare all of the given entities for rendering with applicable fields.
ParagraphsTableFormatter::getTable public function
ParagraphsTableFormatter::getTableVertical public function
ParagraphsTableFormatter::googleChartsOption private function Support google chart.
ParagraphsTableFormatter::paragraphsTableLinksAction private function Links action.
ParagraphsTableFormatter::settingsForm public function Returns a form to configure settings for the formatter. Overrides FormatterBase::settingsForm
ParagraphsTableFormatter::settingsSummary public function Returns a short summary for the current formatter settings. Overrides FormatterBase::settingsSummary
ParagraphsTableFormatter::viewElements public function Builds a renderable array for a field value. Overrides FormatterInterface::viewElements
ParagraphsTableFormatter::viewValue protected function Generate the output appropriate for one field item.
ParagraphsTableFormatter::__construct public function Constructs a FormatterBase object. Overrides FormatterBase::__construct
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::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 6
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.