PageLayoutController.php 52.5 KB
Newer Older
1
2
3
<?php
namespace TYPO3\CMS\Backend\Controller;

4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
8
9
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
10
 *
11
12
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
15
 * The TYPO3 project - inspiring people to share!
 */
16

Nicole Cordes's avatar
Nicole Cordes committed
17
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\Utility\IconUtility;
19
use TYPO3\CMS\Core\Type\Bitmask\Permission;
Nicole Cordes's avatar
Nicole Cordes committed
20
21
22
23
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
24
use TYPO3\CMS\Extbase\Object\ObjectManager;
25
use TYPO3\CMS\Fluid\View\StandaloneView;
26
use TYPO3\CMS\Fluid\ViewHelpers\Be\InfoboxViewHelper;
Nicole Cordes's avatar
Nicole Cordes committed
27

28
29
30
31
32
33
34
/**
 * Script Class for Web > Layout module
 *
 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
 */
class PageLayoutController {

35
36
37
38
39
	/**
	 * Page Id for which to make the listing
	 *
	 * @var int
	 */
40
41
	public $id;

42
43
44
45
46
	/**
	 * Pointer - for browsing list of records.
	 *
	 * @var int
	 */
47
48
	public $pointer;

49
50
51
52
53
	/**
	 * Thumbnails or not
	 *
	 * @var string
	 */
54
55
	public $imagemode;

56
57
58
59
60
	/**
	 * Search-fields
	 *
	 * @var string
	 */
61
62
	public $search_field;

63
64
65
66
67
	/**
	 * Search-levels
	 *
	 * @var int
	 */
68
69
	public $search_levels;

70
71
72
73
74
	/**
	 * Show-limit
	 *
	 * @var int
	 */
75
76
	public $showLimit;

77
78
79
80
81
	/**
	 * Return URL
	 *
	 * @var string
	 */
82
83
	public $returnUrl;

84
85
86
87
88
	/**
	 * Clear-cache flag - if set, clears page cache for current id.
	 *
	 * @var bool
	 */
89
90
	public $clear_cache;

91
92
93
94
95
	/**
	 * PopView id - for opening a window with the page
	 *
	 * @var bool
	 */
96
97
	public $popView;

98
99
100
101
102
103
	/**
	 * QuickEdit: Variable, that tells quick edit what to show/edit etc.
	 * Format is [tablename]:[uid] with some exceptional values for both parameters (with special meanings).
	 *
	 * @var string
	 */
104
105
	public $edit_record;

106
107
108
109
110
111
112
113
	/**
	 * QuickEdit: If set, this variable tells quick edit that the last edited record had
	 * this value as UID and we should look up the new, real uid value in sys_log.
	 *
	 * @var string
	 */
	public $new_unique_uid;

114
115
116
117
118
	/**
	 * Page select perms clause
	 *
	 * @var string
	 */
119
120
	public $perms_clause;

121
122
123
124
125
	/**
	 * Module TSconfig
	 *
	 * @var array
	 */
126
127
	public $modTSconfig;

128
129
130
131
132
133
134
	/**
	 * Module shared TSconfig
	 *
	 * @var array
	 */
	public $modSharedTSconfig;

135
136
137
138
139
	/**
	 * Current ids page record
	 *
	 * @var array
	 */
140
141
142
143
144
	public $pageinfo;

	/**
	 * Document template object
	 *
145
	 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
146
147
148
	 */
	public $doc;

149
150
151
152
153
	/**
	 * Back path of the module
	 *
	 * @var string
	 */
154
155
	public $backPath;

156
157
158
159
160
	/**
	 * "Pseudo" Description -table name
	 *
	 * @var string
	 */
161
162
	public $descrTable;

163
164
165
166
167
	/**
	 * List of column-integers to edit. Is set from TSconfig, default is "1,0,2,3"
	 *
	 * @var string
	 */
168
169
	public $colPosList;

170
171
172
173
174
	/**
	 * Flag: If content can be edited or not.
	 *
	 * @var bool
	 */
175
176
	public $EDIT_CONTENT;

177
178
179
180
181
	/**
	 * Users permissions integer for this page.
	 *
	 * @var int
	 */
182
183
	public $CALC_PERMS;

184
185
186
187
188
	/**
	 * Currently selected language for editing content elements
	 *
	 * @var int
	 */
189
190
	public $current_sys_language;

191
192
193
194
195
	/**
	 * Module configuration
	 *
	 * @var array
	 */
196
197
	public $MCONF = array();

198
199
200
201
202
	/**
	 * Menu configuration
	 *
	 * @var array
	 */
203
204
	public $MOD_MENU = array();

205
206
207
208
209
	/**
	 * Module settings (session variable)
	 *
	 * @var array
	 */
210
211
	public $MOD_SETTINGS = array();

212
213
214
215
216
	/**
	 * Array of tables to be listed by the Web > Page module in addition to the default tables
	 *
	 * @var array
	 */
217
218
	public $externalTables = array();

219
220
221
222
223
	/**
	 * Module output accumulation
	 *
	 * @var string
	 */
224
225
	public $content;

226
227
228
229
230
	/**
	 * Function menu temporary storage
	 *
	 * @var string
	 */
231
232
	public $topFuncMenu;

233
234
235
236
237
238
239
240
	/**
	 * List of column-integers accessible to the current BE user.
	 * Is set from TSconfig, default is $colPosList
	 *
	 * @var string
	 */
	public $activeColPosList;

241
	/**
242
243
244
	 * Markers array
	 *
	 * @var array
245
246
247
	 */
	protected $markers = array();

248
249
250
251
252
253
	/**
	 * Initializing the module
	 *
	 * @return void
	 */
	public function init() {
254
255
		$GLOBALS['LANG']->includeLLFile('EXT:cms/layout/locallang.xlf');

256
257
258
259
		// Setting module configuration / page select clause
		$this->MCONF = $GLOBALS['MCONF'];
		$this->perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
		$this->backPath = $GLOBALS['BACK_PATH'];
260
261
262
		// Get session data
		$sessionData = $GLOBALS['BE_USER']->getSessionData(\TYPO3\CMS\Recordlist\RecordList::class);
		$this->search_field = !empty($sessionData['search_field']) ? $sessionData['search_field'] : '';
263
		// GPvars:
264
		$this->id = (int)GeneralUtility::_GP('id');
Nicole Cordes's avatar
Nicole Cordes committed
265
266
267
268
269
		$this->pointer = GeneralUtility::_GP('pointer');
		$this->imagemode = GeneralUtility::_GP('imagemode');
		$this->clear_cache = GeneralUtility::_GP('clear_cache');
		$this->popView = GeneralUtility::_GP('popView');
		$this->edit_record = GeneralUtility::_GP('edit_record');
270
		$this->new_unique_uid = GeneralUtility::_GP('new_unique_uid');
271
		$this->search_field = GeneralUtility::_GP('search_field');
Nicole Cordes's avatar
Nicole Cordes committed
272
273
274
		$this->search_levels = GeneralUtility::_GP('search_levels');
		$this->showLimit = GeneralUtility::_GP('showLimit');
		$this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
275
		$this->externalTables = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cms']['db_layout']['addTables'];
276
		$sessionData['search_field'] = $this->search_field;
277
278
		// Store session data
		$GLOBALS['BE_USER']->setAndSaveSessionData(\TYPO3\CMS\Recordlist\RecordList::class, $sessionData);
279
		// Load page info array:
Nicole Cordes's avatar
Nicole Cordes committed
280
		$this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
281
282
283
		// Initialize menu
		$this->menuConfig();
		// Setting sys language from session var:
284
		$this->current_sys_language = (int)$this->MOD_SETTINGS['language'];
285
286
		// CSH / Descriptions:
		$this->descrTable = '_MOD_' . $this->MCONF['name'];
287
288
289

		$this->markers['SEARCHBOX'] = '';
		$this->markers['BUTTONLIST_ADDITIONAL'] = '';
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
	}

	/**
	 * Initialize menu array
	 *
	 * @return void
	 */
	public function menuConfig() {
		// MENU-ITEMS:
		$this->MOD_MENU = array(
			'tt_content_showHidden' => '',
			'showPalettes' => '',
			'showDescriptions' => '',
			'function' => array(
				0 => $GLOBALS['LANG']->getLL('m_function_0'),
				1 => $GLOBALS['LANG']->getLL('m_function_1'),
				2 => $GLOBALS['LANG']->getLL('m_function_2')
			),
			'language' => array(
				0 => $GLOBALS['LANG']->getLL('m_default')
			)
		);
		// example settings:
		// 	$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cms']['db_layout']['addTables']['tx_myext'] =
		//		array ('default' => array(
315
		//				'MENU' => 'LLL:EXT:tx_myext/locallang_db.xlf:menuDefault',
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
		//				'fList' =>  'title,description,image',
		//				'icon' => TRUE));
		if (is_array($this->externalTables)) {
			foreach ($this->externalTables as $table => $tableSettings) {
				// delete the default settings from above
				if (is_array($this->MOD_MENU[$table])) {
					unset($this->MOD_MENU[$table]);
				}
				if (is_array($tableSettings) && count($tableSettings) > 1) {
					foreach ($tableSettings as $key => $settings) {
						$this->MOD_MENU[$table][$key] = $GLOBALS['LANG']->sL($settings['MENU']);
					}
				}
			}
		}
		// First, select all pages_language_overlay records on the current page. Each represents a possibility for a language on the page. Add these to language selector.
		$res = $this->exec_languageQuery($this->id);
		while ($lrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
			if ($GLOBALS['BE_USER']->checkLanguageAccess($lrow['uid'])) {
335
				$this->MOD_MENU['language'][$lrow['uid']] = $lrow['hidden'] ? '(' . $lrow['title'] . ')' : $lrow['title'];
336
337
338
339
340
341
342
343
			}
		}
		// Find if there are ANY languages at all (and if not, remove the language option from function menu).
		$count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'sys_language', $GLOBALS['BE_USER']->isAdmin() ? '' : 'hidden=0');
		if (!$count) {
			unset($this->MOD_MENU['function']['2']);
		}
		// page/be_user TSconfig settings and blinding of menu-items
Nicole Cordes's avatar
Nicole Cordes committed
344
345
		$this->modSharedTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.SHARED');
		$this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->MCONF['name']);
346
347
348
		if ($this->modTSconfig['properties']['QEisDefault']) {
			ksort($this->MOD_MENU['function']);
		}
Nicole Cordes's avatar
Nicole Cordes committed
349
		$this->MOD_MENU['function'] = BackendUtility::unsetMenuItems($this->modTSconfig['properties'], $this->MOD_MENU['function'], 'menu.function');
350
		// Remove QuickEdit as option if page type is not...
351
		if (!GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['FE']['content_doktypes'] . ',6', $this->pageinfo['doktype'])) {
352
353
354
355
356
357
358
			unset($this->MOD_MENU['function'][0]);
		}
		// Setting alternative default label:
		if (($this->modSharedTSconfig['properties']['defaultLanguageLabel'] || $this->modTSconfig['properties']['defaultLanguageLabel']) && isset($this->MOD_MENU['language'][0])) {
			$this->MOD_MENU['language'][0] = $this->modTSconfig['properties']['defaultLanguageLabel'] ? $this->modSharedTSconfig['properties']['defaultLanguageLabel'] : $this->modSharedTSconfig['properties']['defaultLanguageLabel'];
		}
		// Clean up settings
359
		$this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_layout');
360
361
362
363
364
365
366
367
368
369
370
371
372
		// For all elements to be shown in draft workspaces & to also show hidden elements by default if user hasn't disabled the option
		if ($GLOBALS['BE_USER']->workspace != 0 || $this->MOD_SETTINGS['tt_content_showHidden'] !== '0') {
			$this->MOD_SETTINGS['tt_content_showHidden'] = 1;
		}
	}

	/**
	 * Clears page cache for the current id, $this->id
	 *
	 * @return void
	 */
	public function clearCache() {
		if ($this->clear_cache) {
373
			$tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
			$tce->stripslashes_values = 0;
			$tce->start(array(), array());
			$tce->clear_cacheCmd($this->id);
		}
	}

	/**
	 * Generate the flashmessages for current pid
	 *
	 * @return string HTML content with flashmessages
	 */
	protected function getHeaderFlashMessagesForCurrentPid() {
		$content = '';
		// If page is a folder
		if ($this->pageinfo['doktype'] == \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_SYSFOLDER) {
			// Access to list module
390
			$moduleLoader = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
391
392
393
			$moduleLoader->load($GLOBALS['TBE_MODULES']);
			$modules = $moduleLoader->modules;
			if (is_array($modules['web']['sub']['list'])) {
394
395
				$title = $GLOBALS['LANG']->getLL('goToListModule');
				$message = '<p>' . $GLOBALS['LANG']->getLL('goToListModuleMessage') . '</p>';
396
				$message .= '<a class="btn btn-info" href="javascript:top.goToModule(\'web_list\',1);">' . $GLOBALS['LANG']->getLL('goToListModule') . '</a>';
397
398
399
400

				$view = GeneralUtility::makeInstance(StandaloneView::class);
				$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html'));
				$view->assignMultiple(array(
401
402
					'title' => $title,
					'message' => $message,
403
404
405
					'state' => InfoboxViewHelper::STATE_INFO
				));
				$content .= $view->render();
406
407
408
409
			}
		}
		// If content from different pid is displayed
		if ($this->pageinfo['content_from_pid']) {
410
			$contentPage = BackendUtility::getRecord('pages', (int)$this->pageinfo['content_from_pid']);
Nicole Cordes's avatar
Nicole Cordes committed
411
			$title = BackendUtility::getRecordTitle('pages', $contentPage);
412
			$linkToPid = $this->local_linkThisScript(array('id' => $this->pageinfo['content_from_pid']));
413
			$link = '<a href="' . $linkToPid . '">' . htmlspecialchars($title) . ' (PID ' . (int)$this->pageinfo['content_from_pid'] . ')</a>';
414
			$flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($GLOBALS['LANG']->getLL('content_from_pid_title'), $link), '', FlashMessage::INFO);
415
416
417
418
419
			$content .= $flashMessage->render();
		}
		return $content;
	}

420
421
422
423
424
425
426
427
428
	/**
	 *
	 * @return string $title
	 */
	protected function getLocalizedPageTitle() {
		if ($this->current_sys_language > 0) {
			$overlayRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
				'title',
				'pages_language_overlay',
429
430
				'pid = ' . (int)$this->id .
						' AND sys_language_uid = ' . (int)$this->current_sys_language .
Nicole Cordes's avatar
Nicole Cordes committed
431
432
						BackendUtility::deleteClause('pages_language_overlay') .
						BackendUtility::versioningPlaceholderClause('pages_language_overlay'),
433
434
435
436
437
438
439
440
441
442
443
				'',
				'',
				'',
				'sys_language_uid'
			);
			return $overlayRecord['title'];
		} else {
			return $this->pageinfo['title'];
		}
	}

444
445
446
447
448
449
450
451
452
453
454
455
456
	/**
	 * Main function.
	 * Creates some general objects and calls other functions for the main rendering of module content.
	 *
	 * @return void
	 */
	public function main() {
		// Access check...
		// The page will show only if there is a valid page and if this page may be viewed by the user
		$access = is_array($this->pageinfo) ? 1 : 0;
		if ($this->id && $access) {
			// Initialize permission settings:
			$this->CALC_PERMS = $GLOBALS['BE_USER']->calcPerms($this->pageinfo);
457
			$this->EDIT_CONTENT = $this->CALC_PERMS & Permission::CONTENT_EDIT ? 1 : 0;
458
			// Start document template object:
459
			$this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
460
			$this->doc->backPath = $GLOBALS['BACK_PATH'];
461
			$this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_layout.html');
462
463
464
465

			// override the default jumpToUrl
			$this->doc->JScodeArray['jumpToUrl'] = '
				function jumpToUrl(URL,formEl) {
466
					if (document.editform && TBE_EDITOR.isFormChanged)	{	// Check if the function exists... (works in all browsers?)
467
						if (!TBE_EDITOR.isFormChanged()) {
468
469
470
471
							window.location.href = URL;
						} else if (formEl) {
							if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1;
						}
472
473
474
					} else {
						window.location.href = URL;
					}
475
				}
476
477
478
479
480
';

			$this->doc->JScode .= $this->doc->wrapScriptTags('
				if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
				if (top.fsMod) top.fsMod.navFrameHighlightedID["web"] = "pages' . (int)$this->id . '_"+top.fsMod.currentBank; ' . (int)$this->id . ';
Nicole Cordes's avatar
Nicole Cordes committed
481
			' . ($this->popView ? BackendUtility::viewOnClick($this->id, $GLOBALS['BACK_PATH'], BackendUtility::BEgetRootLine($this->id)) : '') . '
482
483

				function deleteRecord(table,id,url) {	//
484
					if (confirm(' . GeneralUtility::quoteJSvalue($GLOBALS['LANG']->getLL('deleteWarning')) . ')) {
485
						window.location.href = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('tce_db') . '&cmd[') . '+table+"]["+id+"][delete]=1&redirect="+escape(url)+"&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '&prErr=1&uPT=1";
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
					}
					return false;
				}
			');
			$this->doc->JScode .= $this->doc->wrapScriptTags('
				var DTM_array = new Array();
				var DTM_origClass = new String();

					// if tabs are used in a popup window the array might not exists
				if(!top.DTM_currentTabs) {
					top.DTM_currentTabs = new Array();
				}

				function DTM_activate(idBase,index,doToogle) {	//
						// Hiding all:
					if (DTM_array[idBase]) {
						for(cnt = 0; cnt < DTM_array[idBase].length ; cnt++) {
							if (DTM_array[idBase][cnt] != idBase+"-"+index) {
Benjamin Kott's avatar
Benjamin Kott committed
504
505
								document.getElementById(DTM_array[idBase][cnt]+"-DIV").className = "tab-pane";
								document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").value = "tab";
506
507
508
509
510
511
							}
						}
					}

						// Showing one:
					if (document.getElementById(idBase+"-"+index+"-DIV")) {
Benjamin Kott's avatar
Benjamin Kott committed
512
513
						if (doToogle && document.getElementById(idBase+"-"+index+"-DIV").className === "tab-pane active") {
							document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane";
514
							if(DTM_origClass=="") {
Benjamin Kott's avatar
Benjamin Kott committed
515
								document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab";
516
517
518
519
520
							} else {
								DTM_origClass = "tab";
							}
							top.DTM_currentTabs[idBase] = -1;
						} else {
Benjamin Kott's avatar
Benjamin Kott committed
521
							document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active";
522
							if(DTM_origClass=="") {
Benjamin Kott's avatar
Benjamin Kott committed
523
								document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active";
524
							} else {
525
								DTM_origClass = "active";
526
527
528
529
530
531
532
533
534
							}
							top.DTM_currentTabs[idBase] = index;
						}
					}
				}
				function DTM_toggle(idBase,index,isInit) {	//
						// Showing one:
					if (document.getElementById(idBase+"-"+index+"-DIV")) {
						if (document.getElementById(idBase+"-"+index+"-DIV").style.display == "block") {
Benjamin Kott's avatar
Benjamin Kott committed
535
							document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane";
536
							if(isInit) {
Benjamin Kott's avatar
Benjamin Kott committed
537
								document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab";
538
539
540
541
542
							} else {
								DTM_origClass = "tab";
							}
							top.DTM_currentTabs[idBase+"-"+index] = 0;
						} else {
Benjamin Kott's avatar
Benjamin Kott committed
543
							document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active";
544
							if(isInit) {
Benjamin Kott's avatar
Benjamin Kott committed
545
								document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active";
546
							} else {
547
								DTM_origClass = "active";
548
549
550
551
552
553
554
							}
							top.DTM_currentTabs[idBase+"-"+index] = 1;
						}
					}
				}
			');
			// Setting doc-header
555
556
557
558
			$this->doc->form = '<form action="' . htmlspecialchars(
				BackendUtility::getModuleUrl(
					'web_layout', array('id' => $this->id, 'imagemode' =>  $this->imagemode)
				)) . '" method="post">';
559
			// Creating the top function menu:
560
561
			$this->topFuncMenu = BackendUtility::getFuncMenu($this->id, 'SET[function]', $this->MOD_SETTINGS['function'], $this->MOD_MENU['function'], '', '');
			$this->languageMenu = count($this->MOD_MENU['language']) > 1 ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xlf:LGL.language', TRUE) . BackendUtility::getFuncMenu($this->id, 'SET[language]', $this->current_sys_language, $this->MOD_MENU['language'], '', '') : '';
562
			// Find backend layout / coumns
563
			$backendLayout = GeneralUtility::callUserFunction(\TYPO3\CMS\Backend\View\BackendLayoutView::class . '->getSelectedBackendLayout', $this->id, $this);
564
565
566
567
			if (count($backendLayout['__colPosList'])) {
				$this->colPosList = implode(',', $backendLayout['__colPosList']);
			}
			// Removing duplicates, if any
568
569
			$this->colPosList = array_unique(GeneralUtility::intExplode(',', $this->colPosList));
			// Accessible columns
570
			if (isset($this->modSharedTSconfig['properties']['colPos_list']) && trim($this->modSharedTSconfig['properties']['colPos_list']) !== '') {
571
572
				$this->activeColPosList = array_unique(GeneralUtility::intExplode(',', trim($this->modSharedTSconfig['properties']['colPos_list'])));
				// Match with the list which is present in the colPosList for the current page
573
574
				if (!empty($this->colPosList) && !empty($this->activeColPosList)) {
					$this->activeColPosList = array_unique(array_intersect(
575
576
						$this->activeColPosList,
						$this->colPosList
577
					));
578
				}
579
580
			} else {
				$this->activeColPosList = $this->colPosList;
581
			}
582
			$this->activeColPosList = implode(',', $this->activeColPosList);
583
584
			$this->colPosList = implode(',', $this->colPosList);

585
			$body = '';
586
587
588
589
590
591
			$body .= $this->getHeaderFlashMessagesForCurrentPid();
			// Render the primary module content:
			if ($this->MOD_SETTINGS['function'] == 0) {
				// QuickEdit
				$body .= $this->renderQuickEdit();
			} else {
592
593
				// Page title
				$body .= $this->doc->header($this->getLocalizedPageTitle());
594
595
596
597
598
				// All other listings
				$body .= $this->renderListContent();
			}
			// Setting up the buttons and markers for docheader
			$docHeaderButtons = $this->getButtons($this->MOD_SETTINGS['function'] == 0 ? 'quickEdit' : '');
599
600
601
602
			$this->markers['CSH'] = $docHeaderButtons['csh'];
			$this->markers['TOP_FUNCTION_MENU'] = $this->topFuncMenu . $this->editSelect;
			$this->markers['LANGSELECTOR'] = $this->languageMenu;
			$this->markers['CONTENT'] = $body;
603
			// Build the <body> for the module
604
			$this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $this->markers);
605
606
607
608
			// Renders the module page
			$this->content = $this->doc->render($GLOBALS['LANG']->getLL('title'), $this->content);
		} else {
			// If no access or id value, create empty document:
609
			$this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
610
			$this->doc->backPath = $GLOBALS['BACK_PATH'];
611
			$this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_layout.html');
612
			$this->doc->JScode = $this->doc->wrapScriptTags('
613
				if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
614
			');
615
616

			$body = $this->doc->header($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']);
617
618
619

			$title = $GLOBALS['LANG']->getLL('clickAPage_header');
			$message = $GLOBALS['LANG']->getLL('clickAPage_content');
620
621
622
623

			$view = GeneralUtility::makeInstance(StandaloneView::class);
			$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html'));
			$view->assignMultiple(array(
624
625
				'title' => $title,
				'message' => $message,
626
627
628
				'state' => InfoboxViewHelper::STATE_INFO
			));
			$body .= $view->render();
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
			// Setting up the buttons and markers for docheader
			$docHeaderButtons = array(
				'view' => '',
				'history_page' => '',
				'new_content' => '',
				'move_page' => '',
				'move_record' => '',
				'new_page' => '',
				'edit_page' => '',
				'csh' => '',
				'shortcut' => '',
				'cache' => '',
				'savedok' => '',
				'savedokshow' => '',
				'closedok' => '',
				'deletedok' => '',
				'undo' => '',
647
648
				'history_record' => '',
				'edit_language' => ''
649
			);
Benni Mack's avatar
Benni Mack committed
650
			$this->markers['CSH'] = '';
651
652
653
654
			$this->markers['TOP_FUNCTION_MENU'] = '';
			$this->markers['LANGSELECTOR'] = '';
			$this->markers['CONTENT'] = $body;
			$this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $this->markers);
655
656
657
658
659
660
661
662
663
664
665
666
			// Renders the module page
			$this->content = $this->doc->render($GLOBALS['LANG']->getLL('title'), $this->content);
		}
	}

	/**
	 * Rendering the quick-edit view.
	 *
	 * @return void
	 */
	public function renderQuickEdit() {
		// Alternative template
667
		$this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_layout_quickedit.html');
668
		// Alternative form tag; Quick Edit submits its content to tce_db.php.
669
		$this->doc->form = '<form action="' . htmlspecialchars(BackendUtility::getModuleUrl('tce_db', ['prErr' => 1, 'uPT' => 1])) . '" method="post" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '" name="editform" onsubmit="return TBE_EDITOR.checkSubmit(1);">';
670
671
672
673
		// Setting up the context sensitive menu:
		$this->doc->getContextMenuCode();
		// Set the edit_record value for internal use in this function:
		$edit_record = $this->edit_record;
674
		// If a command to edit all records in a column is issue, then select all those elements, and redirect to FormEngine
675
		if (substr($edit_record, 0, 9) == '_EDIT_COL') {
676
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tt_content', 'pid=' . (int)$this->id . ' AND colPos=' . (int)substr($edit_record, 10) . ' AND sys_language_uid=' . (int)$this->current_sys_language . ($this->MOD_SETTINGS['tt_content_showHidden'] ? '' : BackendUtility::BEenableFields('tt_content')) . BackendUtility::deleteClause('tt_content') . BackendUtility::versioningPlaceholderClause('tt_content'), '', 'sorting');
677
678
679
680
			$idListA = array();
			while ($cRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
				$idListA[] = $cRow['uid'];
			}
681
682
			$url = BackendUtility::getModuleUrl('record_edit', array(
				'edit[tt_content][' . implode(',', $idListA) . ']' => 'edit',
683
				'returnUrl' => $this->local_linkThisScript(array('edit_record' => ''))
684
			));
685
686
			\TYPO3\CMS\Core\Utility\HttpUtility::redirect($url);
		}
687
688
689
690
691
692
693
694
		// If the former record edited was the creation of a NEW record, this will look up the created records uid:
		if ($this->new_unique_uid) {
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_log', 'userid=' . (int)$GLOBALS['BE_USER']->user['uid'] . ' AND NEWid=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->new_unique_uid, 'sys_log'));
			$sys_log_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
			if (is_array($sys_log_row)) {
				$edit_record = $sys_log_row['tablename'] . ':' . $sys_log_row['recuid'];
			}
		}
695
696
697
698
699
		// Creating the selector box, allowing the user to select which element to edit:
		$opt = array();
		$is_selected = 0;
		$languageOverlayRecord = '';
		if ($this->current_sys_language) {
700
			list($languageOverlayRecord) = BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $this->id, 'AND sys_language_uid=' . (int)$this->current_sys_language);
701
702
703
		}
		if (is_array($languageOverlayRecord)) {
			$inValue = 'pages_language_overlay:' . $languageOverlayRecord['uid'];
704
			$is_selected += (int)$edit_record == $inValue;
705
			$opt[] = '<option value="' . $inValue . '"' . ($edit_record == $inValue ? ' selected="selected"' : '') . '>[ ' . $GLOBALS['LANG']->getLL('editLanguageHeader', TRUE) . ' ]</option>';
706
707
		} else {
			$inValue = 'pages:' . $this->id;
708
			$is_selected += (int)$edit_record == $inValue;
709
			$opt[] = '<option value="' . $inValue . '"' . ($edit_record == $inValue ? ' selected="selected"' : '') . '>[ ' . $GLOBALS['LANG']->getLL('editPageProperties', TRUE) . ' ]</option>';
710
711
		}
		// Selecting all content elements from this language and allowed colPos:
712
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tt_content', 'pid=' . (int)$this->id . ' AND sys_language_uid=' . (int)$this->current_sys_language . ' AND colPos IN (' . $this->colPosList . ')' . ($this->MOD_SETTINGS['tt_content_showHidden'] ? '' : BackendUtility::BEenableFields('tt_content')) . BackendUtility::deleteClause('tt_content') . BackendUtility::versioningPlaceholderClause('tt_content'), '', 'colPos,sorting');
713
		$colPos = NULL;
714
715
716
717
		$first = 1;
		// Page is the pid if no record to put this after.
		$prev = $this->id;
		while ($cRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
Nicole Cordes's avatar
Nicole Cordes committed
718
			BackendUtility::workspaceOL('tt_content', $cRow);
719
720
721
722
723
724
725
			if (is_array($cRow)) {
				if ($first) {
					if (!$edit_record) {
						$edit_record = 'tt_content:' . $cRow['uid'];
					}
					$first = 0;
				}
726
				if (!isset($colPos) || $cRow['colPos'] !== $colPos) {
727
728
					$colPos = $cRow['colPos'];
					$opt[] = '<option value=""></option>';
729
					$opt[] = '<option value="_EDIT_COL:' . $colPos . '">__' . $GLOBALS['LANG']->sL(BackendUtility::getLabelFromItemlist('tt_content', 'colPos', $colPos), TRUE) . ':__</option>';
730
731
				}
				$inValue = 'tt_content:' . $cRow['uid'];
732
				$is_selected += (int)$edit_record == $inValue;
Nicole Cordes's avatar
Nicole Cordes committed
733
				$opt[] = '<option value="' . $inValue . '"' . ($edit_record == $inValue ? ' selected="selected"' : '') . '>' . htmlspecialchars(GeneralUtility::fixed_lgd_cs(($cRow['header'] ? $cRow['header'] : '[' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.no_title') . '] ' . strip_tags($cRow['bodytext'])), $GLOBALS['BE_USER']->uc['titleLen'])) . '</option>';
734
735
736
737
738
				$prev = -$cRow['uid'];
			}
		}
		// If edit_record is not set (meaning, no content elements was found for this language) we simply set it to create a new element:
		if (!$edit_record) {
739
740
			$edit_record = 'tt_content:new/' . $prev . '/' . $colPos;
			$inValue = 'tt_content:new/' . $prev . '/' . $colPos;
741
			$is_selected += (int)$edit_record == $inValue;
742
			$opt[] = '<option value="' . $inValue . '"' . ($edit_record == $inValue ? ' selected="selected"' : '') . '>[ ' . $GLOBALS['LANG']->getLL('newLabel', 1) . ' ]</option>';
743
744
745
746
		}
		// If none is yet selected...
		if (!$is_selected) {
			$opt[] = '<option value=""></option>';
747
			$opt[] = '<option value="' . $edit_record . '"  selected="selected">[ ' . $GLOBALS['LANG']->getLL('newLabel', TRUE) . ' ]</option>';
748
749
750
751
		}
		// Splitting the edit-record cmd value into table/uid:
		$this->eRParts = explode(':', $edit_record);
		// Delete-button flag?
752
		$this->deleteButton = MathUtility::canBeInterpretedAsInteger($this->eRParts[1]) && $edit_record && ($this->eRParts[0] != 'pages' && $this->EDIT_CONTENT || $this->eRParts[0] == 'pages' && $this->CALC_PERMS & Permission::PAGE_DELETE);
753
754
		// If undo-button should be rendered (depends on available items in sys_history)
		$this->undoButton = 0;
755
		$undoRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp', 'sys_history', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->eRParts[0], 'sys_history') . ' AND recuid=' . (int)$this->eRParts[1], '', 'tstamp DESC', '1');
756
757
758
759
		if ($this->undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) {
			$this->undoButton = 1;
		}
		// Setting up the Return URL for coming back to THIS script (if links take the user to another script)
Nicole Cordes's avatar
Nicole Cordes committed
760
761
		$R_URL_parts = parse_url(GeneralUtility::getIndpEnv('REQUEST_URI'));
		$R_URL_getvars = GeneralUtility::_GET();
762
		unset($R_URL_getvars['popView']);
763
		unset($R_URL_getvars['new_unique_uid']);
764
		$R_URL_getvars['edit_record'] = $edit_record;
Nicole Cordes's avatar
Nicole Cordes committed
765
		$this->R_URI = $R_URL_parts['path'] . '?' . GeneralUtility::implodeArrayForUrl('', $R_URL_getvars);
766
767
768
769
770
771
772
		// Setting close url/return url for exiting this script:
		// Goes to 'Columns' view if close is pressed (default)
		$this->closeUrl = $this->local_linkThisScript(array('SET' => array('function' => 1)));
		if ($this->returnUrl) {
			$this->closeUrl = $this->returnUrl;
		}
		// Return-url for JavaScript:
773
		$retUrlStr = $this->returnUrl ? '+\'&returnUrl=\'+' . GeneralUtility::quoteJSvalue(rawurlencode($this->returnUrl)) : '';
774
		// Drawing the edit record selectbox
775
776
777
		$this->editSelect = '<select name="edit_record" onchange="' . htmlspecialchars('jumpToUrl(' . GeneralUtility::quoteJSvalue(
			BackendUtility::getModuleUrl('web_layout') . '&id=' . $this->id . '&edit_record='
		) . '+escape(this.options[this.selectedIndex].value)' . $retUrlStr . ',this);') . '">' . implode('', $opt) . '</select>';
778
		// Creating editing form:
779
		if ($GLOBALS['BE_USER']->check('tables_modify', $this->eRParts[0]) && $edit_record && ($this->eRParts[0] !== 'pages' && $this->EDIT_CONTENT || $this->eRParts[0] === 'pages' && $this->CALC_PERMS & Permission::PAGE_SHOW)) {
780
781
782
783
			// Splitting uid parts for special features, if new:
			list($uidVal, $ex_pid, $ex_colPos) = explode('/', $this->eRParts[1]);
			// Convert $uidVal to workspace version if any:
			if ($uidVal != 'new') {
Nicole Cordes's avatar
Nicole Cordes committed
784
				if ($draftRecord = BackendUtility::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $this->eRParts[0], $uidVal, 'uid')) {
785
786
787
788
					$uidVal = $draftRecord['uid'];
				}
			}
			// Initializing transfer-data object:
789
			$trData = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Form\DataPreprocessor::class);
790
791
			$trData->addRawData = TRUE;
			$trData->defVals[$this->eRParts[0]] = array(
792
793
				'colPos' => (int)$ex_colPos,
				'sys_language_uid' => (int)$this->current_sys_language
794
795
796
797
798
799
800
801
			);
			$trData->lockRecords = 1;
			// 'new'
			$trData->fetchRecord($this->eRParts[0], $uidVal == 'new' ? $this->id : $uidVal, $uidVal);
			// Getting/Making the record:
			reset($trData->regTableItems_data);
			$rec = current($trData->regTableItems_data);
			if ($uidVal == 'new') {
802
				$new_unique_uid = uniqid('NEW', TRUE);
803
				$rec['uid'] = $new_unique_uid;
804
				$rec['pid'] = (int)$ex_pid ?: $this->id;
805
806
807
808
809
810
811
812
				$recordAccess = TRUE;
			} else {
				$rec['uid'] = $uidVal;
				// Checking internals access:
				$recordAccess = $GLOBALS['BE_USER']->recordEditAccessInternals($this->eRParts[0], $uidVal);
			}
			if (!$recordAccess) {
				// If no edit access, print error message:
813
				$content = $this->doc->section($GLOBALS['LANG']->getLL('noAccess'), $GLOBALS['LANG']->getLL('noAccess_msg') . '<br /><br />' . ($GLOBALS['BE_USER']->errorMsg ? 'Reason: ' . $GLOBALS['BE_USER']->errorMsg . '<br /><br />' : ''), 0, 1);
814
815
816
			} elseif (is_array($rec)) {
				// If the record is an array (which it will always be... :-)
				// Create instance of TCEforms, setting defaults:
817
				$tceforms = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Form\FormEngine::class);
818
819
820
821
822
823
824
825
				$tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes'];
				// Render form, wrap it:
				$panel = '';
				$panel .= $tceforms->getMainFields($this->eRParts[0], $rec);
				$panel = $tceforms->wrapTotal($panel, $rec, $this->eRParts[0]);
				// Add hidden fields:
				$theCode = $panel;
				if ($uidVal == 'new') {
826
					$theCode .= '<input type="hidden" name="data[' . $this->eRParts[0] . '][' . $rec['uid'] . '][pid]" value="' . $rec['pid'] . '" />';
827
				}
828
829
830
				$theCode .= '
					<input type="hidden" name="_serialNumber" value="' . md5(microtime()) . '" />
					<input type="hidden" name="edit_record" value="' . $edit_record . '" />
831
832
833
834
835
836
837
838
					<input type="hidden" name="redirect" value="' . htmlspecialchars(($uidVal == 'new' ? BackendUtility::getModuleUrl(
						'web_layout',
						array(
							'id' => $this->id,
							'new_unique_uid' => $new_unique_uid,
							'returnUrl' => $this->returnUrl
						)
					) : $this->R_URI)) . '" />
839
					' . \TYPO3\CMS\Backend\Form\FormEngine::getHiddenTokenField('tceAction');
840
				// Add JavaScript as needed around the form:
841
				$theCode = $tceforms->printNeededJSFunctions_top() . $theCode . $tceforms->printNeededJSFunctions();
842
				// Add warning sign if record was "locked":
Nicole Cordes's avatar
Nicole Cordes committed
843
				if ($lockInfo = BackendUtility::isRecordLocked($this->eRParts[0], $rec['uid'])) {
844
					$flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, htmlspecialchars($lockInfo['msg']), '', FlashMessage::WARNING);
845
					/** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
846
					$flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
847
848
849
					/** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
					$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
					$defaultFlashMessageQueue->enqueue($flashMessage);
850
851
				}
				// Add whole form as a document section:
852
				$content = $this->doc->section('', $theCode);
853
854
855
			}
		} else {
			// If no edit access, print error message:
856
			$content = $this->doc->section($GLOBALS['LANG']->getLL('noAccess'), $GLOBALS['LANG']->getLL('noAccess_msg') . '<br /><br />', 0, 1);
857
858
859
		}
		// Bottom controls (function menus):
		$q_count = $this->getNumberOfHiddenElements();
860
861
862

		$h_func_b = '<div class="checkbox">' .
			'<label for="checkTt_content_showHidden">' .
863
			BackendUtility::getFuncCheck($this->id, 'SET[tt_content_showHidden]', $this->MOD_SETTINGS['tt_content_showHidden'], '', '', 'id="checkTt_content_showHidden"') .
864
			(!$q_count ? ('<span class="text-muted">' . $GLOBALS['LANG']->getLL('hiddenCE', TRUE) . '</span>') : $GLOBALS['LANG']->getLL('hiddenCE', TRUE) . ' (' . $q_count . ')') .
865
866
867
868
869
			'</label>' .
			'</div>';

		$h_func_b .= '<div class="checkbox">' .
			'<label for="checkShowPalettes">' .
870
			BackendUtility::getFuncCheck($this->id, 'SET[showPalettes]', $this->MOD_SETTINGS['showPalettes'], '', '', 'id="checkShowPalettes"') .
871
872
873
874
			$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPalettes', TRUE) .
			'</label>' .
			'</div>';

Nicole Cordes's avatar
Nicole Cordes committed
875
		if (ExtensionManagementUtility::isLoaded('context_help')) {
876
877
			$h_func_b .= '<div class="checkbox">' .
				'<label for="checkShowDescriptions">' .
878
				BackendUtility::getFuncCheck($this->id, 'SET[showDescriptions]', $this->MOD_SETTINGS['showDescriptions'], '', '', 'id="checkShowDescriptions"') .
879
880
881
				$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showDescriptions', TRUE) .
				'</label>' .
				'</div>';
882
883
884
885
886
		}
		// Add the function menus to bottom:
		$content .= $this->doc->section('', $h_func_b, 0, 0);
		$content .= $this->doc->spacer(10);
		// Select element matrix:
Nicole Cordes's avatar
Nicole Cordes committed
887
		if ($this->eRParts[0] == 'tt_content' && MathUtility::canBeInterpretedAsInteger($this->eRParts[1])) {
888
			$posMap = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\ContentLayoutPagePositionMap::class);
889
890
891
892
			$posMap->backPath = $GLOBALS['BACK_PATH'];
			$posMap->cur_sys_language = $this->current_sys_language;
			$HTMLcode = '';
			// CSH:
Benni Mack's avatar
Benni Mack committed
893
			$HTMLcode .= BackendUtility::cshItem($this->descrTable, 'quickEdit_selElement', NULL, '|<br />');
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
			$HTMLcode .= $posMap->printContentElementColumns($this->id, $this->eRParts[1], $this->colPosList, $this->MOD_SETTINGS['tt_content_showHidden'], $this->R_URI);
			$content .= $this->doc->spacer(20);
			$content .= $this->doc->section($GLOBALS['LANG']->getLL('CEonThisPage'), $HTMLcode, 0, 1);
			$content .= $this->doc->spacer(20);
		}
		return $content;
	}

	/**
	 * Rendering all other listings than QuickEdit
	 *
	 * @return void
	 */
	public function renderListContent() {
		// Initialize list object (see "class.db_layout.inc"):
		/** @var $dblist \TYPO3\CMS\Backend\View\PageLayoutView */
910
		$dblist = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\View\PageLayoutView::class);
911
912
913
914
		$dblist->backPath = $GLOBALS['BACK_PATH'];
		$dblist->thumbs = $this->imagemode;
		$dblist->no_noWrap = 1;
		$dblist->descrTable = $this->descrTable;
Nicole Cordes's avatar
Nicole Cordes committed
915
		$this->pointer = MathUtility::forceIntegerInRange($this->pointer, 0, 100000);
916
		$dblist->script = BackendUtility::getModuleUrl('web_layout');
917
918
919
920
		$dblist->showIcon = 0;
		$dblist->setLMargin = 0;
		$dblist->doEdit = $this->EDIT_CONTENT;
		$dblist->ext_CALC_PERMS = $this->CALC_PERMS;
921
		$dblist->agePrefixes = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears');
922
		$dblist->id = $this->id;
Nicole Cordes's avatar
Nicole Cordes committed
923
		$dblist->nextThree = MathUtility::forceIntegerInRange($this->modTSconfig['properties']['editFieldsAtATime'], 0, 10);
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
		$dblist->option_showBigButtons = $this->modTSconfig['properties']['disableBigButtons'] === '0';
		$dblist->option_newWizard = $this->modTSconfig['properties']['disableNewContentElementWizard'] ? 0 : 1;
		$dblist->defLangBinding = $this->modTSconfig['properties']['defLangBinding'] ? 1 : 0;
		if (!$dblist->nextThree) {
			$dblist->nextThree = 1;
		}
		$dblist->externalTables = $this->externalTables;
		// Create menu for selecting a table to jump to (this is, if more than just pages/tt_content elements are found on the page!)
		$h_menu = $dblist->getTableMenu($this->id);
		// Initialize other variables:
		$h_func = '';
		$tableOutput = array();
		$tableJSOutput = array();
		$CMcounter = 0;
		// Traverse the list of table names which has records on this page (that array is populated
		// by the $dblist object during the function getTableMenu()):
		foreach ($dblist->activeTables as $table => $value) {
			if (!isset($dblist->externalTables[$table])) {
				$q_count = $this->getNumberOfHiddenElements();
943
944
945

				$h_func_b = '<div class="checkbox">' .
					'<label for="checkTt_content_showHidden">' .
946
					BackendUtility::getFuncCheck($this->id, 'SET[tt_content_showHidden]', $this->MOD_SETTINGS['tt_content_showHidden'], '', '', 'id="checkTt_content_showHidden"') .
947
					(!$q_count ? ('<span class="text-muted">' . $GLOBALS['LANG']->getLL('hiddenCE') . '</span>') : $GLOBALS['LANG']->getLL('hiddenCE') . ' (' . $q_count . ')') .
948
949
950
					'</label>' .
					'</div>';

951
952
953
954
955
956
957
				// Boolean: Display up/down arrows and edit icons for tt_content records
				$dblist->tt_contentConfig['showCommands'] = 1;
				// Boolean: Display info-marks or not
				$dblist->tt_contentConfig['showInfo'] = 1;
				// Setting up the tt_content columns to show:
				if (is_array($GLOBALS['TCA']['tt_content']['columns']['colPos']['config']['items'])) {
					$colList = array();
958
					$tcaItems = GeneralUtility::callUserFunction(\TYPO3\CMS\Backend\View\BackendLayoutView::class . '->getColPosListItemsParsed', $this->id, $this);
959
960
961
962
963
964
965
					foreach ($tcaItems as $temp) {
						$colList[] = $temp[1];
					}
				} else {
					// ... should be impossible that colPos has no array. But this is the fallback should it make any sense:
					$colList = array('1', '0', '2', '3');
				}
966
				if ($this->colPosList !== '') {
Nicole Cordes's avatar
Nicole Cordes committed
967
					$colList = array_intersect(GeneralUtility::intExplode(',', $this->colPosList), $colList);
968
969
970
				}
				// The order of the rows: Default is left(1), Normal(0), right(2), margin(3)
				$dblist->tt_contentConfig['cols'] = implode(',', $colList);
971
				$dblist->tt_contentConfig['activeCols'] = $this->activeColPosList;
972
				$dblist->tt_contentConfig['showHidden'] = $this->MOD_SETTINGS['tt_content_showHidden'];
973
				$dblist->tt_contentConfig['sys_language_uid'] = (int)$this->current_sys_language;
974
975
976
977
978
979
980
981
982
				// If the function menu is set to "Language":
				if ($this->MOD_SETTINGS['function'] == 2) {
					$dblist->tt_contentConfig['single'] = 0;
					$dblist->tt_contentConfig['languageMode'] = 1;
					$dblist->tt_contentConfig['languageCols'] = $this->MOD_MENU['language'];
					$dblist->tt_contentConfig['languageColsPointer'] = $this->current_sys_language;
				}
			} else {
				if (isset($this->MOD_SETTINGS) && isset($this->MOD_MENU)) {
983
					$h_func = BackendUtility::getFuncMenu($this->id, 'SET[' . $table . ']', $this->MOD_SETTINGS[$table], $this->MOD_MENU[$table], '', '');
984
985
986
987
988
989
990
991
992
993
994
995
996
997
				} else {
					$h_func = '';
				}
			}
			// Start the dblist object:
			$dblist->itemsLimitSingleTable = 1000;
			$dblist->start($this->id, $table, $this->pointer, $this->search_field, $this->search_levels, $this->showLimit);
			$dblist->counter = $CMcounter;
			$dblist->ext_function = $this->MOD_SETTINGS['function'];
			// Render versioning selector:
			$dblist->HTMLcode .= $this->doc->getVersionSelector($this->id);
			// Generate the list of elements here:
			$dblist->generateList();
			// Adding the list content to the tableOutput variable:
998
			$tableOutput[$table] = ($h_func ? $h_func . '<br /><img src="clear.gif" width="1" height="4" alt="" /><br />' : '') . $dblist->HTMLcode . ($h_func_b ? '<img src="clear.gif" width="1" height="10" alt="" /><br />' . $h_func_b : '');
999
1000
			// ... and any accumulated JavaScript goes the same way!
			$tableJSOutput[$table] = $dblist->JScode;