5aacb46e0bf8740b504c6e94eca9e61bfb332237
[Packages/TYPO3.CMS.git] / typo3 / sysext / belog / Classes / Domain / Repository / LogEntryRepository.php
1 <?php
2 namespace TYPO3\CMS\Belog\Domain\Repository;
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 use TYPO3\CMS\Belog\Domain\Model\LogEntry;
17 use TYPO3\CMS\Core\Database\ConnectionPool;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Sys log entry repository
22 */
23 class LogEntryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
24 {
25 /**
26 * Backend users, with UID as key
27 *
28 * @var array
29 */
30 protected $beUserList = [];
31
32 /**
33 * Initialize some local variables to be used during creation of objects
34 */
35 public function initializeObject()
36 {
37 $this->beUserList = $this->getBackendUsers();
38 /** @var $defaultQuerySettings \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface */
39 $defaultQuerySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface::class);
40 $defaultQuerySettings->setRespectStoragePage(false);
41 $this->setDefaultQuerySettings($defaultQuerySettings);
42 }
43
44 /**
45 * Finds all log entries that match all given constraints.
46 *
47 * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
48 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface<\TYPO3\CMS\Belog\Domain\Model\LogEntry>
49 */
50 public function findByConstraint(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
51 {
52 $query = $this->createQuery();
53 $queryConstraints = $this->createQueryConstraints($query, $constraint);
54 if (!empty($queryConstraints)) {
55 $query->matching($query->logicalAnd($queryConstraints));
56 }
57 $query->setOrderings(['uid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING]);
58 $query->setLimit($constraint->getNumber());
59 return $query->execute();
60 }
61
62 /**
63 * Create an array of query constraints from constraint object
64 *
65 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
66 * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
67 * @return array<\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface>
68 */
69 protected function createQueryConstraints(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query, \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
70 {
71 $queryConstraints = [];
72 // User / group handling
73 $this->addUsersAndGroupsToQueryConstraints($constraint, $query, $queryConstraints);
74 // Workspace
75 if ($constraint->getWorkspaceUid() != \TYPO3\CMS\Belog\Domain\Model\Workspace::UID_ANY_WORKSPACE) {
76 $queryConstraints[] = $query->equals('workspace', $constraint->getWorkspaceUid());
77 }
78 // Action (type):
79 if ($constraint->getAction() > 0) {
80 $queryConstraints[] = $query->equals('type', $constraint->getAction());
81 } elseif ($constraint->getAction() == -1) {
82 $queryConstraints[] = $query->equals('type', 5);
83 }
84 // Start / endtime handling: The timestamp calculation was already done
85 // in the controller, since we need those calculated values in the view as well.
86 $queryConstraints[] = $query->greaterThanOrEqual('tstamp', $constraint->getStartTimestamp());
87 $queryConstraints[] = $query->lessThan('tstamp', $constraint->getEndTimestamp());
88 // Page and level constraint if in page context
89 $this->addPageTreeConstraintsToQuery($constraint, $query, $queryConstraints);
90 return $queryConstraints;
91 }
92
93 /**
94 * Adds constraints for the page(s) to the query; this could be one single page or a whole subtree beneath a given
95 * page.
96 *
97 * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
98 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
99 * @param array &$queryConstraints the query constraints to add to, will be modified
100 */
101 protected function addPageTreeConstraintsToQuery(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$queryConstraints)
102 {
103 if (!$constraint->getIsInPageContext()) {
104 return;
105 }
106 $pageIds = [];
107 // Check if we should get a whole tree of pages and not only a single page
108 if ($constraint->getDepth() > 0) {
109 /** @var $pageTree \TYPO3\CMS\Backend\Tree\View\PageTreeView */
110 $pageTree = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\PageTreeView::class);
111 $pageTree->init('AND ' . $GLOBALS['BE_USER']->getPagePermsClause(1));
112 $pageTree->makeHTML = 0;
113 $pageTree->fieldArray = ['uid'];
114 $pageTree->getTree($constraint->getPageId(), $constraint->getDepth());
115 $pageIds = $pageTree->ids;
116 }
117 $pageIds[] = $constraint->getPageId();
118 $queryConstraints[] = $query->in('eventPid', $pageIds);
119 }
120
121 /**
122 * Adds users and groups to the query constraints.
123 *
124 * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
125 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
126 * @param array &$queryConstraints the query constraints to add to, will be modified
127 */
128 protected function addUsersAndGroupsToQueryConstraints(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$queryConstraints)
129 {
130 $userOrGroup = $constraint->getUserOrGroup();
131 if ($userOrGroup === '') {
132 return;
133 }
134 // Constraint for a group
135 if (substr($userOrGroup, 0, 3) === 'gr-') {
136 $groupId = (int)substr($userOrGroup, 3);
137 $userIds = [];
138 foreach ($this->beUserList as $userId => $userData) {
139 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($userData['usergroup_cached_list'], $groupId)) {
140 $userIds[] = $userId;
141 }
142 }
143 if (!empty($userIds)) {
144 $queryConstraints[] = $query->in('userid', $userIds);
145 } else {
146 // If there are no group members -> use -1 as constraint to not find anything
147 $queryConstraints[] = $query->in('userid', [-1]);
148 }
149 } elseif (substr($userOrGroup, 0, 3) === 'us-') {
150 $queryConstraints[] = $query->equals('userid', (int)substr($userOrGroup, 3));
151 } elseif ($userOrGroup === '-1') {
152 $queryConstraints[] = $query->equals('userid', (int)$GLOBALS['BE_USER']->user['uid']);
153 }
154 }
155
156 /**
157 * Deletes all messages which have the same message details
158 *
159 * @param LogEntry $logEntry
160 * @return int
161 */
162 public function deleteByMessageDetails(LogEntry $logEntry): int
163 {
164 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
165 ->getQueryBuilderForTable('sys_log');
166 $constraints = [];
167 $constraints[] = $queryBuilder->expr()->eq('details', $queryBuilder->createNamedParameter($logEntry->getDetails()));
168 // If the detailsNo is 11 or 12 we got messages that are heavily using placeholders. In this case
169 // we need to compare both the message and the actual log data to not remove too many log entries.
170 if (GeneralUtility::inList('11,12', $logEntry->getDetailsNumber())) {
171 $constraints[] = $queryBuilder->expr()->eq('log_data', $queryBuilder->createNamedParameter($logEntry->getLogData()));
172 }
173 return $queryBuilder->delete('sys_log')
174 ->where(...$constraints)
175 ->execute();
176 }
177
178 /**
179 * Get a list of all backend users that are not deleted
180 *
181 * @return array
182 */
183 protected function getBackendUsers()
184 {
185 return \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames();
186 }
187 }