connectionPool->getQueryBuilderForTable('sys_log'); $row = $queryBuilder ->select('*') ->from('sys_log') ->where( $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT)) ) ->fetchAssociative(); return $row ? LogEntry::createFromDatabaseRecord($row) : null; } /** * Finds all log entries that match all given constraints. * * @return array */ public function findByConstraint(Constraint $constraint): array { $query = $this->connectionPool->getQueryBuilderForTable('sys_log'); $query->select('*') ->from('sys_log') ->orderBy('uid', 'DESC'); $queryConstraints = $this->createQueryConstraints($query, $constraint); $stmt = $query ->where(...$queryConstraints) ->setMaxResults($constraint->getNumber()) ->executeQuery(); $result = []; while ($row = $stmt->fetchAssociative()) { $result[] = LogEntry::createFromDatabaseRecord($row); } return $result; } /** * Create an array of query constraints from constraint object */ protected function createQueryConstraints(QueryBuilder $query, Constraint $constraint): array { // User / group handling $queryConstraints = $this->addUsersAndGroupsToQueryConstraints($constraint, $query); // Workspace if ($constraint->getWorkspaceUid() !== -99) { $queryConstraints[] = $query->expr()->eq('workspace', $query->createNamedParameter($constraint->getWorkspaceUid(), Connection::PARAM_INT)); } // Channel if ($channel = $constraint->getChannel()) { $queryConstraints[] = $query->expr()->eq('channel', $query->createNamedParameter($channel)); } // Level if ($level = $constraint->getLevel()) { $queryConstraints[] = $query->expr()->in('level', $query->createNamedParameter(Typo3LogLevel::atLeast($level), Connection::PARAM_STR_ARRAY)); } // Start / endtime handling: The timestamp calculation was already done // in the controller, since we need those calculated values in the view as well. $queryConstraints[] = $query->expr()->gte('tstamp', $query->createNamedParameter($constraint->getStartTimestamp(), Connection::PARAM_INT)); $queryConstraints[] = $query->expr()->lt('tstamp', $query->createNamedParameter($constraint->getEndTimestamp(), Connection::PARAM_INT)); // Page and level constraint if in page context $constraint = $this->addPageTreeConstraintsToQuery($constraint, $query); if ($constraint) { $queryConstraints[] = $constraint; } return $queryConstraints; } /** * Adds constraints for the page(s) to the query; this could be one single page or a whole subtree beneath a given * page. */ protected function addPageTreeConstraintsToQuery(Constraint $constraint, QueryBuilder $query): ?string { $pageIds = []; // Check if we should get a whole tree of pages and not only a single page if ($constraint->getDepth() > 0) { $repository = GeneralUtility::makeInstance(PageTreeRepository::class); $repository->setAdditionalWhereClause($GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW)); $pages = $repository->getFlattenedPages([$constraint->getPageId()], $constraint->getDepth()); foreach ($pages as $page) { $pageIds[] = (int)$page['uid']; } } if (!empty($constraint->getPageId())) { $pageIds[] = $constraint->getPageId(); } if (!empty($pageIds)) { return $query->expr()->in('event_pid', $query->createNamedParameter($pageIds, Connection::PARAM_INT_ARRAY)); } return null; } /** * Adds users and groups to the query constraints. */ protected function addUsersAndGroupsToQueryConstraints(Constraint $constraint, QueryBuilder $query): array { $userOrGroup = $constraint->getUserOrGroup(); if ($userOrGroup === '') { return []; } $queryConstraints = []; // Constraint for a group if (str_starts_with($userOrGroup, 'gr-')) { $groupId = (int)substr($userOrGroup, 3); $userIds = $this->groupResolver->findAllUsersInGroups([$groupId], 'be_groups', 'be_users'); if (!empty($userIds)) { $userIds = array_column($userIds, 'uid'); $userIds = array_map(intval(...), $userIds); $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter($userIds, Connection::PARAM_INT_ARRAY)); } else { // If there are no group members -> use -1 as constraint to not find anything $queryConstraints[] = $query->expr()->eq('userid', $query->createNamedParameter(-1, Connection::PARAM_INT)); } } elseif (str_starts_with($userOrGroup, 'us-')) { $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter((int)substr($userOrGroup, 3), Connection::PARAM_INT)); } elseif ($userOrGroup === '-1') { $queryConstraints[] = $query->expr()->in('userid', $query->createNamedParameter((int)$GLOBALS['BE_USER']->user['uid'], Connection::PARAM_INT)); } return $queryConstraints; } /** * Deletes all messages which have the same message details */ public function deleteByMessageDetails(LogEntry $logEntry): int { $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_log'); return $queryBuilder->delete('sys_log') ->where($queryBuilder->expr()->eq('details', $queryBuilder->createNamedParameter($logEntry->getDetails()))) ->executeStatement(); } public function getUsedChannels(): array { $channels = $this->connectionPool->getQueryBuilderForTable('sys_log') ->select('channel') ->distinct() ->from('sys_log') ->orderBy('channel') ->executeQuery() ->fetchFirstColumn(); return array_combine($channels, $channels); } public function getUsedLevels(): array { static $allLevels = [ LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::ERROR, LogLevel::WARNING, LogLevel::NOTICE, LogLevel::INFO, LogLevel::DEBUG, ]; $levels = $this->connectionPool->getQueryBuilderForTable('sys_log') ->select('level') ->distinct() ->from('sys_log') ->executeQuery() ->fetchFirstColumn(); $levelsUsed = array_intersect($allLevels, $levels); return array_combine($levelsUsed, $levelsUsed); } }