[TASK] Split action buttons into two groups
[Packages/TYPO3.CMS.git] / typo3 / sysext / recordlist / Classes / RecordList.php
1 <?php
2 namespace TYPO3\CMS\Recordlist;
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\Backend\Clipboard\Clipboard;
18 use TYPO3\CMS\Backend\Template\DocumentTemplate;
19 use TYPO3\CMS\Backend\Utility\IconUtility;
20 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
21 use TYPO3\CMS\Core\DataHandling\DataHandler;
22 use TYPO3\CMS\Core\Messaging\FlashMessage;
23 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Backend\Utility\BackendUtility;
26 use TYPO3\CMS\Core\Utility\MathUtility;
27 use TYPO3\CMS\Lang\LanguageService;
28
29 /**
30 * Script Class for the Web > List module; rendering the listing of records on a page
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 */
34 class RecordList {
35
36 /**
37 * Page Id for which to make the listing
38 *
39 * @var int
40 */
41 public $id;
42
43 /**
44 * Pointer - for browsing list of records.
45 *
46 * @var int
47 */
48 public $pointer;
49
50 /**
51 * Thumbnails or not
52 *
53 * @var string
54 */
55 public $imagemode;
56
57 /**
58 * Which table to make extended listing for
59 *
60 * @var string
61 */
62 public $table;
63
64 /**
65 * Search-fields
66 *
67 * @var string
68 */
69 public $search_field;
70
71 /**
72 * Search-levels
73 *
74 * @var int
75 */
76 public $search_levels;
77
78 /**
79 * Show-limit
80 *
81 * @var int
82 */
83 public $showLimit;
84
85 /**
86 * Return URL
87 *
88 * @var string
89 */
90 public $returnUrl;
91
92 /**
93 * Clear-cache flag - if set, clears page cache for current id.
94 *
95 * @var bool
96 */
97 public $clear_cache;
98
99 /**
100 * Command: Eg. "delete" or "setCB" (for TCEmain / clipboard operations)
101 *
102 * @var string
103 */
104 public $cmd;
105
106 /**
107 * Table on which the cmd-action is performed.
108 *
109 * @var string
110 */
111 public $cmd_table;
112
113 /**
114 * Page select perms clause
115 *
116 * @var int
117 */
118 public $perms_clause;
119
120 /**
121 * Module TSconfig
122 *
123 * @var array
124 */
125 public $modTSconfig;
126
127 /**
128 * Current ids page record
129 *
130 * @var mixed[]|bool
131 */
132 public $pageinfo;
133
134 /**
135 * Document template object
136 *
137 * @var DocumentTemplate
138 */
139 public $doc;
140
141 /**
142 * Module configuration
143 *
144 * @var array
145 * @deprecated since TYPO3 CMS 7, will be removed in CMS 8.
146 */
147 public $MCONF = array();
148
149 /**
150 * Menu configuration
151 *
152 * @var string[]
153 */
154 public $MOD_MENU = array();
155
156 /**
157 * Module settings (session variable)
158 *
159 * @var string[]
160 */
161 public $MOD_SETTINGS = array();
162
163 /**
164 * Module output accumulation
165 *
166 * @var string
167 */
168 public $content;
169
170 /**
171 * The name of the module
172 *
173 * @var string
174 */
175 protected $moduleName = 'web_list';
176
177 /**
178 * @var string
179 */
180 public $body = '';
181
182 /**
183 * Constructor
184 */
185 public function __construct() {
186 $this->getLanguageService()->includeLLFile('EXT:lang/locallang_mod_web_list.xlf');
187 }
188
189 /**
190 * Initializing the module
191 *
192 * @return void
193 */
194 public function init() {
195 $backendUser = $this->getBackendUserAuthentication();
196 $this->perms_clause = $backendUser->getPagePermsClause(1);
197 // Get session data
198 $sessionData = $backendUser->getSessionData(__CLASS__);
199 $this->search_field = !empty($sessionData['search_field']) ? $sessionData['search_field'] : '';
200 // GPvars:
201 $this->id = (int)GeneralUtility::_GP('id');
202 $this->pointer = GeneralUtility::_GP('pointer');
203 $this->imagemode = GeneralUtility::_GP('imagemode');
204 $this->table = GeneralUtility::_GP('table');
205 if (!empty(GeneralUtility::_GP('search_field'))) {
206 $this->search_field = GeneralUtility::_GP('search_field');
207 $sessionData['search_field'] = $this->search_field;
208 }
209 $this->search_levels = (int)GeneralUtility::_GP('search_levels');
210 $this->showLimit = GeneralUtility::_GP('showLimit');
211 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
212 $this->clear_cache = GeneralUtility::_GP('clear_cache');
213 $this->cmd = GeneralUtility::_GP('cmd');
214 $this->cmd_table = GeneralUtility::_GP('cmd_table');
215 if (!empty(GeneralUtility::_GP('search')) && empty(GeneralUtility::_GP('search_field'))) {
216 $this->search_field = '';
217 $sessionData['search_field'] = $this->search_field;
218 }
219 // Initialize menu
220 $this->menuConfig();
221 // Store session data
222 $backendUser->setAndSaveSessionData(RecordList::class, $sessionData);
223 $this->getDocumentTemplate()->getPageRenderer()->addInlineLanguageLabelFile('EXT:lang/locallang_mod_web_list.xlf');
224 }
225
226 /**
227 * Initialize function menu array
228 *
229 * @return void
230 */
231 public function menuConfig() {
232 // MENU-ITEMS:
233 $this->MOD_MENU = array(
234 'bigControlPanel' => '',
235 'clipBoard' => '',
236 'localization' => ''
237 );
238 // Loading module configuration:
239 $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->moduleName);
240 // Clean up settings:
241 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->moduleName);
242 }
243
244 /**
245 * Clears page cache for the current id, $this->id
246 *
247 * @return void
248 */
249 public function clearCache() {
250 if ($this->clear_cache) {
251 $tce = GeneralUtility::makeInstance(DataHandler::class);
252 $tce->stripslashes_values = 0;
253 $tce->start(array(), array());
254 $tce->clear_cacheCmd($this->id);
255 }
256 }
257
258 /**
259 * Main function, starting the rendering of the list.
260 *
261 * @return void
262 */
263 public function main() {
264 $backendUser = $this->getBackendUserAuthentication();
265 $lang = $this->getLanguageService();
266 // Start document template object:
267 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
268 $this->doc->backPath = $GLOBALS['BACK_PATH'];
269 $this->doc->setModuleTemplate('EXT:recordlist/Resources/Private/Templates/db_list.html');
270 $this->doc->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/AjaxDataHandler');
271 // Loading current page record and checking access:
272 $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
273 $access = is_array($this->pageinfo) ? 1 : 0;
274
275 // Apply predefined values for hidden checkboxes
276 // Set predefined value for DisplayBigControlPanel:
277 if ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'activated') {
278 $this->MOD_SETTINGS['bigControlPanel'] = TRUE;
279 } elseif ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'deactivated') {
280 $this->MOD_SETTINGS['bigControlPanel'] = FALSE;
281 }
282 // Set predefined value for Clipboard:
283 if ($this->modTSconfig['properties']['enableClipBoard'] === 'activated') {
284 $this->MOD_SETTINGS['clipBoard'] = TRUE;
285 } elseif ($this->modTSconfig['properties']['enableClipBoard'] === 'deactivated') {
286 $this->MOD_SETTINGS['clipBoard'] = FALSE;
287 }
288 // Set predefined value for LocalizationView:
289 if ($this->modTSconfig['properties']['enableLocalizationView'] === 'activated') {
290 $this->MOD_SETTINGS['localization'] = TRUE;
291 } elseif ($this->modTSconfig['properties']['enableLocalizationView'] === 'deactivated') {
292 $this->MOD_SETTINGS['localization'] = FALSE;
293 }
294
295 // Initialize the dblist object:
296 /** @var $dblist RecordList\DatabaseRecordList */
297 $dblist = GeneralUtility::makeInstance(RecordList\DatabaseRecordList::class);
298 $dblist->backPath = $GLOBALS['BACK_PATH'];
299 $dblist->script = BackendUtility::getModuleUrl('web_list', array(), '');
300 $dblist->calcPerms = $backendUser->calcPerms($this->pageinfo);
301 $dblist->thumbs = $backendUser->uc['thumbnailsByDefault'];
302 $dblist->returnUrl = $this->returnUrl;
303 $dblist->allFields = $this->MOD_SETTINGS['bigControlPanel'] || $this->table ? 1 : 0;
304 $dblist->localizationView = $this->MOD_SETTINGS['localization'];
305 $dblist->showClipboard = 1;
306 $dblist->disableSingleTableView = $this->modTSconfig['properties']['disableSingleTableView'];
307 $dblist->listOnlyInSingleTableMode = $this->modTSconfig['properties']['listOnlyInSingleTableView'];
308 $dblist->hideTables = $this->modTSconfig['properties']['hideTables'];
309 $dblist->hideTranslations = $this->modTSconfig['properties']['hideTranslations'];
310 $dblist->tableTSconfigOverTCA = $this->modTSconfig['properties']['table.'];
311 $dblist->allowedNewTables = GeneralUtility::trimExplode(',', $this->modTSconfig['properties']['allowedNewTables'], TRUE);
312 $dblist->deniedNewTables = GeneralUtility::trimExplode(',', $this->modTSconfig['properties']['deniedNewTables'], TRUE);
313 $dblist->newWizards = $this->modTSconfig['properties']['newWizards'] ? 1 : 0;
314 $dblist->pageRow = $this->pageinfo;
315 $dblist->counter++;
316 $dblist->MOD_MENU = array('bigControlPanel' => '', 'clipBoard' => '', 'localization' => '');
317 $dblist->modTSconfig = $this->modTSconfig;
318 $clickTitleMode = trim($this->modTSconfig['properties']['clickTitleMode']);
319 $dblist->clickTitleMode = $clickTitleMode === '' ? 'edit' : $clickTitleMode;
320 // Clipboard is initialized:
321 // Start clipboard
322 $dblist->clipObj = GeneralUtility::makeInstance(Clipboard::class);
323 // Initialize - reads the clipboard content from the user session
324 $dblist->clipObj->initializeClipboard();
325 // Clipboard actions are handled:
326 // CB is the clipboard command array
327 $CB = GeneralUtility::_GET('CB');
328 if ($this->cmd == 'setCB') {
329 // CBH is all the fields selected for the clipboard, CBC is the checkbox fields which were checked.
330 // By merging we get a full array of checked/unchecked elements
331 // This is set to the 'el' array of the CB after being parsed so only the table in question is registered.
332 $CB['el'] = $dblist->clipObj->cleanUpCBC(array_merge(GeneralUtility::_POST('CBH'), (array)GeneralUtility::_POST('CBC')), $this->cmd_table);
333 }
334 if (!$this->MOD_SETTINGS['clipBoard']) {
335 // If the clipboard is NOT shown, set the pad to 'normal'.
336 $CB['setP'] = 'normal';
337 }
338 // Execute commands.
339 $dblist->clipObj->setCmd($CB);
340 // Clean up pad
341 $dblist->clipObj->cleanCurrent();
342 // Save the clipboard content
343 $dblist->clipObj->endClipboard();
344 // This flag will prevent the clipboard panel in being shown.
345 // It is set, if the clickmenu-layer is active AND the extended view is not enabled.
346 $dblist->dontShowClipControlPanels = ($dblist->clipObj->current == 'normal' && !$this->modTSconfig['properties']['showClipControlPanelsDespiteOfCMlayers']);
347 // If there is access to the page or root page is used for searching, then render the list contents and set up the document template object:
348 if ($access || ($this->id === 0 && $this->search_levels > 0 && $this->search_field !== '')) {
349 // Deleting records...:
350 // Has not to do with the clipboard but is simply the delete action. The clipboard object is used to clean up the submitted entries to only the selected table.
351 if ($this->cmd == 'delete') {
352 $items = $dblist->clipObj->cleanUpCBC(GeneralUtility::_POST('CBC'), $this->cmd_table, 1);
353 if (count($items)) {
354 $cmd = array();
355 foreach ($items as $iK => $value) {
356 $iKParts = explode('|', $iK);
357 $cmd[$iKParts[0]][$iKParts[1]]['delete'] = 1;
358 }
359 $tce = GeneralUtility::makeInstance(DataHandler::class);
360 $tce->stripslashes_values = 0;
361 $tce->start(array(), $cmd);
362 $tce->process_cmdmap();
363 if (isset($cmd['pages'])) {
364 BackendUtility::setUpdateSignal('updatePageTree');
365 }
366 $tce->printLogErrorMessages(GeneralUtility::getIndpEnv('REQUEST_URI'));
367 }
368 }
369 // Initialize the listing object, dblist, for rendering the list:
370 $this->pointer = MathUtility::forceIntegerInRange($this->pointer, 0, 100000);
371 $dblist->start($this->id, $this->table, $this->pointer, $this->search_field, $this->search_levels, $this->showLimit);
372 $dblist->setDispFields();
373 // Render versioning selector:
374 if (ExtensionManagementUtility::isLoaded('version')) {
375 $dblist->HTMLcode .= $this->doc->getVersionSelector($this->id);
376 }
377 // Render the list of tables:
378 $dblist->generateList();
379 $listUrl = substr($dblist->listURL(), strlen($GLOBALS['BACK_PATH']));
380 // Add JavaScript functions to the page:
381 $this->doc->JScode = $this->doc->wrapScriptTags('
382 function jumpExt(URL,anchor) { //
383 var anc = anchor?anchor:"";
384 window.location.href = URL+(T3_THIS_LOCATION?"&returnUrl="+T3_THIS_LOCATION:"")+anc;
385 return false;
386 }
387 function jumpSelf(URL) { //
388 window.location.href = URL+(T3_RETURN_URL?"&returnUrl="+T3_RETURN_URL:"");
389 return false;
390 }
391
392 function setHighlight(id) { //
393 top.fsMod.recentIds["web"]=id;
394 top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_"+top.fsMod.currentBank; // For highlighting
395
396 if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
397 top.content.nav_frame.refresh_nav();
398 }
399 }
400 ' . $this->doc->redirectUrls($listUrl) . '
401 ' . $dblist->CBfunctions() . '
402 function editRecords(table,idList,addParams,CBflag) { //
403 window.location.href="' . $GLOBALS['BACK_PATH'] . 'alt_doc.php?returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')) . '&edit["+table+"]["+idList+"]=edit"+addParams;
404 }
405 function editList(table,idList) { //
406 var list="";
407
408 // Checking how many is checked, how many is not
409 var pointer=0;
410 var pos = idList.indexOf(",");
411 while (pos!=-1) {
412 if (cbValue(table+"|"+idList.substr(pointer,pos-pointer))) {
413 list+=idList.substr(pointer,pos-pointer)+",";
414 }
415 pointer=pos+1;
416 pos = idList.indexOf(",",pointer);
417 }
418 if (cbValue(table+"|"+idList.substr(pointer))) {
419 list+=idList.substr(pointer)+",";
420 }
421
422 return list ? list : idList;
423 }
424
425 if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
426 ');
427 // Setting up the context sensitive menu:
428 $this->doc->getContextMenuCode();
429 }
430 // access
431 // Begin to compile the whole page, starting out with page header:
432 if (!$this->id) {
433 $this->body = $this->doc->header($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']);
434 } else {
435 $this->body = $this->doc->header($this->pageinfo['title']);
436 }
437
438 if (!empty($dblist->HTMLcode)) {
439 $output = $dblist->HTMLcode;
440 } else {
441 $output = $flashMessage = GeneralUtility::makeInstance(
442 FlashMessage::class,
443 $lang->getLL('noRecordsOnThisPage'),
444 '',
445 FlashMessage::INFO
446 )->render();
447 }
448
449 $this->body .= '<form action="' . htmlspecialchars($dblist->listURL()) . '" method="post" name="dblistForm">';
450 $this->body .= $output;
451 $this->body .= '<input type="hidden" name="cmd_table" /><input type="hidden" name="cmd" /></form>';
452 // If a listing was produced, create the page footer with search form etc:
453 if ($dblist->HTMLcode) {
454 // Making field select box (when extended view for a single table is enabled):
455 if ($dblist->table) {
456 $this->body .= $dblist->fieldSelectBox($dblist->table);
457 }
458 // Adding checkbox options for extended listing and clipboard display:
459 $this->body .= '
460
461 <!--
462 Listing options for extended view, clipboard and localization view
463 -->
464 <div id="typo3-listOptions">
465 <form action="" method="post">';
466
467 // Add "display bigControlPanel" checkbox:
468 if ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'selectable') {
469 $this->body .= '<div class="checkbox">' .
470 '<label for="checkLargeControl">' .
471 BackendUtility::getFuncCheck($this->id, 'SET[bigControlPanel]', $this->MOD_SETTINGS['bigControlPanel'], '', $this->table ? '&table=' . $this->table : '', 'id="checkLargeControl"') .
472 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', $lang->getLL('largeControl', TRUE)) .
473 '</label>' .
474 '</div>';
475 }
476
477 // Add "clipboard" checkbox:
478 if ($this->modTSconfig['properties']['enableClipBoard'] === 'selectable') {
479 if ($dblist->showClipboard) {
480 $this->body .= '<div class="checkbox">' .
481 '<label for="checkShowClipBoard">' .
482 BackendUtility::getFuncCheck($this->id, 'SET[clipBoard]', $this->MOD_SETTINGS['clipBoard'], '', $this->table ? '&table=' . $this->table : '', 'id="checkShowClipBoard"') .
483 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', $lang->getLL('showClipBoard', TRUE)) .
484 '</label>' .
485 '</div>';
486 }
487 }
488
489 // Add "localization view" checkbox:
490 if ($this->modTSconfig['properties']['enableLocalizationView'] === 'selectable') {
491 $this->body .= '<div class="checkbox">' .
492 '<label for="checkLocalization">' .
493 BackendUtility::getFuncCheck($this->id, 'SET[localization]', $this->MOD_SETTINGS['localization'], '', $this->table ? '&table=' . $this->table : '', 'id="checkLocalization"') .
494 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', $lang->getLL('localization', TRUE)) .
495 '</label>' .
496 '</div>';
497 }
498
499 $this->body .= '
500 </form>
501 </div>';
502 }
503 // Printing clipboard if enabled
504 if ($this->MOD_SETTINGS['clipBoard'] && $dblist->showClipboard && ($dblist->HTMLcode || $dblist->clipObj->hasElements())) {
505 $this->body .= '<div class="db_list-dashboard">' . $dblist->clipObj->printClipboard() . '</div>';
506 }
507 // Additional footer content
508 $footerContentHook = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/mod1/index.php']['drawFooterHook'];
509 if (is_array($footerContentHook)) {
510 foreach ($footerContentHook as $hook) {
511 $params = array();
512 $this->body .= GeneralUtility::callUserFunction($hook, $params, $this);
513 }
514 }
515 // Setting up the buttons and markers for docheader
516 $docHeaderButtons = $dblist->getButtons();
517 $markers = array(
518 'CSH' => $docHeaderButtons['csh'],
519 'CONTENT' => $this->body,
520 'EXTRACONTAINERCLASS' => $this->table ? 'singletable' : '',
521 'BUTTONLIST_ADDITIONAL' => '',
522 'SEARCHBOX' => '',
523 );
524 // searchbox toolbar
525 if (!$this->modTSconfig['properties']['disableSearchBox'] && ($dblist->HTMLcode || !empty($dblist->searchString))) {
526 $markers['SEARCHBOX'] = $dblist->getSearchBox();
527 $markers['BUTTONLIST_ADDITIONAL'] = '<a href="#" onclick="toggleSearchToolbox(); return false;" title="'
528 . $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.searchIcon', TRUE) . '">'
529 . IconUtility::getSpriteIcon('apps-toolbar-menu-search').'</a>';
530 }
531 // Build the <body> for the module
532 $this->content = $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
533 // Renders the module page
534 $this->content = $this->doc->render('DB list', $this->content);
535 }
536
537 /**
538 * Outputting the accumulated content to screen
539 *
540 * @return void
541 */
542 public function printContent() {
543 echo $this->content;
544 }
545
546 /**
547 * @return BackendUserAuthentication
548 */
549 protected function getBackendUserAuthentication() {
550 return $GLOBALS['BE_USER'];
551 }
552
553 /**
554 * @return LanguageService
555 */
556 protected function getLanguageService() {
557 return $GLOBALS['LANG'];
558 }
559
560 /**
561 * @return DocumentTemplate
562 */
563 protected function getDocumentTemplate() {
564 return $GLOBALS['TBE_TEMPLATE'];
565 }
566
567 }