7e182f594c7d3e22ee98a0c65f9c7fe35d0defd0
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / PageTitle / PageTitleProviderManager.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Core\PageTitle;
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 TYPO3\CMS\Core\Cache\CacheManager;
20 use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
21 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
22 use TYPO3\CMS\Core\Service\DependencyOrderingService;
23 use TYPO3\CMS\Core\SingletonInterface;
24 use TYPO3\CMS\Core\TypoScript\TypoScriptService;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
27
28 /**
29 * This class will take care of the different providers and returns the title with the highest priority
30 */
31 class PageTitleProviderManager implements SingletonInterface
32 {
33 /**
34 * @var FrontendInterface
35 */
36 protected $pageCache;
37
38 public function __construct()
39 {
40 $this->initCaches();
41 }
42
43 /**
44 * @return string
45 * @throws \TYPO3\CMS\Core\Cache\Exception
46 * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException
47 */
48 public function getTitle(): string
49 {
50 $pageTitle = '';
51
52 $titleProviders = $this->getPageTitleProviderConfiguration();
53 $titleProviders = $this->setProviderOrder($titleProviders);
54
55 $orderedTitleProviders = GeneralUtility::makeInstance(DependencyOrderingService::class)
56 ->orderByDependencies($titleProviders);
57
58 foreach ($orderedTitleProviders as $provider => $configuration) {
59 $cacheIdentifier = $this->getTypoScriptFrontendController()->newHash . '-titleTag-' . $provider;
60 if ($this->pageCache instanceof FrontendInterface &&
61 $pageTitle = $this->pageCache->get($cacheIdentifier)
62 ) {
63 break;
64 }
65 if (class_exists($configuration['provider']) && is_subclass_of($configuration['provider'], PageTitleProviderInterface::class)) {
66 /** @var PageTitleProviderInterface $titleProviderObject */
67 $titleProviderObject = GeneralUtility::makeInstance($configuration['provider']);
68 if ($pageTitle = $titleProviderObject->getTitle()) {
69 $this->pageCache->set(
70 $cacheIdentifier,
71 $pageTitle,
72 ['pageId_' . $this->getTypoScriptFrontendController()->page['uid']],
73 $this->getTypoScriptFrontendController()->get_cache_timeout()
74 );
75 break;
76 }
77 }
78 }
79
80 return $pageTitle;
81 }
82
83 /**
84 * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
85 */
86 private function getTypoScriptFrontendController(): TypoScriptFrontendController
87 {
88 return $GLOBALS['TSFE'];
89 }
90
91 /**
92 * Get the TypoScript configuration for pageTitleProviders
93 * @return array
94 */
95 private function getPageTitleProviderConfiguration(): array
96 {
97 $typoscriptService = GeneralUtility::makeInstance(TypoScriptService::class);
98 $config = $typoscriptService->convertTypoScriptArrayToPlainArray(
99 $this->getTypoScriptFrontendController()->config['config'] ?? []
100 );
101
102 return $config['pageTitleProviders'] ?? [];
103 }
104
105 /**
106 * Initializes the caching system.
107 */
108 protected function initCaches(): void
109 {
110 try {
111 $this->pageCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('pages');
112 } catch (NoSuchCacheException $e) {
113 // Intended fall-through
114 }
115 }
116
117 /**
118 * @param array $orderInformation
119 * @return string[]
120 * @throws \UnexpectedValueException
121 */
122 protected function setProviderOrder(array $orderInformation): array
123 {
124 foreach ($orderInformation as $provider => &$configuration) {
125 if (isset($configuration['before'])) {
126 if (is_string($configuration['before'])) {
127 $configuration['before'] = GeneralUtility::trimExplode(',', $configuration['before'], true);
128 } elseif (!is_array($configuration['before'])) {
129 throw new \UnexpectedValueException(
130 'The specified "before" order configuration for provider "' . $provider . '" is invalid.',
131 1535803185
132 );
133 }
134 }
135 if (isset($configuration['after'])) {
136 if (is_string($configuration['after'])) {
137 $configuration['after'] = GeneralUtility::trimExplode(',', $configuration['after'], true);
138 } elseif (!is_array($configuration['after'])) {
139 throw new \UnexpectedValueException(
140 'The specified "after" order configuration for provider "' . $provider . '" is invalid.',
141 1535803186
142 );
143 }
144 }
145 }
146 return $orderInformation;
147 }
148 }