From 730f30e1f79fd216862a2ca87583cddee7f05659 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Thu, 20 Dec 2018 10:26:41 +0100
Subject: [PATCH] [!!!][TASK] Remove sys_domain and LegacyDomains

Removes the legary sys_domain table and handling.

Resolves: #87276
Releases: master
Change-Id: If2a5eeb1ebcc113c8b00162f4c02ea3a58edcefe
Reviewed-on: https://review.typo3.org/59233
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
---
 .../Classes/Utility/BackendUtility.php        |  31 ---
 .../Functional/Utility/BackendUtilityTest.php |  47 ----
 .../Utility/Fixtures/sys_domain.xml           |  17 --
 .../Hooks/SiteDataHandlerCacheHook.php        |   7 +-
 .../core/Classes/Site/PseudoSiteFinder.php    |  20 +-
 .../core/Classes/Utility/MailUtility.php      |  40 +---
 .../Configuration/DefaultConfiguration.php    |   1 -
 ...g-87193-DeprecatedFunctionalityRemoved.rst |  16 +-
 .../Controller/FrontendLoginController.php    |  22 +-
 .../FrontendLoginControllerTest.php           |  99 ++-------
 .../Compatibility/LegacyDomainResolver.php    | 202 ------------------
 .../Classes/Typolink/PageLinkBuilder.php      |   9 -
 .../frontend/Configuration/TCA/sys_domain.php |  62 ------
 .../Language/locallang_csh_sysdomain.xlf      |  59 -----
 .../Private/Language/locallang_tca.xlf        |   6 -
 .../SiteHandling/Fixtures/PlainScenario.yaml  |   5 -
 .../SiteHandling/Fixtures/SlugScenario.yaml   |   5 -
 .../Tca/DomainVisibleFieldsTest.php           |  46 ----
 .../LegacyDomainResolverTest.php              | 101 ---------
 typo3/sysext/frontend/ext_tables.php          |   3 +-
 typo3/sysext/frontend/ext_tables.sql          |  10 -
 .../Updates/RedirectsExtensionUpdate.php      |  10 +
 .../Php/MethodCallStaticMatcher.php           |   1 +
 .../Classes/Linktype/InternalLinktype.php     |  10 -
 .../ValuePickerItemDataProvider.php           |  30 +--
 .../ValuePickerItemDataProviderTest.php       |  43 +---
 .../JavaScript/Mode/typoscript/typoscript.js  |   1 -
 .../Controller/ViewModuleController.php       |   5 +-
 28 files changed, 62 insertions(+), 846 deletions(-)
 delete mode 100644 typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
 delete mode 100644 typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml
 delete mode 100644 typo3/sysext/frontend/Classes/Compatibility/LegacyDomainResolver.php
 delete mode 100644 typo3/sysext/frontend/Configuration/TCA/sys_domain.php
 delete mode 100644 typo3/sysext/frontend/Resources/Private/Language/locallang_csh_sysdomain.xlf
 delete mode 100644 typo3/sysext/frontend/Tests/Functional/Tca/DomainVisibleFieldsTest.php
 delete mode 100644 typo3/sysext/frontend/Tests/Unit/Compatibility/LegacyDomainResolverTest.php

diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
index cfea4fdd3bc3..f2667b166cb6 100644
--- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php
+++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
@@ -45,7 +45,6 @@ use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
 use TYPO3\CMS\Core\Routing\RouterInterface;
 use TYPO3\CMS\Core\Routing\SiteMatcher;
 use TYPO3\CMS\Core\Site\Entity\PseudoSite;
-use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
@@ -56,7 +55,6 @@ use TYPO3\CMS\Core\Utility\HttpUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Core\Utility\PathUtility;
 use TYPO3\CMS\Core\Versioning\VersionState;
-use TYPO3\CMS\Frontend\Compatibility\LegacyDomainResolver;
 use TYPO3\CMS\Frontend\Page\PageRepository;
 
 /**
@@ -2636,15 +2634,6 @@ class BackendUtility
                 } else {
                     $domainName = $previewDomainConfig;
                 }
-            } else {
-                $domainResolver = GeneralUtility::makeInstance(LegacyDomainResolver::class);
-                foreach ($rootLine as $row) {
-                    $domainRecord = $domainResolver->matchRootPageId((int)$row['uid']);
-                    if (is_array($domainRecord)) {
-                        $domainName = rtrim($domainRecord['domainName'], '/');
-                        break;
-                    }
-                }
             }
             if ($domainName === null) {
                 // Fetch the "sys_domain" record: First, check for the given domain,
@@ -3284,26 +3273,6 @@ class BackendUtility
         return [$TScID, $cPid];
     }
 
-    /**
-     * Returns first found domain record "domainName" (without trailing slash) if found in the input $rootLine
-     *
-     * @param array $rootLine Root line array
-     * @return string|null Domain name or NULL
-     * @deprecated since TYPO3 v9.4, will be removed in TYPO3 v10.0. Use Link Generation / Router instead.
-     */
-    public static function firstDomainRecord($rootLine)
-    {
-        trigger_error('BackendUtility::firstDomainRecord() will be removed in TYPO3 v10.0. Use the new LigetDomainStartPagenk Generation functionality instead.', E_USER_DEPRECATED);
-        $domainResolver = GeneralUtility::makeInstance(LegacyDomainResolver::class);
-        foreach ($rootLine as $row) {
-            $domain = $domainResolver->matchRootPageId($row['uid']);
-            if (is_array($domain)) {
-                return rtrim($domain['domainName'], '/');
-            }
-        }
-        return null;
-    }
-
     /**
      * Returns soft-reference parser for the softRef processing type
      * Usage: $softRefObj = &BackendUtility::softRefParserObj('[parser key]');
diff --git a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
deleted file mode 100644
index f459293db8af..000000000000
--- a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Tests\Functional\Utility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\RootlineUtility;
-use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
-
-/**
- * Test case for TYPO3\CMS\Backend\Controller\Page\LocalizationController
- */
-class BackendUtilityTest extends FunctionalTestCase
-{
-    /**
-     * Sets up this test case.
-     */
-    protected function setUp()
-    {
-        parent::setUp();
-
-        $this->importDataSet('PACKAGE:typo3/testing-framework/Resources/Core/Functional/Fixtures/pages.xml');
-        $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml');
-    }
-
-    /**
-     * @test
-     */
-    public function determineFirstDomainRecord()
-    {
-        $rootLineUtility = GeneralUtility::makeInstance(RootlineUtility::class, 4);
-        $rootLine = $rootLineUtility->get();
-        $this->assertEquals('example.com', BackendUtility::firstDomainRecord($rootLine));
-    }
-}
diff --git a/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml b/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml
deleted file mode 100644
index 849138eeac51..000000000000
--- a/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<dataset>
-    <sys_domain>
-        <uid>1</uid>
-        <pid>1</pid>
-        <tstamp>1487563944</tstamp>
-        <hidden>0</hidden>
-        <domainName>example.com</domainName>
-    </sys_domain>
-    <sys_domain>
-        <uid>2</uid>
-        <pid>7</pid>
-        <tstamp>1487563945</tstamp>
-        <hidden>0</hidden>
-        <domainName>www.example.net</domainName>
-    </sys_domain>
-</dataset>
diff --git a/typo3/sysext/core/Classes/Hooks/SiteDataHandlerCacheHook.php b/typo3/sysext/core/Classes/Hooks/SiteDataHandlerCacheHook.php
index 5ba4f992f12f..25ad9696bbe7 100644
--- a/typo3/sysext/core/Classes/Hooks/SiteDataHandlerCacheHook.php
+++ b/typo3/sysext/core/Classes/Hooks/SiteDataHandlerCacheHook.php
@@ -41,12 +41,10 @@ class SiteDataHandlerCacheHook
      */
     public function processDatamap_afterDatabaseOperations(string $status, string $table, $recordId, array $updatedFields, DataHandler $dataHandler)
     {
-        if ($table === 'sys_domain'
-            || $table === 'sys_language'
+        if ($table === 'sys_language'
             || ($status === 'new' && $table === 'pages' && (int)$updatedFields['pid'] === 0)
         ) {
             $this->getCache()->remove('pseudo-sites');
-            $this->getCache()->remove('legacy-domains');
             // After evicting caches, we need to make sure these are re-initialized within the
             // current request if needed. Easiest solution is to purge the SiteMatcher singleton.
             GeneralUtility::removeSingletonInstance(SiteMatcher::class, GeneralUtility::makeInstance(SiteMatcher::class));
@@ -66,9 +64,8 @@ class SiteDataHandlerCacheHook
      */
     public function processCmdmap_postProcess(string $command, string $table, $id, $value, DataHandler $dataHandler, $pasteUpdate, array $pasteDatamap)
     {
-        if ($table === 'sys_domain' || $table === 'sys_language') {
+        if ($table === 'sys_language') {
             $this->getCache()->remove('pseudo-sites');
-            $this->getCache()->remove('legacy-domains');
         }
     }
 
diff --git a/typo3/sysext/core/Classes/Site/PseudoSiteFinder.php b/typo3/sysext/core/Classes/Site/PseudoSiteFinder.php
index 534bfc98a4c5..1a072af9a9f0 100644
--- a/typo3/sysext/core/Classes/Site/PseudoSiteFinder.php
+++ b/typo3/sysext/core/Classes/Site/PseudoSiteFinder.php
@@ -29,7 +29,6 @@ use TYPO3\CMS\Core\Site\Entity\PseudoSite;
 use TYPO3\CMS\Core\Site\Entity\SiteInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\RootlineUtility;
-use TYPO3\CMS\Frontend\Compatibility\LegacyDomainResolver;
 
 /**
  * Methods related to "pseudo-sites" = sites that do not have a configuration yet.
@@ -58,7 +57,7 @@ class PseudoSiteFinder
     }
 
     /**
-     * Fetches all site root pages, all sys_language and sys_domain records and forms pseudo-sites,
+     * Fetches all site root pages, all sys_language records and forms pseudo-sites,
      * but only for the pagetree's that do not have a site configuration available.
      */
     protected function populate()
@@ -66,35 +65,24 @@ class PseudoSiteFinder
         $data = $this->cache->get($this->cacheIdentifier);
         if (empty($data)) {
             $allLanguages = $this->getAllLanguageRecords();
-            $groupedDomains = GeneralUtility::makeInstance(LegacyDomainResolver::class)->getGroupedDomainsPerPage();
             $availablePages = $this->getAllRootPagesWithoutSiteConfiguration();
-            $this->cache->set($this->cacheIdentifier, json_encode([$allLanguages, $groupedDomains, $availablePages]));
+            $this->cache->set($this->cacheIdentifier, json_encode([$allLanguages, $availablePages]));
         } else {
             // Due to the nature of PhpFrontend, the `<?php` and `#` wraps have to be removed
             $data = preg_replace('/^<\?php\s*|\s*#$/', '', $data);
-            list($allLanguages, $groupedDomains, $availablePages) = json_decode($data, true);
+            list($allLanguages, $availablePages) = json_decode($data, true);
         }
 
         $this->pseudoSites = [];
         foreach ($availablePages as $row) {
             $rootPageId = (int)$row['uid'];
             $site = new PseudoSite($rootPageId, [
-                'domains' => $groupedDomains[$rootPageId] ?? [],
+                'domains' => [],
                 'languages' => $allLanguages
             ]);
-            unset($groupedDomains[$rootPageId]);
             $this->pseudoSites[$rootPageId] = $site;
         }
 
-        // Now add the records where there is a sys_domain record but not configured as root page
-        foreach ($groupedDomains as $rootPageId => $domainRecords) {
-            $site = new PseudoSite((int)$rootPageId, [
-                'domains' => $domainRecords,
-                'languages' => $allLanguages
-            ]);
-            $this->pseudoSites[(int)$rootPageId] = $site;
-        }
-
         // Now lets an empty Pseudo-Site for visiting things on pid=0
         $this->pseudoSites[0] = new NullSite($allLanguages);
     }
diff --git a/typo3/sysext/core/Classes/Utility/MailUtility.php b/typo3/sysext/core/Classes/Utility/MailUtility.php
index 95b69459db0c..e2d62f5b90a2 100644
--- a/typo3/sysext/core/Classes/Utility/MailUtility.php
+++ b/typo3/sysext/core/Classes/Utility/MailUtility.php
@@ -14,9 +14,6 @@ namespace TYPO3\CMS\Core\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
-
 /**
  * Class to handle mail specific functionality
  */
@@ -75,40 +72,11 @@ class MailUtility
         // default, first check the localconf setting
         $address = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
         if (!GeneralUtility::validEmail($address)) {
-            // just get us a domain record we can use as the host
-            $host = '';
-            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-                ->getQueryBuilderForTable('sys_domain');
-
-            $queryBuilder->getRestrictions()
-                ->removeAll()
-                ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
-
-            $domainRecord = $queryBuilder
-                ->select('domainName')
-                ->from('sys_domain')
-                ->orderBy('pid', 'ASC')
-                ->orderBy('sorting', 'ASC')
-                ->execute()
-                ->fetch();
-
-            if (!empty($domainRecord['domainName'])) {
-                $tempUrl = $domainRecord['domainName'];
-                if (!GeneralUtility::isFirstPartOfStr($tempUrl, 'http')) {
-                    // shouldn't be the case anyways, but you never know
-                    // ... there're crazy people out there
-                    $tempUrl = 'http://' . $tempUrl;
-                }
-                $host = parse_url($tempUrl, PHP_URL_HOST);
-            }
-            $address = 'no-reply@' . $host;
+            // still nothing, get host name from server
+            $address = 'no-reply@' . php_uname('n');
             if (!GeneralUtility::validEmail($address)) {
-                // still nothing, get host name from server
-                $address = 'no-reply@' . php_uname('n');
-                if (!GeneralUtility::validEmail($address)) {
-                    // if everything fails use a dummy address
-                    $address = 'no-reply@example.com';
-                }
+                // if everything fails use a dummy address
+                $address = 'no-reply@example.com';
             }
         }
         return $address;
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index 1e90dd5a4d8c..ad1fb9c23422 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -1147,7 +1147,6 @@ return [
                 fe_users.before = pages
                 sys_template.after = pages
                 backend_layout.after = pages
-                sys_domain.after = sys_template
                 tt_content.after = pages,backend_layout,sys_template
                 sys_category.after = tt_content
             }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst
index 1a4797b43533..8e67c7d8fd5c 100644
--- a/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst
+++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst
@@ -373,17 +373,18 @@ The following PHP class methods that have been previously deprecated for v9 have
 The following PHP static class methods that have been previously deprecated for v9 have been removed:
 
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause()`
-* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getOriginalTranslationTable()`
-* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getTCAtypes()`
-* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::storeHash()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::firstDomainRecord()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getDomainStartPage()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getHash()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getListGroupNames()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getModTSconfig()`
-* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::unsetMenuItems()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getOriginalTranslationTable()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getPidForModTSconfig()`
-* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getDomainStartPage()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getTCAtypes()`
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::shortcutExists()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::storeHash()`
+* :php:`TYPO3\CMS\Backend\Utility\BackendUtility::unsetMenuItems()`
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::determineSaltingHashingMethod()`
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::getSaltingInstance()`
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::setPreferredHashingMethod()`
@@ -898,6 +899,11 @@ The following features have been removed:
   Instead, they must contain a target (callable, class/method, function).
 
 
+The following database tables have been removed:
+
+* `sys_domain` - Use site configuration instead
+
+
 The following database fields have been removed:
 
 * `index_phash.data_page_reg1`
diff --git a/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php b/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php
index e48fc15e59cb..b5da2cba6185 100644
--- a/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php
+++ b/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php
@@ -1063,27 +1063,7 @@ class FrontendLoginController extends AbstractPlugin implements LoggerAwareInter
                     $site = $this->siteFinder->getSiteByPageId((int)$this->frontendController->id);
                     return $site->getBase()->getHost() === $host;
                 } catch (SiteNotFoundException $e) {
-
-                    // Removes the last path segment and slash sequences like /// (if given):
-                    $path = preg_replace('#/+[^/]*$#', '', $parsedUrl['path'] ?? '');
-
-                    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_domain');
-                    $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
-                    $localDomains = $queryBuilder->select('domainName')
-                        ->from('sys_domain')
-                        ->execute()
-                        ->fetchAll();
-
-                    if (is_array($localDomains)) {
-                        foreach ($localDomains as $localDomain) {
-                            // strip trailing slashes (if given)
-                            $domainName = rtrim($localDomain['domainName'], '/');
-                            if (GeneralUtility::isFirstPartOfStr($host . $path . '/', $domainName . '/')) {
-                                $result = true;
-                                break;
-                            }
-                        }
-                    }
+                    // nothing found
                 }
             }
         }
diff --git a/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php b/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php
index 1a246d896f22..a9e6c4bc0f60 100644
--- a/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php
+++ b/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php
@@ -15,18 +15,10 @@ namespace TYPO3\CMS\Felogin\Tests\Unit\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Prophecy\Argument;
-use Prophecy\Prophecy\ObjectProphecy;
 use Psr\Log\NullLogger;
 use TYPO3\CMS\Core\Authentication\LoginType;
-use TYPO3\CMS\Core\Database\Connection;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
-use TYPO3\CMS\Core\Database\Query\QueryBuilder;
-use TYPO3\CMS\Core\Exception\SiteNotFoundException;
+use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\SiteFinder;
-use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockPlatform;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
@@ -51,10 +43,7 @@ class FrontendLoginControllerTest extends UnitTestCase
      */
     protected $testSitePath;
 
-    /**
-     * @var string
-     */
-    protected $testTableName;
+    protected $resetSingletonInstances = true;
 
     /**
      * Set up
@@ -62,7 +51,6 @@ class FrontendLoginControllerTest extends UnitTestCase
     protected function setUp()
     {
         $GLOBALS['TSFE'] = new \stdClass();
-        $this->testTableName = 'sys_domain';
         $this->testHostName = 'hostname.tld';
         $this->testSitePath = '/';
         $this->accessibleFixture = $this->getAccessibleMock(\TYPO3\CMS\Felogin\Controller\FrontendLoginController::class, ['dummy']);
@@ -70,24 +58,14 @@ class FrontendLoginControllerTest extends UnitTestCase
         $this->accessibleFixture->_set('frontendController', $this->createMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class));
         $this->accessibleFixture->setLogger(new NullLogger());
 
+        $site = new Site('dummy', 1, ['base' => 'http://sub.domainhostname.tld/path/']);
         $mockedSiteFinder = $this->getAccessibleMock(SiteFinder::class, ['getSiteByPageId'], [], '', false, false);
-        $mockedSiteFinder->method('getSiteByPageId')->willThrowException(new SiteNotFoundException('Site not found', 1536819047));
+        $mockedSiteFinder->method('getSiteByPageId')->willReturn($site);
         $this->accessibleFixture->_set('siteFinder', $mockedSiteFinder);
 
         $this->setUpFakeSitePathAndHost();
     }
 
-    /**
-     * Tear down
-     */
-    protected function tearDown()
-    {
-        // setUpDatabaseMock() prepares some instances via addInstance(), but not all
-        // tests use that instance. purgeInstances() removes left overs
-        GeneralUtility::purgeInstances();
-        parent::tearDown();
-    }
-
     /**
      * Set up a fake site path and host
      */
@@ -97,42 +75,6 @@ class FrontendLoginControllerTest extends UnitTestCase
         $_SERVER['HTTP_HOST'] = $this->testHostName;
     }
 
-    /**
-     * Mock database
-     */
-    protected function setUpDatabaseMock()
-    {
-        /** @var Connection|ObjectProphecy $connection */
-        $connection = $this->prophesize(Connection::class);
-        $connection->getDatabasePlatform()->willReturn(new MockPlatform());
-        $connection->getExpressionBuilder()->willReturn(new ExpressionBuilder($connection->reveal()));
-        $connection->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
-
-        // TODO: This should rather be a functional test if we need a query builder
-        // or we should clean up the code itself to not need to mock internal behavior here
-        $queryBuilder = new QueryBuilder(
-            $connection->reveal(),
-            null,
-            new \Doctrine\DBAL\Query\QueryBuilder($connection->reveal())
-        );
-
-        /** @var \Doctrine\DBAL\Driver\Statement|ObjectProphecy $resultSet */
-        $resultSet = $this->prophesize(\Doctrine\DBAL\Driver\Statement::class);
-        $resultSet->fetchAll()->willReturn([
-            ['domainName' => 'domainhostname.tld'],
-            ['domainName' => 'otherhostname.tld/path'],
-            ['domainName' => 'sub.domainhostname.tld/path/']
-        ]);
-
-        /** @var ConnectionPool|ObjectProphecy $connectionPool */
-        $connectionPool = $this->prophesize(ConnectionPool::class);
-        $connectionPool->getQueryBuilderForTable('sys_domain')->willReturn($queryBuilder);
-        GeneralUtility::addInstance(ConnectionPool::class, $connectionPool->reveal());
-
-        $connection->executeQuery('SELECT domainName FROM sys_domain', Argument::cetera())
-            ->willReturn($resultSet->reveal());
-    }
-
     /**
      * @test
      */
@@ -179,10 +121,10 @@ class FrontendLoginControllerTest extends UnitTestCase
     public function validateRedirectUrlClearsUrlDataProvider()
     {
         return [
-            'absolute URL, hostname not in sys_domain, trailing slash' => ['http://badhost.tld/'],
-            'absolute URL, hostname not in sys_domain, no trailing slash' => ['http://badhost.tld'],
-            'absolute URL, subdomain in sys_domain, but main domain not, trailing slash' => ['http://domainhostname.tld.badhost.tld/'],
-            'absolute URL, subdomain in sys_domain, but main domain not, no trailing slash' => ['http://domainhostname.tld.badhost.tld'],
+            'absolute URL, hostname not in site, trailing slash' => ['http://badhost.tld/'],
+            'absolute URL, hostname not in site, no trailing slash' => ['http://badhost.tld'],
+            'absolute URL, subdomain in site, but main domain not, trailing slash' => ['http://domainhostname.tld.badhost.tld/'],
+            'absolute URL, subdomain in site, but main domain not, no trailing slash' => ['http://domainhostname.tld.badhost.tld'],
             'non http absolute URL 1' => ['its://domainhostname.tld/itunes/'],
             'non http absolute URL 2' => ['ftp://domainhostname.tld/download/'],
             'XSS attempt 1' => ['javascript:alert(123)'],
@@ -203,7 +145,6 @@ class FrontendLoginControllerTest extends UnitTestCase
      */
     public function validateRedirectUrlClearsUrl($url)
     {
-        $this->setUpDatabaseMock();
         $this->assertEquals('', $this->accessibleFixture->_call('validateRedirectUrl', $url));
     }
 
@@ -215,17 +156,11 @@ class FrontendLoginControllerTest extends UnitTestCase
     public function validateRedirectUrlKeepsCleanUrlDataProvider()
     {
         return [
-            'sane absolute URL' => ['http://domainhostname.tld/'],
-            'sane absolute URL with script' => ['http://domainhostname.tld/index.php?id=1'],
-            'sane absolute URL with realurl' => ['http://domainhostname.tld/foo/bar/foo.html'],
-            'sane absolute URL with homedir' => ['http://domainhostname.tld/~user/'],
-            'sane absolute URL with some strange chars encoded' => ['http://domainhostname.tld/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'],
-            'sane absolute URL (domain record with path)' => ['http://otherhostname.tld/path/'],
-            'sane absolute URL with script (domain record with path)' => ['http://otherhostname.tld/path/index.php?id=1'],
-            'sane absolute URL with realurl (domain record with path)' => ['http://otherhostname.tld/path/foo/bar/foo.html'],
-            'sane absolute URL (domain record with path and slash)' => ['http://sub.domainhostname.tld/path/'],
-            'sane absolute URL with script (domain record with path slash)' => ['http://sub.domainhostname.tld/path/index.php?id=1'],
-            'sane absolute URL with realurl (domain record with path slash)' => ['http://sub.domainhostname.tld/path/foo/bar/foo.html'],
+            'sane absolute URL' => ['http://sub.domainhostname.tld/path/'],
+            'sane absolute URL with script' => ['http://sub.domainhostname.tld/path/index.php?id=1'],
+            'sane absolute URL with realurl' => ['http://sub.domainhostname.tld/path/foo/bar/foo.html'],
+            'sane absolute URL with homedir' => ['http://sub.domainhostname.tld/path/~user/'],
+            'sane absolute URL with some strange chars encoded' => ['http://sub.domainhostname.tld/path/~user/a%cc%88o%cc%88%c3%9fa%cc%82/foo.html'],
             'relative URL, no leading slash 1' => ['index.php?id=1'],
             'relative URL, no leading slash 2' => ['foo/bar/index.php?id=2'],
             'relative URL, leading slash, no realurl' => ['/index.php?id=1'],
@@ -240,7 +175,6 @@ class FrontendLoginControllerTest extends UnitTestCase
      */
     public function validateRedirectUrlKeepsCleanUrl($url)
     {
-        $this->setUpDatabaseMock();
         $this->assertEquals($url, $this->accessibleFixture->_call('validateRedirectUrl', $url));
     }
 
@@ -255,8 +189,6 @@ class FrontendLoginControllerTest extends UnitTestCase
             'absolute URL, missing subdirectory' => ['http://hostname.tld/'],
             'absolute URL, wrong subdirectory' => ['http://hostname.tld/hacker/index.php'],
             'absolute URL, correct subdirectory, no trailing slash' => ['http://hostname.tld/subdir'],
-            'absolute URL, correct subdirectory of sys_domain record, no trailing slash' => ['http://otherhostname.tld/path'],
-            'absolute URL, correct subdirectory of sys_domain record, no trailing slash, subdomain' => ['http://sub.domainhostname.tld/path'],
             'relative URL, leading slash, no path' => ['/index.php?id=1'],
             'relative URL, leading slash, wrong path' => ['/de/sub/site.html'],
             'relative URL, leading slash, slash only' => ['/'],
@@ -272,7 +204,6 @@ class FrontendLoginControllerTest extends UnitTestCase
     {
         $this->testSitePath = '/subdir/';
         $this->setUpFakeSitePathAndHost();
-        $this->setUpDatabaseMock();
         $this->assertEquals('', $this->accessibleFixture->_call('validateRedirectUrl', $url));
     }
 
@@ -287,8 +218,7 @@ class FrontendLoginControllerTest extends UnitTestCase
             'absolute URL, correct subdirectory' => ['http://hostname.tld/subdir/'],
             'absolute URL, correct subdirectory, realurl' => ['http://hostname.tld/subdir/de/imprint.html'],
             'absolute URL, correct subdirectory, no realurl' => ['http://hostname.tld/subdir/index.php?id=10'],
-            'absolute URL, correct subdirectory of sys_domain record' => ['http://otherhostname.tld/path/'],
-            'absolute URL, correct subdirectory of sys_domain record, subdomain' => ['http://sub.domainhostname.tld/path/'],
+            'absolute URL, correct subdirectory of site base' => ['http://sub.domainhostname.tld/path/'],
             'relative URL, no leading slash, realurl' => ['de/service/imprint.html'],
             'relative URL, no leading slash, no realurl' => ['index.php?id=1'],
             'relative nested URL, no leading slash, no realurl' => ['foo/bar/index.php?id=2']
@@ -304,7 +234,6 @@ class FrontendLoginControllerTest extends UnitTestCase
     {
         $this->testSitePath = '/subdir/';
         $this->setUpFakeSitePathAndHost();
-        $this->setUpDatabaseMock();
         $this->assertEquals($url, $this->accessibleFixture->_call('validateRedirectUrl', $url));
     }
 
diff --git a/typo3/sysext/frontend/Classes/Compatibility/LegacyDomainResolver.php b/typo3/sysext/frontend/Classes/Compatibility/LegacyDomainResolver.php
deleted file mode 100644
index 0129e1640b18..000000000000
--- a/typo3/sysext/frontend/Classes/Compatibility/LegacyDomainResolver.php
+++ /dev/null
@@ -1,202 +0,0 @@
-<?php
-declare(strict_types = 1);
-
-namespace TYPO3\CMS\Frontend\Compatibility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Core\Cache\CacheManager;
-use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Exception\Page\RootLineException;
-use TYPO3\CMS\Core\Http\NormalizedParams;
-use TYPO3\CMS\Core\SingletonInterface;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\RootlineUtility;
-
-/**
- * Resolves sys_domain entries when a Request object is given,
- * or a pageId is given or a rootpage Id is given (= if there is a sys_domain record on that specific page).
- * Always keeps the sorting in line.
- *
- * @internal this functionality is for compatibility reasons and might be removed in TYPO3 v10.0.
- */
-class LegacyDomainResolver implements SingletonInterface
-{
-    /**
-     * Runtime cache of domains per processed page ids.
-     *
-     * @var array
-     */
-    protected $domainDataCache = [];
-
-    /**
-     * @var string
-     */
-    protected $cacheIdentifier = 'legacy-domains';
-
-    /**
-     * @var FrontendInterface
-     */
-    protected $cache;
-
-    /**
-     * all entries in sys_domain grouped by page (pid)
-     * @var array
-     */
-    protected $groupedDomainsPerPage;
-
-    public function __construct()
-    {
-        $this->cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_core');
-        $this->populate();
-    }
-
-    /**
-     * Builds up all domain records from DB and all routes
-     */
-    protected function populate()
-    {
-        if ($data = $this->cache->get($this->cacheIdentifier)) {
-            // Due to the nature of PhpFrontend, the `<?php` and `#` wraps have to be removed
-            $data = preg_replace('/^<\?php\s*|\s*#$/', '', $data);
-            $this->groupedDomainsPerPage = json_decode($data, true);
-        } else {
-            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_domain');
-            $queryBuilder->getRestrictions()->removeAll();
-            $statement = $queryBuilder
-                ->select('*')
-                ->from('sys_domain')
-                ->orderBy('sorting', 'ASC')
-                ->execute();
-
-            while ($row = $statement->fetch()) {
-                $row['domainName'] = rtrim($row['domainName'], '/');
-                $this->groupedDomainsPerPage[(int)$row['pid']][] = $row;
-            }
-
-            $this->cache->set($this->cacheIdentifier, json_encode($this->groupedDomainsPerPage));
-        }
-    }
-
-    /**
-     * @return array
-     */
-    public function getGroupedDomainsPerPage(): array
-    {
-        return $this->groupedDomainsPerPage ?? [];
-    }
-
-    /**
-     * Obtains a sys_domain record that fits for a given page ID by traversing the rootline up and finding
-     * a suitable page with sys_domain records.
-     * As all sys_domains have been fetched already, the internal grouped list of sys_domains can be used directly.
-     *
-     * Usually used in the Frontend to find out the domain of a page to link to.
-     *
-     * Includes a runtime cache if a frontend request links to the same page multiple times.
-     *
-     * @param int $pageId Target page id
-     * @param ServerRequestInterface|null $currentRequest if given, the domain record is marked with "isCurrentDomain"
-     * @return array|null the sys_domain record if found
-     */
-    public function matchPageId(int $pageId, ServerRequestInterface $currentRequest = null): ?array
-    {
-        // Using array_key_exists() here, nice $result can be NULL
-        // (happens, if there's no domain records defined)
-        if (array_key_exists($pageId, $this->domainDataCache)) {
-            return $this->domainDataCache[$pageId];
-        }
-        try {
-            $this->domainDataCache[$pageId] = $this->resolveDomainEntry(
-                $pageId,
-                $currentRequest
-            );
-        } catch (RootLineException $e) {
-            $this->domainDataCache[$pageId] = null;
-        }
-        return $this->domainDataCache[$pageId];
-    }
-
-    /**
-     * Returns the full sys_domain record, based on a page record, which is assumed the "pid" of the sys_domain record.
-     * Since ordering is taken into account, this is the first sys_domain record on that page Id.
-     *
-     * @param int $pageId
-     * @return array|null
-     */
-    public function matchRootPageId(int $pageId): ?array
-    {
-        return !empty($this->groupedDomainsPerPage[$pageId]) ? reset($this->groupedDomainsPerPage[$pageId]) : null;
-    }
-
-    /**
-     * @param int $pageId
-     * @param ServerRequestInterface|null $currentRequest
-     * @return array|null
-     */
-    protected function resolveDomainEntry(int $pageId, ?ServerRequestInterface $currentRequest): ?array
-    {
-        $rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get();
-        // walk the rootline downwards from the target page
-        // to the root page, until a domain record is found
-        foreach ($rootLine as $pageInRootline) {
-            $pidInRootline = (int)$pageInRootline['uid'];
-            if (empty($this->groupedDomainsPerPage[$pidInRootline])) {
-                continue;
-            }
-
-            $domainEntriesOfPage = $this->groupedDomainsPerPage[$pidInRootline];
-            foreach ($domainEntriesOfPage as $domainEntry) {
-                if ($domainEntry['hidden']) {
-                    continue;
-                }
-                // When no currentRequest is given, let's take the first non-hidden sys_domain page
-                if ($currentRequest === null) {
-                    return $domainEntry;
-                }
-                // Otherwise the check should match against the current domain (and set "isCurrentDomain")
-                // Current domain is "forced", however, otherwise the first one is fine
-                if ($this->domainNameMatchesCurrentRequest($domainEntry['domainName'], $currentRequest)) {
-                    $result = $domainEntry;
-                    $result['isCurrentDomain'] = true;
-                    return $result;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Whether the given domain name (potentially including a path segment) matches currently requested host or
-     * the host including the path segment
-     *
-     * @param string $domainName
-     * @param ServerRequestInterface|null $request
-     * @return bool
-     */
-    protected function domainNameMatchesCurrentRequest($domainName, ServerRequestInterface $request): bool
-    {
-        /** @var NormalizedParams $normalizedParams */
-        $normalizedParams = $request->getAttribute('normalizedParams');
-        if (!($normalizedParams instanceof NormalizedParams)) {
-            return false;
-        }
-        $currentDomain = $normalizedParams->getHttpHost();
-        // remove the script filename from the path segment.
-        $currentPathSegment = trim(preg_replace('|/[^/]*$|', '', $normalizedParams->getScriptName()));
-        return $currentDomain === $domainName || $currentDomain . $currentPathSegment === $domainName;
-    }
-}
diff --git a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
index eae80186307d..e419db74309d 100644
--- a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
+++ b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
@@ -34,7 +34,6 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\HttpUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Core\Utility\RootlineUtility;
-use TYPO3\CMS\Frontend\Compatibility\LegacyDomainResolver;
 use TYPO3\CMS\Frontend\ContentObject\TypolinkModifyLinkConfigForPageLinksHookInterface;
 use TYPO3\CMS\Frontend\Page\CacheHashCalculator;
 use TYPO3\CMS\Frontend\Page\PageRepository;
@@ -407,14 +406,6 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
         $enableLinksAcrossDomains = $tsfe->config['config']['typolinkEnableLinksAcrossDomains'];
         $targetDomain = '';
         $currentDomain = (string)GeneralUtility::getIndpEnv('HTTP_HOST');
-        if (!empty($MPvarAcc)) {
-            $domainResolver = GeneralUtility::makeInstance(LegacyDomainResolver::class);
-            $targetDomainRecord = $domainResolver->matchPageId((int)$page['uid'], $GLOBALS['TYPO3_REQUEST']);
-            // Do not prepend the domain if it is the current hostname
-            if (!empty($targetDomainRecord) && !$targetDomainRecord['isCurrentDomain']) {
-                $targetDomain = $targetDomainRecord['domainName'];
-            }
-        }
         $absoluteUrlScheme = GeneralUtility::getIndpEnv('TYPO3_SSL') ? 'https' : 'http';
         // URL shall be absolute:
         if (isset($conf['forceAbsoluteUrl']) && $conf['forceAbsoluteUrl']) {
diff --git a/typo3/sysext/frontend/Configuration/TCA/sys_domain.php b/typo3/sysext/frontend/Configuration/TCA/sys_domain.php
deleted file mode 100644
index 423b9fd017e5..000000000000
--- a/typo3/sysext/frontend/Configuration/TCA/sys_domain.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-return [
-    'ctrl' => [
-        'label' => 'domainName',
-        'tstamp' => 'tstamp',
-        'crdate' => 'crdate',
-        'cruser_id' => 'cruser_id',
-        'sortby' => 'sorting',
-        'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:sys_domain',
-        'enablecolumns' => [
-            'disabled' => 'hidden'
-        ],
-        'typeicon_classes' => [
-            'default' => 'mimetypes-x-content-domain'
-        ],
-        'searchFields' => 'domainName'
-    ],
-    'interface' => [
-        'showRecordFieldList' => 'hidden,domainName'
-    ],
-    'columns' => [
-        'domainName' => [
-            'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:sys_domain.domainName',
-            'config' => [
-                'type' => 'input',
-                'size' => 35,
-                'max' => 255,
-                'eval' => 'required,unique,lower,trim,domainname',
-                'softref' => 'substitute'
-            ]
-        ],
-        'hidden' => [
-            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.enabled',
-            'exclude' => true,
-            'config' => [
-                'type' => 'check',
-                'renderType' => 'checkboxToggle',
-                'default' => 0,
-                'items' => [
-                    [
-                        0 => '',
-                        1 => '',
-                        'invertStateDisplay' => true,
-                    ],
-                ],
-            ],
-        ],
-    ],
-    'types' => [
-        '1' => [
-            'showitem' => '
-                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
-                    domainName,
-                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
-                    hidden,
-                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
-            ',
-        ],
-    ],
-    'palettes' => [
-    ]
-];
diff --git a/typo3/sysext/frontend/Resources/Private/Language/locallang_csh_sysdomain.xlf b/typo3/sysext/frontend/Resources/Private/Language/locallang_csh_sysdomain.xlf
deleted file mode 100644
index b80d323bf6c7..000000000000
--- a/typo3/sysext/frontend/Resources/Private/Language/locallang_csh_sysdomain.xlf
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
-	<file t3:id="1415814800" source-language="en" datatype="plaintext" original="messages" date="2011-10-17T20:22:32Z" product-name="context_help">
-		<header/>
-		<body>
-			<trans-unit id=".description">
-				<source>Determines the entrypoint of a certain host name.</source>
-			</trans-unit>
-			<trans-unit id=".details" xml:space="preserve">
-				<source>When a TYPO3 database contains more than a single website, you'll typically have to assign a domain name to each new websites "root-page". In practice you point all the domains to the same TYPO3 database on the server, but then you insert these Domain records at the positions in the page tree where you want to direct requests to the domain. And thus pages 'outside' that point will not be accessible from that domain.
-This is like "Virtual hosts" in Apache servers.
-
-(Should probably be available for admin only.)</source>
-			</trans-unit>
-			<trans-unit id="_.seeAlso" xml:space="preserve">
-				<source>sys_language
-sys_template</source>
-			</trans-unit>
-			<trans-unit id="domainName.description">
-				<source>Enter the host name, eg. "www.my-domain.com".</source>
-			</trans-unit>
-			<trans-unit id="domainName.details" xml:space="preserve">
-				<source>Before a domain record will have any effect you must make sure that the domains A-record is pointed towards the server and that your server is setup to direct requests to this TYPO3 database. So basically before entering anything here, make sure a request to the domain you wish to enter arrives at the root of the current page tree.
-When you create a domain record and the host name in it (be it a real domain name or an IP address) matches the hostname of the URL, the TypoScript based front end will limit the available page to only those in the page tree from this point and outwards. In effect you will 'arrive' at the page where this record is and furthermore users cannot see pages with ids outside this branch.
-
-&lt;strong&gt;Notice, &lt;/strong&gt;if you run TYPO3 from a subdirectory of the domain name, you must include the subdirectory as well, eg. "www.my-domain.org/typo3_subdir/"</source>
-			</trans-unit>
-			<trans-unit id="redirectTo.description">
-				<source>All requests to the domain will be redirected to this URL, if any value is entered.</source>
-			</trans-unit>
-			<trans-unit id="redirectTo.details" xml:space="preserve">
-				<source>Make sure to prepend "http://" or equally to the value! Basically a "Location: " header is just issued to this value!
-&lt;strong&gt;Warning:&lt;/strong&gt; You cannot use this to 'redirect' to a specific page id within the same domain as the record has! If you do that it'll just go into an endless loop because the redirect is redirecting to itself!
-
-Good Example:
-Domain: "my-domain.org"
-Redirect: "www.my-domain.org"
-
-This redirects requests to what is infact another domain name, namely "www.my-domain.org"
-
-Bad Example:
-Domain: "www.my-domain.org"
-Redirect: "www.my-domain.org/?id=10"
-
-This will go into an eternal loop because the domain name has in fact not changed!
-
-
-Virtual directories:
-If you're using TYPO3 on a unix computer you can make 'virtual subdirectories' to a website, still within the same database. See document list for more information. In that case you should enter the hostname with the subdirectory appended, like this: "my-domain.org/subdir/". If the combination of host name and current subdirectory matches the value, the domain record will be correctly detected and limit page access to the page tree below the Domain record.</source>
-			</trans-unit>
-			<trans-unit id="hidden.description">
-				<source>Use this option to temporarily disable the Domain record.</source>
-			</trans-unit>
-			<trans-unit id="prepend_params.description">
-				<source>If set, any GET parameters in the calling URL will be transferred to the redirect URL.</source>
-			</trans-unit>
-		</body>
-	</file>
-</xliff>
diff --git a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
index 85f547a6b52e..913100b4285f 100644
--- a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
+++ b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
@@ -474,12 +474,6 @@
 			<trans-unit id="fe_groups.tabs.extended">
 				<source>Extended</source>
 			</trans-unit>
-			<trans-unit id="sys_domain">
-				<source>Domain</source>
-			</trans-unit>
-			<trans-unit id="sys_domain.domainName">
-				<source>Domain</source>
-			</trans-unit>
 			<trans-unit id="sys_template">
 				<source>Template</source>
 			</trans-unit>
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/PlainScenario.yaml b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/PlainScenario.yaml
index 7b5064462ce5..4b4e43ad0f37 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/PlainScenario.yaml
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/PlainScenario.yaml
@@ -26,8 +26,6 @@ entitySettings:
     tableName: 'tt_content'
     languageColumnNames: ['l18n_parent', 'l10n_source']
     columnNames: {title: 'header', type: 'CType'}
-  domain:
-    tableName: 'sys_domain'
   workspace:
     tableName: 'sys_workspace'
   language:
@@ -136,9 +134,6 @@ entities:
             - self: {id: 3110, title: 'EN: Markets'}
             - self: {id: 3120, title: 'EN: Products'}
             - self: {id: 3130, title: 'EN: Partners'}
-      entities:
-        domain:
-          - self: {domainName: 'archive.acme.com'}
     - self: {id: 7000, title: 'Common Collection', type: *pageFolder}
       children:
         - self: {id: 7100, title: 'Announcements & News'}
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/SlugScenario.yaml b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/SlugScenario.yaml
index cdb2710b61a2..28d78abe2f35 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/SlugScenario.yaml
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/SlugScenario.yaml
@@ -26,8 +26,6 @@ entitySettings:
     tableName: 'tt_content'
     languageColumnNames: ['l18n_parent', 'l10n_source']
     columnNames: {title: 'header', type: 'CType'}
-  domain:
-    tableName: 'sys_domain'
   workspace:
     tableName: 'sys_workspace'
   language:
@@ -136,9 +134,6 @@ entities:
             - self: {id: 3110, title: 'EN: Markets', slug: '/archive/markets'}
             - self: {id: 3120, title: 'EN: Products', slug: '/archive/products'}
             - self: {id: 3130, title: 'EN: Partners', slug: '/archive/partners'}
-      entities:
-        domain:
-          - self: {domainName: 'archive.acme.com'}
     - self: {id: 7000, title: 'Common Collection', type: *pageFolder, slug: '/common'}
       children:
         - self: {id: 7100, title: 'Announcements & News', slug: '/common/news'}
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/DomainVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/DomainVisibleFieldsTest.php
deleted file mode 100644
index 6ae63c4e61b8..000000000000
--- a/typo3/sysext/frontend/Tests/Functional/Tca/DomainVisibleFieldsTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-class DomainVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
-{
-    protected static $domainFields = [
-        'hidden',
-        'domainName'
-    ];
-
-    /**
-     * @test
-     */
-    public function domainFormContainsExpectedFields()
-    {
-        $this->setUpBackendUserFromFixture(1);
-        $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class);
-
-        $formEngineTestService = GeneralUtility::makeInstance(FormTestService::class);
-        $formResult = $formEngineTestService->createNewRecordForm('sys_domain');
-
-        foreach (static::$domainFields as $expectedField) {
-            $this->assertNotFalse(
-                $formEngineTestService->formHtmlContainsField($expectedField, $formResult['html']),
-                'The field ' . $expectedField . ' is not in the form HTML'
-            );
-        }
-    }
-}
diff --git a/typo3/sysext/frontend/Tests/Unit/Compatibility/LegacyDomainResolverTest.php b/typo3/sysext/frontend/Tests/Unit/Compatibility/LegacyDomainResolverTest.php
deleted file mode 100644
index 3b88e4b91eff..000000000000
--- a/typo3/sysext/frontend/Tests/Unit/Compatibility/LegacyDomainResolverTest.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-declare(strict_types = 1);
-namespace TYPO3\CMS\Frontend\Tests\Unit\Compatibility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Core\Environment;
-use TYPO3\CMS\Core\Http\NormalizedParams;
-use TYPO3\CMS\Core\Http\ServerRequestFactory;
-use TYPO3\CMS\Frontend\Compatibility\LegacyDomainResolver;
-use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
-
-class LegacyDomainResolverTest extends UnitTestCase
-{
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface|LegacyDomainResolver
-     */
-    protected $subject;
-
-    protected $resetSingletonInstances = true;
-
-    protected $backupEnvironment = true;
-
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->subject = $this->getAccessibleMock(LegacyDomainResolver::class, ['dummy'], [], '', false);
-    }
-
-    /**
-     * Tests concerning domainNameMatchesCurrentRequest
-     */
-
-    /**
-     * @return array
-     */
-    public function domainNameMatchesCurrentRequestDataProvider()
-    {
-        return [
-            'same domains' => [
-                'typo3.org',
-                'typo3.org',
-                '/index.php',
-                true,
-            ],
-            'same domains with subdomain' => [
-                'www.typo3.org',
-                'www.typo3.org',
-                '/index.php',
-                true,
-            ],
-            'different domains' => [
-                'foo.bar',
-                'typo3.org',
-                '/index.php',
-                false,
-            ],
-            'domain record with script name' => [
-                'typo3.org',
-                'typo3.org/foo/bar',
-                '/foo/bar/index.php',
-                true,
-            ],
-            'domain record with wrong script name' => [
-                'typo3.org',
-                'typo3.org/foo/bar',
-                '/bar/foo/index.php',
-                false,
-            ],
-        ];
-    }
-
-    /**
-     * @param string $currentDomain
-     * @param string $domainRecord
-     * @param string $scriptName
-     * @param bool $expectedResult
-     * @test
-     * @dataProvider domainNameMatchesCurrentRequestDataProvider
-     */
-    public function domainNameMatchesCurrentRequest(string $currentDomain, string $domainRecord, string $scriptName, bool $expectedResult)
-    {
-        $_SERVER['HTTP_HOST'] = $currentDomain;
-        $_SERVER['SCRIPT_NAME'] = $scriptName;
-        $request = ServerRequestFactory::fromGlobals();
-        $normalizedParams = new NormalizedParams($_SERVER, [], Environment::getCurrentScript(), Environment::getPublicPath());
-        $request = $request->withAttribute('normalizedParams', $normalizedParams);
-        $this->assertEquals($expectedResult, $this->subject->_call('domainNameMatchesCurrentRequest', $domainRecord, $request));
-    }
-}
diff --git a/typo3/sysext/frontend/ext_tables.php b/typo3/sysext/frontend/ext_tables.php
index 63a983fc1713..e8ce5071e265 100644
--- a/typo3/sysext/frontend/ext_tables.php
+++ b/typo3/sysext/frontend/ext_tables.php
@@ -2,11 +2,10 @@
 defined('TYPO3_MODE') or die();
 
 // Add allowed records to pages
-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tt_content,sys_template,sys_domain,backend_layout');
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tt_content,sys_template,backend_layout');
 
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('_MOD_web_layout', 'EXT:frontend/Resources/Private/Language/locallang_csh_weblayout.xlf');
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('fe_groups', 'EXT:frontend/Resources/Private/Language/locallang_csh_fe_groups.xlf');
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('fe_users', 'EXT:frontend/Resources/Private/Language/locallang_csh_fe_users.xlf');
-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('sys_domain', 'EXT:frontend/Resources/Private/Language/locallang_csh_sysdomain.xlf');
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('sys_template', 'EXT:frontend/Resources/Private/Language/locallang_csh_systmpl.xlf');
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tt_content', 'EXT:frontend/Resources/Private/Language/locallang_csh_ttcontent.xlf');
diff --git a/typo3/sysext/frontend/ext_tables.sql b/typo3/sysext/frontend/ext_tables.sql
index 419869d6e1e6..23cab4f1bc7e 100644
--- a/typo3/sysext/frontend/ext_tables.sql
+++ b/typo3/sysext/frontend/ext_tables.sql
@@ -117,16 +117,6 @@ CREATE TABLE pages_language_overlay (
 	KEY parent (pid,sys_language_uid)
 );
 
-#
-# Table structure for table 'sys_domain'
-#
-CREATE TABLE sys_domain (
-	domainName varchar(255) DEFAULT '' NOT NULL,
-
-	KEY getSysDomain (hidden),
-	KEY getDomainStartPage (pid,hidden,domainName(100))
-);
-
 #
 # Table structure for table 'sys_template'
 #
diff --git a/typo3/sysext/install/Classes/Updates/RedirectsExtensionUpdate.php b/typo3/sysext/install/Classes/Updates/RedirectsExtensionUpdate.php
index 081a7310e78e..ce003b92c393 100644
--- a/typo3/sysext/install/Classes/Updates/RedirectsExtensionUpdate.php
+++ b/typo3/sysext/install/Classes/Updates/RedirectsExtensionUpdate.php
@@ -129,6 +129,16 @@ class RedirectsExtensionUpdate extends AbstractDownloadExtensionUpdate
     {
         $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
         $connection = $connectionPool->getConnectionByName('Default');
+        $tables = $connection->getSchemaManager()->listTables();
+        $tableExists = false;
+        foreach ($tables as $table) {
+            if (strtolower($table->getName()) === 'sys_domain') {
+                $tableExists = true;
+            }
+        }
+        if (!$tableExists) {
+            return false;
+        }
         $columns = $connection->getSchemaManager()->listTableColumns('sys_domain');
         if (isset($columns['redirectto'])) {
             // table is available, now check if there are entries in it
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
index 6876dc052099..0570c14f3868 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
@@ -825,6 +825,7 @@ return [
         'maximumNumberOfArguments' => 1,
         'restFiles' => [
             'Deprecation-85892-VariousMethodsRegardingSysDomainResolving.rst',
+            'Breaking-87193-DeprecatedFunctionalityRemoved.rst',
         ],
     ],
     'TYPO3\CMS\Core\Utility\GeneralUtility::_GETset' => [
diff --git a/typo3/sysext/linkvalidator/Classes/Linktype/InternalLinktype.php b/typo3/sysext/linkvalidator/Classes/Linktype/InternalLinktype.php
index 4c1c80c700c8..dc7f9ab6decf 100644
--- a/typo3/sysext/linkvalidator/Classes/Linktype/InternalLinktype.php
+++ b/typo3/sysext/linkvalidator/Classes/Linktype/InternalLinktype.php
@@ -14,7 +14,6 @@ namespace TYPO3\CMS\Linkvalidator\Linktype;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -337,15 +336,6 @@ class InternalLinktype extends AbstractLinktype
     public function getBrokenUrl($row)
     {
         $domain = rtrim(GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), '/');
-        $rootLine = BackendUtility::BEgetRootLine($row['record_pid']);
-        // checks alternate domains
-        if (!empty($rootLine)) {
-            $protocol = GeneralUtility::getIndpEnv('TYPO3_SSL') ? 'https://' : 'http://';
-            $domainRecord = BackendUtility::firstDomainRecord($rootLine);
-            if (!empty($domainRecord)) {
-                $domain = $protocol . $domainRecord;
-            }
-        }
         return $domain . '/index.php?id=' . $row['url'];
     }
 }
diff --git a/typo3/sysext/redirects/Classes/FormDataProvider/ValuePickerItemDataProvider.php b/typo3/sysext/redirects/Classes/FormDataProvider/ValuePickerItemDataProvider.php
index 13963f65a517..c4eb9adfa055 100644
--- a/typo3/sysext/redirects/Classes/FormDataProvider/ValuePickerItemDataProvider.php
+++ b/typo3/sysext/redirects/Classes/FormDataProvider/ValuePickerItemDataProvider.php
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Redirects\FormDataProvider;
  */
 
 use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
-use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -49,7 +48,7 @@ class ValuePickerItemDataProvider implements FormDataProviderInterface
     public function addData(array $result): array
     {
         if ($result['tableName'] === 'sys_redirect' && isset($result['processedTca']['columns']['source_host'])) {
-            $domains = $this->getDomains();
+            $domains = $this->getHosts();
             foreach ($domains as $domain) {
                 $result['processedTca']['columns']['source_host']['config']['valuePicker']['items'][] =
                     [
@@ -62,32 +61,11 @@ class ValuePickerItemDataProvider implements FormDataProviderInterface
     }
 
     /**
-     * Get sys_domain records from database, and all from pseudo-sites
+     * Get all hosts from sites
      *
      * @return array domain records
      */
-    protected function getDomains(): array
-    {
-        $domains = $this->getDomainsFromAllSites();
-
-        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_domain');
-        $sysDomainRecords = $queryBuilder
-            ->select('domainName')
-            ->from('sys_domain')
-            ->execute()
-            ->fetchAll();
-        foreach ($sysDomainRecords as $domainRecord) {
-            $domains[] = $domainRecord['domainName'];
-        }
-        $domains = array_unique($domains);
-        sort($domains, SORT_NATURAL);
-        return $domains;
-    }
-
-    /**
-     * @return array
-     */
-    protected function getDomainsFromAllSites(): array
+    protected function getHosts(): array
     {
         $domains = [];
         foreach ($this->siteFinder->getAllSites() as $site) {
@@ -95,6 +73,8 @@ class ValuePickerItemDataProvider implements FormDataProviderInterface
                 $domains[] = $language->getBase()->getHost();
             }
         }
+        $domains = array_unique($domains);
+        sort($domains, SORT_NATURAL);
         return $domains;
     }
 }
diff --git a/typo3/sysext/redirects/Tests/Unit/FormDataProvider/ValuePickerItemDataProviderTest.php b/typo3/sysext/redirects/Tests/Unit/FormDataProvider/ValuePickerItemDataProviderTest.php
index a8c8114e84d6..0d2b91983abf 100644
--- a/typo3/sysext/redirects/Tests/Unit/FormDataProvider/ValuePickerItemDataProviderTest.php
+++ b/typo3/sysext/redirects/Tests/Unit/FormDataProvider/ValuePickerItemDataProviderTest.php
@@ -15,13 +15,8 @@ namespace TYPO3\CMS\Redirects\Tests\Unit\FormDataProvider;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Doctrine\DBAL\Driver\Statement;
-use Prophecy\Prophecy\ObjectProphecy;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Query\QueryBuilder;
-use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface;
+use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\SiteFinder;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Redirects\FormDataProvider\ValuePickerItemDataProvider;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
@@ -61,18 +56,14 @@ class ValuePickerItemDataProviderTest extends UnitTestCase
     /**
      * @test
      */
-    public function addDataAddsDomainNameAsKeyAndValueToRedirectValuePicker()
+    public function addDataAddsHostsAsKeyAndValueToRedirectValuePicker()
     {
-        $statementProphecy = $this->setUpDatabase();
-        $statementProphecy->fetchAll()->willReturn(
-            [
-                ['domainName' => 'bar.test'],
-                ['domainName' => 'foo.test'],
-            ]
-        );
         // no results for now
         $siteFinderProphecy = $this->prophesize(SiteFinder::class);
-        $siteFinderProphecy->getAllSites()->willReturn([]);
+        $siteFinderProphecy->getAllSites()->willReturn([
+            new Site('bar', 13, ['base' => 'bar.test']),
+            new Site('foo', 14, ['base' => 'foo.test'])
+        ]);
         $valuePickerItemDataProvider = new ValuePickerItemDataProvider($siteFinderProphecy->reveal());
         $actualResult = $valuePickerItemDataProvider->addData($this->sysRedirectResultSet);
         $expected = $this->sysRedirectResultSet;
@@ -86,10 +77,8 @@ class ValuePickerItemDataProviderTest extends UnitTestCase
     /**
      * @test
      */
-    public function addDataDoesNotChangeResultSetIfNoSysDomainsAreFound()
+    public function addDataDoesNotChangeResultSetIfNoSitessAreFound()
     {
-        $statementProphecy = $this->setUpDatabase();
-        $statementProphecy->fetchAll()->willReturn([]);
         $siteFinderProphecy = $this->prophesize(SiteFinder::class);
         $siteFinderProphecy->getAllSites()->willReturn([]);
         $valuePickerItemDataProvider = new ValuePickerItemDataProvider($siteFinderProphecy->reveal());
@@ -97,22 +86,4 @@ class ValuePickerItemDataProviderTest extends UnitTestCase
 
         self::assertSame($this->sysRedirectResultSet, $actualResult);
     }
-
-    /**
-     * @return \Doctrine\DBAL\Driver\Statement|\Prophecy\Prophecy\ObjectProphecy
-     */
-    private function setUpDatabase(): ObjectProphecy
-    {
-        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
-        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
-        $connectionPoolProphecy->getQueryBuilderForTable('sys_domain')->willReturn($queryBuilderProphecy->reveal());
-        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
-        $queryBuilderProphecy->getRestrictions()->willReturn($queryRestrictionContainerProphecy->reveal());
-        $queryBuilderProphecy->select('domainName')->willReturn($queryBuilderProphecy->reveal());
-        $queryBuilderProphecy->from('sys_domain')->willReturn($queryBuilderProphecy->reveal());
-        $statementProphecy = $this->prophesize(Statement::class);
-        $queryBuilderProphecy->execute()->willReturn($statementProphecy->reveal());
-        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
-        return $statementProphecy;
-    }
 }
diff --git a/typo3/sysext/t3editor/Resources/Public/JavaScript/Mode/typoscript/typoscript.js b/typo3/sysext/t3editor/Resources/Public/JavaScript/Mode/typoscript/typoscript.js
index 591421f0a89f..f46a6c93be44 100644
--- a/typo3/sysext/t3editor/Resources/Public/JavaScript/Mode/typoscript/typoscript.js
+++ b/typo3/sysext/t3editor/Resources/Public/JavaScript/Mode/typoscript/typoscript.js
@@ -828,7 +828,6 @@
         'SWORD_PARAMS': kw('SWORD_PARAMS'),
         'sword_standAlone': kw('sword_standAlone'),
         'sys_dmail': B,
-        'sys_domain': B,
         'sys_filemounts': B,
         'sys_language_mode': kw('sys_language_mode'),
         'sys_language_overlay': kw('sys_language_overlay'),
diff --git a/typo3/sysext/viewpage/Classes/Controller/ViewModuleController.php b/typo3/sysext/viewpage/Classes/Controller/ViewModuleController.php
index 67b9524ddcd1..b5ee12c9f1b7 100644
--- a/typo3/sysext/viewpage/Classes/Controller/ViewModuleController.php
+++ b/typo3/sysext/viewpage/Classes/Controller/ViewModuleController.php
@@ -295,12 +295,11 @@ class ViewModuleController
      * Get domain name for requested page id
      *
      * @param int $pageId
-     * @return string|null Domain name from first sys_domains-Record or from TCEMAIN.previewDomain, NULL if neither is configured
+     * @return string|null Domain name from TCEMAIN.previewDomain, NULL if not configured
      */
     protected function getDomainName(int $pageId)
     {
-        $previewDomainConfig = BackendUtility::getPagesTSconfig($pageId)['TCEMAIN.']['previewDomain'] ?? '';
-        return $previewDomainConfig ?: BackendUtility::firstDomainRecord(BackendUtility::BEgetRootLine($pageId));
+        return BackendUtility::getPagesTSconfig($pageId)['TCEMAIN.']['previewDomain'] ?? '';
     }
 
     /**
-- 
GitLab