[BUGFIX] Move issueCommand to BackendUtility
[Packages/TYPO3.CMS.git] / typo3 / sysext / version / Classes / Controller / VersionModuleController.php
1 <?php
2 namespace TYPO3\CMS\Version\Controller;
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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Core\Imaging\Icon;
20 use TYPO3\CMS\Core\Utility\ArrayUtility;
21 use TYPO3\CMS\Core\Utility\DiffUtility;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
24 use TYPO3\CMS\Backend\Template\ModuleTemplate;
25
26 /**
27 * Versioning module, including workspace management
28 */
29 class VersionModuleController extends \TYPO3\CMS\Backend\Module\BaseScriptClass
30 {
31 /**
32 * Module configuration
33 *
34 * @var array
35 */
36 public $MCONF = array();
37
38 /**
39 * Module menu items
40 *
41 * @var array
42 */
43 public $MOD_MENU = array();
44
45 /**
46 * Module session settings
47 *
48 * @var array
49 */
50 public $MOD_SETTINGS = array();
51
52 /**
53 * document template object
54 *
55 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
56 */
57 public $doc;
58
59 /**
60 * @var string
61 */
62 public $content;
63
64 /**
65 * Accumulated content
66 *
67 * @var int
68 */
69 public $showWorkspaceCol = 0;
70
71 /**
72 * @var array
73 */
74 public $formatWorkspace_cache = array();
75
76 /**
77 * @var array
78 */
79 public $formatCount_cache = array();
80
81 /**
82 * @var array
83 */
84 public $targets = array();
85
86 /**
87 * Accumulation of online targets.
88 *
89 * @var string
90 */
91 public $pageModule = '';
92
93 /**
94 * Name of page module
95 *
96 * @var bool
97 */
98 public $publishAccess = false;
99
100 /**
101 * @var array
102 */
103 public $stageIndex = array();
104
105 /**
106 * @var array
107 */
108 public $recIndex = array();
109
110 /**
111 * The name of the module
112 *
113 * @var string
114 */
115 protected $moduleName = 'web_txversionM1';
116
117 /**
118 * ModuleTemplate object
119 *
120 * @var ModuleTemplate
121 */
122 protected $moduleTemplate;
123
124 /**
125 * Initialize language files
126 */
127 public function __construct()
128 {
129 $GLOBALS['SOBE'] = $this;
130 $GLOBALS['LANG']->includeLLFile('EXT:version/Resources/Private/Language/locallang.xlf');
131 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
132 }
133
134 /**
135 * Initialize menu configuration
136 *
137 * @return void
138 */
139 public function menuConfig()
140 {
141 // CLEANSE SETTINGS
142 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->moduleName, 'ses');
143 }
144
145 /**
146 * Main function of the module. Write the content to $this->content
147 *
148 * @return void
149 */
150 public function main()
151 {
152 // Template markers
153 $markers = array(
154 'CSH' => '',
155 'FUNC_MENU' => '',
156 'WS_MENU' => '',
157 'CONTENT' => ''
158 );
159 // Setting module configuration:
160 $this->MCONF['name'] = $this->moduleName;
161 $this->REQUEST_URI = str_replace('&sendToReview=1', '', GeneralUtility::getIndpEnv('REQUEST_URI'));
162 // Draw the header.
163 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
164 $this->doc->setModuleTemplate('EXT:version/Resources/Private/Templates/version.html');
165
166 // Setting up the context sensitive menu:
167 $this->doc->getContextMenuCode();
168 // Getting input data:
169 $this->id = (int)GeneralUtility::_GP('id');
170
171 // Record uid. Goes with table name to indicate specific record
172 $this->uid = (int)GeneralUtility::_GP('uid');
173 // // Record table. Goes with uid to indicate specific record
174 $this->table = GeneralUtility::_GP('table');
175
176 $this->details = GeneralUtility::_GP('details');
177 // Page id. If set, indicates activation from Web>Versioning module
178 $this->diffOnly = GeneralUtility::_GP('diffOnly');
179 // Flag. If set, shows only the offline version and with diff-view
180 // Force this setting:
181 $this->MOD_SETTINGS['expandSubElements'] = true;
182 $this->MOD_SETTINGS['diff'] = $this->details || $this->MOD_SETTINGS['diff'] ? 1 : 0;
183 // Reading the record:
184 $record = BackendUtility::getRecord($this->table, $this->uid);
185 if ($record['pid'] == -1) {
186 $record = BackendUtility::getRecord($this->table, $record['t3ver_oid']);
187 }
188 $this->recordFound = is_array($record);
189 $pidValue = $this->table === 'pages' ? $this->uid : $record['pid'];
190 // Checking access etc.
191 if ($this->recordFound && $GLOBALS['TCA'][$this->table]['ctrl']['versioningWS'] && !$this->id) {
192 $this->uid = $record['uid'];
193 // Might have changed if new live record was found!
194 // Access check!
195 // The page will show only if there is a valid page and if this page may be viewed by the user
196 $this->pageinfo = BackendUtility::readPageAccess($pidValue, $this->perms_clause);
197 $access = is_array($this->pageinfo) ? 1 : 0;
198 if ($pidValue && $access || $GLOBALS['BE_USER']->user['admin'] && !$pidValue) {
199 // If another page module was specified, replace the default Page module with the new one
200 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
201 $this->pageModule = BackendUtility::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
202 // Setting publish access permission for workspace:
203 $this->publishAccess = $GLOBALS['BE_USER']->workspacePublishAccess($GLOBALS['BE_USER']->workspace);
204 $this->versioningMgm();
205 }
206 // Setting up the buttons and markers for docheader
207 $docHeaderButtons = $this->getButtons();
208 $markers['CSH'] = $docHeaderButtons['csh'];
209 $markers['FUNC_MENU'] = BackendUtility::getFuncMenu($this->id, 'SET[function]', $this->MOD_SETTINGS['function'], $this->MOD_MENU['function']);
210 $markers['CONTENT'] = $this->content;
211 } else {
212 // If no access or id value, create empty document
213 $this->content = $this->doc->section($GLOBALS['LANG']->getLL('clickAPage_header'), $GLOBALS['LANG']->getLL('clickAPage_content'), 0, 1);
214 // Setting up the buttons and markers for docheader
215 $docHeaderButtons = $this->getButtons();
216 $markers['CONTENT'] = $this->content;
217 }
218 // Build the <body> for the module
219 $this->content = $this->doc->startPage($GLOBALS['LANG']->getLL('title'));
220 $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
221 $this->content .= $this->doc->endPage();
222 $this->content = $this->doc->insertStylesAndJS($this->content);
223 }
224
225 /**
226 * Outputs accumulated module content to browser.
227 *
228 * @return void
229 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
230 */
231 public function printContent()
232 {
233 GeneralUtility::logDeprecatedFunction();
234 echo $this->content;
235 }
236
237 /**
238 * Create the panel of buttons for submitting the form or otherwise perform operations.
239 *
240 * @return array All available buttons as an assoc. array
241 */
242 protected function getButtons()
243 {
244 $buttons = array(
245 'csh' => '',
246 'view' => '',
247 'record_list' => '',
248 'shortcut' => ''
249 );
250 // CSH
251 if ($this->recordFound && $GLOBALS['TCA'][$this->table]['ctrl']['versioningWS']) {
252 // View page
253 $buttons['view'] = '
254 <a href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid']))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', true) . '">
255 ' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '
256 </a>';
257 // Shortcut
258 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
259 $buttons['shortcut'] = $this->doc->makeShortcutIcon('id, edit_record, pointer, new_unique_uid, search_field, search_levels, showLimit', implode(',', array_keys($this->MOD_MENU)), $this->moduleName);
260 }
261 // If access to Web>List for user, then link to that module.
262 $buttons['record_list'] = BackendUtility::getListViewLink(array(
263 'id' => $this->pageinfo['uid'],
264 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
265 ), '', $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showList'));
266 }
267 return $buttons;
268 }
269
270 /******************************
271 *
272 * Versioning management
273 *
274 ******************************/
275 /**
276 * Management of versions for record
277 *
278 * @return void
279 */
280 public function versioningMgm()
281 {
282 // Diffing:
283 $diff_1 = GeneralUtility::_POST('diff_1');
284 $diff_2 = GeneralUtility::_POST('diff_2');
285 if (GeneralUtility::_POST('do_diff')) {
286 $content = '';
287 $content .= '<div class="panel panel-space panel-default">';
288 $content .= '<div class="panel-heading">' . $GLOBALS['LANG']->getLL('diffing') . '</div>';
289 if ($diff_1 && $diff_2) {
290 $diff_1_record = BackendUtility::getRecord($this->table, $diff_1);
291 $diff_2_record = BackendUtility::getRecord($this->table, $diff_2);
292 if (is_array($diff_1_record) && is_array($diff_2_record)) {
293 $diffUtility = GeneralUtility::makeInstance(DiffUtility::class);
294 $rows = array();
295 $rows[] = '
296 <tr>
297 <th>' . $GLOBALS['LANG']->getLL('fieldname') . '</th>
298 <th width="98%">' . $GLOBALS['LANG']->getLL('coloredDiffView') . ':</th>
299 </tr>
300 ';
301 foreach ($diff_1_record as $fN => $fV) {
302 if ($GLOBALS['TCA'][$this->table]['columns'][$fN] && $GLOBALS['TCA'][$this->table]['columns'][$fN]['config']['type'] !== 'passthrough' && !GeneralUtility::inList('t3ver_label', $fN)) {
303 if ((string)$diff_1_record[$fN] !== (string)$diff_2_record[$fN]) {
304 $diffres = $diffUtility->makeDiffDisplay(
305 BackendUtility::getProcessedValue($this->table, $fN, $diff_2_record[$fN], 0, 1),
306 BackendUtility::getProcessedValue($this->table, $fN, $diff_1_record[$fN], 0, 1)
307 );
308 $rows[] = '
309 <tr>
310 <td>' . $fN . '</td>
311 <td width="98%">' . $diffres . '</td>
312 </tr>
313 ';
314 }
315 }
316 }
317 if (count($rows) > 1) {
318 $content .= '<div class="table-fit"><table class="table">' . implode('', $rows) . '</table></div>';
319 } else {
320 $content .= '<div class="panel-body">' . $GLOBALS['LANG']->getLL('recordsMatchesCompletely') . '</div>';
321 }
322 } else {
323 $content .= '<div class="panel-body">' . $GLOBALS['LANG']->getLL('errorRecordsNotFound') . '</div>';
324 }
325 } else {
326 $content .= '<div class="panel-body">' . $GLOBALS['LANG']->getLL('errorDiffSources') . '</div>';
327 }
328 $content .= '</div>';
329 }
330 // Element:
331 $record = BackendUtility::getRecord($this->table, $this->uid);
332 $recTitle = BackendUtility::getRecordTitle($this->table, $record, true);
333 // Display versions:
334 $content .= '
335 <form name="theform" action="' . str_replace('&sendToReview=1', '', $this->REQUEST_URI) . '" method="post">
336 <div class="panel panel-space panel-default">
337 <div class="panel-heading">' . $recTitle . '</div>
338 <div class="table-fit">
339 <table class="table">
340 <thead>
341 <tr>
342 <th colspan="2" class="col-icon"></th>
343 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_title') . '">' . $GLOBALS['LANG']->getLL('tblHeader_title') . '</th>
344 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_uid') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_uid') . '</i></th>
345 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_oid') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_oid') . '</i></th>
346 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_id') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_id') . '</i></th>
347 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_wsid') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_wsid') . '</i></th>
348 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_state', true) . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_state') . '</i></th>
349 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_stage') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_stage') . '</i></th>
350 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_count') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_count') . '</i></th>
351 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_pid') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_pid') . '</i></th>
352 <th title="' . $GLOBALS['LANG']->getLL('tblHeaderDesc_t3ver_label') . '"><i>' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_label') . '</i></th>
353 <th></th>
354 <th colspan="2">
355 <button class="btn btn-default btn-sm" type="submit" name="do_diff" value="true">
356 ' . $GLOBALS['LANG']->getLL('diff') . '
357 </button>
358 </th>
359 </tr>
360 </thead>
361 <tbody>
362 ';
363 $versions = BackendUtility::selectVersionsOfRecord($this->table, $this->uid, '*', $GLOBALS['BE_USER']->workspace);
364 foreach ($versions as $row) {
365 $adminLinks = $this->adminLinks($this->table, $row);
366
367 $editUrl = BackendUtility::getModuleUrl('record_edit', [
368 'edit' => [
369 $this->table => [
370 $row['uid'] => 'edit'
371 ]
372 ],
373 'columnsOnly' => 't3ver_label',
374 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
375 ]);
376 $content .= '
377 <tr' . ($row['uid'] != $this->uid ? '' : ' class="active"') . '>
378 <td class="col-icon">' .
379 ($row['uid'] != $this->uid ?
380 '<a href="' . BackendUtility::getLinkToDataHandlerAction('&cmd[' . $this->table . '][' . $this->uid . '][version][swapWith]=' . $row['uid'] . '&cmd[' . $this->table . '][' . $this->uid . '][version][action]=swap') . '" title="' . $GLOBALS['LANG']->getLL('swapWithCurrent', true) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-version-swap-version', Icon::SIZE_SMALL)->render() . '</a>' :
381 '<span title="' . $GLOBALS['LANG']->getLL('currentOnlineVersion', true) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('status-status-current', Icon::SIZE_SMALL)->render() . '</span>'
382 ) . '
383 </td>
384 <td class="col-icon">' . $this->moduleTemplate->getIconFactory()->getIconForRecord($this->table, $row, Icon::SIZE_SMALL)->render() . '</td>
385 <td>' . htmlspecialchars(BackendUtility::getRecordTitle($this->table, $row, true)) . '</td>
386 <td>' . $row['uid'] . '</td>
387 <td>' . $row['t3ver_oid'] . '</td>
388 <td>' . $row['t3ver_id'] . '</td>
389 <td>' . $row['t3ver_wsid'] . '</td>
390 <td>' . $row['t3ver_state'] . '</td>
391 <td>' . $row['t3ver_stage'] . '</td>
392 <td>' . $row['t3ver_count'] . '</td>
393 <td>' . $row['pid'] . '</td>
394 <td>
395 <a href="' . htmlspecialchars($editUrl) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.edit', true) . '">
396 ' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '
397 </a>' . htmlspecialchars($row['t3ver_label']) . '
398 </td>
399 <td class="col-control">' . $adminLinks . '</td>
400 <td class="text-center success"><input type="radio" name="diff_1" value="' . $row['uid'] . '"' . ($diff_1 == $row['uid'] ? ' checked="checked"' : '') . '/></td>
401 <td class="text-center danger"><input type="radio" name="diff_2" value="' . $row['uid'] . '"' . ($diff_2 == $row['uid'] ? ' checked="checked"' : '') . '/></td>
402 </tr>';
403 // Show sub-content if the table is pages AND it is not the online branch (because that will mostly render the WHOLE tree below - not smart;)
404 if ($this->table === 'pages' && $row['uid'] != $this->uid) {
405 $sub = $this->pageSubContent($row['uid']);
406 if ($sub) {
407 $content .= '
408 <tr>
409 <td colspan="2"></td>
410 <td colspan="11">' . $sub . '</td>
411 <td class="success"></td>
412 <td class="danger"></td>
413 </tr>';
414 }
415 }
416 }
417 $content .= '
418 </tbody>
419 </table>
420 </div>
421 </div>
422 </form>';
423 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('title'), $content, 0, 1);
424 // Create new:
425 $content = '
426 <form action="' . htmlspecialchars(BackendUtility::getModuleUrl('tce_db')) . '" method="post">
427 <div class="row">
428 <div class="col-sm-6 col-md-4 col-lg-3">
429 <div class="form-group">
430 <label for="typo3-new-version-label">' . $GLOBALS['LANG']->getLL('tblHeader_t3ver_label') . '</label>
431 <input id="typo3-new-version-label" class="form-control" type="text" name="cmd[' . $this->table . '][' . $this->uid . '][version][label]" />
432 </div>
433 <div class="form-group">
434 <input type="hidden" name="cmd[' . $this->table . '][' . $this->uid . '][version][action]" value="new" />
435 <input type="hidden" name="prErr" value="1" />
436 <input type="hidden" name="redirect" value="' . htmlspecialchars($this->REQUEST_URI) . '" />
437 <input class="btn btn-default" type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('createNewVersion') . '" />
438 </div>
439 </div>
440 </div>
441 </form>
442
443 ';
444 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('createNewVersion'), $content, 0, 1);
445 }
446
447 /**
448 * Recursively look for children for page version with $pid
449 *
450 * @param int $pid UID of page record for which to look up sub-elements following that version
451 * @param int $c Counter, do not set (limits to 100 levels)
452 * @return string Table with content if any
453 */
454 public function pageSubContent($pid, $c = 0)
455 {
456 $tableNames = ArrayUtility::removeArrayEntryByValue(array_keys($GLOBALS['TCA']), 'pages');
457 $tableNames[] = 'pages';
458 $content = '';
459 foreach ($tableNames as $table) {
460 // Basically list ALL tables - not only those being copied might be found!
461 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'pid=' . (int)$pid . BackendUtility::deleteClause($table), '', $GLOBALS['TCA'][$table]['ctrl']['sortby'] ? $GLOBALS['TCA'][$table]['ctrl']['sortby'] : '');
462 if ($GLOBALS['TYPO3_DB']->sql_num_rows($mres)) {
463 $content .= '
464 <table class="table">
465 <tr>
466 <th class="col-icon">' . $this->moduleTemplate->getIconFactory()->getIconForRecord($table, array(), Icon::SIZE_SMALL)->render() . '</th>
467 <th class="col-title">' . $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title'], true) . '</th>
468 <th></th>
469 <th></th>
470 </tr>';
471 while ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
472 $ownVer = $this->lookForOwnVersions($table, $subrow['uid']);
473 $content .= '
474 <tr>
475 <td class="col-icon">' . $this->moduleTemplate->getIconFactory()->getIconForRecord($table, $subrow, Icon::SIZE_SMALL)->render() . '</td>
476 <td class="col-title">' . htmlspecialchars(BackendUtility::getRecordTitle($table, $subrow, true)) . '</td>
477 <td>' . ($ownVer > 1 ? '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('web_txversionM1', array('table' => $table, 'uid' => $subrow['uid']))) . '">' . ($ownVer - 1) . '</a>' : '') . '</td>
478 <td class="col-control">' . $this->adminLinks($table, $subrow) . '</td>
479 </tr>';
480 if ($table == 'pages' && $c < 100) {
481 $sub = $this->pageSubContent($subrow['uid'], $c + 1);
482 if ($sub) {
483 $content .= '
484 <tr>
485 <td></td>
486 <td></td>
487 <td></td>
488 <td width="98%">' . $sub . '</td>
489 </tr>';
490 }
491 }
492 }
493 $content .= '</table>';
494 }
495 $GLOBALS['TYPO3_DB']->sql_free_result($mres);
496 }
497 return $content;
498 }
499
500 /**
501 * Look for number of versions of a record
502 *
503 * @param string $table Table name
504 * @param int $uid Record uid
505 * @return int Number of versions for record, FALSE if none.
506 */
507 public function lookForOwnVersions($table, $uid)
508 {
509 $versions = BackendUtility::selectVersionsOfRecord($table, $uid, 'uid', null);
510 if (is_array($versions)) {
511 return count($versions);
512 }
513 return false;
514 }
515
516 /**
517 * Administrative links for a table / record
518 *
519 * @param string $table Table name
520 * @param array $row Record for which administrative links are generated.
521 * @return string HTML link tags.
522 */
523 public function adminLinks($table, $row)
524 {
525 // Edit link:
526 $editUrl = BackendUtility::getModuleUrl('record_edit', [
527 'edit' => [
528 $table => [
529 $row['uid'] => 'edit'
530 ]
531 ],
532 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
533 ]);
534 $adminLink = '<a class="btn btn-default" href="' . htmlspecialchars($editUrl) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.edit', true) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
535 // Delete link:
536 $adminLink .= '<a class="btn btn-default" href="' . htmlspecialchars(BackendUtility::getLinkToDataHandlerAction('&cmd[' . $table . '][' . $row['uid'] . '][delete]=1')) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.delete', true) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</a>';
537 if ($table === 'pages') {
538 // If another page module was specified, replace the default Page module with the new one
539 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
540 $pageModule = BackendUtility::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
541 // Perform some access checks:
542 $a_wl = $GLOBALS['BE_USER']->check('modules', 'web_list');
543 $a_wp = $GLOBALS['BE_USER']->check('modules', $pageModule);
544 $adminLink .= '<a class="btn btn-default" href="#" onclick="top.loadEditId(' . $row['uid'] . ');top.goToModule(\'' . $pageModule . '\'); return false;">'
545 . $this->moduleTemplate->getIconFactory()->getIcon('actions-page-open', Icon::SIZE_SMALL)->render()
546 . '</a>';
547 $adminLink .= '<a class="btn btn-default" href="#" onclick="top.loadEditId(' . $row['uid'] . ');top.goToModule(\'web_list\'); return false;">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-system-list-open', Icon::SIZE_SMALL)->render() . '</a>';
548 // "View page" icon is added:
549 $adminLink .= '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($row['uid'], '', BackendUtility::BEgetRootLine($row['uid']))) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '</a>';
550 } else {
551 if ($row['pid'] == -1) {
552 $getVars = '&ADMCMD_vPrev[' . rawurlencode(($table . ':' . $row['t3ver_oid'])) . ']=' . $row['uid'];
553 // "View page" icon is added:
554 $adminLink .= '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars(BackendUtility::viewOnClick($row['_REAL_PID'], '', BackendUtility::BEgetRootLine($row['_REAL_PID']), '', '', $getVars)) . '">' . $this->moduleTemplate->getIconFactory()->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '</a>';
555 }
556 }
557 return '<div class="btn-group btn-group-sm" role="group">' . $adminLink . '</div>';
558 }
559
560
561 /**
562 * Injects the request object for the current request and gathers all data.
563 *
564 * @param ServerRequestInterface $request the current request
565 * @param ResponseInterface $response the prepared response
566 * @return ResponseInterface the response with the content
567 */
568 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
569 {
570 $this->init();
571 $this->main();
572
573 $response->getBody()->write($this->content);
574 return $response;
575 }
576 }