‪TYPO3CMS  ‪main
LogEntryRepository.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\Log\LogLevel;
27 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
28 use ‪TYPO3\CMS\Core\Log\LogLevel as Typo3LogLevel;
31 
37 {
38  public function ‪findByUid(‪$uid): ?‪LogEntry
39  {
40  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_log');
41  $row = $queryBuilder
42  ->select('*')
43  ->from('sys_log')
44  ->where(
45  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT))
46  )
47  ->fetchAssociative();
48  return $row ? ‪LogEntry::createFromDatabaseRecord($row) : null;
49  }
50 
51  protected function ‪createQuery(): QueryBuilder
52  {
53  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_log');
54  $queryBuilder
55  ->select('*')
56  ->from('sys_log')
57  ->orderBy('uid', 'DESC');
58  return $queryBuilder;
59  }
60 
66  public function ‪findByConstraint(‪Constraint $constraint): array
67  {
68  $query = $this->‪createQuery();
69  $queryConstraints = $this->‪createQueryConstraints($query, $constraint);
70  $stmt = $query
71  ->where(...$queryConstraints)
72  ->setMaxResults($constraint->‪getNumber())
73  ->executeQuery();
74 
75  $result = [];
76  while ($row = $stmt->fetchAssociative()) {
77  $result[] = ‪LogEntry::createFromDatabaseRecord($row);
78  }
79  return $result;
80  }
81 
85  protected function ‪createQueryConstraints(QueryBuilder $query, ‪Constraint $constraint): array
86  {
87  // User / group handling
88  $queryConstraints = $this->‪addUsersAndGroupsToQueryConstraints($constraint, $query);
89  // Workspace
90  if ($constraint->‪getWorkspaceUid() !== -99) {
91  $queryConstraints[] = $query->expr()->eq('workspace', $query->createNamedParameter($constraint->‪getWorkspaceUid(), ‪Connection::PARAM_INT));
92  }
93  // Channel
94  if ($channel = $constraint->‪getChannel()) {
95  $queryConstraints[] = $query->expr()->eq('channel', $query->createNamedParameter($channel));
96  }
97  // Level
98  if ($level = $constraint->‪getLevel()) {
99  $queryConstraints[] = $query->expr()->in('level', $query->createNamedParameter(Typo3LogLevel::atLeast($level), ‪Connection::PARAM_INT_ARRAY));
100  }
101  // Start / endtime handling: The timestamp calculation was already done
102  // in the controller, since we need those calculated values in the view as well.
103  $queryConstraints[] = $query->expr()->gte('tstamp', $query->createNamedParameter($constraint->‪getStartTimestamp(), ‪Connection::PARAM_INT));
104  $queryConstraints[] = $query->expr()->lt('tstamp', $query->createNamedParameter($constraint->‪getEndTimestamp(), ‪Connection::PARAM_INT));
105  // Page and level constraint if in page context
106  $constraint = $this->‪addPageTreeConstraintsToQuery($constraint, $query);
107  if ($constraint) {
108  $queryConstraints[] = $constraint;
109  }
110  return $queryConstraints;
111  }
112 
118  ‪Constraint $constraint,
119  QueryBuilder $query,
120  ): ?string {
121  $pageIds = [];
122  // Check if we should get a whole tree of pages and not only a single page
123  if ($constraint->‪getDepth() > 0) {
124  $repository = GeneralUtility::makeInstance(PageTreeRepository::class);
125  $repository->setAdditionalWhereClause(‪$GLOBALS['BE_USER']->getPagePermsClause(‪Permission::PAGE_SHOW));
126  $pages = $repository->getFlattenedPages([$constraint->‪getPageId()], $constraint->‪getDepth());
127  foreach ($pages as $page) {
128  $pageIds[] = (int)$page['uid'];
129  }
130  }
131  if (!empty($constraint->‪getPageId())) {
132  $pageIds[] = $constraint->‪getPageId();
133  }
134  if (!empty($pageIds)) {
135  return $query->expr()->in('event_pid', $query->createNamedParameter($pageIds, ‪Connection::PARAM_INT_ARRAY));
136  }
137  return null;
138  }
139 
144  ‪Constraint $constraint,
145  QueryBuilder $query
146  ): array {
147  $userOrGroup = $constraint->‪getUserOrGroup();
148  if ($userOrGroup === '') {
149  return [];
150  }
151  $queryConstraints = [];
152  // Constraint for a group
153  if (str_starts_with($userOrGroup, 'gr-')) {
154  $groupId = (int)substr($userOrGroup, 3);
155  $groupResolver = GeneralUtility::makeInstance(GroupResolver::class);
156  $userIds = $groupResolver->findAllUsersInGroups([$groupId], 'be_groups', 'be_users');
157  if (!empty($userIds)) {
158  $userIds = array_column($userIds, 'uid');
159  $userIds = array_map(intval(...), $userIds);
160  $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter($userIds, ‪Connection::PARAM_INT_ARRAY));
161  } else {
162  // If there are no group members -> use -1 as constraint to not find anything
163  $queryConstraints[] = $query->expr()->eq('userid', $query->createNamedParameter(-1, ‪Connection::PARAM_INT));
164  }
165  } elseif (str_starts_with($userOrGroup, 'us-')) {
166  $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter((int)substr($userOrGroup, 3), ‪Connection::PARAM_INT));
167  } elseif ($userOrGroup === '-1') {
168  $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter((int)‪$GLOBALS['BE_USER']->user['uid'], ‪Connection::PARAM_INT));
169  }
170  return $queryConstraints;
171  }
172 
176  public function ‪deleteByMessageDetails(‪LogEntry $logEntry): int
177  {
178  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
179  ->getQueryBuilderForTable('sys_log');
180  $constraints = [];
181  $constraints[] = $queryBuilder->expr()->eq('details', $queryBuilder->createNamedParameter($logEntry->‪getDetails()));
182  // If the detailsNo is 11 or 12 we got messages that are heavily using placeholders. In this case
183  // we need to compare both the message and the actual log data to not remove too many log entries.
184  if (in_array($logEntry->‪getDetailsNumber(), [11, 12], true)) {
185  $constraints[] = $queryBuilder->expr()->eq('log_data', $queryBuilder->createNamedParameter($logEntry->‪getLogData()));
186  }
187  return (int)$queryBuilder->delete('sys_log')
188  ->where(...$constraints)
189  ->executeStatement();
190  }
191 
192  public function ‪getUsedChannels(): array
193  {
194  $conn = GeneralUtility::makeInstance(ConnectionPool::class)
195  ->getConnectionForTable('sys_log');
196 
197  $channels = $conn->createQueryBuilder()
198  ->select('channel')
199  ->distinct()
200  ->from('sys_log')
201  ->orderBy('channel')
202  ->executeQuery()
203  ->fetchFirstColumn();
204 
205  return array_combine($channels, $channels);
206  }
207 
208  public function ‪getUsedLevels(): array
209  {
210  static $allLevels = [
211  LogLevel::EMERGENCY,
212  LogLevel::ALERT,
213  LogLevel::CRITICAL,
214  LogLevel::ERROR,
215  LogLevel::WARNING,
216  LogLevel::NOTICE,
217  LogLevel::INFO,
218  LogLevel::DEBUG,
219  ];
220 
221  $conn = GeneralUtility::makeInstance(ConnectionPool::class)
222  ->getConnectionForTable('sys_log');
223 
224  $levels = $conn->createQueryBuilder()
225  ->select('level')
226  ->distinct()
227  ->from('sys_log')
228  ->executeQuery()
229  ->fetchFirstColumn();
230 
231  $levelsUsed = array_intersect($allLevels, $levels);
232 
233  return array_combine($levelsUsed, $levelsUsed);
234  }
235 }
‪TYPO3\CMS\Belog\Domain\Model\LogEntry\getDetails
‪getDetails()
Definition: LogEntry.php:174
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository
Definition: LogEntryRepository.php:37
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\addPageTreeConstraintsToQuery
‪addPageTreeConstraintsToQuery(Constraint $constraint, QueryBuilder $query,)
Definition: LogEntryRepository.php:117
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getLevel
‪getLevel()
Definition: Constraint.php:128
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getStartTimestamp
‪getStartTimestamp()
Definition: Constraint.php:138
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\addUsersAndGroupsToQueryConstraints
‪addUsersAndGroupsToQueryConstraints(Constraint $constraint, QueryBuilder $query)
Definition: LogEntryRepository.php:143
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getDepth
‪getDepth()
Definition: Constraint.php:168
‪TYPO3\CMS\Belog\Domain\Model\LogEntry\getLogData
‪getLogData()
Definition: LogEntry.php:217
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\deleteByMessageDetails
‪deleteByMessageDetails(LogEntry $logEntry)
Definition: LogEntryRepository.php:176
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getEndTimestamp
‪getEndTimestamp()
Definition: Constraint.php:148
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\findByConstraint
‪array< LogEntry > findByConstraint(Constraint $constraint)
Definition: LogEntryRepository.php:66
‪TYPO3\CMS\Belog\Domain\Model\LogEntry\getDetailsNumber
‪getDetailsNumber()
Definition: LogEntry.php:202
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getWorkspaceUid
‪getWorkspaceUid()
Definition: Constraint.php:108
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\getUsedLevels
‪getUsedLevels()
Definition: LogEntryRepository.php:208
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\getUsedChannels
‪getUsedChannels()
Definition: LogEntryRepository.php:192
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getNumber
‪getNumber()
Definition: Constraint.php:98
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\createQuery
‪createQuery()
Definition: LogEntryRepository.php:51
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getUserOrGroup
‪getUserOrGroup()
Definition: Constraint.php:88
‪TYPO3\CMS\Core\Authentication\GroupResolver
Definition: GroupResolver.php:36
‪TYPO3\CMS\Belog\Domain\Model\LogEntry
Definition: LogEntry.php:29
‪TYPO3\CMS\Belog\Domain\Repository
Definition: LogEntryRepository.php:18
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\findByUid
‪findByUid($uid)
Definition: LogEntryRepository.php:38
‪TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository\createQueryConstraints
‪createQueryConstraints(QueryBuilder $query, Constraint $constraint)
Definition: LogEntryRepository.php:85
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository
Definition: PageTreeRepository.php:41
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getChannel
‪getChannel()
Definition: Constraint.php:118
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Belog\Domain\Model\Constraint\getPageId
‪getPageId()
Definition: Constraint.php:158
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Belog\Domain\Model\Constraint
Definition: Constraint.php:27
‪TYPO3\CMS\Belog\Domain\Model\LogEntry\createFromDatabaseRecord
‪static createFromDatabaseRecord(array $row)
Definition: LogEntry.php:246
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT_ARRAY
‪const PARAM_INT_ARRAY
Definition: Connection.php:72
‪TYPO3\CMS\Core\Log\LogLevel
Definition: LogLevel.php:24