RedirectPathTranslatorSubscriber.php in Decoupled Router 8
File
src/EventSubscriber/RedirectPathTranslatorSubscriber.php
View source
<?php
namespace Drupal\decoupled_router\EventSubscriber;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\GeneratedUrl;
use Drupal\Core\Url;
use Drupal\decoupled_router\PathTranslatorEvent;
class RedirectPathTranslatorSubscriber extends RouterPathTranslatorSubscriber {
public static function getSubscribedEvents() {
$events[PathTranslatorEvent::TRANSLATE][] = [
'onPathTranslation',
10,
];
return $events;
}
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;
}
$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());
$results = $redirect_storage
->getQuery()
->condition('redirect_source.path', ltrim($destination, '/'))
->execute();
$rid = reset($results);
if (!$rid) {
break;
}
$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();
$infinite_loop = in_array($destination, array_map(function (GeneratedUrl $url) {
return $url
->getGeneratedUrl();
}, $traced_urls));
$traced_urls[] = $url;
if ($infinite_loop) {
break;
}
}
if (!$redirect) {
return;
}
$event
->setPath($this
->makeRedirectUrl($destination, $original_query_string));
parent::onPathTranslation($event);
if (!$response
->isSuccessful()) {
return;
}
$content = Json::decode($response
->getContent());
$response
->setData(array_merge($content, [
'redirect' => $redirects_trace,
]));
array_walk($traced_urls, function ($traced_url) use ($response) {
$response
->addCacheableDependency($traced_url);
});
$event
->stopPropagation();
}
private function makeRedirectUrl($path, $query) {
return $query && $this->configFactory
->get('redirect.settings')
->get('passthrough_querystring') ? "{$path}?{$query}" : $path;
}
}