PathAliasXtProcessorAlias.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. namespace Drupal\path_alias_xt;
  3. use Drupal\Component\Utility\Unicode;
  4. use Drupal\Core\Config\ConfigFactory;
  5. use Drupal\Core\Path\AliasManagerInterface;
  6. use Drupal\Core\PathProcessor\PathProcessorAlias;
  7. use Drupal\Core\Render\BubbleableMetadata;
  8. use Symfony\Component\HttpFoundation\Request;
  9. /**
  10. * Processes inbound and outbound path determining alias.
  11. */
  12. class PathAliasXtProcessorAlias extends PathProcessorAlias {
  13. /**
  14. * The config factory.
  15. *
  16. * @var \Drupal\Core\Config\ConfigFactory
  17. */
  18. protected $configFactory;
  19. /**
  20. * Constructs a Path alias processor.
  21. *
  22. * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
  23. * The alias manager service.
  24. * @param \Drupal\Core\Config\ConfigFactory $config_factory
  25. * The config factory service.
  26. */
  27. public function __construct(AliasManagerInterface $alias_manager, ConfigFactory $config_factory) {
  28. parent::__construct($alias_manager);
  29. $this->configFactory = $config_factory;
  30. }
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public function processInbound($path, Request $request) {
  35. $path_to_process = ltrim($path, '/');
  36. $removed_elements = [];
  37. $path_elements = explode('/', $path_to_process);
  38. foreach ($path_elements as $element) {
  39. $candidate_alias = '/' . implode('/', $path_elements);
  40. $source = $this->aliasManager->getPathByAlias($candidate_alias);
  41. if ($source != $candidate_alias) {
  42. // Change the order of the elements.
  43. krsort($removed_elements);
  44. $return_path = $source;
  45. if (!empty($removed_elements)) {
  46. $return_path .= '/' . implode('/', $removed_elements);
  47. }
  48. // Validate the path.
  49. // Injecting the service threw ServiceCircularReferenceException.
  50. if (\Drupal::service('path.validator')->getUrlIfValidWithoutAccessCheck($return_path)) {
  51. return $return_path;
  52. }
  53. }
  54. // Remove the last element from the elements array to be able to add it
  55. // to the end of the found path.
  56. $removed_elements[] = array_pop($path_elements);
  57. }
  58. return $path;
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
  64. $path = parent::processOutbound($path, $options, $request, $bubbleable_metadata);
  65. $config = $this->configFactory->get('path_alias_xt.settings');
  66. if (preg_match($config->get('regex_pattern'), Unicode::substr($path, 1), $matches)) {
  67. $langcode = isset($options['language']) ? $options['language']->getId() : NULL;
  68. if ($alias = $this->aliasManager->getAliasByPath("/$matches[1]/$matches[2]", $langcode)) {
  69. $path = "$alias/$matches[3]";
  70. }
  71. }
  72. return $path;
  73. }
  74. }