‪TYPO3CMS  9.5
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 
17 use Doctrine\DBAL\DBALException;
32 
38 {
42  protected ‪$taskObject;
43 
49  protected ‪$hookObjects = [];
50 
56  protected ‪$moduleUrl;
57 
61  protected ‪$iconFactory;
62 
67  public function ‪__construct(\‪TYPO3\CMS\Taskcenter\Controller\TaskModuleController ‪$taskObject)
68  {
69  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
71  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
72  $this->moduleUrl = (string)$uriBuilder->buildUriFromRoute('user_task');
73  $this->taskObject = ‪$taskObject;
74  $this->‪getLanguageService()->includeLLFile('EXT:sys_action/Resources/Private/Language/locallang.xlf');
75  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['sys_action']['tx_sysaction_task'] ?? [] as $className) {
76  $this->hookObjects[] = GeneralUtility::makeInstance($className);
77  }
78  }
79 
85  public function ‪getTask()
86  {
87  $content = '';
88  $show = (int)GeneralUtility::_GP('show');
89  foreach ($this->hookObjects as $hookObject) {
90  if (method_exists($hookObject, 'getTask')) {
91  $show = $hookObject->getTask($show, $this);
92  }
93  }
94  // If no task selected, render the menu
95  if ($show == 0) {
96  $content .= $this->taskObject->description($this->‪getLanguageService()->getLL('sys_action'), $this->‪getLanguageService()->getLL('description'));
97  $content .= $this->‪renderActionList();
98  } else {
99  $record = ‪BackendUtility::getRecord('sys_action', $show);
100  // If the action is not found
101  if (empty($record)) {
102  $this->‪addMessage(
103  $this->‪getLanguageService()->getLL('action_error-not-found'),
104  $this->‪getLanguageService()->getLL('action_error'),
106  );
107  } else {
108  // Render the task
109  $content .= $this->taskObject->description($record['title'], $record['description']);
110  // Output depends on the type
111  switch ($record['type']) {
112  case 1:
113  $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
114  $pageRenderer->loadRequireJsModule('TYPO3/CMS/SysAction/ActionTask');
115  $content .= $this->‪viewNewBackendUser($record);
116  break;
117  case 2:
118  $content .= $this->‪viewSqlQuery($record);
119  break;
120  case 3:
121  $content .= $this->‪viewRecordList($record);
122  break;
123  case 4:
124  $content .= $this->‪viewEditRecord($record);
125  break;
126  case 5:
127  $content .= $this->‪viewNewRecord($record);
128  break;
129  default:
130  $this->‪addMessage(
131  $this->‪getLanguageService()->getLL('action_noType'),
132  $this->‪getLanguageService()->getLL('action_error'),
134  );
135  $content .= $this->‪renderFlashMessages();
136  }
137  }
138  }
139  return $content;
140  }
141 
147  public function ‪getOverview()
148  {
149  $content = '<p>' . htmlspecialchars($this->‪getLanguageService()->getLL('description')) . '</p>';
150  // Get the actions
151  $actionList = $this->‪getActions();
152  if (!empty($actionList)) {
153  $items = '';
154  // Render a single action menu item
155  foreach ($actionList as $action) {
156  $active = GeneralUtility::_GP('show') === $action['uid'] ? 'active' : '';
157  $items .= '<a class="list-group-item ' . $active . '" href="' . $action['link'] . '" title="' . htmlspecialchars($action['description']) . '">' . htmlspecialchars($action['title']) . '</a>';
158  }
159  $content .= '<div class="list-group">' . $items . '</div>';
160  }
161  return $content;
162  }
163 
170  protected function ‪getActions()
171  {
172  $backendUser = $this->‪getBackendUser();
173  $actionList = [];
174 
175  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_action');
176  $queryBuilder->select('sys_action.*')
177  ->from('sys_action');
178 
179  if (!empty(‪$GLOBALS['TCA']['sys_action']['ctrl']['sortby'])) {
180  $queryBuilder->orderBy('sys_action.' . ‪$GLOBALS['TCA']['sys_action']['ctrl']['sortby']);
181  }
182 
183  $queryBuilder->getRestrictions()
184  ->removeAll()
185  ->add(GeneralUtility::makeInstance(RootLevelRestriction::class, ['sys_action']));
186 
187  // Editors can only see the actions which are assigned to a usergroup they belong to
188  if (!$backendUser->isAdmin()) {
189  $groupList = $backendUser->groupList ?: '0';
190 
191  $queryBuilder->getRestrictions()
192  ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
193 
194  $queryBuilder
195  ->join(
196  'sys_action',
197  'sys_action_asgr_mm',
198  'sys_action_asgr_mm',
199  $queryBuilder->expr()->eq(
200  'sys_action_asgr_mm.uid_local',
201  $queryBuilder->quoteIdentifier('sys_action.uid')
202  )
203  )
204  ->join(
205  'sys_action_asgr_mm',
206  'be_groups',
207  'be_groups',
208  $queryBuilder->expr()->eq(
209  'sys_action_asgr_mm.uid_foreign',
210  $queryBuilder->quoteIdentifier('be_groups.uid')
211  )
212  )
213  ->where(
214  $queryBuilder->expr()->in(
215  'be_groups.uid',
216  $queryBuilder->createNamedParameter(
217  GeneralUtility::intExplode(',', $groupList, true),
218  Connection::PARAM_INT_ARRAY
219  )
220  )
221  )
222  ->groupBy('sys_action.uid');
223  }
225  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
226  $queryResult = $queryBuilder->execute();
227  while ($actionRow = $queryResult->fetch()) {
228  $editActionLink = '';
229 
230  // Admins are allowed to edit sys_action records
231  if ($this->‪getBackendUser()->isAdmin()) {
232  $uidEditArgument = 'edit[sys_action][' . (int)$actionRow['uid'] . ']';
233 
234  $link = (string)$uriBuilder->buildUriFromRoute(
235  'record_edit',
236  [
237  $uidEditArgument => 'edit',
238  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
239  ]
240  );
241 
242  $title = $this->‪getLanguageService()->getLL('edit-sys_action');
243  $icon = $this->iconFactory->getIcon('actions-open', ‪Icon::SIZE_SMALL)->render();
244  $editActionLink = '<a class="btn btn-default btn-sm" href="' . htmlspecialchars($link) . '" title="' . htmlspecialchars($title) . '">';
245  $editActionLink .= $icon . ' ' . htmlspecialchars($title) . '</a>';
246  }
247 
248  $actionList[] = [
249  'uid' => 'actiontask' . $actionRow['uid'],
250  'title' => $actionRow['title'],
251  'description' => $actionRow['description'],
252  'descriptionHtml' => (
253  $actionRow['description']
254  ? '<p>' . nl2br(htmlspecialchars($actionRow['description'])) . '</p>'
255  : ''
256  ) . $editActionLink,
257  'link' => $this->moduleUrl
258  . '&SET[function]=sys_action.'
259  . self::class
260  . '&show='
261  . (int)$actionRow['uid']
262  ];
263  }
264 
265  return $actionList;
266  }
267 
273  protected function ‪renderActionList()
274  {
275  $content = '';
276  // Get the sys_action records
277  $actionList = $this->‪getActions();
278  // If any actions are found for the current users
279  if (!empty($actionList)) {
280  $content .= $this->taskObject->renderListMenu($actionList);
281  } else {
282  $this->‪addMessage(
283  $this->‪getLanguageService()->getLL('action_not-found-description'),
284  $this->‪getLanguageService()->getLL('action_not-found'),
286  );
287  }
288  // Admin users can create a new action
289  if ($this->‪getBackendUser()->isAdmin()) {
291  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
292  $link = (string)$uriBuilder->buildUriFromRoute(
293  'record_edit',
294  [
295  'edit[sys_action][0]' => 'new',
296  'returnUrl' => $this->moduleUrl
297  ]
298  );
299 
300  $title = $this->‪getLanguageService()->getLL('new-sys_action');
301  $content .= '<p>' .
302  '<a class="btn btn-default" href="' . htmlspecialchars($link) . '" title="' . htmlspecialchars($title) . '">' .
303  $this->iconFactory->getIcon('actions-add', ‪Icon::SIZE_SMALL)->render() . ' ' . htmlspecialchars($title) .
304  '</a></p>';
305  }
306  return $content;
307  }
308 
315  protected function ‪viewNewBackendUser($record)
316  {
317  $content = '';
318  $beRec = ‪BackendUtility::getRecord('be_users', (int)$record['t1_copy_of_user']);
319  // A record is need which is used as copy for the new user
320  if (!is_array($beRec)) {
321  $this->‪addMessage(
322  $this->‪getLanguageService()->getLL('action_notReady'),
323  $this->‪getLanguageService()->getLL('action_error'),
325  );
326  $content .= $this->‪renderFlashMessages();
327  return $content;
328  }
329  $vars = GeneralUtility::_POST('data');
330  $key = 'NEW';
331  if ($vars['sent'] == 1) {
332  ‪$errors = [];
333  // Basic error checks
334  if (!empty($vars['email']) && !GeneralUtility::validEmail($vars['email'])) {
335  ‪$errors[] = $this->‪getLanguageService()->getLL('error-wrong-email');
336  }
337  if (empty($vars['username'])) {
338  ‪$errors[] = $this->‪getLanguageService()->getLL('error-username-empty');
339  }
340  if ($vars['key'] === 'NEW' && empty($vars['password'])) {
341  ‪$errors[] = $this->‪getLanguageService()->getLL('error-password-empty');
342  }
343  if ($vars['key'] !== 'NEW' && !$this->‪isCreatedByUser($vars['key'], $record)) {
344  ‪$errors[] = $this->‪getLanguageService()->getLL('error-wrong-user');
345  }
346  foreach ($this->hookObjects as $hookObject) {
347  if (method_exists($hookObject, 'viewNewBackendUser_Error')) {
348  ‪$errors = $hookObject->viewNewBackendUser_Error($vars, ‪$errors, $this);
349  }
350  }
351  // Show errors if there are any
352  if (!empty(‪$errors)) {
353  $this->‪addMessage(
354  implode(LF, ‪$errors),
355  $this->‪getLanguageService()->getLL('action_error'),
357  );
358  } else {
359  // Save user
360  $key = $this->‪saveNewBackendUser($record, $vars);
361  // Success message
362  $message = $vars['key'] === 'NEW'
363  ? $this->‪getLanguageService()->getLL('success-user-created')
364  : $this->‪getLanguageService()->getLL('success-user-updated');
365  $this->‪addMessage(
366  $message,
367  $this->‪getLanguageService()->getLL('success')
368  );
369  }
370  $content .= $this->‪renderFlashMessages();
371  }
372  // Load BE user to edit
373  if ((int)GeneralUtility::_GP('be_users_uid') > 0) {
374  $tmpUserId = (int)GeneralUtility::_GP('be_users_uid');
375  // Check if the selected user is created by the current user
376  $rawRecord = $this->‪isCreatedByUser($tmpUserId, $record);
377  if ($rawRecord) {
378  // Delete user
379  if (GeneralUtility::_GP('delete') == 1) {
380  $this->‪deleteUser($tmpUserId, $record['uid']);
381  }
382  $key = $tmpUserId;
383  $vars = $rawRecord;
384  }
385  }
386  $content .= '<form action="" class="panel panel-default" method="post" enctype="multipart/form-data">
387  <fieldset class="form-section">
388  <h4 class="form-section-headline">' . htmlspecialchars($this->‪getLanguageService()->getLL('action_t1_legend_generalFields')) . '</h4>
389  <div class="form-group">
390  <label for="field_disable">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.disable')) . '</label>
391  <input type="checkbox" id="field_disable" name="data[disable]" value="1" class="checkbox" ' . ($vars['disable'] == 1 ? ' checked="checked" ' : '') . ' />
392  </div>
393  <div class="form-group">
394  <label for="field_realname">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.name')) . '</label>
395  <input type="text" id="field_realname" class="form-control" name="data[realName]" value="' . htmlspecialchars($vars['realName']) . '" />
396  </div>
397  <div class="form-group">
398  <label for="field_username">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.username')) . '</label>
399  <input type="text" id="field_username" class="form-control" name="data[username]" value="' . htmlspecialchars($vars['username']) . '" />
400  </div>
401  <div class="form-group">
402  <label for="field_password">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.password')) . '</label>
403  <input type="password" id="field_password" class="form-control" name="data[password]" value="" />
404  </div>
405  <div class="form-group">
406  <label for="field_email">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.email')) . '</label>
407  <input type="text" id="field_email" class="form-control" name="data[email]" value="' . htmlspecialchars($vars['email']) . '" />
408  </div>
409  </fieldset>
410  <fieldset class="form-section">
411  <h4 class="form-section-headline">' . htmlspecialchars($this->‪getLanguageService()->getLL('action_t1_legend_configuration')) . '</h4>
412  <div class="form-group">
413  <label for="field_usergroup">' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.usergroup')) . '</label>
414  <select id="field_usergroup" class="form-control" name="data[usergroup][]" multiple="multiple">
415  ' . $this->‪getUsergroups($record, $vars) . '
416  </select>
417  </div>
418  <div class="form-group">
419  <input type="hidden" name="data[key]" value="' . $key . '" />
420  <input type="hidden" name="data[sent]" value="1" />
421  <input class="btn btn-default" type="submit" value="' . htmlspecialchars($this->‪getLanguageService()->getLL($key === 'NEW' ? 'action_Create' : 'action_Update')) . '" />
422  </div>
423  </fieldset>
424  </form>';
425  $content .= $this->‪getCreatedUsers($record, $key);
426  return $content;
427  }
428 
435  protected function ‪deleteUser($userId, $actionId)
436  {
437  GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users')->update(
438  'be_users',
439  ['deleted' => 1, 'tstamp' => (int)‪$GLOBALS['ACCESS_TIME']],
440  ['uid' => (int)$userId]
441  );
442 
443  // redirect to the original task
444  ‪HttpUtility::redirect($this->moduleUrl . '&show=' . (int)$actionId);
445  }
446 
454  protected function ‪isCreatedByUser($id, $action)
455  {
456  $record = ‪BackendUtility::getRecord('be_users', $id, '*', ' AND cruser_id=' . $this->‪getBackendUser()->user['uid'] . ' AND createdByAction=' . $action['uid']);
457  if (is_array($record)) {
458  return $record;
459  }
460  return false;
461  }
462 
470  protected function ‪getCreatedUsers($action, $selectedUser)
471  {
472  $content = '';
473  $userList = [];
474 
475  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
476  ->getQueryBuilderForTable('be_users');
477 
478  $queryBuilder->getRestrictions()
479  ->removeAll()
480  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
481 
482  $res = $queryBuilder
483  ->select('*')
484  ->from('be_users')
485  ->where(
486  $queryBuilder->expr()->eq(
487  'cruser_id',
488  $queryBuilder->createNamedParameter($this->getBackendUser()->user['uid'], \PDO::PARAM_INT)
489  ),
490  $queryBuilder->expr()->eq(
491  'createdByAction',
492  $queryBuilder->createNamedParameter($action['uid'], \PDO::PARAM_INT)
493  )
494  )
495  ->orderBy('username')
496  ->execute();
497 
498  // Render the user records
499  while ($row = $res->fetch()) {
500  $icon = '<span title="' . htmlspecialchars('uid=' . $row['uid']) . '">' . $this->iconFactory->getIconForRecord('be_users', $row, ‪Icon::SIZE_SMALL)->render() . '</span>';
501  $line = $icon . $this->‪action_linkUserName($row['username'], $row['realName'], $action['uid'], $row['uid']);
502  // Selected user
503  if ($row['uid'] == $selectedUser) {
504  $line = '<strong>' . $line . '</strong>';
505  }
506  $userList[] = '<li class="list-group-item">' . $line . '</li>';
507  }
508 
509  // If any records found
510  if (!empty($userList)) {
511  $content .= '<div class="panel panel-default">';
512  $content .= '<div class="panel-heading">';
513  $content .= '<h3 class="panel-title">' . htmlspecialchars($this->‪getLanguageService()->getLL('action_t1_listOfUsers')) . '</h3>';
514  $content .= '</div>';
515  $content .= '<ul class="list-group">' . implode($userList) . '</ul>';
516  $content .= '</div>';
517  }
518  return $content;
519  }
520 
530  protected function ‪action_linkUserName($username, $realName, $sysActionUid, $userId)
531  {
532  if (!empty($realName)) {
533  $username .= ' (' . $realName . ')';
534  }
535  // Link to update the user record
536  $href = $this->moduleUrl . '&SET[function]=sys_action.TYPO3\\CMS\\SysAction\\ActionTask&show=' . (int)$sysActionUid . '&be_users_uid=' . (int)$userId;
537  $link = '<a href="' . htmlspecialchars($href) . '">' . htmlspecialchars($username) . '</a>';
538  // Link to delete the user record
539  $link .= '
540  <a href="' . htmlspecialchars($href . '&delete=1') . '" class="t3js-confirm-trigger" data-title="' . htmlspecialchars($this->‪getLanguageService()->getLL('lDelete_warning_title')) . '" data-message="' . htmlspecialchars($this->‪getLanguageService()->getLL('lDelete_warning')) . '">'
541  . $this->iconFactory->getIcon('actions-edit-delete', ‪Icon::SIZE_SMALL)->render() .
542  '</a>';
543  return $link;
544  }
545 
553  protected function ‪saveNewBackendUser($record, $vars)
554  {
555  // Check if the usergroup is allowed
556  $vars['usergroup'] = $this->‪fixUserGroup($vars['usergroup'], $record);
557  $key = $vars['key'];
558  $vars['password'] = trim($vars['password']);
559  // Check if md5 is used as password encryption
560  if ($vars['password'] !== '' && strpos(‪$GLOBALS['TCA']['be_users']['columns']['password']['config']['eval'], 'md5') !== false) {
561  $vars['password'] = md5($vars['password']);
562  }
563  $data = '';
564  $newUserId = 0;
565  if ($key === 'NEW') {
566  $beRec = ‪BackendUtility::getRecord('be_users', (int)$record['t1_copy_of_user']);
567  if (is_array($beRec)) {
568  $data = [];
569  $data['be_users'][$key] = $beRec;
570  $data['be_users'][$key]['username'] = $this->‪fixUsername($vars['username'], $record['t1_userprefix']);
571  $data['be_users'][$key]['password'] = $vars['password'];
572  $data['be_users'][$key]['realName'] = $vars['realName'];
573  $data['be_users'][$key]['email'] = $vars['email'];
574  $data['be_users'][$key]['disable'] = (int)$vars['disable'];
575  $data['be_users'][$key]['admin'] = 0;
576  $data['be_users'][$key]['usergroup'] = $vars['usergroup'];
577  $data['be_users'][$key]['createdByAction'] = $record['uid'];
578  }
579  } else {
580  // Check ownership
581  $beRec = ‪BackendUtility::getRecord('be_users', (int)$key);
582  if (is_array($beRec) && $beRec['cruser_id'] == $this->‪getBackendUser()->user['uid']) {
583  $data = [];
584  $data['be_users'][$key]['username'] = $this->‪fixUsername($vars['username'], $record['t1_userprefix']);
585  if ($vars['password'] !== '') {
586  $data['be_users'][$key]['password'] = $vars['password'];
587  }
588  $data['be_users'][$key]['realName'] = $vars['realName'];
589  $data['be_users'][$key]['email'] = $vars['email'];
590  $data['be_users'][$key]['disable'] = (int)$vars['disable'];
591  $data['be_users'][$key]['admin'] = 0;
592  $data['be_users'][$key]['usergroup'] = $vars['usergroup'];
593  $newUserId = $key;
594  }
595  }
596  // Save/update user by using DataHandler
597  if (is_array($data)) {
598  $dataHandler = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\DataHandling\DataHandler::class);
599  $dataHandler->start($data, [], $this->‪getBackendUser());
600  $dataHandler->admin = 1;
601  $dataHandler->process_datamap();
602  $newUserId = (int)$dataHandler->substNEWwithIDs['NEW'];
603  if ($newUserId) {
604  // Create
605  $this->‪action_createDir($newUserId);
606  } else {
607  // Update
608  $newUserId = (int)$key;
609  }
610  unset($tce);
611  }
612  return $newUserId;
613  }
614 
622  protected function ‪fixUsername($username, $prefix)
623  {
624  $prefix = trim($prefix);
625  if ($prefix !== '' && strpos($username, $prefix) === 0) {
626  $username = substr($username, strlen($prefix));
627  }
628  return $prefix . $username;
629  }
630 
638  protected function ‪fixUserGroup($appliedUsergroups, $actionRecord)
639  {
640  if (is_array($appliedUsergroups)) {
641  $cleanGroupList = [];
642  // Create an array from the allowed usergroups using the uid as key
643  $allowedUsergroups = array_flip(explode(',', $actionRecord['t1_allowed_groups']));
644  // Walk through the array and check every uid if it is under the allowed ines
645  foreach ($appliedUsergroups as $group) {
646  if (isset($allowedUsergroups[$group])) {
647  $cleanGroupList[] = $group;
648  }
649  }
650  $appliedUsergroups = $cleanGroupList;
651  }
652  return $appliedUsergroups;
653  }
654 
661  protected function ‪checkRootline($pageId)
662  {
663  $access = false;
664  $dbMounts = array_flip(explode(',', trim($this->‪getBackendUser()->dataLists['webmount_list'], ',')));
665  $rootline = ‪BackendUtility::BEgetRootLine($pageId);
666  foreach ($rootline as $page) {
667  if (isset($dbMounts[$page['uid']]) && !$access) {
668  $access = true;
669  }
670  }
671  return $access;
672  }
673 
679  protected function ‪action_createDir($uid)
680  {
681  $path = $this->‪action_getUserMainDir();
682  if ($path) {
683  GeneralUtility::mkdir($path . $uid);
684  GeneralUtility::mkdir($path . $uid . '/_temp_/');
685  }
686  }
687 
693  protected function ‪action_getUserMainDir()
694  {
695  $path = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'];
696  // If path is set and a valid directory
697  if ($path && @is_dir($path) && ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] && GeneralUtility::isFirstPartOfStr($path, ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath']) && substr($path, -1) === '/') {
698  return $path;
699  }
700  }
701 
709  protected function ‪getUsergroups($record, $vars)
710  {
711  $content = '';
712  // Do nothing if no groups are allowed
713  if (empty($record['t1_allowed_groups'])) {
714  return $content;
715  }
716  $content .= '<option value=""></option>';
717  $grList = GeneralUtility::trimExplode(',', $record['t1_allowed_groups'], true);
718  foreach ($grList as $group) {
719  $checkGroup = ‪BackendUtility::getRecord('be_groups', $group);
720  if (is_array($checkGroup)) {
721  $selected = GeneralUtility::inList($vars['usergroup'], $checkGroup['uid']) ? ' selected="selected" ' : '';
722  $content .= '<option ' . $selected . 'value="' . (int)$checkGroup['uid'] . '">' . htmlspecialchars($checkGroup['title']) . '</option>';
723  }
724  }
725  return $content;
726  }
727 
733  protected function ‪viewNewRecord($record)
734  {
736  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
737  $link = (string)$uriBuilder->buildUriFromRoute(
738  'record_edit',
739  [
740  'edit[' . $record['t3_tables'] . '][' . (int)$record['t3_listPid'] . ']' => 'new',
741  'returnUrl' => ‪$this->moduleUrl
742  ]
743  );
745  }
746 
753  protected function ‪viewEditRecord($record)
754  {
755  $content = '';
756  $actionList = [];
757  $dbAnalysis = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Database\RelationHandler::class);
758  $dbAnalysis->setFetchAllFields(true);
759  $dbAnalysis->start($record['t4_recordsToEdit'], '*');
760  $dbAnalysis->getFromDB();
761  // collect the records
762  foreach ($dbAnalysis->itemArray as $el) {
764  $el['id'],
765  $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW),
766  $this->‪getBackendUser()->uc['titleLen']
767  );
768  $record = ‪BackendUtility::getRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']]);
769  $title = ‪BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]);
770  $description = htmlspecialchars($this->‪getLanguageService()->sL(‪$GLOBALS['TCA'][$el['table']]['ctrl']['title']));
771  // @todo: which information could be needful
772  if (isset($record['crdate'])) {
773  $description .= ' - ' . htmlspecialchars(‪BackendUtility::dateTimeAge($record['crdate']));
774  }
776  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
777  $link = (string)$uriBuilder->buildUriFromRoute(
778  'record_edit',
779  [
780  'edit[' . $el['table'] . '][' . $el['id'] . ']' => 'edit',
781  'returnUrl' => $this->moduleUrl
782  ]
783  );
784  $actionList[$el['id']] = [
785  'uid' => 'record-' . $el['table'] . '-' . $el['id'],
786  'title' => $title,
787  'description' => ‪BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]),
788  'descriptionHtml' => $description,
789  'link' => $link,
790  'icon' => '<span title="' . htmlspecialchars($path) . '">' . $this->iconFactory->getIconForRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']], ‪Icon::SIZE_SMALL)->render() . '</span>'
791  ];
792  }
793  // Render the record list
794  $content .= $this->taskObject->renderListMenu($actionList);
795  return $content;
796  }
797 
804  protected function ‪viewSqlQuery($record)
805  {
806  $content = '';
807  if (\‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('lowlevel')) {
808  $sql_query = unserialize($record['t2_data']);
809  if (!is_array($sql_query) || is_array($sql_query) && stripos(trim($sql_query['qSelect']), 'SELECT') === 0) {
810  $actionContent = '';
811  $type = $sql_query['qC']['search_query_makeQuery'];
812  if ($sql_query['qC']['labels_noprefix'] === 'on') {
813  $this->taskObject->MOD_SETTINGS['labels_noprefix'] = 'on';
814  }
815  $sqlQuery = $sql_query['qSelect'];
816  $queryIsEmpty = false;
817  if ($sqlQuery) {
818  try {
819  $dataRows = GeneralUtility::makeInstance(ConnectionPool::class)
820  ->getConnectionForTable($sql_query['qC']['queryTable'])
821  ->executeQuery($sqlQuery)->fetchAll();
822  // Additional configuration
823  $this->taskObject->MOD_SETTINGS['search_result_labels'] = $sql_query['qC']['search_result_labels'];
824  $this->taskObject->MOD_SETTINGS['queryFields'] = $sql_query['qC']['queryFields'];
825 
826  $fullsearch = GeneralUtility::makeInstance(\‪TYPO3\CMS\Core\Database\QueryView::class, ‪$GLOBALS['SOBE']->MOD_SETTINGS);
827  $fullsearch->noDownloadB = 1;
828  $fullsearch->formW = 48;
829  $cP = $fullsearch->getQueryResultCode($type, $dataRows, $sql_query['qC']['queryTable']);
830  $actionContent = $cP['content'];
831  // If the result is rendered as csv or xml, show a download link
832  if ($type === 'csv' || $type === 'xml') {
833  $actionContent .= '<a href="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI') . '&download_file=1') . '">'
834  . '<strong>' . htmlspecialchars($this->‪getLanguageService()->getLL('action_download_file')) . '</strong></a>';
835  }
836  } catch (DBALException $e) {
837  $actionContent .= $e->getMessage();
838  }
839  } else {
840  // Query is empty (not built)
841  $queryIsEmpty = true;
842  $this->‪addMessage(
843  $this->‪getLanguageService()->getLL('action_emptyQuery'),
844  $this->‪getLanguageService()->getLL('action_error'),
846  );
847  $content .= $this->‪renderFlashMessages();
848  }
849  // Admin users are allowed to see and edit the query
850  if ($this->‪getBackendUser()->isAdmin()) {
851  if (!$queryIsEmpty) {
852  $actionContent .= '<div class="panel panel-default"><div class="panel-body"><pre>' . htmlspecialchars($sql_query['qSelect']) . '</pre></div></div>';
853  }
855  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
856  $actionContent .= '<a title="' . htmlspecialchars($this->‪getLanguageService()->getLL('action_editQuery')) . '" class="btn btn-default" href="'
857  . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('system_dbint')
858  . '&id=' . '&SET[function]=search' . '&SET[search]=query'
859  . '&storeControl[STORE]=-' . $record['uid'] . '&storeControl[LOAD]=1')
860  . '">'
861  . $this->iconFactory->getIcon('actions-open', ‪Icon::SIZE_SMALL)->render() . ' '
862  . $this->‪getLanguageService()->getLL(($queryIsEmpty ? 'action_createQuery'
863  : 'action_editQuery')) . '</a>';
864  }
865  $content .= '<h2>' . htmlspecialchars($this->‪getLanguageService()->getLL('action_t2_result')) . '</h2>' . $actionContent;
866  } else {
867  // Query is not configured
868  $this->‪addMessage(
869  $this->‪getLanguageService()->getLL('action_notReady'),
870  $this->‪getLanguageService()->getLL('action_error'),
872  );
873  $content .= $this->‪renderFlashMessages();
874  }
875  } else {
876  // Required sysext lowlevel is not installed
877  $this->‪addMessage(
878  $this->‪getLanguageService()->getLL('action_lowlevelMissing'),
879  $this->‪getLanguageService()->getLL('action_error'),
881  );
882  $content .= $this->‪renderFlashMessages();
883  }
884  return $content;
885  }
886 
893  protected function ‪viewRecordList($record)
894  {
895  $content = '';
896  $this->id = (int)$record['t3_listPid'];
897  $this->table = $record['t3_tables'];
898  if ($this->id == 0) {
899  $this->‪addMessage(
900  $this->‪getLanguageService()->getLL('action_notReady'),
901  $this->‪getLanguageService()->getLL('action_error'),
903  );
904  $content .= $this->‪renderFlashMessages();
905  return $content;
906  }
907  // Loading current page record and checking access:
908  $this->pageinfo = ‪BackendUtility::readPageAccess(
909  $this->id,
910  $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW)
911  );
912  $access = is_array($this->pageinfo);
913  // If there is access to the page, then render the list contents and set up the document template object:
914  if ($access) {
915  // Initialize the dblist object:
916  $dblist = GeneralUtility::makeInstance(\‪TYPO3\CMS\SysAction\ActionList::class);
917  $dblist->script = GeneralUtility::getIndpEnv('REQUEST_URI');
918  $dblist->calcPerms = $this->‪getBackendUser()->calcPerms($this->pageinfo);
919  $dblist->thumbs = $this->‪getBackendUser()->uc['thumbnailsByDefault'];
920  $dblist->allFields = 1;
921  $dblist->showClipboard = 0;
922  $dblist->disableSingleTableView = 1;
923  $dblist->pageRow = $this->pageinfo;
924  $dblist->counter++;
925  $dblist->MOD_MENU = ['bigControlPanel' => '', 'clipBoard' => ''];
926  $dblist->modTSconfig = $this->taskObject->modTSconfig;
927  $dblist->dontShowClipControlPanels = (!$this->taskObject->MOD_SETTINGS['bigControlPanel'] && $dblist->clipObj->current === 'normal' && !$this->modTSconfig['properties']['showClipControlPanelsDespiteOfCMlayers']);
928  // Initialize the listing object, dblist, for rendering the list:
929  $this->pointer = ‪\TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange(GeneralUtility::_GP('pointer'), 0, 100000);
930  $dblist->start($this->id, $this->table, $this->pointer);
931  $dblist->setDispFields();
932  // Render the list of tables:
933  $dblist->generateList();
935  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
936  // Add JavaScript functions to the page:
937  $this->taskObject->getModuleTemplate()->addJavaScriptCode(
938  'ActionTaskInlineJavascript',
939  '
940 
941  function jumpExt(URL,anchor) {
942  var anc = anchor?anchor:"";
943  window.location.href = URL+(T3_THIS_LOCATION?"&returnUrl="+T3_THIS_LOCATION:"")+anc;
944  return false;
945  }
946  function jumpSelf(URL) {
947  window.location.href = URL+(T3_RETURN_URL?"&returnUrl="+T3_RETURN_URL:"");
948  return false;
949  }
950 
951  function setHighlight(id) {
952  top.fsMod.recentIds["web"] = id;
953  top.fsMod.navFrameHighlightedID["web"] = top.fsMod.currentBank + "_" + id; // For highlighting
954 
955  if (top.nav_frame && top.nav_frame.refresh_nav) {
956  top.nav_frame.refresh_nav();
957  }
958  }
959 
960  ' . $dblist->CBfunctions() . '
961  function editRecords(table,idList,addParams,CBflag) {
962  var recordEditUrl = ' . GeneralUtility::quoteJSvalue($uriBuilder->buildUriFromRoute('record_edit', ['returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')])) . ';
963  window.location.href = recordEditUrl + "&edit[" + table + "][" + idList + "]=edit" + addParams;
964  }
965  function editList(table,idList) {
966  var list="";
967 
968  // Checking how many is checked, how many is not
969  var pointer=0;
970  var pos = idList.indexOf(",");
971  while (pos!=-1) {
972  if (cbValue(table+"|"+idList.substr(pointer,pos-pointer))) {
973  list+=idList.substr(pointer,pos-pointer)+",";
974  }
975  pointer=pos+1;
976  pos = idList.indexOf(",",pointer);
977  }
978  if (cbValue(table+"|"+idList.substr(pointer))) {
979  list+=idList.substr(pointer)+",";
980  }
981 
982  return list ? list : idList;
983  }
984  T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'))) . ';
985 
986  if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
987  '
988  );
989  // Setting up the context sensitive menu:
990  $this->taskObject->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
991  $this->taskObject->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/AjaxDataHandler');
992  // Begin to compile the whole page
993  $content .= '<form action="' . htmlspecialchars($dblist->listURL()) . '" method="post" name="dblistForm">' . $dblist->HTMLcode . '<input type="hidden" name="cmd_table" /><input type="hidden" name="cmd" /></form>';
994  // If a listing was produced, create the page footer with search form etc:
995  // Making field select box (when extended view for a single table is enabled):
996  if ($dblist->HTMLcode && $dblist->table) {
997  $content .= $dblist->fieldSelectBox($dblist->table);
998  }
999  } else {
1000  // Not enough rights to access the list view or the page
1001  $this->‪addMessage(
1002  $this->‪getLanguageService()->getLL('action_error-access'),
1003  $this->‪getLanguageService()->getLL('action_error'),
1005  );
1006  $content .= $this->‪renderFlashMessages();
1007  }
1008  return $content;
1009  }
1010 
1018  protected function ‪addMessage($message, $title = '', $severity = ‪FlashMessage::OK)
1019  {
1020  $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $message, $title, $severity);
1021  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
1022  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
1023  $defaultFlashMessageQueue->enqueue($flashMessage);
1024  }
1025 
1031  protected function ‪renderFlashMessages()
1032  {
1033  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
1034  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
1035  return $defaultFlashMessageQueue->renderFlashMessages();
1036  }
1037 
1043  protected function ‪getLanguageService()
1044  {
1045  return ‪$GLOBALS['LANG'];
1046  }
1047 
1053  protected function ‪getBackendUser()
1054  {
1055  return ‪$GLOBALS['BE_USER'];
1056  }
1057 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction
Definition: HiddenRestriction.php:25
‪TYPO3\CMS\SysAction\ActionTask\renderActionList
‪string renderActionList()
Definition: ActionTask.php:269
‪TYPO3\CMS\SysAction\ActionTask\getBackendUser
‪TYPO3 CMS Core Authentication BackendUserAuthentication getBackendUser()
Definition: ActionTask.php:1049
‪TYPO3\CMS\SysAction\ActionTask\$hookObjects
‪array $hookObjects
Definition: ActionTask.php:47
‪TYPO3\CMS\SysAction\ActionTask\deleteUser
‪deleteUser($userId, $actionId)
Definition: ActionTask.php:431
‪TYPO3\CMS\SysAction\ActionTask\getLanguageService
‪TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: ActionTask.php:1039
‪TYPO3\CMS\SysAction\ActionTask\$moduleUrl
‪string $moduleUrl
Definition: ActionTask.php:53
‪TYPO3\CMS\SysAction\ActionTask\isCreatedByUser
‪mixed isCreatedByUser($id, $action)
Definition: ActionTask.php:450
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3\CMS\SysAction\ActionTask\viewEditRecord
‪string viewEditRecord($record)
Definition: ActionTask.php:749
‪TYPO3\CMS\SysAction\ActionTask\viewNewBackendUser
‪string viewNewBackendUser($record)
Definition: ActionTask.php:311
‪TYPO3
‪TYPO3\CMS\SysAction\ActionTask\getActions
‪array getActions()
Definition: ActionTask.php:166
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
‪TYPO3\CMS\SysAction\ActionTask\saveNewBackendUser
‪int saveNewBackendUser($record, $vars)
Definition: ActionTask.php:549
‪TYPO3\CMS\SysAction\ActionTask\addMessage
‪addMessage($message, $title='', $severity=FlashMessage::OK)
Definition: ActionTask.php:1014
‪TYPO3\CMS\SysAction\ActionTask\checkRootline
‪bool checkRootline($pageId)
Definition: ActionTask.php:657
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪TYPO3\CMS\Backend\Utility\BackendUtility\BEgetRootLine
‪static array BEgetRootLine($uid, $clause='', $workspaceOL=false, array $additionalFields=[])
Definition: BackendUtility.php:374
‪TYPO3\CMS\SysAction\ActionTask\getOverview
‪string getOverview()
Definition: ActionTask.php:143
‪TYPO3\CMS\SysAction
Definition: ActionList.php:2
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\SysAction\ActionTask\getTask
‪string getTask()
Definition: ActionTask.php:81
‪TYPO3\CMS\SysAction\ActionTask\viewNewRecord
‪viewNewRecord($record)
Definition: ActionTask.php:729
‪TYPO3\CMS\SysAction\ActionTask\getUsergroups
‪string getUsergroups($record, $vars)
Definition: ActionTask.php:705
‪TYPO3\CMS\SysAction\ActionTask\action_createDir
‪action_createDir($uid)
Definition: ActionTask.php:675
‪TYPO3\CMS\SysAction\ActionTask\action_getUserMainDir
‪string action_getUserMainDir()
Definition: ActionTask.php:689
‪TYPO3\CMS\SysAction\ActionTask\fixUsername
‪string fixUsername($username, $prefix)
Definition: ActionTask.php:618
‪TYPO3\CMS\SysAction\ActionTask
Definition: ActionTask.php:38
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:35
‪TYPO3\CMS\SysAction\ActionTask\__construct
‪__construct(\TYPO3\CMS\Taskcenter\Controller\TaskModuleController $taskObject)
Definition: ActionTask.php:63
‪TYPO3\CMS\SysAction\ActionTask\fixUserGroup
‪array fixUserGroup($appliedUsergroups, $actionRecord)
Definition: ActionTask.php:634
‪TYPO3\CMS\Taskcenter\TaskInterface
Definition: TaskInterface.php:21
‪TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction
Definition: RootLevelRestriction.php:25
‪TYPO3\CMS\SysAction\ActionTask\getCreatedUsers
‪string getCreatedUsers($action, $selectedUser)
Definition: ActionTask.php:466
‪TYPO3\CMS\SysAction\ActionTask\viewSqlQuery
‪string viewSqlQuery($record)
Definition: ActionTask.php:800
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1811
‪TYPO3\CMS\SysAction\ActionTask\$taskObject
‪TYPO3 CMS Taskcenter Controller TaskModuleController $taskObject
Definition: ActionTask.php:41
‪TYPO3\CMS\SysAction\ActionTask\$iconFactory
‪IconFactory $iconFactory
Definition: ActionTask.php:57
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:32
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\SysAction\ActionTask\renderFlashMessages
‪string renderFlashMessages()
Definition: ActionTask.php:1027
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:130
‪$errors
‪$errors
Definition: annotationChecker.php:115
‪TYPO3\CMS\Core\Messaging\AbstractMessage\OK
‪const OK
Definition: AbstractMessage.php:27
‪TYPO3\CMS\Backend\Utility\BackendUtility\dateTimeAge
‪static string dateTimeAge($tstamp, $prefix=1, $date='')
Definition: BackendUtility.php:1248
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:31
‪TYPO3\CMS\Core\Messaging\AbstractMessage\INFO
‪const INFO
Definition: AbstractMessage.php:26
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:21
‪TYPO3\CMS\SysAction\ActionTask\viewRecordList
‪string viewRecordList($record)
Definition: ActionTask.php:889
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordPath
‪static mixed getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
Definition: BackendUtility.php:572
‪TYPO3\CMS\SysAction\ActionTask\action_linkUserName
‪string action_linkUserName($username, $realName, $sysActionUid, $userId)
Definition: ActionTask.php:526
‪TYPO3\CMS\Core\Utility\HttpUtility\redirect
‪static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:103
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:25
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Backend\Utility\BackendUtility\readPageAccess
‪static array bool readPageAccess($id, $perms_clause)
Definition: BackendUtility.php:635