display_builder-1.0.x-dev/modules/display_builder_devel/src/Controller/DisplayBuilderDevelController.php

modules/display_builder_devel/src/Controller/DisplayBuilderDevelController.php
<?php

declare(strict_types=1);

namespace Drupal\display_builder_devel\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\display_builder\DisplayBuilderHelpers;
use Drupal\display_builder\StateManager\StateManagerInterface;
use Drupal\display_builder_entity_view\Event\DisplayBuilderEntityViewEventsSubscriber;
use Drupal\display_builder_page_layout\DisplayBuilderPageLayout;
use Drupal\display_builder_views\DisplayBuilderViewsManager;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Returns responses for Display Builder ui routes.
 */
class DisplayBuilderDevelController extends ControllerBase {

  public function __construct(
    private readonly StateManagerInterface $stateManager,
  ) {}

  /**
   * Generate a simple index of saved display.
   *
   * @return array
   *   A render array.
   */
  public function index(): array {
    $build = [];
    $build['display_builder_table'] = [
      '#theme' => 'table',
      '#header' => [
        'id' => ['data' => $this->t('Id')],
        'type' => ['data' => $this->t('Type')],
        'display_builder_config' => ['data' => $this->t('Config')],
        'updated' => ['data' => $this->t('Updated')],
        'log' => ['data' => $this->t('Last log')],
        'operations' => ['data' => $this->t('Operations')],
      ],
    ];

    foreach (array_keys($this->stateManager->loadAll()) as $builder_id) {
      $build['display_builder_table']['#rows'][$builder_id] = $this->buildRow($builder_id, $this->stateManager->load($builder_id));
    }

    $build['pager'] = ['#type' => 'pager'];

    return $build;
  }

  /**
   * Provides a generic title callback for a display.
   *
   * @param string $builder_id
   *   The uniq display id.
   *
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|null
   *   The title for the display page, if found.
   */
  public function title(string $builder_id): ?TranslatableMarkup {
    if (empty($builder_id)) {
      return $this->t('Display builder');
    }

    return $this->t('Display builder: @id', ['@id' => $builder_id]);
  }

  /**
   * Load a display builder demo by id.
   *
   * @param string $builder_id
   *   The display builder demo id.
   *
   * @return array
   *   The display build.
   */
  public function view(string $builder_id): array {
    // \Drupal::service('plugin.cache_clearer')->clearCachedDefinitions();
    // \Drupal::service('page_cache_kill_switch')->trigger();
    $display_builder_id = $this->stateManager->getEntityConfigId($builder_id);

    $storage = $this->entityTypeManager()->getStorage('display_builder');
    /** @var \Drupal\display_builder\DisplayBuilderInterface $displayBuilderConfig */
    $displayBuilderConfig = $storage->load($display_builder_id);

    if ($displayBuilderConfig) {
      // @todo no contexts as it's a generic loader, but can fail if calling a
      // display with context.
      // $builder = $displayBuilderConfig->build($builder_id);
      // $builder['#cache']['max-age'] = 0;
      // return $builder;
      return $displayBuilderConfig->build($builder_id);
    }

    return [
      '#plain_text' => $this->t('Missing @builder_id config.', ['@builder_id' => $display_builder_id]),
    ];
  }

  /**
   * Delete a sample entity generated by UI Patterns.
   *
   * @param string $entity_type_id
   *   The entity type id.
   * @param string $bundle
   *   The bundle id.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   A message and redirect.
   */
  public function deleteSample(string $entity_type_id, string $bundle): RedirectResponse {
    /** @var \Drupal\ui_patterns\Entity\SampleEntityGenerator $sample */
    $sample = \Drupal::service('ui_patterns.sample_entity_generator'); // phpcs:ignore
    $sample->delete($entity_type_id, $bundle);

    $params = ['@entity_type_id' => $entity_type_id, '@bundle' => $bundle];
    $this->messenger()->addStatus($this->t('Sample @entity_type_id @bundle deleted!', $params));

    $redirect = $this->redirect('display_builder_devel.collection');
    $redirect->send();

    return $redirect;
  }

  /**
   * Redirect to user DB demo.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   A message and redirect.
   */
  public function viewUserDemo(): RedirectResponse {
    $user = \Drupal::currentUser(); // phpcs:ignore
    $builder_id = \Drupal::state()->get(\sprintf('db_demo_user_%s', $user->id()), NULL); // phpcs:ignore
    if (!$builder_id) {
      $this->messenger()->addError($this->t('No display builder demo found for you!'));

      $redirect = $this->redirect('<front>');
      $redirect->send();

      return $redirect;
    }

    $redirect = $this->redirect('display_builder_devel.view', ['builder_id' => $builder_id]);
    $redirect->send();

    return $redirect;
  }

  /**
   * Delete associated user DB for demo.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   A message and redirect.
   *
   * @see modules/display_builder_devel/src/Hook/DisplayBuilderDevelHooks.php
   */
  public function resetUserDb(): RedirectResponse {
    $user = \Drupal::currentUser(); // phpcs:ignore
    $builder_id = \Drupal::state()->get(\sprintf('db_demo_user_%s', $user->id()), NULL); // phpcs:ignore
    if (!$builder_id) {
      $this->messenger()->addError($this->t('No display builder demo found for you!'));

      $redirect = $this->redirect('<front>');
      $redirect->send();

      return $redirect;
    }

    $contexts = $this->stateManager->getContexts($builder_id);
    $this->stateManager->delete($builder_id);
    $builder_data = DisplayBuilderHelpers::getFixtureDataFromModule('display_builder_devel', '', 'ui_suite_bootstrap_demo');

    $this->stateManager->create(
      $builder_id,
      'demo',
      $builder_data,
      $contexts,
    );
    $this->messenger()->addStatus($this->t('Display builder demo reset successfully!'));

    $redirect = $this->redirect('display_builder_devel.view', ['builder_id' => $builder_id]);
    $redirect->send();

    return $redirect;
  }

  /**
   * Builds a table row for a display builder.
   *
   * @param string $builder_id
   *   The builder id.
   * @param array $builder
   *   An builder to display.
   *
   * @return array
   *   A table row.
   *
   * @SuppressWarnings(PHPMD.CyclomaticComplexity)
   */
  protected function buildRow(string $builder_id, array $builder): array {
    $row = [];

    $route_name = 'display_builder_devel.view';
    $route_params = ['builder_id' => $builder_id];
    $type = $this->t('None');
    $extra_links = [];

    // Simple switch to url based on context.
    if (class_exists('Drupal\display_builder_views\DisplayBuilderViewsManager') && $this->stateManager->hasSaveContextsRequirement($builder_id, DisplayBuilderViewsManager::VIEWS_CONTEXT_REQUIREMENT)) {
      $route_name = 'display_builder_views.views.manage';
      $type = $this->t('Views');
    }
    elseif (class_exists('Drupal\display_builder_page_layout\DisplayBuilderPageLayout') && $this->stateManager->hasSaveContextsRequirement($builder_id, DisplayBuilderPageLayout::PAGE_LAYOUT_CONTEXT_REQUIREMENT)) {
      $route_name = 'display_builder_page_layout.manage';
      $type = $this->t('Page layout');
    }
    elseif (class_exists('Drupal\display_builder_entity_view\Event\DisplayBuilderEntityViewEventsSubscriber') && $this->stateManager->hasSaveContextsRequirement($builder_id, DisplayBuilderEntityViewEventsSubscriber::CONTEXT_REQUIREMENT)) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      $entity = $builder['contexts']['entity']->getContextValue();
      $entity_type_id = $entity->getEntityTypeId();
      $route_name = \sprintf('display_builder.%s.view', $entity_type_id);
      $bundle = $builder['contexts']['bundle']->getContextValue();

      $route_params[$entity->getEntityType()->getBundleEntityType()] = $bundle;
      $route_params['view_mode_name'] = $builder['contexts']['view_mode']->getContextValue();
      $type = $this->t('Entity');
      $extra_links['refresh_sample'] = [
        'title' => $this->t('Refresh sample'),
        'url' => Url::fromRoute('display_builder_devel.delete_sample', [
          'entity_type_id' => $entity_type_id,
          'bundle' => $bundle,
        ]),
      ];
    }
    elseif (class_exists('Drupal\display_builder_page_layout\DisplayBuilderPageLayout') && $this->stateManager->hasSaveContextsRequirement($builder_id, DisplayBuilderPageLayout::PAGE_MANAGER_CONTEXT_REQUIREMENT)) {
      $route_name = 'display_builder_page_layout.page_manager.manage';
      $type = $this->t('Page manager');
    }

    // If related module is disabled, use devel default view.
    try {
      $url = Url::fromRoute($route_name, $route_params);
    }
    catch (\Throwable $th) {
      $url = Url::fromRoute('display_builder_devel.view', $route_params);
    }

    $row['id']['data'] = [
      '#type' => 'link',
      '#title' => $builder_id,
      '#url' => $url,
    ];

    $row['type']['data'] = $type;

    $row['display_builder_config']['data'] = $builder['entity_config_id'];

    $present = $builder['present'];

    if (!$present) {
      $present = ['time' => NULL, 'log' => NULL];
    }
    $row['updated']['data'] = $present['time'] ?? '-';

    if (isset($present['log']) && $present['log'] instanceof TranslatableMarkup) {
      $row['log']['data'] = $this->formatLog($present['log']);
    }
    else {
      $row['log']['data'] = '-';
    }

    $links = $this->getOperationLinks($builder_id, $extra_links);

    if (\count($links) > 0) {
      $row['operations']['data']['operations'] = [
        '#type' => 'operations',
        '#links' => $links,
      ];
    }

    return ['data' => $row];
  }

  /**
   * Format the log.
   *
   * @param \Drupal\Core\StringTranslation\TranslatableMarkup $log
   *   The log to format.
   *
   * @return string
   *   The formatted log.
   */
  private function formatLog(TranslatableMarkup $log): string {
    return $log->render();
  }

  /**
   * Operations for a display builder instance.
   *
   * @param string $builder_id
   *   The display builder id.
   * @param array $extra
   *   Some more specific links.
   *
   * @return array
   *   The operation links
   */
  private function getOperationLinks(string $builder_id, array $extra): array {
    $links = [
      'import' => [
        'title' => $this->t('Import'),
        'url' => Url::fromRoute('display_builder_devel.import', [
          'builder_id' => $builder_id,
        ]),
      ],
      'export' => [
        'title' => $this->t('Export'),
        'url' => Url::fromRoute('display_builder_devel.export', [
          'builder_id' => $builder_id,
        ]),
      ],
      'edit' => [
        'title' => $this->t('Edit'),
        'url' => Url::fromRoute('display_builder_devel.edit', [
          'builder_id' => $builder_id,
        ]),
      ],
      'delete' => [
        'title' => $this->t('Delete'),
        'url' => Url::fromRoute('display_builder_devel.delete', [
          'builder_id' => $builder_id,
        ]),
      ],
    ];

    return array_merge($links, $extra);
  }

}

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

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