[BUGFIX] Ensure most site related exceptions are handled
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Typolink / PageLinkBuilder.php
index f440829..a8d7caf 100644 (file)
@@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Exception\Page\RootLineException;
 use TYPO3\CMS\Core\Exception\SiteNotFoundException;
+use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
 use TYPO3\CMS\Core\Routing\RouterInterface;
 use TYPO3\CMS\Core\Routing\SiteMatcher;
 use TYPO3\CMS\Core\Site\Entity\Site;
@@ -44,6 +45,7 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
 {
     /**
      * @inheritdoc
+     * @throws UnableToLinkException
      */
     public function build(array &$linkDetails, string $linkText, string $target, array $conf): array
     {
@@ -332,7 +334,7 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
         $currentSiteLanguage = $this->getCurrentSiteLanguage();
         // Happens when currently on a pseudo-site configuration
         // We assume to use the default language then
-        if (!($currentSiteLanguage instanceof SiteLanguage)) {
+        if ($currentSite && !($currentSiteLanguage instanceof SiteLanguage)) {
             $currentSiteLanguage = $currentSite->getDefaultLanguage();
         }
 
@@ -352,20 +354,26 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
         // Use the config option to override this.
         $useAbsoluteUrl = $conf['forceAbsoluteUrl'] ?? false;
         // Check if the current page equal to the site of the target page, now only set the absolute URL
-        if ($currentSite->getRootPageId() !== $siteOfTargetPage->getRootPageId()) {
-            $useAbsoluteUrl = true;
-        } elseif ($siteLanguageOfTargetPage->getBase()->getHost() !== $currentSiteLanguage->getBase()->getHost()) {
+        // Always generate absolute URLs if no current site is set
+        if (
+            !$currentSite
+            || $currentSite->getRootPageId() !== $siteOfTargetPage->getRootPageId()
+            || $siteLanguageOfTargetPage->getBase()->getHost() !== $currentSiteLanguage->getBase()->getHost()) {
             $useAbsoluteUrl = true;
         }
 
         $targetPageId = (int)($page['l10n_parent'] > 0 ? $page['l10n_parent'] : $page['uid']);
         $queryParameters['_language'] = $siteLanguageOfTargetPage;
-        $uri = $siteOfTargetPage->getRouter()->generateUri(
-            $targetPageId,
-            $queryParameters,
-            $fragment,
-            $useAbsoluteUrl ? RouterInterface::ABSOLUTE_URL : RouterInterface::ABSOLUTE_PATH
-        );
+        try {
+            $uri = $siteOfTargetPage->getRouter()->generateUri(
+                $targetPageId,
+                $queryParameters,
+                $fragment,
+                $useAbsoluteUrl ? RouterInterface::ABSOLUTE_URL : RouterInterface::ABSOLUTE_PATH
+            );
+        } catch (InvalidRouteArgumentsException $e) {
+            throw new UnableToLinkException('The target page could not be linked. Error: ' . $e->getMessage(), 1535472406);
+        }
         // Override scheme, but only if the site does not define a scheme yet AND the site defines a domain/host
         if ($useAbsoluteUrl && !$uri->getScheme() && $uri->getHost()) {
             $scheme = $conf['forceAbsoluteUrl.']['scheme'] ?? 'https';
@@ -780,7 +788,12 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
         }
         if (MathUtility::canBeInterpretedAsInteger($GLOBALS['TSFE']->id) && $GLOBALS['TSFE']->id > 0) {
             $matcher = GeneralUtility::makeInstance(SiteMatcher::class);
-            return $matcher->matchByPageId((int)$GLOBALS['TSFE']->id);
+            try {
+                $site = $matcher->matchByPageId((int)$GLOBALS['TSFE']->id);
+            } catch (SiteNotFoundException $e) {
+                $site = null;
+            }
+            return $site;
         }
         return null;
     }