Commit 85b968eb authored by Volodymyr Mostepaniuk's avatar Volodymyr Mostepaniuk
Browse files

Issue #3295753 by mostepaniukvm: Support raw and auto rendering options.

parent 4eb249ae
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -4,7 +4,3 @@ services:
    arguments: [ '@entity_type.manager' ]
    tags:
      - { name: event_subscriber }
  custom_elements_ui.processor.default_content_entity_ui:
    class: Drupal\custom_elements_ui\Processor\DefaultContentEntityUiProcessor
    tags:
      - { name: custom_elements_processor, priority: 100 }
+25 −52
Original line number Diff line number Diff line
@@ -78,22 +78,31 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
      ],
    ];

    // Add custom formatter field with needed options.
    $formatter_options = [
      'auto' => $this->t('Auto'),
      'raw' => $this->t('Raw'),
    ];
    $formatters = [
      'formatter' => [
        '#type' => 'select',
        '#title' => $this->t('Formatter'),
        '#title_display' => 'invisible',
        '#options' => $formatter_options,
        '#default_value' => $display_options['type'] ?? 'auto',
      ],
    ];

    // Insert additional fields.
    $label_position = array_search('plugin', array_keys($field_row));
    $field_row = array_slice($field_row, 0, $label_position, TRUE) + $label + array_slice($field_row, $label_position, count($field_row) - 1, TRUE);
    $field_row = array_slice($field_row, 0, $label_position + 1, TRUE) + $is_slot + array_slice($field_row, $label_position, count($field_row) - 1, TRUE);
    $field_row = array_slice($field_row, 0, $label_position + 2, TRUE) + $formatters + array_slice($field_row, $label_position, count($field_row) - 1, TRUE);

    // Update the (invisible) title of the 'plugin' column.
    $field_row['plugin']['#title'] = $this->t('Formatter for @title', ['@title' => $field_definition->getLabel()]);
    // @todo Activate when implemented.
    $field_row['plugin']['#disabled'] = TRUE;
    $field_row["settings_edit"]['#access'] = FALSE;

    // @todo Needed?
    if (!empty($field_row['plugin']['settings_edit_form']) && ($plugin = $this->entity->getRenderer($field_name))) {
      $plugin_type_info = $plugin->getPluginDefinition();
      $field_row['plugin']['settings_edit_form']['label']['#markup'] = $this->t('Format settings:') . ' <span class="plugin-name">' . $plugin_type_info['label'] . '</span>';
    }
    // Hide plugin field as it was replaced with custom one.
    $field_row['plugin']['#access'] = FALSE;
    $field_row['settings_edit']['#access'] = FALSE;
    $field_row['settings_summary']['#access'] = FALSE;

    return $field_row;
  }
@@ -112,11 +121,6 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
    }
    $ce_fields = $entity->getThirdPartySetting('custom_elements', 'custom_element_fields', []);

    if ($this->entity instanceof EntityWithPluginCollectionInterface) {
      // Do not manually update values represented by plugin collections.
      $form_values = array_diff_key($form_values, $this->entity->getPluginCollections());
    }

    // Collect data for 'regular' fields.
    foreach ($form['#fields'] as $field_name) {
      $values = $form_values['fields'][$field_name];
@@ -125,17 +129,7 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
      }
      else {
        $options = $ce_fields[$field_name] ?? [];

        // Update field settings only if the submit handler told us to.
        if ($form_state->get('plugin_settings_update') === $field_name) {
          // Only store settings actually used by the selected plugin.
          $default_settings = $this->pluginManager->getDefaultSettings($options['type']);
          $options['settings'] = isset($values['settings_edit_form']['settings']) ? array_intersect_key($values['settings_edit_form']['settings'], $default_settings) : [];
          $options['third_party_settings'] = $values['settings_edit_form']['third_party_settings'] ?? [];
          $form_state->set('plugin_settings_update', NULL);
        }

        $options['type'] = $values['type'];
        $options['type'] = $values['formatter'] ?? 'auto';
        $options['weight'] = (int) $values['weight'];
        $options['region'] = $values['region'];
        // Only formatters have configurable label visibility.
@@ -197,7 +191,8 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
      $bundle = $route_parameters['bundle'];
    }

    return $this->entityTypeManager->getStorage('entity_view_display')->load($route_parameters['entity_type_id'] . '.' . $bundle . '.' . $route_parameters['view_mode_name']);
    return $this->entityTypeManager->getStorage('entity_view_display')
      ->load($route_parameters['entity_type_id'] . '.' . $bundle . '.' . $route_parameters['view_mode_name']);
  }

  /**
@@ -211,8 +206,7 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
   * {@inheritdoc}
   */
  protected function getDefaultPlugin($field_type) {
    // @todo Implement with ce formatters.
    return NULL;
    return 'auto';
  }

  /**
@@ -254,34 +248,13 @@ class EntityCustomElementsDisplayForm extends EntityDisplayFormBase {
   * {@inheritdoc}
   */
  protected function thirdPartySettingsForm(PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state) {
    $settings_form = [];
    // Invoke hook_field_formatter_third_party_settings_form(), keying resulting
    // subforms by module name.
    $this->moduleHandler->invokeAllWith(
      'field_formatter_third_party_settings_form',
      function (callable $hook, string $module) use (&$settings_form, &$plugin, &$field_definition, &$form, &$form_state) {
        $settings_form[$module] = $hook(
          $plugin,
          $field_definition,
          $this->entity->getMode(),
          $form,
          $form_state,
        );
      }
    );
    return $settings_form;
    return [];
  }

  /**
   * {@inheritdoc}
   */
  protected function alterSettingsSummary(array &$summary, PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition) {
    $context = [
      'formatter' => $plugin,
      'field_definition' => $field_definition,
      'view_mode' => $this->entity->getMode(),
    ];
    $this->moduleHandler->alter('field_formatter_settings_summary', $summary, $context);
  }

}
+85 −16
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\custom_elements\CustomElement;
@@ -168,22 +170,16 @@ class DefaultContentEntityProcessor implements CustomElementProcessorInterface {
    $ce_display_fields = $display->getThirdPartySetting('custom_elements', 'custom_element_fields', []);
    foreach ($ce_display_fields as $field_name => $field_options) {
      if ($this->fieldIsAccessible($entity, $field_name, $custom_element)) {
        if ($field_options['is_slot']) {
          $nested_elements = [];
          foreach ($entity->get($field_name) as $field_item) {
            $nested_element = new CustomElement();
            $nested_element->setTagPrefix('field');
            $nested_element->setTag($entity->get($field_name)->getFieldDefinition()->getType());
            // @todo Check if $display->id() returns expected value.
            $this->getCustomElementGenerator()->process($field_item, $nested_element, $display->id());
            $nested_elements[] = $nested_element;
          }
          $custom_element->setSlotFromNestedElements($field_options['label'], $nested_elements);
        }
        else {
        $field_items = $entity->get($field_name);
          $property = $field_items->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
          $custom_element->setAttribute($field_options['label'], $field_items->{$property});
        switch ($field_options['type']) {
          // @todo Move implementation to separate service/plugin.
          case 'auto':
            $this->processAuto($field_items, $custom_element, $field_options['is_slot'], $field_options['label'], $display->getMode());
            break;
          case 'raw':
          default:
            $this->processRaw($field_items, $custom_element, $field_options['is_slot'], $field_options['label']);
            break;
        }
      }
    }
@@ -225,4 +221,77 @@ class DefaultContentEntityProcessor implements CustomElementProcessorInterface {
    return $elements;
  }

  /**
   * Automatically process field items and adds to the custom element.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $field_items
   *   Field item list object.
   * @param \Drupal\custom_elements\CustomElement $custom_element
   *   The custom element to which to add it.
   * @param bool $is_slot
   *   Whether it should be rendered as slot.
   * @param string $element_name
   *   Configured element name.
   * @param string $view_mode
   *   The current view-mode.
   */
  protected function processAuto(FieldItemListInterface $field_items, CustomElement $custom_element, bool $is_slot, string $element_name, string $view_mode) {
    if ($is_slot) {
      $nested_elements = [];
      foreach ($field_items as $field_item) {
        $nested_element = new CustomElement();
        $nested_element->setTagPrefix('field');
        $nested_element->setTag($field_items->getFieldDefinition()->getType());
        $this->getCustomElementGenerator()->process($field_item, $nested_element, $view_mode);
        $nested_elements[] = $nested_element;
      }
      $custom_element->setSlotFromNestedElements($element_name, $nested_elements);
    }
    else {
      if ($field_items instanceof EntityReferenceFieldItemListInterface) {
        $entities = $field_items->referencedEntities();
        array_filter($entities, function ($entity) {
          return $entity->access('view');
        });
        $values = array_map(function ($entity) {
          return $entity->label();
        }, $entities);
      }
      else {
        $property = $field_items->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
        $values = array_column($field_items->getValue(), $property);
      }
      if (count($values) === 1) {
        $values = reset($values);
      }
      $custom_element->setAttribute($element_name, $values);
    }
  }

  /**
   * Fetch raw field items data and adds to the custom element.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $field_items
   *   Field item list object.
   * @param \Drupal\custom_elements\CustomElement $custom_element
   *   The custom element to which to add it.
   * @param bool $is_slot
   *   Whether it should be rendered as slot.
   * @param string $element_name
   *   Configured element name.
   */
  protected function processRaw(FieldItemListInterface $field_items, CustomElement $custom_element, bool $is_slot, string $element_name) {
    $property = $field_items->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
    $values = array_column($field_items->getValue(), $property);
    if (count($values) === 1) {
      $values = reset($values);
    }
    if ($is_slot) {
      $custom_element->addSlot($element_name, $values);
    }
    else {
      $custom_element->setAttribute($element_name, $values);
    }
  }

}