class RedirectPathTranslatorSubscriber in Decoupled Router 8
Same name and namespace in other branches
- 2.x src/EventSubscriber/RedirectPathTranslatorSubscriber.php \Drupal\decoupled_router\EventSubscriber\RedirectPathTranslatorSubscriber
Event subscriber that processes a path translation with the redirect info.
Hierarchy
- class \Drupal\decoupled_router\EventSubscriber\RouterPathTranslatorSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface uses StringTranslationTrait
- class \Drupal\decoupled_router\EventSubscriber\RedirectPathTranslatorSubscriber
Expanded class hierarchy of RedirectPathTranslatorSubscriber
1 string reference to 'RedirectPathTranslatorSubscriber'
1 service uses RedirectPathTranslatorSubscriber
File
- src/
EventSubscriber/ RedirectPathTranslatorSubscriber.php, line 14
Namespace
Drupal\decoupled_router\EventSubscriberView source
class RedirectPathTranslatorSubscriber extends RouterPathTranslatorSubscriber {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
// We wanna run before the router-based path translator because redirects
// naturally act before routing subsystem in Drupal HTTP kernel.
$events[PathTranslatorEvent::TRANSLATE][] = [
'onPathTranslation',
10,
];
return $events;
}
/**
* {@inheritdoc}
*/
public function onPathTranslation(PathTranslatorEvent $event) {
$response = $event
->getResponse();
if (!$response instanceof CacheableJsonResponse) {
$this->logger
->error('Unable to get the response object for the decoupled router event.');
return;
}
if (!$this->moduleHandler
->moduleExists('redirect')) {
return;
}
// Find the redirected path. Bear in mind that we need to go through several
// redirection levels before handing off to the route translator.
$entity_type_manager = $this->container
->get('entity_type.manager');
$redirect_storage = $entity_type_manager
->getStorage('redirect');
$destination = parse_url($event
->getPath(), PHP_URL_PATH);
$original_query_string = parse_url($event
->getPath(), PHP_URL_QUERY);
$traced_urls = [];
$redirect = NULL;
$redirects_trace = [];
while (TRUE) {
$destination = $this
->cleanSubdirInPath($destination, $event
->getRequest());
// Find if there is a redirect for this path.
$results = $redirect_storage
->getQuery()
->condition('redirect_source.path', ltrim($destination, '/'))
->execute();
$rid = reset($results);
if (!$rid) {
break;
}
/** @var \Drupal\redirect\Entity\Redirect $redirect */
$redirect = $redirect_storage
->load($rid);
$response
->addCacheableDependency($redirect);
$uri = $redirect
->get('redirect_redirect')->uri;
$url = Url::fromUri($uri)
->toString(TRUE);
$redirects_trace[] = [
'from' => $this
->makeRedirectUrl($destination, $original_query_string),
'to' => $this
->makeRedirectUrl($url
->getGeneratedUrl(), $original_query_string),
'status' => $redirect
->getStatusCode(),
];
$destination = $url
->getGeneratedUrl();
// Detect infinite loops and break if there is one.
$infinite_loop = in_array($destination, array_map(function (GeneratedUrl $url) {
return $url
->getGeneratedUrl();
}, $traced_urls));
// Accumulate all the URLs we go through to add the necessary cacheability
// metadata at the end.
$traced_urls[] = $url;
if ($infinite_loop) {
break;
}
}
if (!$redirect) {
return;
}
// At this point we should be pointing to a system route or path alias.
$event
->setPath($this
->makeRedirectUrl($destination, $original_query_string));
// Now call the route level.
parent::onPathTranslation($event);
if (!$response
->isSuccessful()) {
return;
}
// Set the content in the response.
$content = Json::decode($response
->getContent());
$response
->setData(array_merge($content, [
'redirect' => $redirects_trace,
]));
// If there is a response object, add the cacheability metadata necessary
// for the traced URLs.
array_walk($traced_urls, function ($traced_url) use ($response) {
$response
->addCacheableDependency($traced_url);
});
$event
->stopPropagation();
}
/**
* Generates URL for the redirect, based on redirect module configurations.
*
* @param string $path URL to redirect to.
* @param string $query Original query string on the requested path.
*
* @return string Redirect URL to use.
*/
private function makeRedirectUrl($path, $query) {
return $query && $this->configFactory
->get('redirect.settings')
->get('passthrough_querystring') ? "{$path}?{$query}" : $path;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
RedirectPathTranslatorSubscriber:: |
public static | function |
Returns an array of event names this subscriber wants to listen to. Overrides RouterPathTranslatorSubscriber:: |
|
RedirectPathTranslatorSubscriber:: |
private | function | Generates URL for the redirect, based on redirect module configurations. | |
RedirectPathTranslatorSubscriber:: |
public | function |
Processes a path translation request. Overrides RouterPathTranslatorSubscriber:: |
|
RouterPathTranslatorSubscriber:: |
protected | property | The alias manager | |
RouterPathTranslatorSubscriber:: |
protected | property | The config factory | |
RouterPathTranslatorSubscriber:: |
protected | property | The service container. | |
RouterPathTranslatorSubscriber:: |
protected | property | The logger. | |
RouterPathTranslatorSubscriber:: |
protected | property | The module handler. | |
RouterPathTranslatorSubscriber:: |
protected | property | The router. | |
RouterPathTranslatorSubscriber:: |
protected | function | Removes the subdir prefix from the path. | |
RouterPathTranslatorSubscriber:: |
protected | function | Get the underlying entity and the type of ID param enhancer for the routes. | |
RouterPathTranslatorSubscriber:: |
protected | function | Extracts the entity type for the route parameters. | |
RouterPathTranslatorSubscriber:: |
protected static | function | Computes the name of the entity route parameter for JSON API routes. | |
RouterPathTranslatorSubscriber:: |
protected | function | Checks if the resolved path is the home path. | |
RouterPathTranslatorSubscriber:: |
public | function | RouterPathTranslatorSubscriber constructor. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |