[TASK] Change Site Base Handling to PSR-7 URI Interface 70/58070/7
authorBenni Mack <benni@typo3.org>
Wed, 29 Aug 2018 15:17:36 +0000 (17:17 +0200)
committerAndreas Fernandez <a.fernandez@scripting-base.de>
Wed, 29 Aug 2018 20:00:55 +0000 (22:00 +0200)
While working with Site Handling API, it's more than obvious
that we should utilize the UriInterface, to integrate PSR-7
more natively.

The Interface changes, however, as it was only introduced
recently, this should not be an issue.

Resolves: #86027
Releases: master
Change-Id: Id06ccbcf2bbced8408342866d295edc3f11a376a
Reviewed-on: https://review.typo3.org/58070
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
15 files changed:
typo3/sysext/backend/Classes/Form/Element/InputSlugElement.php
typo3/sysext/backend/Tests/Functional/View/PageLayoutViewTest.php
typo3/sysext/core/Classes/Http/Uri.php
typo3/sysext/core/Classes/Routing/PageUriBuilder.php
typo3/sysext/core/Classes/Routing/SiteMatcher.php
typo3/sysext/core/Classes/Site/Entity/NullSite.php
typo3/sysext/core/Classes/Site/Entity/PseudoSite.php
typo3/sysext/core/Classes/Site/Entity/Site.php
typo3/sysext/core/Classes/Site/Entity/SiteLanguage.php
typo3/sysext/core/Tests/Unit/Http/UriTest.php
typo3/sysext/core/Tests/Unit/Site/Entity/PseudoSiteTest.php
typo3/sysext/core/Tests/Unit/Site/Entity/SiteTest.php
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/frontend/Classes/Middleware/SiteResolver.php
typo3/sysext/frontend/Tests/Unit/Middleware/SiteResolverTest.php

index 5d63f18..7cd49b3 100644 (file)
@@ -141,13 +141,11 @@ class InputSlugElement extends AbstractFormElement
     protected function getPrefix(SiteInterface $site, int $requestLanguageId = 0): string
     {
         $language = $site->getLanguageById($requestLanguageId);
-        $baseUrl = $language->getBase();
+        $base = $language->getBase();
+        $baseUrl = (string)$base;
         $baseUrl = rtrim($baseUrl, '/');
-        if (!empty($baseUrl)) {
-            $urlParts = parse_url($baseUrl);
-            if (!isset($urlParts['scheme']) && isset($urlParts['host'])) {
-                $baseUrl = 'http:' . $baseUrl;
-            }
+        if (!empty($baseUrl) && empty($base->getScheme()) && $base->getHost() !== '') {
+            $baseUrl = 'http:' . $baseUrl;
         }
         return $baseUrl;
     }
index 94afeda..d514f9c 100644 (file)
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Backend\Tests\Functional\View;
 
 use TYPO3\CMS\Backend\View\PageLayoutView;
 use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
@@ -42,16 +43,16 @@ class PageLayoutViewTest extends FunctionalTestCase
 
         $this->subject = $this->getAccessibleMock(PageLayoutView::class, ['dummy']);
         $this->subject->_set('siteLanguages', [
-            0 => new SiteLanguage(0, '', '/', [
+            0 => new SiteLanguage(0, '', new Uri('/'), [
                 'title' => 'default',
             ]),
-            1 => new SiteLanguage(1, '', '/', [
+            1 => new SiteLanguage(1, '', new Uri('/'), [
                 'title' => 'german',
             ]),
-            2 => new SiteLanguage(2, '', '/', [
+            2 => new SiteLanguage(2, '', new Uri('/'), [
                 'title' => 'french',
             ]),
-            3 => new SiteLanguage(3, '', '/', [
+            3 => new SiteLanguage(3, '', new Uri('/'), [
                 'title' => 'polish',
             ]),
         ]);
index 30254fe..59774d9 100644 (file)
@@ -610,7 +610,7 @@ class Uri implements UriInterface
     protected function isNonStandardPort($scheme, $host, $port)
     {
         if (empty($scheme)) {
-            return true;
+            return empty($host) || !empty($port);
         }
 
         if (empty($host) || empty($port)) {
index 7b68445..077b9c6 100644 (file)
@@ -100,7 +100,7 @@ class PageUriBuilder implements SingletonInterface
             } else {
                 $pageRecord = BackendUtility::getRecord('pages', $pageId);
             }
-            $prefix = $siteLanguage->getBase();
+            $prefix = (string)$siteLanguage->getBase();
             if (!empty($pageRecord['slug'] ?? '')) {
                 $prefix = rtrim($prefix, '/') . '/' . ltrim($pageRecord['slug'], '/');
             } else {
index 79a743a..b086268 100644 (file)
@@ -190,30 +190,30 @@ class SiteMatcher implements SingletonInterface
         $groupedRoutes = [];
         foreach ($this->finder->getAllSites() as $site) {
             // Add the site as entrypoint
-            $urlParts = parse_url($site->getBase());
+            $uri = $site->getBase();
             $route = new Route(
-                ($urlParts['path'] ?? '/') . '{tail}',
+                ($uri->getPath() ?: '/') . '{tail}',
                 ['site' => $site, 'language' => null, 'tail' => ''],
-                array_filter(['tail' => '.*', 'port' => (string)($urlParts['port'] ?? '')]),
+                array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
                 ['utf8' => true],
-                $urlParts['host'] ?? '',
-                !empty($urlParts['scheme']) ? [$urlParts['scheme']] : null
+                $uri->getHost() ?: '',
+                $uri->getScheme()
             );
             $identifier = 'site_' . $site->getIdentifier();
-            $groupedRoutes[($urlParts['scheme'] ?? '-') . ($urlParts['host'] ?? '-')][$urlParts['path'] ?? '/'][$identifier] = $route;
+            $groupedRoutes[($uri->getScheme() ?: '-') . ($uri->getHost() ?: '-')][$uri->getPath() ?: '/'][$identifier] = $route;
             // Add all languages
             foreach ($site->getAllLanguages() as $siteLanguage) {
-                $urlParts = parse_url($siteLanguage->getBase());
+                $uri = $siteLanguage->getBase();
                 $route = new Route(
-                    ($urlParts['path'] ?? '/') . '{tail}',
+                    ($uri->getPath() ?: '/') . '{tail}',
                     ['site' => $site, 'language' => $siteLanguage, 'tail' => ''],
-                    array_filter(['tail' => '.*', 'port' => (string)($urlParts['port'] ?? '')]),
+                    array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
                     ['utf8' => true],
-                    $urlParts['host'] ?? '',
-                    !empty($urlParts['scheme']) ? [$urlParts['scheme']] : null
+                    $uri->getHost() ?: '',
+                    $uri->getScheme()
                 );
                 $identifier = 'site_' . $site->getIdentifier() . '_' . $siteLanguage->getLanguageId();
-                $groupedRoutes[($urlParts['scheme'] ?? '-') . ($urlParts['host'] ?? '-')][$urlParts['path'] ?? '/'][$identifier] = $route;
+                $groupedRoutes[($uri->getScheme() ?: '-') . ($uri->getHost() ?: '-')][$uri->getPath() ?: '/'][$identifier] = $route;
             }
         }
         return $this->createRouteCollectionFromGroupedRoutes($groupedRoutes);
@@ -234,23 +234,22 @@ class SiteMatcher implements SingletonInterface
             if (!$site instanceof PseudoSite) {
                 continue;
             }
-            foreach ($site->getEntryPoints() as $domainName) {
+            foreach ($site->getEntryPoints() as $uri) {
                 // Site has no sys_domain record, it is not valid for a routing entrypoint, but only available
-                // via "id" GET parameter which is handled before
-                if ($domainName === '/') {
+                // via "id" GET parameter which is handled separately
+                if (!$uri->getHost()) {
                     continue;
                 }
-                $urlParts = parse_url($domainName);
                 $route = new Route(
-                    ($urlParts['path'] ?? '/') . '{tail}',
+                    ($uri->getPath() ?: '/') . '{tail}',
                     ['site' => $site, 'language' => null, 'tail' => ''],
-                    array_filter(['tail' => '.*', 'port' => (string)($urlParts['port'] ?? '')]),
+                    array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
                     ['utf8' => true],
-                    $urlParts['host'] ?? '',
-                    !empty($urlParts['scheme']) ? [$urlParts['scheme']] : null
+                    $uri->getHost(),
+                    $uri->getScheme()
                 );
-                $identifier = 'site_' . $site->getIdentifier() . '_' . $domainName;
-                $groupedRoutes[($urlParts['scheme'] ?? '-') . ($urlParts['host'] ?? '-')][$urlParts['path'] ?? '/'][$identifier] = $route;
+                $identifier = 'site_' . $site->getIdentifier() . '_' . (string)$uri;
+                $groupedRoutes[($uri->getScheme() ?: '-') . ($uri->getHost() ?: '-')][$uri->getPath() ?: '/'][$identifier] = $route;
             }
         }
         return $this->createRouteCollectionFromGroupedRoutes($groupedRoutes);
index 1950153..774ec6c 100644 (file)
@@ -16,9 +16,11 @@ namespace TYPO3\CMS\Core\Site\Entity;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Psr\Http\Message\UriInterface;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
+use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -48,11 +50,10 @@ class NullSite implements SiteInterface
             $languageUid = (int)$languageConfiguration['languageId'];
             // Language configuration does not have a base defined
             // So the main site base is used (usually done for default languages)
-            $base = '/';
             $this->languages[$languageUid] = new SiteLanguage(
                 $languageUid,
                 $languageConfiguration['locale'] ?? '',
-                $base,
+                new Uri('/'),
                 $languageConfiguration
             );
         }
@@ -71,9 +72,9 @@ class NullSite implements SiteInterface
     /**
      * Always "/"
      */
-    public function getBase(): string
+    public function getBase(): UriInterface
     {
-        return '/';
+        return new Uri('/');
     }
 
     /**
index 13b3e79..454f881 100644 (file)
@@ -16,6 +16,9 @@ namespace TYPO3\CMS\Core\Site\Entity;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Psr\Http\Message\UriInterface;
+use TYPO3\CMS\Core\Http\Uri;
+
 /**
  * Entity representing a site with legacy configuration (sys_domain) and all available
  * languages in the system (sys_language)
@@ -48,21 +51,20 @@ class PseudoSite extends NullSite implements SiteInterface
                 continue;
             }
             $this->domainRecords[] = $domain;
-            $this->entryPoints[] = $this->sanitizeBaseUrl($domain['domainName'] ?: '');
+            $this->entryPoints[] = new Uri($this->sanitizeBaseUrl($domain['domainName'] ?: ''));
         }
         if (empty($this->entryPoints)) {
-            $this->entryPoints = ['/'];
+            $this->entryPoints = [new Uri('/')];
         }
         $baseEntryPoint = reset($this->entryPoints);
         foreach ($configuration['languages'] as $languageConfiguration) {
             $languageUid = (int)$languageConfiguration['languageId'];
             // Language configuration does not have a base defined
             // So the main site base is used (usually done for default languages)
-            $base = $this->sanitizeBaseUrl(rtrim($baseEntryPoint, '/') . '/');
             $this->languages[$languageUid] = new SiteLanguage(
                 $languageUid,
                 $languageConfiguration['locale'] ?? '',
-                $base,
+                $baseEntryPoint,
                 $languageConfiguration
             );
         }
@@ -81,15 +83,15 @@ class PseudoSite extends NullSite implements SiteInterface
     /**
      * Returns the first base URL of this site, falls back to "/"
      */
-    public function getBase(): string
+    public function getBase(): UriInterface
     {
-        return $this->entryPoints[0] ?? '/';
+        return $this->entryPoints[0] ?? new Uri('/');
     }
 
     /**
      * Returns the base URLs of this site, if none given, it's always "/"
      *
-     * @return array
+     * @return UriInterface[]
      */
     public function getEntryPoints(): array
     {
index f00df0c..a3f07da 100644 (file)
@@ -16,12 +16,14 @@ namespace TYPO3\CMS\Core\Site\Entity;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Psr\Http\Message\UriInterface;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler;
 use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerNotConfiguredException;
+use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Routing\PageRouter;
 use TYPO3\CMS\Core\Routing\RouterInterface;
@@ -42,7 +44,7 @@ class Site implements SiteInterface
     protected $identifier;
 
     /**
-     * @var string
+     * @var UriInterface
      */
     protected $base;
 
@@ -92,23 +94,21 @@ class Site implements SiteInterface
                 'direction' => '',
             ]
         ];
-        $this->base = $this->sanitizeBaseUrl($configuration['base'] ?? '');
+        $this->base = new Uri($this->sanitizeBaseUrl($configuration['base'] ?? ''));
         foreach ($configuration['languages'] as $languageConfiguration) {
             $languageUid = (int)$languageConfiguration['languageId'];
             // site language has defined its own base, this is the case most of the time.
             if (!empty($languageConfiguration['base'])) {
-                $base = $languageConfiguration['base'];
-                $base = $this->sanitizeBaseUrl($base);
-                $baseParts = parse_url($base);
+                $base = new Uri($this->sanitizeBaseUrl($languageConfiguration['base']));
                 // no host given by the language-specific base, so lets prefix the main site base
-                if (empty($baseParts['scheme']) && empty($baseParts['host'])) {
-                    $base = rtrim($this->base, '/') . '/' . ltrim($base, '/');
-                    $base = $this->sanitizeBaseUrl($base);
+                if ($base->getScheme() === null && $base->getHost() === '') {
+                    $base = rtrim((string)$this->base, '/') . '/' . ltrim((string)$base, '/');
+                    $base = new Uri($this->sanitizeBaseUrl($base));
                 }
             } else {
                 // Language configuration does not have a base defined
                 // So the main site base is used (usually done for default languages)
-                $base = $this->sanitizeBaseUrl(rtrim($this->base, '/') . '/');
+                $base = new Uri($this->sanitizeBaseUrl(rtrim((string)$this->base, '/') . '/'));
             }
             if (!empty($languageConfiguration['flag'])) {
                 if ($languageConfiguration['flag'] === 'global') {
@@ -145,9 +145,9 @@ class Site implements SiteInterface
     /**
      * Returns the base URL of this site
      *
-     * @return string
+     * @return UriInterface
      */
-    public function getBase(): string
+    public function getBase(): UriInterface
     {
         return $this->base;
     }
index 7b5be8a..6c18a4c 100644 (file)
@@ -16,6 +16,8 @@ namespace TYPO3\CMS\Core\Site\Entity;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Psr\Http\Message\UriInterface;
+
 /**
  * Entity representing a site_language configuration of a site object.
  */
@@ -38,7 +40,7 @@ class SiteLanguage
     /**
      * The Base URL for this language
      *
-     * @var string
+     * @var UriInterface
      */
     protected $base;
 
@@ -115,10 +117,10 @@ class SiteLanguage
      *
      * @param int $languageId
      * @param string $locale
-     * @param string $base
+     * @param UriInterface $base
      * @param array $attributes
      */
-    public function __construct(int $languageId, string $locale, string $base, array $attributes)
+    public function __construct(int $languageId, string $locale, UriInterface $base, array $attributes)
     {
         $this->languageId = $languageId;
         $this->locale = $locale;
@@ -167,7 +169,7 @@ class SiteLanguage
         return [
             'languageId' => $this->getLanguageId(),
             'locale' => $this->getLocale(),
-            'base' => $this->getBase(),
+            'base' => (string)$this->getBase(),
             'title' => $this->getTitle(),
             'navigationTitle' => $this->getNavigationTitle(),
             'twoLetterIsoCode' => $this->getTwoLetterIsoCode(),
@@ -198,9 +200,9 @@ class SiteLanguage
     }
 
     /**
-     * @return string
+     * @return UriInterface
      */
-    public function getBase(): string
+    public function getBase(): UriInterface
     {
         return $this->base;
     }
index d90a30c..e196ceb 100644 (file)
@@ -203,6 +203,33 @@ class UriTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     /**
      * @test
      */
+    public function standardPortAndSchemeDoesNotRenderPort()
+    {
+        $subject = new Uri('http://www.example.com:80');
+        $this->assertEquals('http://www.example.com', (string)$subject);
+    }
+
+    /**
+     * @test
+     */
+    public function standardPortAndNoSchemeDoesRenderPort()
+    {
+        $subject = new Uri('www.example.com:80');
+        $this->assertEquals('//www.example.com:80', (string)$subject);
+    }
+
+    /**
+     * @test
+     */
+    public function noPortAndNoSchemeDoesNotRenderPort()
+    {
+        $subject = new Uri('www.example.com');
+        $this->assertEquals('/www.example.com', (string)$subject);
+    }
+
+    /**
+     * @test
+     */
     public function withPathReturnsNewInstanceWithProvidedPath()
     {
         $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
index eb7360c..bea711a 100644 (file)
@@ -16,12 +16,12 @@ namespace TYPO3\CMS\Core\Tests\Unit\Site\Entity;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Site\Entity\PseudoSite;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 class PseudoSiteTest extends UnitTestCase
 {
-
     /**
      * @return array
      */
@@ -30,22 +30,28 @@ class PseudoSiteTest extends UnitTestCase
         return [
             'no domain' => [
                 [],
-                ['/'],
-                '/'
+                [
+                    new Uri('/')
+                ],
+                new Uri('/')
             ],
             'invalid domain argument' => [
                 [
                     ['domain_name' => 'not.recognized.com']
                 ],
-                ['/'],
-                '/'
+                [
+                    new Uri('/')
+                ],
+                new Uri('/')
             ],
             'regular domain given' => [
                 [
                     ['domainName' => 'blog.example.com/download']
                 ],
-                ['//blog.example.com/download'],
-                '//blog.example.com/download'
+                [
+                    new Uri('//blog.example.com/download')
+                ],
+                new Uri('//blog.example.com/download')
             ],
             'multiple domains given' => [
                 [
@@ -54,11 +60,11 @@ class PseudoSiteTest extends UnitTestCase
                     ['domainName' => 'blog.example.com/food-koma'],
                 ],
                 [
-                    '//www.example.com',
-                    '//blog.example.com',
-                    '//blog.example.com/food-koma',
+                    new Uri('//www.example.com'),
+                    new Uri('//blog.example.com'),
+                    new Uri('//blog.example.com/food-koma'),
                 ],
-                '//www.example.com'
+                new Uri('//www.example.com')
             ]
         ];
     }
@@ -70,7 +76,7 @@ class PseudoSiteTest extends UnitTestCase
     public function pseudoSiteReturnsProperEntryPoints($sysDomainRecords, $expectedResolvedEntryPoints, $expectedFirstEntryPoint)
     {
         $subject = new PseudoSite(13, ['domains' => $sysDomainRecords, 'languages' => []]);
-        $this->assertSame($expectedResolvedEntryPoints, $subject->getEntryPoints());
-        $this->assertSame($expectedFirstEntryPoint, $subject->getBase());
+        $this->assertEquals($expectedResolvedEntryPoints, $subject->getEntryPoints());
+        $this->assertEquals($expectedFirstEntryPoint, $subject->getBase());
     }
 }
index cd0916b..3854126 100644 (file)
@@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerNotConfiguredException;
+use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
@@ -55,7 +56,7 @@ class SiteTest extends UnitTestCase
             'base' => $input,
             'languages' => []
         ]);
-        $this->assertEquals($expected, $subject->getBase());
+        $this->assertEquals(new Uri($expected), $subject->getBase());
     }
 
     /**
@@ -119,7 +120,7 @@ class SiteTest extends UnitTestCase
                 ]
             ]
         ]);
-        $this->assertEquals($expected, $subject->getLanguageById(0)->getBase());
+        $this->assertEquals(new Uri($expected), $subject->getLanguageById(0)->getBase());
     }
 
     /**
index d4a504c..9df0947 100644 (file)
@@ -2441,7 +2441,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
     {
         // Ensure the language base is used for the hash base calculation as well, otherwise TypoScript and page-related rendering
         // is not cached properly as we don't have any language-specific conditions anymore
-        $siteBase = $this->getCurrentSiteLanguage() ? $this->getCurrentSiteLanguage()->getBase() : '';
+        $siteBase = $this->getCurrentSiteLanguage() ? (string)$this->getCurrentSiteLanguage()->getBase() : '';
 
         // Fetch the list of user groups
         /** @var UserAspect $userAspect */
index 3679208..85b23c6 100644 (file)
@@ -21,7 +21,6 @@ use Psr\Http\Server\MiddlewareInterface;
 use Psr\Http\Server\RequestHandlerInterface;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Http\RedirectResponse;
-use TYPO3\CMS\Core\Http\Uri;
 use TYPO3\CMS\Core\Routing\SiteMatcher;
 use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
@@ -74,7 +73,7 @@ class SiteResolver implements MiddlewareInterface
         // So a redirect to the first possible language is done.
         if ($site instanceof Site && !($language instanceof SiteLanguage)) {
             $language = $site->getDefaultLanguage();
-            $uri = new Uri($language->getBase());
+            $uri = $language->getBase();
             return new RedirectResponse($uri, 307);
         }
         // language is found, and hidden but also not visible to the BE user, this needs to fail
@@ -94,7 +93,7 @@ class SiteResolver implements MiddlewareInterface
                 return new RedirectResponse($uri, 307);
             }
             // Request was "/fr-FR" but the site is actually called "/fr-FR/", let's do a redirect
-            if ($tail === '' && (string)(new Uri($language->getBase()))->getPath() !== (string)$requestedUri->getPath()) {
+            if ($tail === '' && $language->getBase()->getPath() !== $requestedUri->getPath()) {
                 $uri = $requestedUri->withPath($requestedUri->getPath() . '/');
                 return new RedirectResponse($uri, 307);
             }
index 490515c..8641346 100644 (file)
@@ -70,7 +70,7 @@ class SiteResolverTest extends UnitTestCase
                         [
                             'site' => $site->getIdentifier(),
                             'language-id' => $language->getLanguageId(),
-                            'language-base' => $language->getBase(),
+                            'language-base' => (string)$language->getBase(),
                             'rootpage' => $site->getRootPageId()
                         ]
                     );