You are here

class TrailingSlashOutboundPathProcessor in Trailing Slash 8

Class TrailingSlashOutboundPathProcessor.

@package Drupal\trailing_slash\PathProcessor

Hierarchy

Expanded class hierarchy of TrailingSlashOutboundPathProcessor

1 string reference to 'TrailingSlashOutboundPathProcessor'
trailing_slash.services.yml in ./trailing_slash.services.yml
trailing_slash.services.yml
1 service uses TrailingSlashOutboundPathProcessor
trailing_slash.path_processor_trailing_slash in ./trailing_slash.services.yml
Drupal\trailing_slash\PathProcessor\TrailingSlashOutboundPathProcessor

File

src/PathProcessor/TrailingSlashOutboundPathProcessor.php, line 20

Namespace

Drupal\trailing_slash\PathProcessor
View source
class TrailingSlashOutboundPathProcessor implements OutboundPathProcessorInterface {

  /**
   * Var to collect which paths I'm checking to prevent maximum function nesting level.
   * @var array
   */
  private $checkingPaths = [];

  /**
   * Var to collect which paths I checked before and prevent maximum function nesting level.
   * @var array
   */
  private $checkedPaths = [];

  /**
   * @var \Drupal\Core\Routing\AdminContext
   */
  protected $adminContext;

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

  /**
   * TrailingSlashOutboundPathProcessor constructor.
   * @param AdminContext $admin_context
   * @param EntityTypeManagerInterface $entity_type_manager
   */
  public function __construct(AdminContext $admin_context, EntityTypeManagerInterface $entity_type_manager) {
    $this->adminContext = $admin_context;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * @inheritdoc
   */
  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    if ($this
      ->isPathWithTrailingSlash($path, $options, $request, $bubbleable_metadata)) {
      TrailingSlashHelper::add($path);
    }
    return $path;
  }

  /**
   * @param                    $path
   * @param array $options
   * @param Request $request
   * @param BubbleableMetadata $bubbleable_metadata
   *
   * @return bool
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function isPathWithTrailingSlash($path, array &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    $is_path_with_trailing_slash = FALSE;
    if (!in_array($path, $this->checkingPaths, TRUE)) {
      $this->checkingPaths[] = $path;
      if (TrailingSlashSettingsHelper::isEnabled() && $path !== '<front>' && !empty($path) && !$this
        ->isAdminPath($path, $options) && ($this
        ->isPathInListWithTrailingSlash($path) || $this
        ->isBundlePathWithTrailingSlash($path))) {
        $is_path_with_trailing_slash = TRUE;
      }
      $this->checkedPaths[$path] = $is_path_with_trailing_slash;
    }
    if (array_key_exists($path, $this->checkedPaths)) {
      return $this->checkedPaths[$path];
    }
    return FALSE;
  }

  /**
   * @param $path
   * @param $options
   * @return bool
   */
  public function isAdminPath($path, $options) : bool {
    if (strpos($path, '/admin') === 0 || strpos($path, '/devel') === 0) {
      return TRUE;
    }
    if (!empty($options['route'])) {
      return $this->adminContext
        ->isAdminRoute($options['route']);
    }
    return FALSE;
  }

  /**
   * @param $path
   *
   * @return bool
   */
  public function isPathInListWithTrailingSlash($path) : bool {
    $paths = TrailingSlashSettingsHelper::getActivePaths();
    return in_array($path, $paths);
  }

  /**
   * @param $path
   *
   * @return bool
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function isBundlePathWithTrailingSlash($path) {
    $active_bundles = TrailingSlashSettingsHelper::getActiveBundles();
    if (!empty($active_bundles)) {
      $url = Url::fromUri('internal:' . $path);
      try {
        if ($url
          ->isRouted() && ($params = $url
          ->getRouteParameters())) {
          $entity_type = key($params);
          if (array_key_exists($entity_type, $active_bundles)) {
            $entity = $this->entityTypeManager
              ->getStorage($entity_type)
              ->load($params[$entity_type]);
            $bundle = $entity
              ->bundle();
            if (isset($active_bundles[$entity_type][$bundle])) {
              return TRUE;
            }
          }
        }
      } catch (Exception $e) {
      }
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
TrailingSlashOutboundPathProcessor::$adminContext protected property
TrailingSlashOutboundPathProcessor::$checkedPaths private property Var to collect which paths I checked before and prevent maximum function nesting level.
TrailingSlashOutboundPathProcessor::$checkingPaths private property Var to collect which paths I'm checking to prevent maximum function nesting level.
TrailingSlashOutboundPathProcessor::$entityTypeManager protected property The entity type manager.
TrailingSlashOutboundPathProcessor::isAdminPath public function
TrailingSlashOutboundPathProcessor::isBundlePathWithTrailingSlash public function
TrailingSlashOutboundPathProcessor::isPathInListWithTrailingSlash public function
TrailingSlashOutboundPathProcessor::isPathWithTrailingSlash public function
TrailingSlashOutboundPathProcessor::processOutbound public function @inheritdoc Overrides OutboundPathProcessorInterface::processOutbound
TrailingSlashOutboundPathProcessor::__construct public function TrailingSlashOutboundPathProcessor constructor.