[TASK] Clean up Admin Panel Code
[Packages/TYPO3.CMS.git] / typo3 / sysext / adminpanel / Classes / View / AdminPanelView.php
1 <?php
2
3 namespace TYPO3\CMS\Adminpanel\View;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Adminpanel\Modules\AdminPanelModuleInterface;
19 use TYPO3\CMS\Adminpanel\Service\EditToolbarService;
20 use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
21 use TYPO3\CMS\Core\Cache\CacheManager;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Core\Utility\PathUtility;
24
25 /**
26 * View class for the admin panel in frontend editing.
27 *
28 * @internal
29 */
30 class AdminPanelView
31 {
32 /**
33 * Force preview
34 *
35 * @var bool
36 */
37 protected $ext_forcePreview = false;
38
39 /**
40 * Array of adminPanel modules
41 *
42 * @var AdminPanelModuleInterface[]
43 */
44 protected $modules = [];
45
46 /**
47 * @var array
48 */
49 protected $configuration;
50
51 /**
52 * Setter for injecting new-style modules
53 *
54 * @see \TYPO3\CMS\Adminpanel\Controller\MainController::render()
55 * @param array $modules
56 * @internal
57 */
58 public function setModules(array $modules): void
59 {
60 $this->modules = $modules;
61 }
62
63 /**
64 * Returns true if admin panel was activated
65 * (switched "on" via GUI)
66 *
67 * @return bool
68 */
69 protected function isAdminPanelActivated(): bool
70 {
71 return $this->getBackendUser()->uc['AdminPanel']['display_top'] ?? false;
72 }
73
74 /**
75 * Returns LanguageService
76 *
77 * @return \TYPO3\CMS\Core\Localization\LanguageService
78 */
79 protected function getLanguageService()
80 {
81 return $GLOBALS['LANG'];
82 }
83
84 /**
85 * Returns the current BE user.
86 *
87 * @return FrontendBackendUserAuthentication
88 */
89 protected function getBackendUser()
90 {
91 return $GLOBALS['BE_USER'];
92 }
93
94 /*****************************************************
95 * Admin Panel: Deprecated API
96 ****************************************************/
97
98 /**
99 * Backwards compatibility method ensuring hook still gets the same content as before
100 *
101 * @deprecated since TYPO3 v9 - remove when hook can be removed
102 * @internal
103 * @return string
104 * @throws \UnexpectedValueException
105 */
106 public function callDeprecatedHookObject(): string
107 {
108 $moduleContent = '';
109 if ($this->isAdminPanelActivated()) {
110 foreach ($this->modules as $module) {
111 $moduleContent .= $this->getModule($module);
112 }
113
114 foreach (
115 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_adminpanel.php']['extendAdminPanel']
116 ??
117 [] as $className
118 ) {
119 trigger_error(
120 'The hook $GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/class.tslib_adminpanel.php\'][\'extendAdminPanel\'] is deprecated, register an AdminPanelModule instead.',
121 E_USER_DEPRECATED
122 );
123 $hookObject = GeneralUtility::makeInstance($className);
124 if (!$hookObject instanceof AdminPanelViewHookInterface) {
125 throw new \UnexpectedValueException(
126 $className . ' must implement interface ' . AdminPanelViewHookInterface::class,
127 1311942539
128 );
129 }
130 $content = $hookObject->extendAdminPanel($moduleContent, $this);
131 if ($content) {
132 $moduleContent .= '<div class="typo3-adminPanel-section typo3-adminPanel-section-open">';
133 $moduleContent .= ' <div class="typo3-adminPanel-section-body">';
134 $moduleContent .= ' ' . $content;
135 $moduleContent .= ' </div>';
136 $moduleContent .= '</div>';
137 }
138 }
139 }
140 return $moduleContent;
141 }
142
143 /**
144 * Render a single module with header panel
145 *
146 * @deprecated Since TYPO3 v9 - only used in deprecated hook call (which triggers the corresponding deprecation error)
147 * @param AdminPanelModuleInterface $module
148 * @return string
149 */
150 protected function getModule(AdminPanelModuleInterface $module): string
151 {
152 $output = [];
153
154 if ($module->isEnabled()) {
155 $output[] = '<div class="typo3-adminPanel-section typo3-adminPanel-section-open">';
156 $output[] = ' <div class="typo3-adminPanel-section-title">';
157 $output[] = ' ' . $this->getSectionOpenerLink($module);
158 $output[] = ' </div>';
159 $output[] = '<div class="typo3-adminPanel-section-body">';
160 $output[] = ' ' . $module->getContent();
161 $output[] = '</div>';
162 $output[] = '</div>';
163 }
164
165 foreach ($module->getJavaScriptFiles() as $javaScriptFile) {
166 $output[] =
167 '<script src="' .
168 PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($javaScriptFile)) .
169 '"></script>';
170 }
171
172 return implode('', $output);
173 }
174
175 /*****************************************************
176 * Admin Panel Layout Helper functions
177 ****************************************************/
178
179 /**
180 * Wraps a string in a link which will open/close a certain part of the Admin Panel
181 *
182 * @deprecated Since TYPO3 v9 - only used in deprecated hook call (which triggers the corresponding deprecation error)
183 * @param AdminPanelModuleInterface $module
184 * @return string
185 */
186 protected function getSectionOpenerLink(AdminPanelModuleInterface $module): string
187 {
188 $identifier = $module->getIdentifier();
189 $onclick = 'document.TSFE_ADMIN_PANEL_FORM[' .
190 GeneralUtility::quoteJSvalue('TSFE_ADMIN_PANEL[display_' . $identifier . ']') .
191 '].value=' .
192 ($this->getBackendUser()->uc['AdminPanel']['display_' . $identifier] ? '0' : '1') .
193 ';document.TSFE_ADMIN_PANEL_FORM.submit();return false;';
194
195 $output = [];
196 $output[] = '<span class="typo3-adminPanel-section-title-identifier"></span>';
197 $output[] = '<a href="javascript:void(0)" onclick="' . htmlspecialchars($onclick) . '">';
198 $output[] = ' ' . htmlspecialchars($module->getLabel());
199 $output[] = '</a>';
200 $output[] = '<input type="hidden" name="TSFE_ADMIN_PANEL[display_' .
201 $identifier .
202 ']" value="' .
203 1 .
204 '" />';
205
206 return implode('', $output);
207 }
208
209 /**
210 * Creates the tool bar links for the "edit" section of the Admin Panel.
211 *
212 * @deprecated Since TYPO3 v9 - use EditToolbarService instead or create buttons via fluid
213 * @deprecated
214 * @return string A string containing images wrapped in <a>-tags linking them to proper functions.
215 */
216 public function ext_makeToolBar(): string
217 {
218 trigger_error(
219 'Deprecated since TYPO3 v9, use fluid and backend uri builder to create a toolbar',
220 E_USER_DEPRECATED
221 );
222 $editToolbarService = GeneralUtility::makeInstance(EditToolbarService::class);
223 return $editToolbarService->createToolbar();
224 }
225
226 /**
227 * Translate given key
228 *
229 * @param string $key Key for a label in the $LOCAL_LANG array of "EXT:core/Resources/Private/Language/locallang_tsfe.xlf
230 * @param bool $convertWithHtmlspecialchars If TRUE the language-label will be sent through htmlspecialchars
231 * @deprecated Since TYPO3 v9, will be removed in TYPO3 v10.0 - only used in deprecated methods
232 * @return string The value for the $key
233 */
234 protected function extGetLL($key, $convertWithHtmlspecialchars = true)
235 {
236 $labelStr = $this->getLanguageService()->getLL($key);
237 if ($convertWithHtmlspecialchars) {
238 $labelStr = htmlspecialchars($labelStr);
239 }
240 return $labelStr;
241 }
242
243 /**
244 * Add an additional stylesheet
245 *
246 * @return string
247 * @deprecated Since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
248 */
249 public function getAdminPanelHeaderData()
250 {
251 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).', E_USER_DEPRECATED);
252 $result = '';
253 if (!empty($GLOBALS['TBE_STYLES']['stylesheets']['admPanel'])) {
254 $stylesheet = GeneralUtility::locationHeaderUrl($GLOBALS['TBE_STYLES']['stylesheets']['admPanel']);
255 $result = '<link rel="stylesheet" type="text/css" href="' .
256 htmlspecialchars($stylesheet, ENT_QUOTES | ENT_HTML5) . '" />';
257 }
258 return $result;
259 }
260
261 /**
262 * Checks if an Admin Panel section ("module") is available for the user. If so, TRUE is returned.
263 *
264 * @param string $key The module key, eg. "edit", "preview", "info" etc.
265 * @return bool
266 * @deprecated Since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
267 */
268 public function isAdminModuleEnabled($key)
269 {
270 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).', E_USER_DEPRECATED);
271 $result = false;
272 // Returns TRUE if the module checked is "preview" and the forcePreview flag is set.
273 if ($key === 'preview' && $this->ext_forcePreview) {
274 $result = true;
275 } elseif (!empty($this->configuration['enable.']['all'])) {
276 $result = true;
277 } elseif (!empty($this->configuration['enable.'][$key])) {
278 $result = true;
279 }
280 return $result;
281 }
282
283 /**
284 * Saves any change in settings made in the Admin Panel.
285 *
286 * @deprecated Since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
287 */
288 public function saveConfigOptions()
289 {
290 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).', E_USER_DEPRECATED);
291 $input = GeneralUtility::_GP('TSFE_ADMIN_PANEL');
292 $beUser = $this->getBackendUser();
293 if (is_array($input)) {
294 // Setting
295 $beUser->uc['AdminPanel'] = array_merge(
296 !is_array($beUser->uc['AdminPanel']) ? [] : $beUser->uc['AdminPanel'],
297 $input
298 );
299 unset($beUser->uc['AdminPanel']['action']);
300
301 foreach ($this->modules as $module) {
302 if ($module->isEnabled()) {
303 // We use TYPO3_REQUEST for compatibility reasons. The object and this method are deprecated anyway, this should be fine.
304 $module->onSubmit($input, $GLOBALS['TYPO3_REQUEST']);
305 }
306 }
307 // Saving
308 $beUser->writeUC();
309 // Flush fluid template cache
310 $cacheManager = new CacheManager();
311 $cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
312 $cacheManager->getCache('fluid_template')->flush();
313 }
314 }
315
316 /**
317 * Returns the value for an Admin Panel setting.
318 *
319 * @param string $sectionName Module key
320 * @param string $val Setting key
321 * @return mixed The setting value
322 * @deprecated Since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
323 */
324 public function extGetFeAdminValue($sectionName, $val = '')
325 {
326 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).', E_USER_DEPRECATED);
327 trigger_error(
328 'Deprecated since TYPO3 v9 - ',
329 E_USER_DEPRECATED
330 );
331 if (!$this->isAdminModuleEnabled($sectionName)) {
332 return null;
333 }
334
335 $beUser = $this->getBackendUser();
336 // Exceptions where the values can be overridden (forced) from backend:
337 // deprecated
338 if (
339 $sectionName === 'edit' && (
340 $val === 'displayIcons' && $this->configuration['module.']['edit.']['forceDisplayIcons'] ||
341 $val === 'displayFieldIcons' && $this->configuration['module.']['edit.']['forceDisplayFieldIcons'] ||
342 $val === 'editNoPopup' && $this->configuration['module.']['edit.']['forceNoPopup']
343 )
344 ) {
345 return true;
346 }
347
348 // Override all settings with user TSconfig
349 if ($val && isset($this->configuration['override.'][$sectionName . '.'][$val])) {
350 return $this->configuration['override.'][$sectionName . '.'][$val];
351 }
352 if (!$val && isset($this->configuration['override.'][$sectionName])) {
353 return $this->configuration['override.'][$sectionName];
354 }
355
356 $returnValue = $val ? $beUser->uc['AdminPanel'][$sectionName . '_' . $val] : 1;
357
358 // Exception for preview
359 if ($sectionName === 'preview' && $this->ext_forcePreview) {
360 return !$val ? true : $returnValue;
361 }
362
363 // See if the menu is expanded!
364 return $this->isAdminModuleOpen($sectionName) ? $returnValue : null;
365 }
366
367 /**
368 * Enables the force preview option.
369 *
370 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - see AdminPanelModule: Preview
371 */
372 public function forcePreview()
373 {
374 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Use new AdminPanel Preview Module instead.', E_USER_DEPRECATED);
375 $this->ext_forcePreview = true;
376 }
377
378 /**
379 * Returns TRUE if admin panel module is open
380 *
381 * @param string $key Module key
382 * @return bool TRUE, if the admin panel is open for the specified admin panel module key.
383 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
384 */
385 public function isAdminModuleOpen($key)
386 {
387 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Use new AdminPanel API instead.', E_USER_DEPRECATED);
388 return $this->getBackendUser()->uc['AdminPanel']['display_top'] &&
389 $this->getBackendUser()->uc['AdminPanel']['display_' . $key];
390 }
391
392 /**
393 * Returns a row (with 4 columns) for content in a section of the Admin Panel.
394 * It will take $pre as a key to a label to display and $element as the content to put into the forth cell.
395 *
396 * @param string $title Key to label
397 * @param string $content The HTML content for the forth table cell.
398 * @param string $checkbox The HTML for a checkbox or hidden fields.
399 * @param string $innerDivClass The Class attribute for the td element.
400 * @param string $outerDivClass The Class attribute for the tr element.
401 * @return string HTML table row.
402 * @see extGetHead()
403 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
404 */
405 public function extGetItem($title, $content = '', $checkbox = '', $outerDivClass = null, $innerDivClass = null)
406 {
407 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Use new AdminPanel API instead.', E_USER_DEPRECATED);
408 $title = $title ? '<label for="' . htmlspecialchars($title) . '">' . $this->extGetLL($title) . '</label>' : '';
409 $out = '';
410 $out .= (string)$outerDivClass ? '<div class="' . htmlspecialchars($outerDivClass) . '">' : '<div>';
411 $out .= (string)$innerDivClass ? '<div class="' . htmlspecialchars($innerDivClass) . '">' : '<div>';
412 $out .= $checkbox . $title . $content . '</div></div>';
413 return $out;
414 }
415
416 /**
417 * Returns a row (with colspan=4) which is a header for a section in the Admin Panel.
418 * It will have a plus/minus icon and a label which is linked so that it submits the form which surrounds the whole Admin Panel when clicked, alterting the TSFE_ADMIN_PANEL[display_' . $pre . '] value
419 * See the functions get*Module
420 *
421 * @param string $sectionSuffix The suffix to the display_ label. Also selects the label from the LOCAL_LANG array.
422 * @return string HTML table row.
423 * @see extGetItem()
424 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
425 */
426 public function extGetHead($sectionSuffix)
427 {
428 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Use new AdminPanel API instead.', E_USER_DEPRECATED);
429 return $this->linkSectionHeader($sectionSuffix, $this->extGetLL($sectionSuffix));
430 }
431
432 /**
433 * Wraps a string in a link which will open/close a certain part of the Admin Panel
434 *
435 * @param string $sectionSuffix The code for the display_ label/key
436 * @param string $sectionTitle Title (HTML-escaped)
437 * @param string $className The classname for the <a> tag
438 * @return string $className Linked input string
439 * @see extGetHead()
440 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
441 */
442 public function linkSectionHeader($sectionSuffix, $sectionTitle, $className = '')
443 {
444 trigger_error('AdminPanelView->' . __METHOD__ . ' will be removed in TYPO3 v10.0. Use new AdminPanel API instead.', E_USER_DEPRECATED);
445 $onclick = 'document.TSFE_ADMIN_PANEL_FORM[' .
446 GeneralUtility::quoteJSvalue('TSFE_ADMIN_PANEL[display_' . $sectionSuffix . ']') .
447 '].value=' .
448 ($this->getBackendUser()->uc['AdminPanel']['display_' . $sectionSuffix] ? '0' : '1') .
449 ';document.TSFE_ADMIN_PANEL_FORM.submit();return false;';
450
451 $output = [];
452 $output[] = '<span class="typo3-adminPanel-section-title-identifier"></span>';
453 $output[] = '<a href="javascript:void(0)" onclick="' . htmlspecialchars($onclick) . '">';
454 $output[] = ' ' . $sectionTitle;
455 $output[] = '</a>';
456 $output[] = '<input type="hidden" name="TSFE_ADMIN_PANEL[display_' .
457 $sectionSuffix .
458 ']" value="' .
459 (int)$this->isAdminModuleOpen($sectionSuffix) .
460 '" />';
461
462 return implode('', $output);
463 }
464 }