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