g2-8.x-1.x-dev/src/Requirements.php

src/Requirements.php
<?php

declare(strict_types=1);

namespace Drupal\g2;

use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;

/**
 * Class Requirements contains the hook_requirements() checks.
 *
 * It is NOT a Symfony service.
 *
 * @phpstan-consistent-constructor
 */
class Requirements implements ContainerInjectionInterface {

  use StringTranslationTrait;

  /**
   * The core entity_type.manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $etm;

  /**
   * The g2.settings configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected ImmutableConfig $g2Config;

  /**
   * The module_handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected ModuleHandlerInterface $moduleHandler;

  /**
   * The accumulated results of requirements checks.
   *
   * @var array<string,array<string,mixed>>
   */
  protected array $result = [];

  /**
   * The router.route_provider service.
   *
   * @var \Drupal\Core\Routing\RouteProviderInterface
   */
  protected RouteProviderInterface $routeProvider;

  /**
   * The statistics.settings configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $statisticsConfig;

  /**
   * Requirements constructor.
   *
   * @param \Drupal\Core\Config\ImmutableConfig $g2_config
   *   The g2.settings configuration.
   * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
   *   The router.route_provider service.
   * @param \Drupal\Core\Config\ImmutableConfig $statistics_config
   *   The statistics.settings configuration.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module_handler service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $etm
   *   The entity_type.manager service.
   */
  public function __construct(
    ImmutableConfig $g2_config,
    RouteProviderInterface $route_provider,
    ImmutableConfig $statistics_config,
    ModuleHandlerInterface $module_handler,
    EntityTypeManagerInterface $etm,
  ) {
    $this->etm = $etm;
    $this->g2Config = $g2_config;
    $this->routeProvider = $route_provider;
    $this->statisticsConfig = $statistics_config;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
    $module_handler = $container->get('module_handler');

    /** @var \Drupal\Core\Routing\RouteProvider $route_provider */
    $route_provider = $container->get('router.route_provider');

    /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $etm */
    $etm = $container->get(G2::SVC_ETM);

    /** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */
    $config_factory = $container->get(G2::SVC_CONF);

    $g2_config = $config_factory->get(G2::CONFIG_NAME);
    $statistics_settings = $config_factory->get('statistics.settings');

    return new static($g2_config, $route_provider, $statistics_settings,
      $module_handler, $etm);
  }

  /**
   * Perform controller requirements checks.
   */
  public function checkControllers(): void {
    $this->result['main.nid'] = $this->checkNid(G2::VARMAINNID,
      $this->t('G2 main page node'));
    $this->result['main.route'] = $this->checkRoute(G2::VARMAINROUTE,
      $this->t('G2 main page route'));
    $this->result['homonyms.nid'] = $this->checkNid(G2::VARHOMONYMSNID,
      $this->t('G2 homonyms page node'));
    $this->result['homonyms.route'] = $this->checkRoute(G2::VARHOMONYMSROUTE,
      $this->t('G2 homonyms page route'));
  }

  /**
   * Check whether a node is valid.
   *
   * @param string $key
   *   The config key for the route to validate.
   * @param \Drupal\Component\Render\MarkupInterface $title
   *   The requirement check title.
   *
   * @return array<string,\Drupal\Component\Render\MarkupInterface|int>
   *   A hook_requirements value.
   */
  protected function checkNid(string $key, MarkupInterface $title): array {
    $result = ['title' => $title];
    $main = $this->g2Config->get($key);

    // Should be guaranteed by config schema.
    assert(is_numeric($main));

    if ($main === 0) {
      $result += [
        'value' => $this->t('Node set to empty.'),
        'severity' => REQUIREMENT_OK,
      ];
      return $result;
    }

    $node = $this->etm
      ->getStorage(G2::TYPE)
      ->load($main);

    if (!($node instanceof NodeInterface)) {
      $result += [
        'value' => $this->t(
          'The node id must be 0 or match an existing node, but "@nid" cannot be found.',
          ['@nid' => $main]),
        'severity' => REQUIREMENT_ERROR,
      ];
      return $result;
    }

    if ($node->isPublished()) {
      $result += [
        'value' => $this->t(
          'The chosen node must not be published, but node "@nid" is.',
          ['@nid' => $main]),
        'severity' => REQUIREMENT_ERROR,
      ];
      return $result;
    }

    $url = Url::fromRoute(
      G2::ROUTE_NODE_CANONICAL,
      [G2::TYPE => $main])
      ->toString();
    $result += [
      'value' => $this->t(
        'Existing unpublished node @nid: <a href=":url">@title</a>. Remember that <a href=":deprecated">such node use is deprecated.</a>', [
          '@nid' => $node->id(),
          '@title' => $node->label(),
          ':url' => $url,
          ':deprecated' => 'https://www.drupal.org/project/g2/issues/3369887',
        ]
      ),
      'severity' => REQUIREMENT_WARNING,
    ];

    return $result;
  }

  /**
   * Check whether a route is valid.
   *
   * @param string $key
   *   The config key for the route to validate.
   * @param \Drupal\Component\Render\MarkupInterface $title
   *   The requirement check title.
   *
   * @return array<string,\Drupal\Component\Render\MarkupInterface|int>
   *   A hook_requirements() value.
   */
  protected function checkRoute($key, MarkupInterface $title): array {
    $result = ['title' => $title];
    $mixedName = $this->g2Config->get($key);
    assert(is_string($mixedName));
    $name = (string) $mixedName;

    $arguments = ['%route' => $name];
    try {
      $route = $this->routeProvider->getRouteByName($name);
      if ($route->hasOption('parameters')) {
        $value = $this->t('Valid parametric route %route', $arguments);
      }
      else {
        $value = $this->t('Valid static route <a href=":url">%route</a>',
          $arguments + [
            ':url' => Url::fromRoute($name)->toString(),
          ]);
      }
      $result += [
        'value' => $value,
        'severity' => REQUIREMENT_OK,
      ];
    }
    catch (RouteNotFoundException $e) {
      $result += [
        'value' => $this->t('The chosen route is not available: %route',
          $arguments),
        'severity' => REQUIREMENT_ERROR,
      ];
    }
    return $result;
  }

  /**
   * Perform statistics-related requirements checks.
   */
  public function checkStatistics(): void {
    [$stats, $count, $severity, $value] = $this->prepareStatisticCheck();
    if ($severity == REQUIREMENT_ERROR) {
      $description = [];
    }
    else {
      $items = [];
      $modules_url = [
        ':link' => Url::fromRoute('system.modules_list', [], [
          'fragment' => 'module-statistics',
        ])->toString(),
      ];
      $items[] = $stats
        ? $this->t('<a href=":link">Statistics module</a> installed: OK.',
          $modules_url)
        : $this->t('<a href=":link">Statistics module</a> not installed.',
          $modules_url);
      $link_text = $count ? $this->t('ON') : $this->t('OFF');
      if ($stats) {
        $stats_url = [
          ':stats_url' => Url::fromRoute('statistics.settings', [], [
            'query' => [
              'destination' => Url::fromRoute('system.status')->toString(),
            ],
            'fragment' => 'edit-content',
          ])->toString(),
        ];
        $items[] = $this->t('Count content views" setting is <a href=":stats_url">@on_off</a>',
          $stats_url + ['@on_off' => $link_text]
        );
      }
      else {
        $items[] = $this->t('G2 relies on statistics.module to provide data for the G2 "Top" block and API.
If you do not use either block, you can leave statistics.module disabled.');
      }
      $description = [
        '#theme' => 'item_list',
        '#items' => $items,
      ];
    }
    $this->result['statistics'] = [
      'title' => $this->t('G2 statistics'),
      'value' => $value,
      'description' => $description,
      'severity' => $severity,
    ];
  }

  /**
   * Helper for checkStatistics(): build the check data.
   *
   * @return array{boolean,int,int,\Drupal\Core\StringTranslation\TranslatableMarkup}
   *   - stats
   *   - count
   *   - severity
   *   - value
   */
  protected function prepareStatisticCheck(): array {
    $stats = $this->moduleHandler->moduleExists('statistics');
    $mixedCount = $this->statisticsConfig->get('count_content_views');
    // See statistics.schema.
    assert(is_int($mixedCount) || is_null($mixedCount));
    $count = (int) $mixedCount;

    if ($stats && is_null($mixedCount)) {
      // Should not happen, see https://www.drupal.org/project/g2/issues/3438261
      $severity = REQUIREMENT_ERROR;
      $value = $this->t('Statistics schema missing. Please uninstall G2 and Statistics, and reinstall G2.');
    }
    elseif (!$stats && !$count) {
      // This one is a (questionable) choice.
      $severity = REQUIREMENT_INFO;
      $value = $this->t('G2 statistics disabled.');
    }
    elseif ($stats xor $count) {
      // This one is inconsistent.
      $severity = REQUIREMENT_WARNING;
      $value = $this->t('G2 statistics incorrectly configured.');
    }
    else {
      // Both on: optimal.
      $severity = REQUIREMENT_OK;
      $value = $this->t('G2 statistics configured correctly.');
    }

    return [$stats, $count, $severity, $value];
  }

  /**
   * Return the check results.
   *
   * @return array<string,array<mixed>>
   *   In the hook_requirements() format.
   */
  public function getResult() {
    return $this->result;
  }

}

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

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