eca-1.0.x-dev/modules/render/eca_render.module

modules/render/eca_render.module
<?php

/**
 * @file
 * ECA Render module file.
 */

use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityFormInterface;
use Drupal\Core\Entity\Display\EntityDisplayInterface;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\eca\Event\RenderEventInterface;

/**
 * Implements hook_theme().
 */
function eca_render_theme(): array {
  return [
    'eca_serialized' => [
      'variables' => [
        'serialized' => '',
        'method' => '',
        'format' => '',
        'data' => NULL,
        'wrap' => TRUE,
      ],
    ],
    'eca_lazy' => [
      'variables' => [
        'name' => '',
        'argument' => NULL,
      ],
    ],
  ];
}

/**
 * Preprocesses for eca-serialized.html.twig.
 *
 * @param array &$variables
 *   The variables consisting of following keys:
 *   - data: The not-serialized data.
 *   - format: The used serialization format (e.g. "json").
 *   - method: The performed method, either "serialize" or "unserialize".
 *   - serialized: The already serialized data as string. When not given,
 *     the theme function will take care of serializing the given data.
 *   - wrap: Boolean indicating whether the serialized string should be wrapped
 *     by an HTML script tag.
 */
function template_preprocess_eca_serialized(array &$variables = []): void {
  if (!isset($variables['wrap'])) {
    $variables['wrap'] = TRUE;
  }
  if (!isset($variables['method'])) {
    $variables['method'] = 'serialize';
  }
  if (isset($variables['data'], $variables['format']) && !isset($variables['serialized'])) {
    $variables['serialized'] = \Drupal::service('serializer')->serialize($variables['data'], $variables['format']);
  }
  if (!empty($variables['wrap'])) {
    if (!isset($variables['attributes'])) {
      $variables['attributes'] = new Attribute();
    }
    elseif (!($variables['attributes'] instanceof Attribute)) {
      $variables['attributes'] = new Attribute($variables['attributes']);
    }
    $attributes = $variables['attributes'];
    if (!isset($attributes['id'])) {
      $attributes['id'] = Html::getUniqueId('eca-serialized');
      if ($attributes instanceof Attribute) {
        $attributes->addClass('eca-serialized');
      }
    }
  }
}

/**
 * Implements hook_entity_operation().
 */
function eca_render_entity_operation(EntityInterface $entity): array {
  $build = [];
  $event = _eca_trigger_event()->dispatchFromPlugin('eca_render:entity_operations', $entity, $build);
  if ($event instanceof RenderEventInterface) {
    $build = &$event->getRenderArray();
  }

  $operations = [];

  // Convert link element builds into operation link arrays.
  $k = 0;
  foreach ($build as $i => $link) {
    if ($link instanceof EntityInterface) {
      if (!($link->hasLinkTemplate('canonical'))) {
        unset($build[$i]);
        continue;
      }
      $link = [
        'title' => $link->label(),
        'url' => $link->toUrl('canonical'),
        'weight' => (++$k * 10),
      ];
    }
    $weight = $link['weight'] ?? ($link['#weight'] ?? (++$k * 10));
    if (isset($link['#title'], $link['#url'])) {
      $link = [
        'title' => $link['#title'],
        'url' => $link['#url'],
      ];
    }
    if (isset($link['url']) && is_string($link['url'])) {
      try {
        $link['url'] = Url::fromUserInput($link['url']);
      }
      catch (\Exception $e1) {
        try {
          $link['url'] = Url::fromUri($link['url']);
        }
        catch (\Exception $e2) {
          \Drupal::logger('eca')->error("Failed to convert to URL when building up entity operation links.");
          continue;
        }
      }
    }
    $link['weight'] = $weight;

    if (isset($link['url']) && ($link['url'] instanceof Url)) {
      $operations[$i] = $link;
    }
  }

  return $operations;
}

/**
 * Implements hook_contextual_links_alter().
 */
function eca_render_contextual_links_alter(array &$links, string $group, array $route_parameters): void {
  $build = [];
  $etm = \Drupal::entityTypeManager();
  $event = _eca_trigger_event()->dispatchFromPlugin('eca_render:contextual_links', $links, $group, $route_parameters, $build, $etm);
  if ($event instanceof RenderEventInterface) {
    $build = &$event->getRenderArray();
  }

  // Convert link element builds into contextual link arrays.
  $k = 0;
  foreach ($build as $i => $link) {
    if ($link instanceof EntityInterface) {
      if (!($link->hasLinkTemplate('canonical'))) {
        unset($build[$i]);
        continue;
      }
      $url = $link->toUrl('canonical');
      $link = [
        'title' => $link->label(),
        'route_name' => $url->getRouteName(),
        'route_parameters' => $url->getRouteParameters(),
        'localized_options' => $url->getOptions(),
        'weight' => (++$k * 10),
      ];
    }
    $weight = $link['weight'] ?? ($link['#weight'] ?? (++$k * 10));
    if (isset($link['#title'], $link['#url'])) {
      $link = [
        'title' => $link['#title'],
        'url' => $link['#url'],
      ];
    }
    if (isset($link['url']) && is_string($link['url'])) {
      try {
        $link['url'] = Url::fromUserInput($link['url']);
      }
      catch (\Exception $e1) {
        try {
          $link['url'] = Url::fromUri($link['url']);
        }
        catch (\Exception $e2) {
          \Drupal::logger('eca')->error("Failed to convert to URL when building up contextual links.");
          continue;
        }
      }
    }

    if (isset($link['url'], $link['title']) && ($link['url'] instanceof Url)) {
      /**
       * @var \Drupal\Core\Url $url
       */
      $url = $link['url'];
      $link = [
        'title' => $link['title'],
        'route_name' => $url->getRouteName(),
        'route_parameters' => $url->getRouteParameters(),
        'localized_options' => $url->getOptions(),
        'weight' => $weight,
      ];
      $links[$i] = $link;
    }
  }
}

/**
 * Implements hook_views_data_alter().
 */
function eca_render_views_data_alter(array &$data): void {
  $data['views']['eca_render'] = [
    'title' => t('ECA Views field'),
    'help' => t("Custom render output, build up via ECA."),
    'field' => [
      'id' => 'eca_render',
    ],
  ];
}

/**
 * Implements hook_entity_extra_field_info().
 */
function eca_render_entity_extra_field_info(): array {
  $etm = \Drupal::entityTypeManager();
  /**
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
   */
  $bundle_info = \Drupal::service('entity_type.bundle.info');

  $extra = [];
  /**
   * @var \Drupal\eca\Entity\Eca $eca
   */
  foreach ($etm->getStorage('eca')->loadMultiple() as $eca) {
    foreach ($eca->get('events') ?? [] as $event) {
      if (($event['plugin'] ?? NULL) !== 'eca_render:extra_field') {
        continue;
      }
      $config = $event['configuration'] ?? [];

      $entity_type_ids = $config['entity_type_id'] === '' ?
        array_keys($etm->getDefinitions()) :
        explode(',', $config['entity_type_id']);
      foreach ($entity_type_ids as $entity_type_id) {
        $name = trim((string) ($config['extra_field_name'] ?? ''));
        $label = trim((string) ($config['extra_field_label'] ?? $name));
        $description = trim((string) ($config['extra_field_description'] ?? ''));
        $display_type = $config['display_type'] ?? 'display';
        $weight = (int) ($config['weight'] ?? 0);
        $visible = (bool) ($config['visible'] ?? FALSE);

        if ($name === '') {
          continue;
        }
        $entity_type_id = trim($entity_type_id);
        if (($entity_type_id === '') || !$etm->hasDefinition($entity_type_id)) {
          continue;
        }
        $bundle = trim($config['bundle'] ?? '');
        $bundles_available = array_keys($bundle_info->getBundleInfo($entity_type_id));
        if ($bundle === '' || $bundle === '*') {
          $bundles = $bundles_available;
        }
        else {
          $bundles = explode(',', $bundle);
          $bundles = array_intersect($bundles, $bundles_available);
        }
        foreach ($bundles as $bundle) {
          $extra[$entity_type_id][$bundle][$display_type]['eca_render__' . $name] = [
            'label' => $label,
            'description' => $description,
            'weight' => $weight,
            'visible' => $visible,
          ];
        }
      }
    }
  }

  return $extra;
}

/**
 * Implements hook_entity_view().
 */
function eca_render_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, string $view_mode): void {
  $event = _eca_trigger_event()->dispatchFromPlugin('eca_render:entity', $entity, $build, $display, $view_mode);
  if ($event instanceof RenderEventInterface) {
    $build = &$event->getRenderArray();
  }
  if (!($entity instanceof FieldableEntityInterface)) {
    return;
  }
  _eca_render_trigger_extra_field($build, $entity, $display, $view_mode, 'display');
}

/**
 * Implements hook_form_alter().
 */
function eca_render_form_alter(array &$form, FormStateInterface $form_state): void {
  $form_object = $form_state->getFormObject();
  if ($form_object instanceof ContentEntityFormInterface) {
    $entity = $form_object->getEntity();
    if (!($entity instanceof FieldableEntityInterface)) {
      return;
    }
    $display = $form_object->getFormDisplay($form_state);
    if ($display instanceof EntityFormDisplayInterface) {
      _eca_render_trigger_extra_field($form, $entity, $display, $display->getMode(), 'form');
    }
  }
}

/**
 * Triggers the rendering of extra fields via ECA.
 *
 * @param array &$build
 *   The render array.
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity.
 * @param \Drupal\Core\Entity\Display\EntityDisplayInterface $display
 *   The entity display.
 * @param string $view_mode
 *   The view mode.
 * @param string $display_type
 *   The display type.
 */
function _eca_render_trigger_extra_field(array &$build, EntityInterface $entity, EntityDisplayInterface $display, string $view_mode, string $display_type): void {
  foreach ($display->getComponents() as $name => $options) {
    if (strpos($name, 'eca_render__') !== 0) {
      continue;
    }
    $extra_field_name = substr($name, 12);
    $render_build = [];
    $event = _eca_trigger_event()->dispatchFromPlugin('eca_render:extra_field', $entity, $extra_field_name, $options, $render_build, $display, $view_mode, $display_type);
    if ($event instanceof RenderEventInterface) {
      $render_build = &$event->getRenderArray();
    }
    $build[$name] = $render_build;
    if (!isset($build['#weight']) && isset($options['weight'])) {
      $build['#weight'] = $options['weight'];
    }
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc