TYPO3 CMS  TYPO3_7-6
ActionTask.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\SysAction;
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 
24 
29 {
33  protected $taskObject;
34 
40  protected $hookObjects = [];
41 
47  protected $moduleUrl;
48 
52  protected $iconFactory;
53 
57  public function __construct(\TYPO3\CMS\Taskcenter\Controller\TaskModuleController $taskObject)
58  {
59  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
60  $this->moduleUrl = BackendUtility::getModuleUrl('user_task');
61  $this->taskObject = $taskObject;
62  $this->getLanguageService()->includeLLFile('EXT:sys_action/Resources/Private/Language/locallang.xlf');
63  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['sys_action']['tx_sysaction_task'])) {
64  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['sys_action']['tx_sysaction_task'] as $classRef) {
65  $this->hookObjects[] = GeneralUtility::getUserObj($classRef);
66  }
67  }
68  }
69 
75  public function getTask()
76  {
77  $content = '';
78  $show = (int)GeneralUtility::_GP('show');
79  foreach ($this->hookObjects as $hookObject) {
80  if (method_exists($hookObject, 'getTask')) {
81  $show = $hookObject->getTask($show, $this);
82  }
83  }
84  // If no task selected, render the menu
85  if ($show == 0) {
86  $content .= $this->taskObject->description($this->getLanguageService()->getLL('sys_action'), $this->getLanguageService()->getLL('description'));
87  $content .= $this->renderActionList();
88  } else {
89  $record = BackendUtility::getRecord('sys_action', $show);
90  // If the action is not found
91  if (empty($record)) {
92  $this->addMessage(
93  $this->getLanguageService()->getLL('action_error-not-found'),
94  $this->getLanguageService()->getLL('action_error'),
96  );
97  } else {
98  // Render the task
99  $content .= $this->taskObject->description($record['title'], $record['description']);
100  // Output depends on the type
101  switch ($record['type']) {
102  case 1:
103  $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
104  $pageRenderer->loadRequireJsModule('TYPO3/CMS/SysAction/ActionTask');
105  $content .= $this->viewNewBackendUser($record);
106  break;
107  case 2:
108  $content .= $this->viewSqlQuery($record);
109  break;
110  case 3:
111  $content .= $this->viewRecordList($record);
112  break;
113  case 4:
114  $content .= $this->viewEditRecord($record);
115  break;
116  case 5:
117  $content .= $this->viewNewRecord($record);
118  break;
119  default:
120  $this->addMessage(
121  $this->getLanguageService()->getLL('action_noType'),
122  $this->getLanguageService()->getLL('action_error'),
124  );
125  $content .= '<br />' . $this->renderFlashMessages();
126  }
127  }
128  }
129  return $content;
130  }
131 
137  public function getOverview()
138  {
139  $content = '<p>' . $this->getLanguageService()->getLL('description') . '</p>';
140  // Get the actions
141  $actionList = $this->getActions();
142  if (!empty($actionList)) {
143  $items = '';
144  // Render a single action menu item
145  foreach ($actionList as $action) {
146  $active = GeneralUtility::_GP('show') === $action['uid'] ? ' class="active" ' : '';
147  $items .= '<li' . $active . '>
148  <a href="' . $action['link'] . '" title="' . htmlspecialchars($action['description']) . '">' . htmlspecialchars($action['title']) . '</a>
149  </li>';
150  }
151  $content .= '<ul>' . $items . '</ul>';
152  }
153  return $content;
154  }
155 
162  protected function getActions()
163  {
164  $actionList = [];
165  // admins can see any record
166  if ($this->getBackendUser()->isAdmin()) {
167  $res = $this->getDatabaseConnection()->exec_SELECTquery('*', 'sys_action', '', '', 'sys_action.sorting');
168  } else {
169  // Editors can only see the actions which are assigned to a usergroup they belong to
170  $additionalWhere = 'be_groups.uid IN (' . ($this->getBackendUser()->groupList ?: 0) . ')';
171  $res = $this->getDatabaseConnection()->exec_SELECT_mm_query('sys_action.*', 'sys_action', 'sys_action_asgr_mm', 'be_groups', ' AND sys_action.hidden=0 AND ' . $additionalWhere, 'sys_action.uid', 'sys_action.sorting');
172  }
173  while ($actionRow = $this->getDatabaseConnection()->sql_fetch_assoc($res)) {
174  $editActionLink = '';
175  // Admins are allowed to edit sys_action records
176  if ($this->getBackendUser()->isAdmin()) {
177  $link = BackendUtility::getModuleUrl(
178  'record_edit',
179  [
180  'edit[sys_action][' . $actionRow['uid'] . ']' => 'edit',
181  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
182  ],
183  false,
184  true
185  );
186  $title = 'title="' . $this->getLanguageService()->getLL('edit-sys_action') . '"';
187  $icon = $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render();
188  $editActionLink = '<a class="edit" href="' . $link . '"' . $title . '>';
189  $editActionLink .= $icon . $this->getLanguageService()->getLL('edit-sys_action') . '</a>';
190  }
191  $actionList[] = [
192  'uid' => $actionRow['uid'],
193  'title' => $actionRow['title'],
194  'description' => $actionRow['description'],
195  'descriptionHtml' => nl2br(htmlspecialchars($actionRow['description'])) . $editActionLink,
196  'link' => $this->moduleUrl . '&SET[function]=sys_action.TYPO3\\CMS\\SysAction\\ActionTask&show=' . $actionRow['uid']
197  ];
198  }
199  $this->getDatabaseConnection()->sql_free_result($res);
200  return $actionList;
201  }
202 
208  protected function renderActionList()
209  {
210  $content = '';
211  // Get the sys_action records
212  $actionList = $this->getActions();
213  // If any actions are found for the current users
214  if (!empty($actionList)) {
215  $content .= $this->taskObject->renderListMenu($actionList);
216  } else {
217  $this->addMessage(
218  $this->getLanguageService()->getLL('action_not-found-description'),
219  $this->getLanguageService()->getLL('action_not-found'),
221  );
222  }
223  // Admin users can create a new action
224  if ($this->getBackendUser()->isAdmin()) {
225  $link = BackendUtility::getModuleUrl(
226  'record_edit',
227  [
228  'edit[sys_action][0]' => 'new',
229  'returnUrl' => $this->moduleUrl
230  ],
231  false,
232  true
233  );
234  $content .= '<p>' .
235  '<a href="' . $link . '" title="' . $this->getLanguageService()->getLL('new-sys_action') . '">' .
236  $this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render() .
237  $this->getLanguageService()->getLL('new-sys_action') .
238  '</a></p>';
239  }
240  return $content;
241  }
242 
249  protected function viewNewBackendUser($record)
250  {
251  $content = '';
252  $beRec = BackendUtility::getRecord('be_users', (int)$record['t1_copy_of_user']);
253  // A record is need which is used as copy for the new user
254  if (!is_array($beRec)) {
255  $this->addMessage(
256  $this->getLanguageService()->getLL('action_notReady'),
257  $this->getLanguageService()->getLL('action_error'),
259  );
260  $content .= $this->renderFlashMessages();
261  return $content;
262  }
263  $vars = GeneralUtility::_POST('data');
264  $key = 'NEW';
265  if ($vars['sent'] == 1) {
266  $errors = [];
267  // Basic error checks
268  if (!empty($vars['email']) && !GeneralUtility::validEmail($vars['email'])) {
269  $errors[] = $this->getLanguageService()->getLL('error-wrong-email');
270  }
271  if (empty($vars['username'])) {
272  $errors[] = $this->getLanguageService()->getLL('error-username-empty');
273  }
274  if ($vars['key'] === 'NEW' && empty($vars['password'])) {
275  $errors[] = $this->getLanguageService()->getLL('error-password-empty');
276  }
277  if ($vars['key'] !== 'NEW' && !$this->isCreatedByUser($vars['key'], $record)) {
278  $errors[] = $this->getLanguageService()->getLL('error-wrong-user');
279  }
280  foreach ($this->hookObjects as $hookObject) {
281  if (method_exists($hookObject, 'viewNewBackendUser_Error')) {
282  $errors = $hookObject->viewNewBackendUser_Error($vars, $errors, $this);
283  }
284  }
285  // Show errors if there are any
286  if (!empty($errors)) {
287  $this->addMessage(
288  implode(LF, $errors),
289  $this->getLanguageService()->getLL('action_error'),
291  );
292  } else {
293  // Save user
294  $key = $this->saveNewBackendUser($record, $vars);
295  // Success message
296  $message = $vars['key'] === 'NEW'
297  ? $this->getLanguageService()->getLL('success-user-created')
298  : $this->getLanguageService()->getLL('success-user-updated');
299  $this->addMessage(
300  $message,
301  $this->getLanguageService()->getLL('success')
302  );
303  }
304  $content .= $this->renderFlashMessages() . '<br />';
305  }
306  // Load BE user to edit
307  if ((int)GeneralUtility::_GP('be_users_uid') > 0) {
308  $tmpUserId = (int)GeneralUtility::_GP('be_users_uid');
309  // Check if the selected user is created by the current user
310  $rawRecord = $this->isCreatedByUser($tmpUserId, $record);
311  if ($rawRecord) {
312  // Delete user
313  if (GeneralUtility::_GP('delete') == 1) {
314  $this->deleteUser($tmpUserId, $record['uid']);
315  }
316  $key = $tmpUserId;
317  $vars = $rawRecord;
318  }
319  }
320  $content .= '<form action="" method="post" enctype="multipart/form-data">
321  <fieldset class="fields">
322  <legend>' . $this->getLanguageService()->getLL('action_t1_legend_generalFields') . '</legend>
323  <div class="row">
324  <label for="field_disable">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_general.xlf:LGL.disable') . '</label>
325  <input type="checkbox" id="field_disable" name="data[disable]" value="1" class="checkbox" ' . ($vars['disable'] == 1 ? ' checked="checked" ' : '') . ' />
326  </div>
327  <div class="row">
328  <label for="field_realname">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_general.xlf:LGL.name') . '</label>
329  <input type="text" id="field_realname" name="data[realName]" value="' . htmlspecialchars($vars['realName']) . '" />
330  </div>
331  <div class="row">
332  <label for="field_username">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_tca.xlf:be_users.username') . '</label>
333  <input type="text" id="field_username" name="data[username]" value="' . htmlspecialchars($vars['username']) . '" />
334  </div>
335  <div class="row">
336  <label for="field_password">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_tca.xlf:be_users.password') . '</label>
337  <input type="password" id="field_password" name="data[password]" value="" />
338  </div>
339  <div class="row">
340  <label for="field_email">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_general.xlf:LGL.email') . '</label>
341  <input type="text" id="field_email" name="data[email]" value="' . htmlspecialchars($vars['email']) . '" />
342  </div>
343  </fieldset>
344  <fieldset class="fields">
345  <legend>' . $this->getLanguageService()->getLL('action_t1_legend_configuration') . '</legend>
346 
347  <div class="row">
348  <label for="field_usergroup">' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_tca.xlf:be_users.usergroup') . '</label>
349  <select id="field_usergroup" name="data[usergroup][]" multiple="multiple">
350  ' . $this->getUsergroups($record, $vars) . '
351  </select>
352  </div>
353  <div class="row">
354  <input type="hidden" name="data[key]" value="' . $key . '" />
355  <input type="hidden" name="data[sent]" value="1" />
356  <input class="btn btn-default" type="submit" value="' . ($key === 'NEW' ? $this->getLanguageService()->getLL('action_Create') : $this->getLanguageService()->getLL('action_Update')) . '" />
357  </div>
358  </fieldset>
359  </form>';
360  $content .= $this->getCreatedUsers($record, $key);
361  return $content;
362  }
363 
371  protected function deleteUser($userId, $actionId)
372  {
373  $this->getDatabaseConnection()->exec_UPDATEquery('be_users', 'uid=' . $userId, [
374  'deleted' => 1,
375  'tstamp' => $GLOBALS['ACCESS_TIME']
376  ]);
377  // redirect to the original task
378  $redirectUrl = $this->moduleUrl . '&show=' . $actionId;
380  }
381 
389  protected function isCreatedByUser($id, $action)
390  {
391  $record = BackendUtility::getRecord('be_users', $id, '*', ' AND cruser_id=' . $this->getBackendUser()->user['uid'] . ' AND createdByAction=' . $action['uid']);
392  if (is_array($record)) {
393  return $record;
394  } else {
395  return false;
396  }
397  }
398 
406  protected function getCreatedUsers($action, $selectedUser)
407  {
408  $content = '';
409  $userList = [];
410  // List of users
411  $res = $this->getDatabaseConnection()->exec_SELECTquery('*', 'be_users', 'cruser_id=' . $this->getBackendUser()->user['uid'] . ' AND createdByAction=' . (int)$action['uid'] . BackendUtility::deleteClause('be_users'), '', 'username');
412  // Render the user records
413  while ($row = $this->getDatabaseConnection()->sql_fetch_assoc($res)) {
414  $icon = '<span title="' . htmlspecialchars('uid=' . $row['uid']) . '">' . $this->iconFactory->getIconForRecord('be_users', $row, Icon::SIZE_SMALL)->render() . '</span>';
415  $line = $icon . $this->action_linkUserName($row['username'], $row['realName'], $action['uid'], $row['uid']);
416  // Selected user
417  if ($row['uid'] == $selectedUser) {
418  $line = '<strong>' . $line . '</strong>';
419  }
420  $userList[] = $line;
421  }
422  $this->getDatabaseConnection()->sql_free_result($res);
423  // If any records found
424  if (!empty($userList)) {
425  $content .= '<br /><h3>' . $this->getLanguageService()->getLL('action_t1_listOfUsers', true) . '</h3><div>' . implode('<br />', $userList) . '</div>';
426  }
427  return $content;
428  }
429 
439  protected function action_linkUserName($username, $realName, $sysActionUid, $userId)
440  {
441  if (!empty($realName)) {
442  $username .= ' (' . $realName . ')';
443  }
444  // Link to update the user record
445  $href = $this->moduleUrl . '&SET[function]=sys_action.TYPO3\\CMS\\SysAction\\ActionTask&show=' . (int)$sysActionUid . '&be_users_uid=' . (int)$userId;
446  $link = '<a href="' . htmlspecialchars($href) . '">' . htmlspecialchars($username) . '</a>';
447  // Link to delete the user record
448  $link .= '
449  <a href="' . htmlspecialchars(($href . '&delete=1')) . '" class="t3js-confirm-trigger" data-title="' . $this->getLanguageService()->getLL('lDelete_warning_title', true) . '" data-message="' . $this->getLanguageService()->getLL('lDelete_warning', true) . '">'
450  . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() .
451  '</a>';
452  return $link;
453  }
454 
462  protected function saveNewBackendUser($record, $vars)
463  {
464  // Check if the db mount is a page the current user is allowed to.);
465  $vars['db_mountpoints'] = $this->fixDbMount($vars['db_mountpoints']);
466  // Check if the usergroup is allowed
467  $vars['usergroup'] = $this->fixUserGroup($vars['usergroup'], $record);
468  $key = $vars['key'];
469  $vars['password'] = trim($vars['password']);
470  // Check if md5 is used as password encryption
471  if ($vars['password'] !== '' && strpos($GLOBALS['TCA']['be_users']['columns']['password']['config']['eval'], 'md5') !== false) {
472  $vars['password'] = md5($vars['password']);
473  }
474  $data = '';
475  $newUserId = 0;
476  if ($key === 'NEW') {
477  $beRec = BackendUtility::getRecord('be_users', (int)$record['t1_copy_of_user']);
478  if (is_array($beRec)) {
479  $data = [];
480  $data['be_users'][$key] = $beRec;
481  $data['be_users'][$key]['username'] = $this->fixUsername($vars['username'], $record['t1_userprefix']);
482  $data['be_users'][$key]['password'] = $vars['password'];
483  $data['be_users'][$key]['realName'] = $vars['realName'];
484  $data['be_users'][$key]['email'] = $vars['email'];
485  $data['be_users'][$key]['disable'] = (int)$vars['disable'];
486  $data['be_users'][$key]['admin'] = 0;
487  $data['be_users'][$key]['usergroup'] = $vars['usergroup'];
488  $data['be_users'][$key]['db_mountpoints'] = $vars['db_mountpoints'];
489  $data['be_users'][$key]['createdByAction'] = $record['uid'];
490  }
491  } else {
492  // Check ownership
493  $beRec = BackendUtility::getRecord('be_users', (int)$key);
494  if (is_array($beRec) && $beRec['cruser_id'] == $this->getBackendUser()->user['uid']) {
495  $data = [];
496  $data['be_users'][$key]['username'] = $this->fixUsername($vars['username'], $record['t1_userprefix']);
497  if ($vars['password'] !== '') {
498  $data['be_users'][$key]['password'] = $vars['password'];
499  }
500  $data['be_users'][$key]['realName'] = $vars['realName'];
501  $data['be_users'][$key]['email'] = $vars['email'];
502  $data['be_users'][$key]['disable'] = (int)$vars['disable'];
503  $data['be_users'][$key]['admin'] = 0;
504  $data['be_users'][$key]['usergroup'] = $vars['usergroup'];
505  $data['be_users'][$key]['db_mountpoints'] = $vars['db_mountpoints'];
506  $newUserId = $key;
507  }
508  }
509  // Save/update user by using TCEmain
510  if (is_array($data)) {
511  $tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
512  $tce->stripslashes_values = 0;
513  $tce->start($data, [], $this->getBackendUser());
514  $tce->admin = 1;
515  $tce->process_datamap();
516  $newUserId = (int)$tce->substNEWwithIDs['NEW'];
517  if ($newUserId) {
518  // Create
519  $this->action_createDir($newUserId);
520  } else {
521  // Update
522  $newUserId = (int)$key;
523  }
524  unset($tce);
525  }
526  return $newUserId;
527  }
528 
536  protected function fixUsername($username, $prefix)
537  {
538  $prefix = trim($prefix);
539  if (substr($username, 0, strlen($prefix)) === $prefix) {
540  $username = substr($username, strlen($prefix));
541  }
542  return $prefix . $username;
543  }
544 
552  protected function fixUserGroup($appliedUsergroups, $actionRecord)
553  {
554  if (is_array($appliedUsergroups)) {
555  $cleanGroupList = [];
556  // Create an array from the allowed usergroups using the uid as key
557  $allowedUsergroups = array_flip(explode(',', $actionRecord['t1_allowed_groups']));
558  // Walk through the array and check every uid if it is under the allowed ines
559  foreach ($appliedUsergroups as $group) {
560  if (isset($allowedUsergroups[$group])) {
561  $cleanGroupList[] = $group;
562  }
563  }
564  $appliedUsergroups = $cleanGroupList;
565  }
566  return $appliedUsergroups;
567  }
568 
575  protected function fixDbMount($appliedDbMounts)
576  {
577  // Admins can see any page, no need to check there
578  if (!empty($appliedDbMounts) && !$this->getBackendUser()->isAdmin()) {
579  $cleanDbMountList = [];
580  $dbMounts = GeneralUtility::trimExplode(',', $appliedDbMounts, true);
581  // Walk through every wanted DB-Mount and check if it allowed for the current user
582  foreach ($dbMounts as $dbMount) {
583  $uid = (int)substr($dbMount, strrpos($dbMount, '_') + 1);
584  $page = BackendUtility::getRecord('pages', $uid);
585  // Check rootline and access rights
586  if ($this->checkRootline($uid) && $this->getBackendUser()->calcPerms($page)) {
587  $cleanDbMountList[] = 'pages_' . $uid;
588  }
589  }
590  // Build the clean list
591  $appliedDbMounts = implode(',', $cleanDbMountList);
592  }
593  return $appliedDbMounts;
594  }
595 
602  protected function checkRootline($pageId)
603  {
604  $access = false;
605  $dbMounts = array_flip(explode(',', trim($this->getBackendUser()->dataLists['webmount_list'], ',')));
606  $rootline = BackendUtility::BEgetRootLine($pageId);
607  foreach ($rootline as $page) {
608  if (isset($dbMounts[$page['uid']]) && !$access) {
609  $access = true;
610  }
611  }
612  return $access;
613  }
614 
621  protected function action_createDir($uid)
622  {
623  $path = $this->action_getUserMainDir();
624  if ($path) {
625  GeneralUtility::mkdir($path . $uid);
626  GeneralUtility::mkdir($path . $uid . '/_temp_/');
627  }
628  }
629 
635  protected function action_getUserMainDir()
636  {
637  $path = $GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'];
638  // If path is set and a valid directory
639  if ($path && @is_dir($path) && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] && GeneralUtility::isFirstPartOfStr($path, $GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath']) && substr($path, -1) == '/') {
640  return $path;
641  }
642  }
643 
651  protected function getUsergroups($record, $vars)
652  {
653  $content = '';
654  // Do nothing if no groups are allowed
655  if (empty($record['t1_allowed_groups'])) {
656  return $content;
657  }
658  $content .= '<option value=""></option>';
659  $grList = GeneralUtility::trimExplode(',', $record['t1_allowed_groups'], true);
660  foreach ($grList as $group) {
661  $checkGroup = BackendUtility::getRecord('be_groups', $group);
662  if (is_array($checkGroup)) {
663  $selected = GeneralUtility::inList($vars['usergroup'], $checkGroup['uid']) ? ' selected="selected" ' : '';
664  $content .= '<option ' . $selected . 'value="' . $checkGroup['uid'] . '">' . htmlspecialchars($checkGroup['title']) . '</option>';
665  }
666  }
667  return $content;
668  }
669 
676  protected function viewNewRecord($record)
677  {
678  $link = BackendUtility::getModuleUrl(
679  'record_edit',
680  [
681  'edit[' . $record['t3_tables'] . '][' . (int)$record['t3_listPid'] . ']' => 'new',
682  'returnUrl' => $this->moduleUrl
683  ],
684  false,
685  true
686  );
688  }
689 
696  protected function viewEditRecord($record)
697  {
698  $content = '';
699  $actionList = [];
700  $dbAnalysis = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\RelationHandler::class);
701  $dbAnalysis->setFetchAllFields(true);
702  $dbAnalysis->start($record['t4_recordsToEdit'], '*');
703  $dbAnalysis->getFromDB();
704  // collect the records
705  foreach ($dbAnalysis->itemArray as $el) {
706  $path = BackendUtility::getRecordPath($el['id'], $this->taskObject->perms_clause, $this->getBackendUser()->uc['titleLen']);
707  $record = BackendUtility::getRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']]);
708  $title = BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]);
709  $description = $this->getLanguageService()->sL($GLOBALS['TCA'][$el['table']]['ctrl']['title'], true);
710  // @todo: which information could be needful
711  if (isset($record['crdate'])) {
712  $description .= ' - ' . BackendUtility::dateTimeAge($record['crdate']);
713  }
714  $link = BackendUtility::getModuleUrl(
715  'record_edit',
716  [
717  'edit[' . $el['table'] . '][' . $el['id'] . ']' => 'edit',
718  'returnUrl' => $this->moduleUrl
719  ],
720  false,
721  true
722  );
723  $actionList[$el['id']] = [
724  'title' => $title,
725  'description' => BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]),
726  'descriptionHtml' => $description,
727  'link' => $link,
728  'icon' => '<span title="' . htmlspecialchars($path) . '">' . $this->iconFactory->getIconForRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']], Icon::SIZE_SMALL)->render() . '</span>'
729  ];
730  }
731  // Render the record list
732  $content .= $this->taskObject->renderListMenu($actionList);
733  return $content;
734  }
735 
742  protected function viewSqlQuery($record)
743  {
744  $content = '';
745  if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('lowlevel')) {
746  $sql_query = unserialize($record['t2_data']);
747  if (!is_array($sql_query) || is_array($sql_query) && strtoupper(substr(trim($sql_query['qSelect']), 0, 6)) === 'SELECT') {
748  $actionContent = '';
749  $fullsearch = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\QueryView::class);
750  $fullsearch->formW = 40;
751  $fullsearch->noDownloadB = 1;
752  $type = $sql_query['qC']['search_query_makeQuery'];
753  if ($sql_query['qC']['labels_noprefix'] === 'on') {
754  $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] = 'on';
755  }
756  $sqlQuery = $sql_query['qSelect'];
757  $queryIsEmpty = false;
758  if ($sqlQuery) {
759  $res = $this->getDatabaseConnection()->sql_query($sqlQuery);
760  if (!$this->getDatabaseConnection()->sql_error()) {
761  $fullsearch->formW = 48;
762  // Additional configuration
763  $GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels'] = 1;
764  $GLOBALS['SOBE']->MOD_SETTINGS['queryFields'] = $sql_query['qC']['queryFields'];
765  $cP = $fullsearch->getQueryResultCode($type, $res, $sql_query['qC']['queryTable']);
766  $actionContent = $cP['content'];
767  // If the result is rendered as csv or xml, show a download link
768  if ($type === 'csv' || $type === 'xml') {
769  $actionContent .= '<br /><br /><a href="' . GeneralUtility::getIndpEnv('REQUEST_URI') . '&download_file=1"><strong>' . $this->getLanguageService()->getLL('action_download_file') . '</strong></a>';
770  }
771  } else {
772  $actionContent .= $this->getDatabaseConnection()->sql_error();
773  }
774  } else {
775  // Query is empty (not built)
776  $queryIsEmpty = true;
777  $this->addMessage(
778  $this->getLanguageService()->getLL('action_emptyQuery'),
779  $this->getLanguageService()->getLL('action_error'),
781  );
782  $content .= '<br />' . $this->renderFlashMessages();
783  }
784  // Admin users are allowed to see and edit the query
785  if ($this->getBackendUser()->isAdmin()) {
786  if (!$queryIsEmpty) {
787  $actionContent .= '<hr /> ' . $fullsearch->tableWrap($sql_query['qSelect']);
788  }
789  $actionContent .= '<br /><a title="' . $this->getLanguageService()->getLL('action_editQuery') . '" href="'
790  . htmlspecialchars(BackendUtility::getModuleUrl('system_dbint')
791  . '&id=' . '&SET[function]=search' . '&SET[search]=query'
792  . '&storeControl[STORE]=-' . $record['uid'] . '&storeControl[LOAD]=1')
793  . '">'
794  . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render()
795  . $this->getLanguageService()->getLL(($queryIsEmpty ? 'action_createQuery'
796  : 'action_editQuery')) . '</a><br /><br />';
797  }
798  $content .= '<h2>' . $this->getLanguageService()->getLL('action_t2_result', true) . '</h2><div>' . $actionContent . '</div>';
799  } else {
800  // Query is not configured
801  $this->addMessage(
802  $this->getLanguageService()->getLL('action_notReady'),
803  $this->getLanguageService()->getLL('action_error'),
805  );
806  $content .= '<br />' . $this->renderFlashMessages();
807  }
808  } else {
809  // Required sysext lowlevel is not installed
810  $this->addMessage(
811  $this->getLanguageService()->getLL('action_lowlevelMissing'),
812  $this->getLanguageService()->getLL('action_error'),
814  );
815  $content .= '<br />' . $this->renderFlashMessages();
816  }
817  return $content;
818  }
819 
826  protected function viewRecordList($record)
827  {
828  $content = '';
829  $this->id = (int)$record['t3_listPid'];
830  $this->table = $record['t3_tables'];
831  if ($this->id == 0) {
832  $this->addMessage(
833  $this->getLanguageService()->getLL('action_notReady'),
834  $this->getLanguageService()->getLL('action_error'),
836  );
837  $content .= '<br />' . $this->renderFlashMessages();
838  return $content;
839  }
840  // Loading current page record and checking access:
841  $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->taskObject->perms_clause);
842  $access = is_array($this->pageinfo) ? 1 : 0;
843  // If there is access to the page, then render the list contents and set up the document template object:
844  if ($access) {
845  // Initialize the dblist object:
846  $dblist = GeneralUtility::makeInstance(\TYPO3\CMS\SysAction\ActionList::class);
847  $dblist->script = GeneralUtility::getIndpEnv('REQUEST_URI');
848  $dblist->backPath = $GLOBALS['BACK_PATH'];
849  $dblist->calcPerms = $this->getBackendUser()->calcPerms($this->pageinfo);
850  $dblist->thumbs = $this->getBackendUser()->uc['thumbnailsByDefault'];
851  $dblist->returnUrl = $this->taskObject->returnUrl;
852  $dblist->allFields = 1;
853  $dblist->localizationView = 1;
854  $dblist->showClipboard = 0;
855  $dblist->disableSingleTableView = 1;
856  $dblist->pageRow = $this->pageinfo;
857  $dblist->counter++;
858  $dblist->MOD_MENU = ['bigControlPanel' => '', 'clipBoard' => '', 'localization' => ''];
859  $dblist->modTSconfig = $this->taskObject->modTSconfig;
860  $dblist->dontShowClipControlPanels = (!$this->taskObject->MOD_SETTINGS['bigControlPanel'] && $dblist->clipObj->current == 'normal' && !$this->modTSconfig['properties']['showClipControlPanelsDespiteOfCMlayers']);
861  // Initialize the listing object, dblist, for rendering the list:
863  $dblist->start($this->id, $this->table, $this->pointer, $this->taskObject->search_field, $this->taskObject->search_levels, $this->taskObject->showLimit);
864  $dblist->setDispFields();
865  // Render the list of tables:
866  $dblist->generateList();
867  // Add JavaScript functions to the page:
868  $this->taskObject->getModuleTemplate()->addJavaScriptCode(
869  'ActionTaskInlineJavascript',
870  '
871 
872  function jumpExt(URL,anchor) {
873  var anc = anchor?anchor:"";
874  window.location.href = URL+(T3_THIS_LOCATION?"&returnUrl="+T3_THIS_LOCATION:"")+anc;
875  return false;
876  }
877  function jumpSelf(URL) {
878  window.location.href = URL+(T3_RETURN_URL?"&returnUrl="+T3_RETURN_URL:"");
879  return false;
880  }
881 
882  function setHighlight(id) {
883  top.fsMod.recentIds["web"]=id;
884  top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_"+top.fsMod.currentBank; // For highlighting
885 
886  if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
887  top.content.nav_frame.refresh_nav();
888  }
889  }
890 
891  ' . $dblist->CBfunctions() . '
892  function editRecords(table,idList,addParams,CBflag) {
893  window.location.href="' . BackendUtility::getModuleUrl('record_edit', ['returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]) . '&edit["+table+"]["+idList+"]=edit"+addParams;
894  }
895  function editList(table,idList) {
896  var list="";
897 
898  // Checking how many is checked, how many is not
899  var pointer=0;
900  var pos = idList.indexOf(",");
901  while (pos!=-1) {
902  if (cbValue(table+"|"+idList.substr(pointer,pos-pointer))) {
903  list+=idList.substr(pointer,pos-pointer)+",";
904  }
905  pointer=pos+1;
906  pos = idList.indexOf(",",pointer);
907  }
908  if (cbValue(table+"|"+idList.substr(pointer))) {
909  list+=idList.substr(pointer)+",";
910  }
911 
912  return list ? list : idList;
913  }
914  T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'))) . ';
915 
916  if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
917  '
918  );
919  // Setting up the context sensitive menu:
920  $this->taskObject->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ClickMenu');
921  // Begin to compile the whole page
922  $content .= '<form action="' . htmlspecialchars($dblist->listURL()) . '" method="post" name="dblistForm">' . $dblist->HTMLcode . '<input type="hidden" name="cmd_table" /><input type="hidden" name="cmd" />
923  </form>';
924  // If a listing was produced, create the page footer with search form etc:
925  if ($dblist->HTMLcode) {
926  // Making field select box (when extended view for a single table is enabled):
927  if ($dblist->table) {
928  $tmpBackpath = $GLOBALS['BACK_PATH'];
929  $GLOBALS['BACK_PATH'] = '';
930  $content .= $dblist->fieldSelectBox($dblist->table);
931  $GLOBALS['BACK_PATH'] = $tmpBackpath;
932  }
933  }
934  } else {
935  // Not enough rights to access the list view or the page
936  $this->addMessage(
937  $this->getLanguageService()->getLL('action_error-access'),
938  $this->getLanguageService()->getLL('action_error'),
940  );
941  $content .= $this->renderFlashMessages();
942  }
943  return $content;
944  }
945 
953  protected function addMessage($message, $title = '', $severity = FlashMessage::OK)
954  {
955  $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $message, $title, $severity);
956  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
957  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
958  $defaultFlashMessageQueue->enqueue($flashMessage);
959  }
960 
966  protected function renderFlashMessages()
967  {
968  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
969  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
970  return $defaultFlashMessageQueue->renderFlashMessages();
971  }
972 
978  protected function getLanguageService()
979  {
980  return $GLOBALS['LANG'];
981  }
982 
988  protected function getBackendUser()
989  {
990  return $GLOBALS['BE_USER'];
991  }
992 
998  protected function getDatabaseConnection()
999  {
1000  return $GLOBALS['TYPO3_DB'];
1001  }
1002 }
deleteUser($userId, $actionId)
Definition: ActionTask.php:371
if(!defined("DB_ERROR")) define("DB_ERROR"
static readPageAccess($id, $perms_clause)
fixUserGroup($appliedUsergroups, $actionRecord)
Definition: ActionTask.php:552
fixUsername($username, $prefix)
Definition: ActionTask.php:536
action_linkUserName($username, $realName, $sysActionUid, $userId)
Definition: ActionTask.php:439
static isFirstPartOfStr($str, $partStr)
fixDbMount($appliedDbMounts)
Definition: ActionTask.php:575
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
static BEgetRootLine($uid, $clause='', $workspaceOL=false)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
saveNewBackendUser($record, $vars)
Definition: ActionTask.php:462
addMessage($message, $title='', $severity=FlashMessage::OK)
Definition: ActionTask.php:953
getCreatedUsers($action, $selectedUser)
Definition: ActionTask.php:406
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:76
$uid
Definition: server.php:38
static getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
__construct(\TYPO3\CMS\Taskcenter\Controller\TaskModuleController $taskObject)
Definition: ActionTask.php:57
static dateTimeAge($tstamp, $prefix=1, $date='')
static deleteClause($table, $tableAlias='')