0d9b06e2e60eef44e8b58be88f99e5f4dac31c5d
[Packages/TYPO3.CMS.git] / typo3 / sysext / seo / Classes / XmlSitemap / RecordsXmlSitemapDataProvider.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Seo\XmlSitemap;
4
5 use Psr\Http\Message\ServerRequestInterface;
6 use TYPO3\CMS\Core\Database\ConnectionPool;
7 use TYPO3\CMS\Core\Utility\GeneralUtility;
8 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
9 use TYPO3\CMS\Seo\XmlSitemap\Exception\MissingConfigurationException;
10
11 /**
12 * XmlSiteDataProvider will provide information for the XML sitemap for a specific database table
13 */
14 class RecordsXmlSitemapDataProvider extends AbstractXmlSitemapDataProvider
15 {
16 /**
17 * @param string $key
18 * @param array $config
19 * @param ContentObjectRenderer|null $cObj
20 * @throws MissingConfigurationException
21 */
22 public function __construct(ServerRequestInterface $request, string $key, array $config = [], ContentObjectRenderer $cObj = null)
23 {
24 parent::__construct($request, $key, $config, $cObj);
25
26 $this->generateItems();
27 }
28
29 /**
30 * @throws MissingConfigurationException
31 */
32 public function generateItems(): void
33 {
34 if (empty($this->config['table'])) {
35 throw new MissingConfigurationException(
36 'No configuration found for sitemap ' . $this->getKey(),
37 1535576053
38 );
39 }
40
41 $pids = GeneralUtility::intExplode(',', $this->config['pid']) ?? $GLOBALS['TSFE']->id;
42 $lastModifiedField = $this->config['lastModifiedField'] ?? 'tstamp';
43 $sortField = $this->config['sortField'] ?? 'sorting';
44
45 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
46 ->getQueryBuilderForTable($this->config['table']);
47
48 $constraints = [
49 $queryBuilder->expr()->in('pid', $pids)
50 ];
51
52 if (!empty($this->config['additionalWhere'])) {
53 $constraints[] = $this->config['additionalWhere'];
54 }
55
56 $rows = $queryBuilder->select('*')
57 ->from($this->config['table'])
58 ->where(
59 ...$constraints
60 )
61 ->orderBy($sortField)
62 ->execute()
63 ->fetchAll();
64
65 foreach ($rows as $row) {
66 $this->items[] = [
67 'loc' => $this->defineUrl($row),
68 'lastMod' => $row[$lastModifiedField]
69 ];
70 }
71 }
72
73 /**
74 * @param array $data
75 * @return string
76 */
77 protected function defineUrl(array $data): string
78 {
79 $pageId = $this->config['url']['pageId'] ?? $GLOBALS['TSFE']->id;
80 $additionalParams = [];
81
82 $additionalParams = $this->getUrlFieldParameterMap($additionalParams, $data);
83 $additionalParams = $this->getUrlAdditionalParams($additionalParams);
84
85 $additionalParamsString = http_build_query(
86 $additionalParams,
87 '',
88 '&',
89 PHP_QUERY_RFC3986
90 );
91
92 $typoLinkConfig = [
93 'parameter' => $pageId,
94 'additionalParams' => $additionalParamsString ? '&' . $additionalParamsString : '',
95 'forceAbsoluteUrl' => 1,
96 'useCacheHash' => $this->config['url']['useCacheHash'] ?? 0
97 ];
98
99 return $this->cObj->typoLink_URL($typoLinkConfig);
100 }
101
102 /**
103 * @param array $additionalParams
104 * @param array $data
105 * @return array
106 */
107 protected function getUrlFieldParameterMap(array $additionalParams, array $data): array
108 {
109 if (!empty($this->config['url']['fieldToParameterMap']) &&
110 \is_array($this->config['url']['fieldToParameterMap'])) {
111 foreach ($this->config['url']['fieldToParameterMap'] as $field => $urlPart) {
112 $additionalParams[$urlPart] = $data[$field];
113 }
114 }
115
116 return $additionalParams;
117 }
118
119 /**
120 * @param array $additionalParams
121 * @return array
122 */
123 protected function getUrlAdditionalParams(array $additionalParams): array
124 {
125 if (!empty($this->config['url']['additionalGetParameters']) &&
126 is_array($this->config['url']['additionalGetParameters'])) {
127 foreach ($this->config['url']['additionalGetParameters'] as $extension => $extensionConfig) {
128 foreach ($extensionConfig as $key => $value) {
129 $additionalParams[$extension . '[' . $key . ']'] = $value;
130 }
131 }
132 }
133
134 return $additionalParams;
135 }
136 }