[BUGFIX] Only show pages of current language in XML sitemap
[Packages/TYPO3.CMS.git] / typo3 / sysext / seo / Classes / XmlSitemap / PagesXmlSitemapDataProvider.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Seo\XmlSitemap;
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 use Psr\Http\Message\ServerRequestInterface;
20 use TYPO3\CMS\Core\Context\Context;
21 use TYPO3\CMS\Core\Context\LanguageAspect;
22 use TYPO3\CMS\Core\Database\ConnectionPool;
23 use TYPO3\CMS\Core\Database\Query\QueryHelper;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
26 use TYPO3\CMS\Frontend\Page\PageRepository;
27
28 /**
29 * Class to generate a XML sitemap for pages
30 * @internal this class is not part of TYPO3's Core API.
31 */
32 class PagesXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
33 {
34 public function __construct(ServerRequestInterface $request, string $key, array $config = [], ContentObjectRenderer $cObj = null)
35 {
36 parent::__construct($request, $key, $config, $cObj);
37
38 $this->generateItems($this->request);
39 }
40
41 /**
42 * @param ServerRequestInterface $request
43 * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
44 */
45 public function generateItems(ServerRequestInterface $request): void
46 {
47 $languageId = $this->getCurrentLanguageAspect()->getId();
48 foreach ($this->getPages() as $page) {
49 /**
50 * @todo Checking if the page has to be shown/hidden should normally be handled by the
51 * PageRepository but to prevent major breaking changes this is checked here for now
52 */
53 if (
54 !(
55 GeneralUtility::hideIfDefaultLanguage($page['l18n_cfg'])
56 && (!$languageId || ($languageId && !$page['_PAGES_OVERLAY']))
57 )
58 &&
59 !(
60 $languageId
61 && GeneralUtility::hideIfNotTranslated($page['l18n_cfg'])
62 && !$page['_PAGES_OVERLAY']
63 )
64 ) {
65 $lastMod = $page['SYS_LASTCHANGED'] ?: $page['tstamp'];
66
67 $this->items[] = [
68 'uid' => $page['uid'],
69 'lastMod' => (int)$lastMod
70 ];
71 }
72 }
73 }
74
75 /**
76 * @return array
77 */
78 protected function getPages(): array
79 {
80 if (!empty($this->config['rootPage'])) {
81 $rootPageId = (int)$this->config['rootPage'];
82 } else {
83 $site = $this->request->getAttribute('site');
84 $rootPageId = $site->getRootPageId();
85 }
86
87 $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
88 $treeList = $cObj->getTreeList(-$rootPageId, 99);
89 $treeListArray = GeneralUtility::intExplode(',', $treeList);
90
91 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
92 ->getQueryBuilderForTable('pages');
93
94 $constraints = [
95 $queryBuilder->expr()->in('uid', $treeListArray)
96 ];
97
98 if (!empty($this->config['additionalWhere'])) {
99 $constraints[] = QueryHelper::stripLogicalOperatorPrefix($this->config['additionalWhere']);
100 }
101
102 if (!empty($this->config['excludedDoktypes'])) {
103 $excludedDoktypes = GeneralUtility::intExplode(',', $this->config['excludedDoktypes']);
104 if (!empty($excludedDoktypes)) {
105 $constraints[] = $queryBuilder->expr()->notIn('doktype', implode(',', $excludedDoktypes));
106 }
107 }
108 $pages = $queryBuilder->select('*')
109 ->from('pages')
110 ->where(...$constraints)
111 ->orderBy('uid', 'ASC')
112 ->execute()
113 ->fetchAll();
114
115 $pageRepository = GeneralUtility::makeInstance(PageRepository::class);
116 return $pageRepository->getPagesOverlay($pages);
117 }
118
119 /**
120 * @return LanguageAspect
121 * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
122 */
123 protected function getCurrentLanguageAspect(): LanguageAspect
124 {
125 return GeneralUtility::makeInstance(Context::class)->getAspect('language');
126 }
127
128 /**
129 * @param array $data
130 * @return array
131 */
132 protected function defineUrl(array $data): array
133 {
134 $typoLinkConfig = [
135 'parameter' => $data['uid'],
136 'forceAbsoluteUrl' => 1,
137 ];
138
139 $data['loc'] = $this->cObj->typoLink_URL($typoLinkConfig);
140
141 return $data;
142 }
143 }