Skip to content

Commit

Permalink
[!!!][TASK] Remove TCEMAIN.previewDomain
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bmack committed Jun 25, 2019
1 parent 7c4a63b commit 8028f2f
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 204 deletions.
67 changes: 38 additions & 29 deletions typo3/sysext/backend/Classes/Controller/EditDocumentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
use TYPO3\CMS\Core\Site\Entity\NullSite;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
Expand Down Expand Up @@ -775,9 +776,10 @@ protected function generatePreviewCode(): string
$previewPageId = $this->getPreviewPageId();
$previewPageRootLine = BackendUtility::BEgetRootLine($previewPageId);
$anchorSection = $this->getPreviewUrlAnchorSection();
$previewUrlParameters = $this->getPreviewUrlParameters($previewPageId);

return '
try {
$previewUrlParameters = $this->getPreviewUrlParameters($previewPageId);
return '
if (window.opener) {
'
. BackendUtility::viewOnClick(
Expand All @@ -789,7 +791,7 @@ protected function generatePreviewCode(): string
$previewUrlParameters,
false
)
. '
. '
} else {
'
. BackendUtility::viewOnClick(
Expand All @@ -800,8 +802,11 @@ protected function generatePreviewCode(): string
$this->viewUrl,
$previewUrlParameters
)
. '
. '
}';
} catch (UnableToLinkToPageException $e) {
return '';
}
}

/**
Expand Down Expand Up @@ -1406,35 +1411,39 @@ protected function registerViewButtonToButtonBar(ButtonBar $buttonBar, string $p
|| isset($pagesTSconfig['TCEMAIN.']['preview.'][$this->firstEl['table'] . '.']['previewPageId'])
) {
$previewPageId = $this->getPreviewPageId();
$previewUrl = BackendUtility::getPreviewUrl(
$previewPageId,
'',
BackendUtility::BEgetRootLine($previewPageId),
$this->getPreviewUrlAnchorSection(),
$this->viewUrl,
$this->getPreviewUrlParameters($previewPageId)
);
try {
$previewUrl = BackendUtility::getPreviewUrl(
$previewPageId,
'',
BackendUtility::BEgetRootLine($previewPageId),
$this->getPreviewUrlAnchorSection(),
$this->viewUrl,
$this->getPreviewUrlParameters($previewPageId)
);

$viewButton = $buttonBar->makeLinkButton()
->setHref($previewUrl)
->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
'actions-view',
Icon::SIZE_SMALL
))
->setShowLabelText(true)
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.viewDoc'));

if (!$this->isSavedRecord) {
if ($this->firstEl['table'] === 'pages') {
$viewButton->setDataAttributes(['is-new' => '']);
}
}

$viewButton = $buttonBar->makeLinkButton()
->setHref($previewUrl)
->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
'actions-view',
Icon::SIZE_SMALL
))
->setShowLabelText(true)
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.viewDoc'));

if (!$this->isSavedRecord) {
if ($this->firstEl['table'] === 'pages') {
$viewButton->setDataAttributes(['is-new' => '']);
if ($classNames !== '') {
$viewButton->setClasses($classNames);
}
}

if ($classNames !== '') {
$viewButton->setClasses($classNames);
$buttonBar->addButton($viewButton, $position, $group);
} catch (UnableToLinkToPageException $e) {
// Do not add any button
}

$buttonBar->addButton($viewButton, $position, $group);
}
}
}
Expand Down
132 changes: 42 additions & 90 deletions typo3/sysext/backend/Classes/Utility/BackendUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\RelationHandler;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
Expand All @@ -39,6 +40,7 @@
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
use TYPO3\CMS\Core\Routing\RouterInterface;
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
Expand Down Expand Up @@ -2306,15 +2308,19 @@ public static function viewOnClick(
$additionalGetVars = '',
$switchFocus = true
) {
$previewUrl = self::getPreviewUrl(
$pageUid,
$backPath,
$rootLine,
$anchorSection,
$alternativeUrl,
$additionalGetVars,
$switchFocus
);
try {
$previewUrl = self::getPreviewUrl(
$pageUid,
$backPath,
$rootLine,
$anchorSection,
$alternativeUrl,
$additionalGetVars,
$switchFocus
);
} catch (UnableToLinkToPageException $e) {
return '';
}

$onclickCode = 'var previewWin = window.open(' . GeneralUtility::quoteJSvalue($previewUrl) . ',\'newTYPO3frontendWindow\');'
. ($switchFocus ? 'previewWin.focus();' : '') . LF
Expand Down Expand Up @@ -2380,21 +2386,25 @@ public static function getPreviewUrl(
$rootLine = $rootLine ?? BackendUtility::BEgetRootLine($pageUid);
try {
$site = $siteFinder->getSiteByPageId((int)$pageUid, $rootLine);
// Create a multi-dimensional array out of the additional get vars
$additionalQueryParams = [];
parse_str($additionalGetVars, $additionalQueryParams);
if (isset($additionalQueryParams['L'])) {
$additionalQueryParams['_language'] = $additionalQueryParams['_language'] ?? $additionalQueryParams['L'];
unset($additionalQueryParams['L']);
}
} catch (SiteNotFoundException $e) {
throw new UnableToLinkToPageException('The page ' . $pageUid . ' had no proper connection to a site, no link could be built.', 1559794919);
}
// Create a multi-dimensional array out of the additional get vars
$additionalQueryParams = [];
parse_str($additionalGetVars, $additionalQueryParams);
if (isset($additionalQueryParams['L'])) {
$additionalQueryParams['_language'] = $additionalQueryParams['_language'] ?? $additionalQueryParams['L'];
unset($additionalQueryParams['L']);
}
try {
$previewUrl = (string)$site->getRouter()->generateUri(
$pageUid,
$additionalQueryParams,
$anchorSection,
RouterInterface::ABSOLUTE_URL
);
} catch (SiteNotFoundException | \InvalidArgumentException | InvalidRouteArgumentsException $e) {
$previewUrl = self::createPreviewUrl($pageUid, $rootLine, $anchorSection, $additionalGetVars, $viewScript);
} catch (\InvalidArgumentException | InvalidRouteArgumentsException $e) {
throw new UnableToLinkToPageException('The page ' . $pageUid . ' had no proper connection to a site, no link could be built.', 1559794914);
}
}

Expand Down Expand Up @@ -2479,96 +2489,38 @@ public static function getLinkToDataHandlerAction($parameters, $redirectUrl = ''
return $url;
}

/**
* Creates the view-on-click preview URL without any alternative URL.
*
* @param int $pageUid Page UID
* @param array $rootLine If rootline is supplied, the function will look for the first found domain record and use that URL instead
* @param string $anchorSection Optional anchor to the URL
* @param string $additionalGetVars Additional GET variables.
* @param string $viewScript The path to the script used to view the page
*
* @return string The preview URL
*/
protected static function createPreviewUrl($pageUid, $rootLine, $anchorSection, $additionalGetVars, $viewScript)
{
// Look if a fixed preview language should be added:
$beUser = static::getBackendUserAuthentication();
$viewLanguageOrder = (string)($beUser->getTSConfig()['options.']['view.']['languageOrder'] ?? '');

if (!empty($viewLanguageOrder)) {
$suffix = '';
// Find allowed languages (if none, all are allowed!)
$allowedLanguages = null;
if (!$beUser->isAdmin() && $beUser->groupData['allowed_languages'] !== '') {
$allowedLanguages = array_flip(explode(',', $beUser->groupData['allowed_languages']));
}
// Traverse the view order, match first occurrence:
$languageOrder = GeneralUtility::intExplode(',', $viewLanguageOrder);
foreach ($languageOrder as $langUid) {
if (is_array($allowedLanguages) && !empty($allowedLanguages)) {
// Choose if set.
if (isset($allowedLanguages[$langUid])) {
$suffix = '&L=' . $langUid;
break;
}
} else {
// All allowed since no lang. are listed.
$suffix = '&L=' . $langUid;
break;
}
}
// Add it
$additionalGetVars .= $suffix;
}

// Check a mount point needs to be previewed
$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
$mountPointInfo = $pageRepository->getMountPointInfo($pageUid);

if ($mountPointInfo && $mountPointInfo['overlay']) {
$pageUid = $mountPointInfo['mount_pid'];
$additionalGetVars .= '&MP=' . $mountPointInfo['MPvar'];
}
$viewDomain = self::getViewDomain($pageUid, $rootLine);

return $viewDomain . $viewScript . $pageUid . $additionalGetVars . $anchorSection;
}

/**
* Builds the frontend view domain for a given page ID with a given root
* line.
*
* @param int $pageId The page ID to use, must be > 0
* @param array|null $rootLine The root line structure to use
* @return string The full domain including the protocol http:// or https://, but without the trailing '/'
* @deprecated since TYPO3 v10.0, will be removed in TYPO3 v11.0. Use PageRouter instead.
*/
public static function getViewDomain($pageId, $rootLine = null)
{
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);
$domain = rtrim(GeneralUtility::getIndpEnv('TYPO3_SITE_URL'), '/');
if (!is_array($rootLine)) {
$rootLine = self::BEgetRootLine($pageId);
}
// Checks alternate domains
if (!empty($rootLine)) {
$protocol = GeneralUtility::getIndpEnv('TYPO3_SSL') ? 'https' : 'http';
$previewDomainConfig = self::getPagesTSconfig($pageId)['TCEMAIN.']['previewDomain'] ?? '';
$domainName = null;
if (!empty($previewDomainConfig)) {
if (strpos($previewDomainConfig, '://') !== false) {
list($protocol, $domainName) = explode('://', $previewDomainConfig);
} else {
$domainName = $previewDomainConfig;
try {
$site = GeneralUtility::makeInstance(SiteFinder::class)
->getSiteByPageId((int)$pageId, $rootLine);
$uri = $site->getBase();
} catch (SiteNotFoundException $e) {
// Just use the current domain
$uri = new Uri($domain);
// Append port number if lockSSLPort is not the standard port 443
$portNumber = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
if ($portNumber > 0 && $portNumber !== 443 && $portNumber < 65536 && $uri->getScheme() === 'https') {
$uri = $uri->withPort((int)$portNumber);
}
}
if ($domainName) {
$domain = $protocol . '://' . $domainName;
}
// Append port number if lockSSLPort is not the standard port 443
$portNumber = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
if ($portNumber > 0 && $portNumber !== 443 && $portNumber < 65536 && $protocol === 'https') {
$domain .= ':' . strval($portNumber);
}
return (string)$uri;
}
return $domain;
}
Expand Down
24 changes: 24 additions & 0 deletions typo3/sysext/core/Classes/Routing/UnableToLinkToPageException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
declare(strict_types = 1);

namespace TYPO3\CMS\Core\Routing;

/*
* 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!
*/

/**
* Exception thrown when a link to a page (or page in a specific translation) cannot be built.
*/
class UnableToLinkToPageException extends \TYPO3\CMS\Core\Exception
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ The following user TSconfig options have been dropped:
* `RTE.proc.keepPDIVattribs`
* `RTE.proc.dontRemoveUnknownTags_db`
* `options.clearCache.system`
* `TCEMAIN.previewDomain`


The following TypoScript options have been dropped:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.. include:: ../../Includes.txt

===================================================
Deprecation: #88499 - BackendUtility::getViewDomain
===================================================

See :issue:`88499`

Description
===========

The static method :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getViewDomain()` has been marked
as deprecated, as it has been superseded by directly using the PageRouter of Site Handling.

Site Handling allows to generate proper frontend preview URLs the same way as TYPO3 Core does in
all other places,by calling the PageRouter of a Site object directly, so the workarounds are not
necessary anymore, making this method obsolete.


Impact
======

Calling :php:`BackendUtility::getViewDomain()` will trigger a deprecation warning.


Affected Installations
======================

Any TYPO3 installations with custom extensions that call this method.


Migration
=========

Substitute the method by directly detecting a site based on a given Page ID in the TYPO3 Backend.
Call the `getRouter()` method on this Site object to create proper links to pages in TYPO3 Frontend.

Example with additional GET parameters:

:php:

$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageId);
$url = $site->getRouter()->generateUri($pageId, ['type' => 13]);

.. index:: PHP-API, FullyScanned
Original file line number Diff line number Diff line change
Expand Up @@ -917,4 +917,11 @@
'Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst',
],
],
'TYPO3\CMS\Backend\Utility\BackendUtility::getViewDomain' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 2,
'restFiles' => [
'Deprecation-88499-BackendUtilitygetViewDomain.rst',
],
],
];
Loading

0 comments on commit 8028f2f

Please sign in to comment.