[BUGFIX] Only show records from current language in XML Sitemap 29/60629/2
authorRichard Haeser <richard@maxserv.com>
Mon, 29 Apr 2019 20:51:30 +0000 (22:51 +0200)
committerRichard Haeser <richard@maxserv.com>
Tue, 30 Apr 2019 12:25:57 +0000 (14:25 +0200)
When generating the XML sitemap for records, the language of the
records will be checked. Only records from the current language or
all languages are added to the XML sitemap.

Resolves: #87912
Resolves: #87841
Releases: master, 9.5
Change-Id: Ibc2bc847840ff7ae6d34aa0b0b40fbe163ce2b78
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60629
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Soren Malling <soren@meteko.dk>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Richard Haeser <richard@maxserv.com>
Reviewed-by: Riny van Tiggelen <info@online-gamer.nl>
Reviewed-by: Soren Malling <soren@meteko.dk>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Richard Haeser <richard@maxserv.com>
typo3/sysext/seo/Classes/XmlSitemap/RecordsXmlSitemapDataProvider.php
typo3/sysext/seo/Tests/Functional/Fixtures/pages-sitemap.xml
typo3/sysext/seo/Tests/Functional/Fixtures/sys_category.xml
typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapRecordsTest.php

index d192dba..06d2845 100644 (file)
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Seo\XmlSitemap;
  */
 
 use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
@@ -47,7 +48,9 @@ class RecordsXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
      */
     public function generateItems(): void
     {
-        if (empty($this->config['table'])) {
+        $table = $this->config['table'];
+
+        if (empty($table)) {
             throw new MissingConfigurationException(
                 'No configuration found for sitemap ' . $this->getKey(),
                 1535576053
@@ -62,9 +65,18 @@ class RecordsXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
         $priorityField = $this->config['priorityField'] ?? '';
 
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-            ->getQueryBuilderForTable($this->config['table']);
+            ->getQueryBuilderForTable($table);
 
         $constraints = [];
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['languageField'])) {
+            $constraints[] = $queryBuilder->expr()->in(
+                $GLOBALS['TCA'][$table]['ctrl']['languageField'],
+                [
+                    -1, // All languages
+                    $this->getLanguageId()  // Current language
+                ]
+            );
+        }
 
         if (!empty($pids)) {
             $recursiveLevel = isset($this->config['recursive']) ? (int)$this->config['recursive'] : 0;
@@ -87,7 +99,7 @@ class RecordsXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
         }
 
         $queryBuilder->select('*')
-            ->from($this->config['table']);
+            ->from($table);
 
         if (!empty($constraints)) {
             $queryBuilder->where(
@@ -177,4 +189,14 @@ class RecordsXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
 
         return $additionalParams;
     }
+
+    /**
+     * @return int
+     * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
+     */
+    protected function getLanguageId(): int
+    {
+        $context = GeneralUtility::makeInstance(Context::class);
+        return (int)$context->getPropertyFromAspect('language', 'id');
+    }
 }
index a9a6023..4295cbc 100644 (file)
         <slug>/clean</slug>
         <deleted>0</deleted>
     </pages>
+    <pages>
+        <uid>100</uid>
+        <pid>0</pid>
+        <title>Root FR</title>
+        <is_siteroot>1</is_siteroot>
+        <slug>/</slug>
+        <deleted>0</deleted>
+        <sys_language_uid>1</sys_language_uid>
+        <l10n_parent>1</l10n_parent>
+    </pages>
 </dataset>
index 6437edf..e58a0ff 100644 (file)
@@ -11,6 +11,7 @@
                <endtime>0</endtime>
                <sorting>256</sorting>
                <title>Examples</title>
+               <sys_language_uid>0</sys_language_uid>
        </sys_category>
        <sys_category>
                <uid>2</uid>
                <endtime>0</endtime>
                <sorting>128</sorting>
                <title>News</title>
+               <sys_language_uid>0</sys_language_uid>
+       </sys_category>
+       <sys_category>
+               <uid>3</uid>
+               <pid>11</pid>
+               <tstamp>1556568228</tstamp>
+               <crdate>1556568228</crdate>
+               <deleted>0</deleted>
+               <hidden>0</hidden>
+               <starttime>0</starttime>
+               <endtime>0</endtime>
+               <sorting>64</sorting>
+               <title>Alternative language</title>
+               <sys_language_uid>1</sys_language_uid>
        </sys_category>
 </data>
index 1504a09..129d57a 100644 (file)
@@ -50,25 +50,26 @@ class XmlSitemapRecordsTest extends AbstractTestCase
                 ],
             ]
         );
-    }
 
-    /**
-     * @test
-     */
-    public function checkIfSiteMapIndexContainsSysCategoryLinks(): void
-    {
         $this->writeSiteConfiguration(
             'website-local',
             $this->buildSiteConfiguration(1, 'http://localhost/'),
             [
                 $this->buildDefaultLanguageConfiguration('EN', '/'),
+                $this->buildLanguageConfiguration('FR', '/fr'),
             ]
         );
+    }
 
+    /**
+     * @test
+     * @dataProvider sitemapEntriesToCheck
+     */
+    public function checkIfSiteMapIndexContainsSysCategoryLinks($host, $expectedEntries, $notExpectedEntries): void
+    {
         $response = $this->executeFrontendRequest(
-            (new InternalRequest('http://localhost/'))->withQueryParameters(
+            (new InternalRequest($host))->withQueryParameters(
                 [
-                    'id' => 1,
                     'type' => 1533906435,
                     'sitemap' => 'records',
                 ]
@@ -80,26 +81,57 @@ class XmlSitemapRecordsTest extends AbstractTestCase
         $stream = $response->getBody();
         $stream->rewind();
         $content = $stream->getContents();
-        self::assertContains('http://localhost/?tx_example_category%5Bid%5D=1&amp;', $content);
-        self::assertContains('http://localhost/?tx_example_category%5Bid%5D=2&amp;', $content);
-        self::assertContains('<priority>0.5</priority>', $content);
+
+        foreach ($expectedEntries as $expectedEntry) {
+            self::assertContains($expectedEntry, $content);
+        }
+
+        foreach ($notExpectedEntries as $notExpectedEntry) {
+            self::assertNotContains($notExpectedEntry, $content);
+        }
 
         $this->assertGreaterThan(0, $response->getHeader('Content-Length')[0]);
     }
 
+    /**
+     * @return array
+     */
+    public function sitemapEntriesToCheck(): array
+    {
+        return [
+            'default-language' => [
+                'http://localhost/',
+                [
+                    'http://localhost/?tx_example_category%5Bid%5D=1&amp;',
+                    'http://localhost/?tx_example_category%5Bid%5D=2&amp;',
+                    '<priority>0.5</priority>'
+                ],
+                [
+                    'http://localhost/?tx_example_category%5Bid%5D=3&amp;',
+                    'http://localhost/fr/?tx_example_category%5Bid%5D=3&amp;',
+                ]
+            ],
+            'french-language' => [
+                'http://localhost/fr',
+                [
+                    'http://localhost/fr/?tx_example_category%5Bid%5D=3&amp;',
+                    '<priority>0.5</priority>'
+                ],
+                [
+                    'http://localhost/fr/?tx_example_category%5Bid%5D=1&amp;',
+                    'http://localhost/fr/?tx_example_category%5Bid%5D=2&amp;',
+                    'http://localhost/?tx_example_category%5Bid%5D=1&amp;',
+                    'http://localhost/?tx_example_category%5Bid%5D=2&amp;',
+                ]
+            ],
+        ];
+    }
+
     /**
      * @test
      */
     public function checkIfSiteMapIndexContainsCustomChangeFreqAndPriorityValues(): void
     {
-        $this->writeSiteConfiguration(
-            'website-local',
-            $this->buildSiteConfiguration(1, 'http://localhost/'),
-            [
-                $this->buildDefaultLanguageConfiguration('EN', '/'),
-            ]
-        );
-
         $response = $this->executeFrontendRequest(
             (new InternalRequest('http://localhost/'))->withQueryParameters(
                 [