Skip to content

Commit 8028f2f

Browse files
committed
[!!!][TASK] Remove TCEMAIN.previewDomain
The functionality to set a custom TCEMAIN.previewDomain via PageTS is not in use anymore as SiteHandling is using the proper domain anyway already. Conceptually this does not work anymore, as the base (domain + path prefix) determines Language + Site / PageTree entry point. Setting this to something else via TCEMAIN.previewDomain would not work anyways, so this hack is removed, as we now can safely determine the full (speaking) URL with Site Handling. In addition, the method BackendUtility::getViewDomain() is now deprecated. Resolves: #88499 Releases: master Change-Id: Id88c16e2e86ccce8a2e7be02af0e2a39802624c0 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60773 Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Susanne Moog <look@susi.dev> Tested-by: Daniel Gorges <daniel.gorges@b13.de> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Susanne Moog <look@susi.dev> Reviewed-by: Daniel Gorges <daniel.gorges@b13.de> Reviewed-by: Benni Mack <benni@typo3.org>
1 parent 7c4a63b commit 8028f2f

File tree

14 files changed

+172
-204
lines changed

14 files changed

+172
-204
lines changed

typo3/sysext/backend/Classes/Controller/EditDocumentController.php

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use TYPO3\CMS\Core\Messaging\FlashMessage;
4242
use TYPO3\CMS\Core\Messaging\FlashMessageService;
4343
use TYPO3\CMS\Core\Page\PageRenderer;
44+
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
4445
use TYPO3\CMS\Core\Site\Entity\NullSite;
4546
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
4647
use TYPO3\CMS\Core\Site\SiteFinder;
@@ -775,9 +776,10 @@ protected function generatePreviewCode(): string
775776
$previewPageId = $this->getPreviewPageId();
776777
$previewPageRootLine = BackendUtility::BEgetRootLine($previewPageId);
777778
$anchorSection = $this->getPreviewUrlAnchorSection();
778-
$previewUrlParameters = $this->getPreviewUrlParameters($previewPageId);
779779

780-
return '
780+
try {
781+
$previewUrlParameters = $this->getPreviewUrlParameters($previewPageId);
782+
return '
781783
if (window.opener) {
782784
'
783785
. BackendUtility::viewOnClick(
@@ -789,7 +791,7 @@ protected function generatePreviewCode(): string
789791
$previewUrlParameters,
790792
false
791793
)
792-
. '
794+
. '
793795
} else {
794796
'
795797
. BackendUtility::viewOnClick(
@@ -800,8 +802,11 @@ protected function generatePreviewCode(): string
800802
$this->viewUrl,
801803
$previewUrlParameters
802804
)
803-
. '
805+
. '
804806
}';
807+
} catch (UnableToLinkToPageException $e) {
808+
return '';
809+
}
805810
}
806811

807812
/**
@@ -1406,35 +1411,39 @@ protected function registerViewButtonToButtonBar(ButtonBar $buttonBar, string $p
14061411
|| isset($pagesTSconfig['TCEMAIN.']['preview.'][$this->firstEl['table'] . '.']['previewPageId'])
14071412
) {
14081413
$previewPageId = $this->getPreviewPageId();
1409-
$previewUrl = BackendUtility::getPreviewUrl(
1410-
$previewPageId,
1411-
'',
1412-
BackendUtility::BEgetRootLine($previewPageId),
1413-
$this->getPreviewUrlAnchorSection(),
1414-
$this->viewUrl,
1415-
$this->getPreviewUrlParameters($previewPageId)
1416-
);
1414+
try {
1415+
$previewUrl = BackendUtility::getPreviewUrl(
1416+
$previewPageId,
1417+
'',
1418+
BackendUtility::BEgetRootLine($previewPageId),
1419+
$this->getPreviewUrlAnchorSection(),
1420+
$this->viewUrl,
1421+
$this->getPreviewUrlParameters($previewPageId)
1422+
);
1423+
1424+
$viewButton = $buttonBar->makeLinkButton()
1425+
->setHref($previewUrl)
1426+
->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
1427+
'actions-view',
1428+
Icon::SIZE_SMALL
1429+
))
1430+
->setShowLabelText(true)
1431+
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.viewDoc'));
1432+
1433+
if (!$this->isSavedRecord) {
1434+
if ($this->firstEl['table'] === 'pages') {
1435+
$viewButton->setDataAttributes(['is-new' => '']);
1436+
}
1437+
}
14171438

1418-
$viewButton = $buttonBar->makeLinkButton()
1419-
->setHref($previewUrl)
1420-
->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
1421-
'actions-view',
1422-
Icon::SIZE_SMALL
1423-
))
1424-
->setShowLabelText(true)
1425-
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.viewDoc'));
1426-
1427-
if (!$this->isSavedRecord) {
1428-
if ($this->firstEl['table'] === 'pages') {
1429-
$viewButton->setDataAttributes(['is-new' => '']);
1439+
if ($classNames !== '') {
1440+
$viewButton->setClasses($classNames);
14301441
}
1431-
}
14321442

1433-
if ($classNames !== '') {
1434-
$viewButton->setClasses($classNames);
1443+
$buttonBar->addButton($viewButton, $position, $group);
1444+
} catch (UnableToLinkToPageException $e) {
1445+
// Do not add any button
14351446
}
1436-
1437-
$buttonBar->addButton($viewButton, $position, $group);
14381447
}
14391448
}
14401449
}

typo3/sysext/backend/Classes/Utility/BackendUtility.php

Lines changed: 42 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
3131
use TYPO3\CMS\Core\Database\RelationHandler;
3232
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
33+
use TYPO3\CMS\Core\Http\Uri;
3334
use TYPO3\CMS\Core\Imaging\Icon;
3435
use TYPO3\CMS\Core\Imaging\IconFactory;
3536
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
@@ -39,6 +40,7 @@
3940
use TYPO3\CMS\Core\Resource\ResourceFactory;
4041
use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
4142
use TYPO3\CMS\Core\Routing\RouterInterface;
43+
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
4244
use TYPO3\CMS\Core\Site\SiteFinder;
4345
use TYPO3\CMS\Core\Type\Bitmask\Permission;
4446
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
@@ -2306,15 +2308,19 @@ public static function viewOnClick(
23062308
$additionalGetVars = '',
23072309
$switchFocus = true
23082310
) {
2309-
$previewUrl = self::getPreviewUrl(
2310-
$pageUid,
2311-
$backPath,
2312-
$rootLine,
2313-
$anchorSection,
2314-
$alternativeUrl,
2315-
$additionalGetVars,
2316-
$switchFocus
2317-
);
2311+
try {
2312+
$previewUrl = self::getPreviewUrl(
2313+
$pageUid,
2314+
$backPath,
2315+
$rootLine,
2316+
$anchorSection,
2317+
$alternativeUrl,
2318+
$additionalGetVars,
2319+
$switchFocus
2320+
);
2321+
} catch (UnableToLinkToPageException $e) {
2322+
return '';
2323+
}
23182324

23192325
$onclickCode = 'var previewWin = window.open(' . GeneralUtility::quoteJSvalue($previewUrl) . ',\'newTYPO3frontendWindow\');'
23202326
. ($switchFocus ? 'previewWin.focus();' : '') . LF
@@ -2380,21 +2386,25 @@ public static function getPreviewUrl(
23802386
$rootLine = $rootLine ?? BackendUtility::BEgetRootLine($pageUid);
23812387
try {
23822388
$site = $siteFinder->getSiteByPageId((int)$pageUid, $rootLine);
2383-
// Create a multi-dimensional array out of the additional get vars
2384-
$additionalQueryParams = [];
2385-
parse_str($additionalGetVars, $additionalQueryParams);
2386-
if (isset($additionalQueryParams['L'])) {
2387-
$additionalQueryParams['_language'] = $additionalQueryParams['_language'] ?? $additionalQueryParams['L'];
2388-
unset($additionalQueryParams['L']);
2389-
}
2389+
} catch (SiteNotFoundException $e) {
2390+
throw new UnableToLinkToPageException('The page ' . $pageUid . ' had no proper connection to a site, no link could be built.', 1559794919);
2391+
}
2392+
// Create a multi-dimensional array out of the additional get vars
2393+
$additionalQueryParams = [];
2394+
parse_str($additionalGetVars, $additionalQueryParams);
2395+
if (isset($additionalQueryParams['L'])) {
2396+
$additionalQueryParams['_language'] = $additionalQueryParams['_language'] ?? $additionalQueryParams['L'];
2397+
unset($additionalQueryParams['L']);
2398+
}
2399+
try {
23902400
$previewUrl = (string)$site->getRouter()->generateUri(
23912401
$pageUid,
23922402
$additionalQueryParams,
23932403
$anchorSection,
23942404
RouterInterface::ABSOLUTE_URL
23952405
);
2396-
} catch (SiteNotFoundException | \InvalidArgumentException | InvalidRouteArgumentsException $e) {
2397-
$previewUrl = self::createPreviewUrl($pageUid, $rootLine, $anchorSection, $additionalGetVars, $viewScript);
2406+
} catch (\InvalidArgumentException | InvalidRouteArgumentsException $e) {
2407+
throw new UnableToLinkToPageException('The page ' . $pageUid . ' had no proper connection to a site, no link could be built.', 1559794914);
23982408
}
23992409
}
24002410

@@ -2479,96 +2489,38 @@ public static function getLinkToDataHandlerAction($parameters, $redirectUrl = ''
24792489
return $url;
24802490
}
24812491

2482-
/**
2483-
* Creates the view-on-click preview URL without any alternative URL.
2484-
*
2485-
* @param int $pageUid Page UID
2486-
* @param array $rootLine If rootline is supplied, the function will look for the first found domain record and use that URL instead
2487-
* @param string $anchorSection Optional anchor to the URL
2488-
* @param string $additionalGetVars Additional GET variables.
2489-
* @param string $viewScript The path to the script used to view the page
2490-
*
2491-
* @return string The preview URL
2492-
*/
2493-
protected static function createPreviewUrl($pageUid, $rootLine, $anchorSection, $additionalGetVars, $viewScript)
2494-
{
2495-
// Look if a fixed preview language should be added:
2496-
$beUser = static::getBackendUserAuthentication();
2497-
$viewLanguageOrder = (string)($beUser->getTSConfig()['options.']['view.']['languageOrder'] ?? '');
2498-
2499-
if (!empty($viewLanguageOrder)) {
2500-
$suffix = '';
2501-
// Find allowed languages (if none, all are allowed!)
2502-
$allowedLanguages = null;
2503-
if (!$beUser->isAdmin() && $beUser->groupData['allowed_languages'] !== '') {
2504-
$allowedLanguages = array_flip(explode(',', $beUser->groupData['allowed_languages']));
2505-
}
2506-
// Traverse the view order, match first occurrence:
2507-
$languageOrder = GeneralUtility::intExplode(',', $viewLanguageOrder);
2508-
foreach ($languageOrder as $langUid) {
2509-
if (is_array($allowedLanguages) && !empty($allowedLanguages)) {
2510-
// Choose if set.
2511-
if (isset($allowedLanguages[$langUid])) {
2512-
$suffix = '&L=' . $langUid;
2513-
break;
2514-
}
2515-
} else {
2516-
// All allowed since no lang. are listed.
2517-
$suffix = '&L=' . $langUid;
2518-
break;
2519-
}
2520-
}
2521-
// Add it
2522-
$additionalGetVars .= $suffix;
2523-
}
2524-
2525-
// Check a mount point needs to be previewed
2526-
$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
2527-
$mountPointInfo = $pageRepository->getMountPointInfo($pageUid);
2528-
2529-
if ($mountPointInfo && $mountPointInfo['overlay']) {
2530-
$pageUid = $mountPointInfo['mount_pid'];
2531-
$additionalGetVars .= '&MP=' . $mountPointInfo['MPvar'];
2532-
}
2533-
$viewDomain = self::getViewDomain($pageUid, $rootLine);
2534-
2535-
return $viewDomain . $viewScript . $pageUid . $additionalGetVars . $anchorSection;
2536-
}
2537-
25382492
/**
25392493
* Builds the frontend view domain for a given page ID with a given root
25402494
* line.
25412495
*
25422496
* @param int $pageId The page ID to use, must be > 0
25432497
* @param array|null $rootLine The root line structure to use
25442498
* @return string The full domain including the protocol http:// or https://, but without the trailing '/'
2499+
* @deprecated since TYPO3 v10.0, will be removed in TYPO3 v11.0. Use PageRouter instead.
25452500
*/
25462501
public static function getViewDomain($pageId, $rootLine = null)
25472502
{
2503+
trigger_error('BackendUtility::getViewDomain() will be removed in TYPO3 v11.0. Use a Site and its PageRouter to link to a page directly', E_USER_DEPRECATED);
25482504
$domain = rtrim(GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), '/');
25492505
if (!is_array($rootLine)) {
25502506
$rootLine = self::BEgetRootLine($pageId);
25512507
}
25522508
// Checks alternate domains
25532509
if (!empty($rootLine)) {
2554-
$protocol = GeneralUtility::getIndpEnv('TYPO3_SSL') ? 'https' : 'http';
2555-
$previewDomainConfig = self::getPagesTSconfig($pageId)['TCEMAIN.']['previewDomain'] ?? '';
2556-
$domainName = null;
2557-
if (!empty($previewDomainConfig)) {
2558-
if (strpos($previewDomainConfig, '://') !== false) {
2559-
list($protocol, $domainName) = explode('://', $previewDomainConfig);
2560-
} else {
2561-
$domainName = $previewDomainConfig;
2510+
try {
2511+
$site = GeneralUtility::makeInstance(SiteFinder::class)
2512+
->getSiteByPageId((int)$pageId, $rootLine);
2513+
$uri = $site->getBase();
2514+
} catch (SiteNotFoundException $e) {
2515+
// Just use the current domain
2516+
$uri = new Uri($domain);
2517+
// Append port number if lockSSLPort is not the standard port 443
2518+
$portNumber = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
2519+
if ($portNumber > 0 && $portNumber !== 443 && $portNumber < 65536 && $uri->getScheme() === 'https') {
2520+
$uri = $uri->withPort((int)$portNumber);
25622521
}
25632522
}
2564-
if ($domainName) {
2565-
$domain = $protocol . '://' . $domainName;
2566-
}
2567-
// Append port number if lockSSLPort is not the standard port 443
2568-
$portNumber = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
2569-
if ($portNumber > 0 && $portNumber !== 443 && $portNumber < 65536 && $protocol === 'https') {
2570-
$domain .= ':' . strval($portNumber);
2571-
}
2523+
return (string)$uri;
25722524
}
25732525
return $domain;
25742526
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace TYPO3\CMS\Core\Routing;
5+
6+
/*
7+
* This file is part of the TYPO3 CMS project.
8+
*
9+
* It is free software; you can redistribute it and/or modify it under
10+
* the terms of the GNU General Public License, either version 2
11+
* of the License, or any later version.
12+
*
13+
* For the full copyright and license information, please read the
14+
* LICENSE.txt file that was distributed with this source code.
15+
*
16+
* The TYPO3 project - inspiring people to share!
17+
*/
18+
19+
/**
20+
* Exception thrown when a link to a page (or page in a specific translation) cannot be built.
21+
*/
22+
class UnableToLinkToPageException extends \TYPO3\CMS\Core\Exception
23+
{
24+
}

typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ The following user TSconfig options have been dropped:
12391239
* `RTE.proc.keepPDIVattribs`
12401240
* `RTE.proc.dontRemoveUnknownTags_db`
12411241
* `options.clearCache.system`
1242+
* `TCEMAIN.previewDomain`
12421243

12431244

12441245
The following TypoScript options have been dropped:
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.. include:: ../../Includes.txt
2+
3+
===================================================
4+
Deprecation: #88499 - BackendUtility::getViewDomain
5+
===================================================
6+
7+
See :issue:`88499`
8+
9+
Description
10+
===========
11+
12+
The static method :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getViewDomain()` has been marked
13+
as deprecated, as it has been superseded by directly using the PageRouter of Site Handling.
14+
15+
Site Handling allows to generate proper frontend preview URLs the same way as TYPO3 Core does in
16+
all other places,by calling the PageRouter of a Site object directly, so the workarounds are not
17+
necessary anymore, making this method obsolete.
18+
19+
20+
Impact
21+
======
22+
23+
Calling :php:`BackendUtility::getViewDomain()` will trigger a deprecation warning.
24+
25+
26+
Affected Installations
27+
======================
28+
29+
Any TYPO3 installations with custom extensions that call this method.
30+
31+
32+
Migration
33+
=========
34+
35+
Substitute the method by directly detecting a site based on a given Page ID in the TYPO3 Backend.
36+
Call the `getRouter()` method on this Site object to create proper links to pages in TYPO3 Frontend.
37+
38+
Example with additional GET parameters:
39+
40+
:php:
41+
42+
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageId);
43+
$url = $site->getRouter()->generateUri($pageId, ['type' => 13]);
44+
45+
.. index:: PHP-API, FullyScanned

typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,4 +917,11 @@
917917
'Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst',
918918
],
919919
],
920+
'TYPO3\CMS\Backend\Utility\BackendUtility::getViewDomain' => [
921+
'numberOfMandatoryArguments' => 1,
922+
'maximumNumberOfArguments' => 2,
923+
'restFiles' => [
924+
'Deprecation-88499-BackendUtilitygetViewDomain.rst',
925+
],
926+
],
920927
];

0 commit comments

Comments
 (0)