redirect-8.x-1.x-dev/modules/redirect_domain/src/EventSubscriber/DomainRedirectRequestSubscriber.php
modules/redirect_domain/src/EventSubscriber/DomainRedirectRequestSubscriber.php
<?php
namespace Drupal\redirect_domain\EventSubscriber;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Path\PathMatcherInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;
use Drupal\redirect\RedirectChecker;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Redirect subscriber for controller requests.
*/
class DomainRedirectRequestSubscriber implements EventSubscriberInterface {
/**
* @var \Drupal\redirect\RedirectChecker
*/
protected $redirectChecker;
/**
* Domain redirect configuration.
*
* @var \Drupal\Core\Config\Config
*/
protected $domainConfig;
/**
* The path matcher.
*
* @var \Drupal\Core\Path\PathMatcherInterface
*/
protected $pathMatcher;
/**
* Redirect configuration.
*
* @var \Drupal\Core\Config\Config
*/
protected $redirectConfig;
/**
* Constructs a \Drupal\redirect\EventSubscriber\RedirectRequestSubscriber object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\redirect\RedirectChecker $redirect_checker
* The redirect checker service.
* @param \Drupal\Core\Path\PathMatcherInterface $path_matcher
* The path matcher.
*/
public function __construct(ConfigFactoryInterface $config_factory, RedirectChecker $redirect_checker, PathMatcherInterface $path_matcher) {
$this->domainConfig = $config_factory->get('redirect_domain.domains');
$this->redirectConfig = $config_factory->get('redirect.settings');
$this->redirectChecker = $redirect_checker;
$this->pathMatcher = $path_matcher;
}
/**
* Handles the domain redirect if any found.
*
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
* The event to process.
*/
public function onKernelRequestCheckDomainRedirect(RequestEvent $event) {
$request = clone $event->getRequest();
if (!$this->redirectChecker->canRedirect($request)) {
return;
}
// Redirect between domains configuration.
$domains = $this->domainConfig->get('domain_redirects');
if (!empty($domains)) {
$host = $request->getHost();
$path = $request->getPathInfo();
$protocol = $request->getScheme() . '://';
$destination = NULL;
// Prior to being saved the source domain value has any periods replaced
// with a colon, which makes it suitable for use as a key. In order to
// match against those values the current hostname must be similarly
// converted.
// @see \Drupal\redirect_domain\Form\RedirectDomainForm::submitForm()
$converted_host = str_replace('.', ':', $host);
// Checks if there is a redirect domain in the configuration.
if (isset($domains[$converted_host])) {
foreach ($domains[$converted_host] as $item) {
if ($this->pathMatcher->matchPath($path, $item['sub_path'])) {
$destination = $item['destination'];
break;
}
}
if ($destination) {
// Use the default status code from Redirect.
$response = new TrustedRedirectResponse(
$protocol . $destination,
$this->redirectConfig->get('default_status_code')
);
$event->setResponse($response);
return;
}
}
}
}
/**
* Prior to set the response it check if we can redirect.
*
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
* The event object.
* @param \Drupal\Core\Url $url
* The Url where we want to redirect.
*/
protected function setResponse(RequestEvent $event, Url $url) {
$request = $event->getRequest();
parse_str($request->getQueryString(), $query);
$url->setOption('query', $query);
$url->setAbsolute(TRUE);
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
// This needs to run before RouterListener::onKernelRequest(), which has
// a priority of 32 and
// RedirectRequestSubscriber::onKernelRequestCheckRedirect(), which has
// a priority of 33. Otherwise, that aborts the request if no matching
// route is found.
$events[KernelEvents::REQUEST][] = ['onKernelRequestCheckDomainRedirect', 34];
return $events;
}
}
