‪TYPO3CMS  ‪main
BackendLogController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
34 
41 {
42  public function ‪__construct(
43  protected readonly ‪ModuleTemplateFactory $moduleTemplateFactory,
44  protected readonly ‪LogEntryRepository $logEntryRepository,
45  protected readonly ‪ConnectionPool $connectionPool,
46  ) {}
47 
51  public function ‪initializeListAction(): void
52  {
53  if (!isset($this->settings['dateFormat'])) {
54  $this->settings['dateFormat'] = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] ?: 'd-m-Y';
55  }
56  if (!isset($this->settings['timeFormat'])) {
57  $this->settings['timeFormat'] = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
58  }
59  // Static format needed for date picker (flatpickr), see BackendController::generateJavascript() and #91606
60  $this->settings['dateTimeFormat'] = 'H:i d-m-Y';
61  $constraintConfiguration = $this->arguments->getArgument('constraint')->getPropertyMappingConfiguration();
62  $constraintConfiguration->allowAllProperties();
63  }
64 
68  public function ‪listAction(‪Constraint $constraint = null, string $operation = ''): ResponseInterface
69  {
70  if ($operation === 'reset-filters') {
71  $constraint = new ‪Constraint();
72  } elseif ($constraint === null) {
73  $constraint = $this->‪getConstraintFromBeUserData();
74  }
75 
76  $access = true;
77  $pageId = $constraint->getPageId();
78  $permsClause = $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW);
79  if ($pageId === 0 || (BackendUtility::readPageAccess($pageId, $permsClause) ?: []) === []) {
80  if (!$this->‪getBackendUser()->isAdmin()) {
81  // User does not have access to selected site
82  $access = false;
83  }
84 
85  if ($pageId === 0) {
86  // In case no page is selected, set depth to 0 to display only "global" logs
87  $constraint->setDepth(0);
88  }
89  }
90 
91  $this->‪persistConstraintInBeUserData($constraint);
93  $this->‪setStartAndEndTimeFromTimeSelector($constraint);
94  $showWorkspaceSelector = $this->‪forceWorkspaceSelectionIfInWorkspace($constraint);
95 
96  $viewVariables = [
97  'access' => $access,
98  'settings' => ‪$this->settings,
99  'pageId' => $pageId,
100  'constraint' => $constraint,
101  'userGroups' => $this->‪createUserAndGroupListForSelectOptions(),
102  'selectableNumberOfLogEntries' => $this->‪createSelectableNumberOfLogEntriesOptions(),
103  'workspaces' => $this->‪createWorkspaceListForSelectOptions(),
104  'pageDepths' => $this->‪createPageDepthOptions(),
105  'channels' => $this->logEntryRepository->getUsedChannels(),
106  'channel' => $constraint->getChannel(),
107  'levels' => $this->logEntryRepository->getUsedLevels(),
108  'level' => $constraint->getLevel(),
109  'showWorkspaceSelector' => $showWorkspaceSelector,
110  ];
111 
112  if ($access) {
113  // Only fetch log entries if user has access
114  $logEntries = $this->logEntryRepository->findByConstraint($constraint);
115  $groupedLogEntries = $this->‪groupLogEntriesDay($logEntries);
116  $viewVariables['groupedLogEntries'] = $groupedLogEntries;
117  }
118 
119  return $this->moduleTemplateFactory
120  ->create($this->request)
121  ->setFlashMessageQueue($this->‪getFlashMessageQueue())
122  ->setTitle(‪LocalizationUtility::translate('LLL:EXT:belog/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'))
123  ->assignMultiple($viewVariables)
124  ->renderResponse('BackendLog/List');
125  }
126 
131  public function ‪deleteMessageAction(int $errorUid): ResponseInterface
132  {
133  $logEntry = $this->logEntryRepository->findByUid($errorUid);
134  if (!$logEntry) {
135  $this->‪addFlashMessage(‪LocalizationUtility::translate('actions.delete.noRowFound', 'belog') ?? '', '', ContextualFeedbackSeverity::WARNING);
136  return $this->‪redirect('list');
137  }
138  $numberOfDeletedRows = $this->logEntryRepository->deleteByMessageDetails($logEntry);
139  $this->‪addFlashMessage(sprintf(‪LocalizationUtility::translate('actions.delete.message', 'belog') ?? '', $numberOfDeletedRows));
140  return $this->‪redirect('list');
141  }
142 
147  {
148  $serializedConstraint = $this->request->getAttribute('moduleData')->get('constraint');
149  $constraint = null;
150  if (is_string($serializedConstraint) && !empty($serializedConstraint)) {
151  $constraint = @unserialize($serializedConstraint, ['allowed_classes' => [Constraint::class, \DateTime::class]]);
152  }
153  return $constraint ?: GeneralUtility::makeInstance(Constraint::class);
154  }
155 
159  protected function ‪persistConstraintInBeUserData(‪Constraint $constraint): void
160  {
161  $moduleData = $this->request->getAttribute('moduleData');
162  $moduleData->set('constraint', serialize($constraint));
163  $this->‪getBackendUser()->pushModuleData($moduleData->getModuleIdentifier(), $moduleData->toArray());
164  }
165 
172  {
173  $reservedMemory = new \SplFixedArray(187500); // 3M
174  register_shutdown_function(function () use (&$reservedMemory): void {
175  $reservedMemory = null; // free the reserved memory
176  $error = error_get_last();
177  if (str_contains($error['message'] ?? '', 'Allowed memory size of')) {
178  $constraint = GeneralUtility::makeInstance(Constraint::class);
179  $this->‪persistConstraintInBeUserData($constraint);
180  }
181  });
182  }
183 
194  protected function ‪groupLogEntriesDay(array $logEntries): array
195  {
196  $targetStructure = [];
197  foreach ($logEntries as $entry) {
198  $pid = -1;
199  // Create array if it is not defined yet
200  if (!is_array($targetStructure[$pid] ?? false)) {
201  $targetStructure[-1] = [];
202  }
203  // Get day timestamp of log entry and create sub array if needed
204  $entryTimestamp = \DateTimeImmutable::createFromFormat('U', (string)$entry->getTstamp());
205  $timestampDay = strtotime($entryTimestamp->format('d.m.Y'));
206  if (!is_array($targetStructure[$pid][$timestampDay] ?? false)) {
207  $targetStructure[$pid][$timestampDay] = [];
208  }
209  // Add row
210  $targetStructure[$pid][$timestampDay][] = $entry;
211  }
212  ksort($targetStructure);
213  return $targetStructure;
214  }
215 
223  protected function ‪createUserAndGroupListForSelectOptions(): array
224  {
225  $userGroupArray = [];
226  // Two meta entries: 'all' and 'self'
227  $userGroupArray[0] = ‪LocalizationUtility::translate('allUsers', 'Belog');
228  $userGroupArray[-1] = ‪LocalizationUtility::translate('self', 'Belog');
229  // List of groups, key is gr-'uid'
230  $groups = BackendUtility::getGroupNames();
231  foreach ($groups as $group) {
232  $userGroupArray['gr-' . $group['uid']] = ‪LocalizationUtility::translate('group', 'Belog') . ' ' . $group['title'];
233  }
234  // List of users, key is us-'uid'
235  $users = BackendUtility::getUserNames();
236  foreach ($users as $user) {
237  $userGroupArray['us-' . $user['uid']] = ‪LocalizationUtility::translate('user', 'Belog') . ' ' . $user['username'];
238  }
239  return $userGroupArray;
240  }
241 
246  {
247  return [
248  50 => 50,
249  100 => 100,
250  200 => 200,
251  500 => 500,
252  1000 => 1000,
253  1000000 => ‪LocalizationUtility::translate('any', 'Belog'),
254  ];
255  }
256 
262  protected function ‪createWorkspaceListForSelectOptions(): array
263  {
264  if (!‪ExtensionManagementUtility::isLoaded('workspaces')) {
265  return [];
266  }
267  $workspaceArray = [];
268  // Two meta entries: 'all' and 'live'
269  $workspaceArray[-99] = ‪LocalizationUtility::translate('any', 'Belog');
270  $workspaceArray[0] = ‪LocalizationUtility::translate('live', 'Belog');
271  $resultSet = $this->connectionPool->getQueryBuilderForTable('sys_workspace')
272  ->select('uid', 'title')
273  ->from('sys_workspace')
274  ->executeQuery();
275  while ($row = $resultSet->fetchAssociative()) {
276  $workspaceArray[$row['uid']] = $row['uid'] . ': ' . $row['title'];
277  }
278  return $workspaceArray;
279  }
280 
286  protected function ‪forceWorkspaceSelectionIfInWorkspace(‪Constraint $constraint): bool
287  {
288  if (!‪ExtensionManagementUtility::isLoaded('workspaces')) {
289  return false;
290  }
291 
292  if ($this->‪getBackendUser()->workspace !== 0) {
293  $constraint->‪setWorkspaceUid($this->‪getBackendUser()->workspace);
294  return false;
295  }
296  return true;
297  }
298 
304  protected function ‪createPageDepthOptions(): array
305  {
306  return [
307  0 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
308  1 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
309  2 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
310  3 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
311  4 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
312  999 => ‪LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi'),
313  ];
314  }
315 
319  protected function ‪setStartAndEndTimeFromTimeSelector(‪Constraint $constraint): void
320  {
321  $startTime = $constraint->‪getManualDateStart() ? $constraint->‪getManualDateStart()->getTimestamp() : 0;
322  $endTime = $constraint->‪getManualDateStop() ? $constraint->‪getManualDateStop()->getTimestamp() : 0;
323  if ($endTime <= $startTime) {
324  $endTime = ‪$GLOBALS['EXEC_TIME'];
325  }
326  $constraint->‪setStartTimestamp($startTime);
327  $constraint->‪setEndTimestamp($endTime);
328  }
329 
331  {
332  return ‪$GLOBALS['BE_USER'];
333  }
334 }
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\addFlashMessage
‪addFlashMessage(string $messageBody, string $messageTitle='', ContextualFeedbackSeverity $severity=ContextualFeedbackSeverity::OK, bool $storeInSession=true)
Definition: ActionController.php:633
‪TYPO3\CMS\Belog\Controller\BackendLogController\initializeListAction
‪initializeListAction()
Definition: BackendLogController.php:51
‪TYPO3\CMS\Belog\Controller\BackendLogController\createUserAndGroupListForSelectOptions
‪array createUserAndGroupListForSelectOptions()
Definition: BackendLogController.php:223
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility
Definition: LocalizationUtility.php:35
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository
Definition: LogEntryRepository.php:37
‪TYPO3\CMS\Belog\Controller\BackendLogController\forceWorkspaceSelectionIfInWorkspace
‪forceWorkspaceSelectionIfInWorkspace(Constraint $constraint)
Definition: BackendLogController.php:286
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:33
‪TYPO3\CMS\Belog\Controller\BackendLogController\createSelectableNumberOfLogEntriesOptions
‪createSelectableNumberOfLogEntriesOptions()
Definition: BackendLogController.php:245
‪TYPO3\CMS\Belog\Controller\BackendLogController\getConstraintFromBeUserData
‪getConstraintFromBeUserData()
Definition: BackendLogController.php:146
‪TYPO3\CMS\Belog\Controller\BackendLogController
Definition: BackendLogController.php:41
‪TYPO3\CMS\Belog\Controller
Definition: BackendLogController.php:18
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:55
‪TYPO3\CMS\Belog\Controller\BackendLogController\__construct
‪__construct(protected readonly ModuleTemplateFactory $moduleTemplateFactory, protected readonly LogEntryRepository $logEntryRepository, protected readonly ConnectionPool $connectionPool,)
Definition: BackendLogController.php:42
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:32
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Belog\Controller\BackendLogController\setStartAndEndTimeFromTimeSelector
‪setStartAndEndTimeFromTimeSelector(Constraint $constraint)
Definition: BackendLogController.php:319
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$settings
‪array $settings
Definition: ActionController.php:112
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\translate
‪static string null translate(string $key, ?string $extensionName=null, array $arguments=null, Locale|string $languageKey=null)
Definition: LocalizationUtility.php:47
‪TYPO3\CMS\Belog\Controller\BackendLogController\deleteMessageAction
‪deleteMessageAction(int $errorUid)
Definition: BackendLogController.php:131
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getManualDateStop
‪getManualDateStop()
Definition: Constraint.php:188
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Belog\Controller\BackendLogController\listAction
‪listAction(Constraint $constraint=null, string $operation='')
Definition: BackendLogController.php:68
‪TYPO3\CMS\Belog\Domain\Model\LogEntry
Definition: LogEntry.php:29
‪TYPO3\CMS\Belog\Controller\BackendLogController\groupLogEntriesDay
‪groupLogEntriesDay(array $logEntries)
Definition: BackendLogController.php:194
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\redirect
‪redirect(?string $actionName, ?string $controllerName=null, ?string $extensionName=null, ?array $arguments=null, ?int $pageUid=null, $_=null, int $statusCode=303)
Definition: ActionController.php:684
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getManualDateStart
‪getManualDateStart()
Definition: Constraint.php:178
‪TYPO3\CMS\Belog\Controller\BackendLogController\createPageDepthOptions
‪array createPageDepthOptions()
Definition: BackendLogController.php:304
‪TYPO3\CMS\Belog\Controller\BackendLogController\persistConstraintInBeUserData
‪persistConstraintInBeUserData(Constraint $constraint)
Definition: BackendLogController.php:159
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController
Definition: ActionController.php:63
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\getFlashMessageQueue
‪getFlashMessageQueue(string $identifier=null)
Definition: ActionController.php:658
‪TYPO3\CMS\Belog\Controller\BackendLogController\createWorkspaceListForSelectOptions
‪array createWorkspaceListForSelectOptions()
Definition: BackendLogController.php:262
‪TYPO3\CMS\Belog\Domain\Model\Constraint\setStartTimestamp
‪setStartTimestamp(int $timestamp)
Definition: Constraint.php:133
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Belog\Controller\BackendLogController\resetConstraintsOnMemoryExhaustionError
‪resetConstraintsOnMemoryExhaustionError()
Definition: BackendLogController.php:171
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Belog\Domain\Model\Constraint
Definition: Constraint.php:27
‪TYPO3\CMS\Belog\Domain\Model\Constraint\setWorkspaceUid
‪setWorkspaceUid(int $workspace)
Definition: Constraint.php:103
‪TYPO3\CMS\Belog\Controller\BackendLogController\getBackendUser
‪getBackendUser()
Definition: BackendLogController.php:330
‪TYPO3\CMS\Belog\Domain\Model\Constraint\setEndTimestamp
‪setEndTimestamp(int $timestamp)
Definition: Constraint.php:143