diff --git a/config/schema/redirect.schema.yml b/config/schema/redirect.schema.yml
index 263e0ae..82d230c 100644
--- a/config/schema/redirect.schema.yml
+++ b/config/schema/redirect.schema.yml
@@ -59,11 +59,13 @@ redirect.domain:
type: sequence
label: 'Domain redirects'
sequence:
- type: mapping
- mapping:
- from:
- type: string
- label: 'From domain'
- to:
- type: string
- label: 'To domain'
+ type: sequence
+ sequence:
+ type: mapping
+ mapping:
+ sub_path:
+ type: string
+ label: 'Sub path'
+ to_domain:
+ type: string
+ label: 'To domain'
diff --git a/src/EventSubscriber/RedirectRequestSubscriber.php b/src/EventSubscriber/RedirectRequestSubscriber.php
index ec549a6..81b2292 100644
--- a/src/EventSubscriber/RedirectRequestSubscriber.php
+++ b/src/EventSubscriber/RedirectRequestSubscriber.php
@@ -137,29 +137,28 @@ class RedirectRequestSubscriber implements EventSubscriberInterface {
if (!empty($domains)) {
$host = $request->getHost();
$path = $request->getRequestUri();
- $from_domain = $request->getHost() . $request->getRequestUri();
$to_domain = NULL;
// Checks if there is a redirect domain in the configuration.
- foreach ($domains as $domain) {
- if (strpos($domain['from'], $from_domain) !== FALSE) {
- $to_domain = $domain['to'];
- break;
- }
- // Check for a wildcard in the domains.
- if (strpos($domain['from'], '*')) {
- $replace_path = substr($domain['from'], strpos($domain['from'], '/'));
- $domain_base_uri = substr($domain['from'], 0, -2);
- if (strpos($from_domain, $domain_base_uri) !== FALSE) {
- $sub_path = substr($path, strlen($replace_path) - 2);
- $to_domain = $domain['to'] . $sub_path;
+ if (isset($domains[str_replace('.', ':', $host)])) {
+ foreach ($domains[str_replace('.', ':', $host)] as $item) {
+ if ($path === $item['sub_path']) {
+ $to_domain = $item['to_domain'];
break;
}
+ // Check for a wildcard in the domains.
+ else if (strpos($item['sub_path'], '*') !== FALSE) {
+ $sub_path = substr($item['sub_path'], 0, -1);
+ if (strpos($path, $sub_path) !== FALSE) {
+ $to_domain = $item['to_domain'] . '/' . substr($path, strlen($sub_path));
+ break;
+ }
+ }
+ }
+ if ($to_domain) {
+ $response = new TrustedRedirectResponse($to_domain);
+ $event->setResponse($response);
+ return;
}
- }
- if ($to_domain) {
- $response = new TrustedRedirectResponse($to_domain);
- $event->setResponse($response);
- return;
}
}
}
diff --git a/src/Form/RedirectDomainForm.php b/src/Form/RedirectDomainForm.php
index ac02587..b9b6944 100644
--- a/src/Form/RedirectDomainForm.php
+++ b/src/Form/RedirectDomainForm.php
@@ -41,6 +41,7 @@ class RedirectDomainForm extends ConfigFormBase {
'#tree' => TRUE,
'#header' => [
$this->t('From domain'),
+ $this->t('Sub path'),
$this->t('To domain')
],
'#prefix' => '
',
@@ -50,17 +51,23 @@ class RedirectDomainForm extends ConfigFormBase {
$rows = [];
// Obtain domain redirects from configuration.
if ($domain_redirects = $this->config('redirect.domain')->get('domain_redirects')) {
- foreach ($domain_redirects as $domain_redirect) {
- $form['redirects'][] = [
- 'from' => [
- '#type' => 'textfield',
- '#value' => $domain_redirect['from'],
- ],
- 'to' => [
- '#type' => 'textfield',
- '#value' => $domain_redirect['to'],
- ],
- ];
+ foreach ($domain_redirects as $key => $value) {
+ foreach ($value as $item) {
+ $form['redirects'][] = [
+ 'from' => [
+ '#type' => 'textfield',
+ '#value' => str_replace(':','.',$key),
+ ],
+ 'sub_path' => [
+ '#type' => 'textfield',
+ '#value' => $item['sub_path'],
+ ],
+ 'to' => [
+ '#type' => 'textfield',
+ '#value' => $item['to_domain'],
+ ],
+ ];
+ }
}
}
@@ -70,6 +77,10 @@ class RedirectDomainForm extends ConfigFormBase {
'from' => [
'#type' => 'textfield',
],
+ 'sub_path' => [
+ '#type' => 'textfield',
+ '#value' => '/',
+ ],
'to' => [
'#type' => 'textfield',
],
@@ -123,7 +134,7 @@ class RedirectDomainForm extends ConfigFormBase {
parent::validateForm($form, $form_state);
if ($redirects = $form_state->getValue('redirects')) {
foreach ($redirects as $redirect) {
- if (strpos($redirect['from'], '://') !== FALSE || strpos($redirect['to'], '://') !== FALSE) {
+ if (strpos($redirect['from'], '://') !== FALSE) {
$form_state->setErrorByName('redirects', t('No protocol should be included in the redirect domain.'));
}
}
@@ -140,9 +151,11 @@ class RedirectDomainForm extends ConfigFormBase {
if ($redirects = $form_state->getValue('redirects')) {
foreach ($redirects as $redirect) {
if (!empty($redirect['from']) && !empty($redirect['to'])) {
- $domain_redirects[] = [
- 'from' => $redirect['from'],
- 'to' => $redirect['to'],
+ // Replace '.' with ':' for an eligible key.
+ $redirect['from'] = str_replace('.',':',$redirect['from']);
+ $domain_redirects[$redirect['from']][] = [
+ 'sub_path' => $redirect['sub_path']? : '/',
+ 'to_domain' => $redirect['to']
];
}
}
diff --git a/src/Tests/GlobalRedirectTest.php b/src/Tests/GlobalRedirectTest.php
index 711a36e..a0fb275 100644
--- a/src/Tests/GlobalRedirectTest.php
+++ b/src/Tests/GlobalRedirectTest.php
@@ -226,6 +226,7 @@ class GlobalRedirectTest extends WebTestBase {
// Assert that there are 2 domain redirect fields.
$this->assertFieldByName('redirects[0][from]');
+ $this->assertFieldByName('redirects[0][sub_path]');
$this->assertFieldByName('redirects[0][to]');
// Add another field for new domain redirect.
diff --git a/tests/src/Unit/RedirectRequestSubscriberTest.php b/tests/src/Unit/RedirectRequestSubscriberTest.php
index 6b161cf..976e58b 100644
--- a/tests/src/Unit/RedirectRequestSubscriberTest.php
+++ b/tests/src/Unit/RedirectRequestSubscriberTest.php
@@ -104,6 +104,80 @@ class RedirectRequestSubscriberTest extends UnitTestCase {
}
/**
+ * Tests redirect between domains.
+ */
+ public function testDomainRedirect() {
+ $redirect = $this->getMockBuilder('Drupal\redirect\Entity\Redirect')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ // Make a request to http://foo.com/example and get the response.
+ $event = $this->getGetResponseEventStub('http://foo.com/example', http_build_query([]));
+ $request = $event->getRequest();
+
+ $checker = $this->getMockBuilder('Drupal\redirect\RedirectChecker')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $checker->expects($this->any())
+ ->method('canRedirect')
+ ->will($this->returnValue(TRUE));
+ $checker->expects($this->any())
+ ->method('isLoop')
+ ->will($this->returnValue(FALSE));
+ $context = $this->getMock('Symfony\Component\Routing\RequestContext');
+
+ $inbound_path_processor = $this->getMockBuilder('Drupal\Core\PathProcessor\InboundPathProcessorInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $inbound_path_processor->expects($this->any())
+ ->method('processInbound')
+ ->with($request->getPathInfo(), $request)
+ ->will($this->returnValue($request->getPathInfo()));
+
+ $alias_manager = $this->getMockBuilder('Drupal\Core\Path\AliasManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
+ ->getMock();
+ $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManagerInterface')
+ ->getMock();
+
+ // Set up the configuration for the requested domain.
+ $config_factory = $this->getConfigFactoryStub([
+ 'redirect.domain' => [
+ 'domain_redirects' => [
+ 'foo:com' => [
+ [
+ 'sub_path' => '/*',
+ 'to_domain' => 'bar.com'
+ ],
+ ]
+ ]
+ ]
+ ]);
+ $subscriber = new RedirectRequestSubscriber(
+ $this->getRedirectRepositoryStub('findMatchingRedirect', $redirect),
+ $this->getLanguageManagerStub(),
+ $config_factory,
+ $alias_manager,
+ $module_handler,
+ $entity_manager,
+ $checker,
+ $context,
+ $inbound_path_processor
+ );
+
+ // Run the main redirect method.
+ $subscriber->onKernelRequestCheckRedirect($event);
+
+ $this->assertTrue($event->getResponse() instanceof RedirectResponse);
+ $response = $event->getResponse();
+ // Make sure that the response is properly redirected.
+ $this->assertEquals('bar.com/example', $response->getTargetUrl());
+ $this->assertEquals(302, $response->getStatusCode());
+ }
+
+ /**
* Instantiates the subscriber and runs onKernelRequestCheckRedirect()
*
* @param $redirect