username-1.0.x-dev/src/Routing/UsernameRouteSubscriber.php

src/Routing/UsernameRouteSubscriber.php
<?php

namespace Drupal\username\Routing;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * Modifies user-related routes to respond with 404 rather than 403.
 *
 * @package Drupal\username
 */
class UsernameRouteSubscriber implements EventSubscriberInterface {

  /**
   * Cache CID with user route IDS.
   */
  const ROUTE_CID = 'username_user_route_ids';

  /**
   * Route provider.
   *
   * @var \Drupal\Core\Routing\RouteProviderInterface
   */
  protected $routeProvider;

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * A cache backend.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $prevention;

  /**
   * {@inheritdoc}
   */
  public function __construct(RouteProviderInterface $routeProvider, EntityTypeManagerInterface $entityTypeManager, CacheBackendInterface $cache, ConfigFactoryInterface $config_factory) {
    $this->routeProvider = $routeProvider;
    $this->entityTypeManager = $entityTypeManager;
    $this->cache = $cache;
    $this->prevention = $config_factory->get('username.settings')->get('prevention');
  }

  /**
   * {@inheritdoc}
   */
  public function onException(ExceptionEvent $event) {
    if ($this->prevention) {
      $routeMatch = RouteMatch::createFromRequest($event->getRequest());
      if ($event->getThrowable() instanceof AccessDeniedHttpException && in_array($routeMatch->getRouteName(), $this->getUserRoutes())) {
        $event->setThrowable(new NotFoundHttpException());
      }
    }
  }

  /**
   * Get an array of user route IDs.
   *
   * @return array
   *   An array of user route IDs.
   */
  protected function getUserRoutes(): array {
    if ($this->prevention) {
      $userRouteIds = $this->cache->get(static::ROUTE_CID);
      if ($userRouteIds !== FALSE) {
        return $userRouteIds->data;
      }

      $userLinkTemplates = $this->entityTypeManager
        ->getDefinition('user')
        ->getLinkTemplates();

      $routes = new RouteCollection();
      foreach ($userLinkTemplates as $path) {
        $routes->addCollection($this->routeProvider->getRoutesByPattern($path));
      }

      $userRouteIds = array_keys(array_filter(iterator_to_array($routes), function (Route $route): bool {
        $parameters = $route->getOption('parameters') ?? [];
        if (is_array($parameters)) {
          foreach ($parameters as $parameter) {
            // Check if the route has user entity parameters.
            if ($parameter['type'] ?? NULL === 'entity:user') {
              return TRUE;
            }
          }
        }
        return strpos($route->getPath(), '{user}') !== FALSE;
      }));

      // Add specific routes to the user route IDs list.
      $userRouteIds[] = 'user.cancel_confirm';
      $userRouteIds[] = 'shortcut.set_switch';
      $this->cache->set(static::ROUTE_CID, $userRouteIds, Cache::PERMANENT, ['routes']);

      return $userRouteIds;
    }

    return [];
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::EXCEPTION] = 'onException';
    return $events;
  }

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('system.entity_autocomplete')) {
      $route->setDefault('_controller', '\Drupal\username\Controller\UsernameAutocompleteController::handleAutocomplete');
    }
  }

}

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

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