[TASK] Streamline phpdoc annotations in EXT:extbase
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Configuration / BackendConfigurationManager.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Configuration;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Database\ConnectionPool;
18 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
19 use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
20 use TYPO3\CMS\Core\Database\QueryGenerator;
21 use TYPO3\CMS\Core\Type\Bitmask\Permission;
22 use TYPO3\CMS\Core\TypoScript\TemplateService;
23 use TYPO3\CMS\Core\Utility\ArrayUtility;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Core\Utility\RootlineUtility;
26 use TYPO3\CMS\Extbase\Mvc\Web\BackendRequestHandler;
27 use TYPO3\CMS\Extbase\Mvc\Web\FrontendRequestHandler;
28
29 /**
30 * A general purpose configuration manager used in backend mode.
31 * @internal only to be used within Extbase, not part of TYPO3 Core API.
32 */
33 class BackendConfigurationManager extends AbstractConfigurationManager
34 {
35 /**
36 * @var array
37 */
38 protected $typoScriptSetupCache = [];
39
40 /**
41 * stores the current page ID
42 * @var int
43 */
44 protected $currentPageId;
45
46 /**
47 * Returns TypoScript Setup array from current Environment.
48 *
49 * @return array the raw TypoScript setup
50 */
51 public function getTypoScriptSetup()
52 {
53 $pageId = $this->getCurrentPageId();
54
55 if (!array_key_exists($pageId, $this->typoScriptSetupCache)) {
56 /** @var TemplateService $template */
57 $template = GeneralUtility::makeInstance(TemplateService::class);
58 // do not log time-performance information
59 $template->tt_track = false;
60 // Explicitly trigger processing of extension static files
61 $template->setProcessExtensionStatics(true);
62 // Get the root line
63 $rootline = [];
64 if ($pageId > 0) {
65 try {
66 $rootline = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get();
67 } catch (\RuntimeException $e) {
68 $rootline = [];
69 }
70 }
71 // This generates the constants/config + hierarchy info for the template.
72 $template->runThroughTemplates($rootline, 0);
73 $template->generateConfig();
74 $this->typoScriptSetupCache[$pageId] = $template->setup;
75 }
76 return $this->typoScriptSetupCache[$pageId];
77 }
78
79 /**
80 * Returns the TypoScript configuration found in module.tx_yourextension_yourmodule
81 * merged with the global configuration of your extension from module.tx_yourextension
82 *
83 * @param string $extensionName
84 * @param string $pluginName in BE mode this is actually the module signature. But we're using it just like the plugin name in FE
85 * @return array
86 */
87 protected function getPluginConfiguration($extensionName, $pluginName = null)
88 {
89 $setup = $this->getTypoScriptSetup();
90 $pluginConfiguration = [];
91 if (is_array($setup['module.']['tx_' . strtolower($extensionName) . '.'] ?? false)) {
92 $pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['module.']['tx_' . strtolower($extensionName) . '.']);
93 }
94 if ($pluginName !== null) {
95 $pluginSignature = strtolower($extensionName . '_' . $pluginName);
96 if (is_array($setup['module.']['tx_' . $pluginSignature . '.'] ?? false)) {
97 $overruleConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['module.']['tx_' . $pluginSignature . '.']);
98 ArrayUtility::mergeRecursiveWithOverrule($pluginConfiguration, $overruleConfiguration);
99 }
100 }
101 return $pluginConfiguration;
102 }
103
104 /**
105 * Returns the configured controller/action pairs of the specified module in the format
106 * array(
107 * 'Controller1' => array('action1', 'action2'),
108 * 'Controller2' => array('action3', 'action4')
109 * )
110 *
111 * @param string $extensionName
112 * @param string $pluginName in BE mode this is actually the module signature. But we're using it just like the plugin name in FE
113 * @return array
114 */
115 protected function getSwitchableControllerActions($extensionName, $pluginName)
116 {
117 $switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$pluginName]['controllers'] ?? false;
118 if (!is_array($switchableControllerActions)) {
119 $switchableControllerActions = [];
120 }
121 return $switchableControllerActions;
122 }
123
124 /**
125 * Returns the page uid of the current page.
126 * If no page is selected, we'll return the uid of the first root page.
127 *
128 * @return int current page id. If no page is selected current root page id is returned
129 */
130 protected function getCurrentPageId()
131 {
132 if ($this->currentPageId !== null) {
133 return $this->currentPageId;
134 }
135
136 $this->currentPageId = $this->getCurrentPageIdFromGetPostData() ?: $this->getCurrentPageIdFromCurrentSiteRoot();
137 $this->currentPageId = $this->currentPageId ?: $this->getCurrentPageIdFromRootTemplate();
138 $this->currentPageId = $this->currentPageId ?: self::DEFAULT_BACKEND_STORAGE_PID;
139
140 return $this->currentPageId;
141 }
142
143 /**
144 * Gets the current page ID from the GET/POST data.
145 *
146 * @return int the page UID, will be 0 if none has been set
147 */
148 protected function getCurrentPageIdFromGetPostData()
149 {
150 return (int)GeneralUtility::_GP('id');
151 }
152
153 /**
154 * Gets the current page ID from the first site root in tree.
155 *
156 * @return int the page UID, will be 0 if none has been set
157 */
158 protected function getCurrentPageIdFromCurrentSiteRoot()
159 {
160 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
161 ->getQueryBuilderForTable('pages');
162
163 $queryBuilder
164 ->getRestrictions()
165 ->removeAll()
166 ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
167 ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
168
169 $rootPage = $queryBuilder
170 ->select('uid')
171 ->from('pages')
172 ->where(
173 $queryBuilder->expr()->eq('is_siteroot', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
174 )
175 ->orderBy('sorting')
176 ->execute()
177 ->fetch();
178
179 if (empty($rootPage)) {
180 return 0;
181 }
182
183 return (int)$rootPage['uid'];
184 }
185
186 /**
187 * Gets the current page ID from the first created root template.
188 *
189 * @return int the page UID, will be 0 if none has been set
190 */
191 protected function getCurrentPageIdFromRootTemplate()
192 {
193 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
194 ->getQueryBuilderForTable('sys_template');
195
196 $queryBuilder
197 ->getRestrictions()
198 ->removeAll()
199 ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
200 ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
201
202 $rootTemplate = $queryBuilder
203 ->select('pid')
204 ->from('sys_template')
205 ->where(
206 $queryBuilder->expr()->eq('root', $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT))
207 )
208 ->orderBy('crdate')
209 ->execute()
210 ->fetch();
211
212 if (empty($rootTemplate)) {
213 return 0;
214 }
215
216 return (int)$rootTemplate['pid'];
217 }
218
219 /**
220 * Returns the default backend storage pid
221 *
222 * @return string
223 */
224 public function getDefaultBackendStoragePid()
225 {
226 return $this->getCurrentPageId();
227 }
228
229 /**
230 * We need to set some default request handler if the framework configuration
231 * could not be loaded; to make sure Extbase also works in Backend modules
232 * in all contexts.
233 *
234 * @param array $frameworkConfiguration
235 * @return array
236 */
237 protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration)
238 {
239 if (!isset($frameworkConfiguration['mvc']['requestHandlers'])) {
240 $frameworkConfiguration['mvc']['requestHandlers'] = [
241 FrontendRequestHandler::class => FrontendRequestHandler::class,
242 BackendRequestHandler::class => BackendRequestHandler::class
243 ];
244 }
245 return $frameworkConfiguration;
246 }
247
248 /**
249 * Returns a comma separated list of storagePid that are below a certain storage pid.
250 *
251 * @param string $storagePid Storage PID to start at; multiple PIDs possible as comma-separated list
252 * @param int $recursionDepth Maximum number of levels to search, 0 to disable recursive lookup
253 * @return string storage PIDs
254 */
255 protected function getRecursiveStoragePids($storagePid, $recursionDepth = 0)
256 {
257 if ($recursionDepth <= 0) {
258 return $storagePid;
259 }
260
261 $recursiveStoragePids = '';
262 $storagePids = GeneralUtility::intExplode(',', $storagePid);
263 $permsClause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
264 $queryGenerator = GeneralUtility::makeInstance(QueryGenerator::class);
265 foreach ($storagePids as $startPid) {
266 $pids = $queryGenerator->getTreeList($startPid, $recursionDepth, 0, $permsClause);
267 if ((string)$pids !== '') {
268 $recursiveStoragePids .= $pids . ',';
269 }
270 }
271
272 return rtrim($recursiveStoragePids, ',');
273 }
274
275 /**
276 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
277 */
278 protected function getBackendUser()
279 {
280 return $GLOBALS['BE_USER'];
281 }
282 }