LogEntryRepository.php 8.07 KB
Newer Older
1
<?php
2
3
namespace TYPO3\CMS\Belog\Domain\Repository;

4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
8
9
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
10
 *
11
12
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
15
 * The TYPO3 project - inspiring people to share!
 */
16
17
use TYPO3\CMS\Belog\Domain\Model\LogEntry;
use TYPO3\CMS\Core\Database\ConnectionPool;
18
use TYPO3\CMS\Core\Type\Bitmask\Permission;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
Wouter Wolters's avatar
Wouter Wolters committed
20

21
22
23
/**
 * Sys log entry repository
 */
24
25
26
27
28
29
30
class LogEntryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
    /**
     * Backend users, with UID as key
     *
     * @var array
     */
31
    protected $beUserList = [];
32

33
34
35
36
37
    /**
     * Initialize some local variables to be used during creation of objects
     */
    public function initializeObject()
    {
38
        $this->beUserList = $this->getBackendUsers();
39
40
41
42
43
        /** @var $defaultQuerySettings \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface */
        $defaultQuerySettings = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface::class);
        $defaultQuerySettings->setRespectStoragePage(false);
        $this->setDefaultQuerySettings($defaultQuerySettings);
    }
44

45
46
47
48
49
50
51
52
53
54
55
56
57
    /**
     * Finds all log entries that match all given constraints.
     *
     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
     * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface<\TYPO3\CMS\Belog\Domain\Model\LogEntry>
     */
    public function findByConstraint(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
    {
        $query = $this->createQuery();
        $queryConstraints = $this->createQueryConstraints($query, $constraint);
        if (!empty($queryConstraints)) {
            $query->matching($query->logicalAnd($queryConstraints));
        }
58
        $query->setOrderings(['uid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING]);
59
60
61
        $query->setLimit($constraint->getNumber());
        return $query->execute();
    }
62

63
64
65
66
67
68
69
70
71
    /**
     * Create an array of query constraints from constraint object
     *
     * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
     * @return array<\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface>
     */
    protected function createQueryConstraints(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query, \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint)
    {
72
        $queryConstraints = [];
73
74
75
76
77
78
79
80
81
82
        // User / group handling
        $this->addUsersAndGroupsToQueryConstraints($constraint, $query, $queryConstraints);
        // Workspace
        if ($constraint->getWorkspaceUid() != \TYPO3\CMS\Belog\Domain\Model\Workspace::UID_ANY_WORKSPACE) {
            $queryConstraints[] = $query->equals('workspace', $constraint->getWorkspaceUid());
        }
        // Action (type):
        if ($constraint->getAction() > 0) {
            $queryConstraints[] = $query->equals('type', $constraint->getAction());
        } elseif ($constraint->getAction() == -1) {
83
            $queryConstraints[] = $query->equals('type', 5);
84
85
86
87
88
89
90
91
92
        }
        // 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->greaterThanOrEqual('tstamp', $constraint->getStartTimestamp());
        $queryConstraints[] = $query->lessThan('tstamp', $constraint->getEndTimestamp());
        // Page and level constraint if in page context
        $this->addPageTreeConstraintsToQuery($constraint, $query, $queryConstraints);
        return $queryConstraints;
    }
93

94
95
96
97
98
99
100
101
102
103
104
105
106
    /**
     * Adds constraints for the page(s) to the query; this could be one single page or a whole subtree beneath a given
     * page.
     *
     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
     * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
     * @param array &$queryConstraints the query constraints to add to, will be modified
     */
    protected function addPageTreeConstraintsToQuery(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$queryConstraints)
    {
        if (!$constraint->getIsInPageContext()) {
            return;
        }
107
        $pageIds = [];
108
109
110
111
        // Check if we should get a whole tree of pages and not only a single page
        if ($constraint->getDepth() > 0) {
            /** @var $pageTree \TYPO3\CMS\Backend\Tree\View\PageTreeView */
            $pageTree = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\PageTreeView::class);
112
            $pageTree->init('AND ' . $GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW));
113
            $pageTree->makeHTML = 0;
114
            $pageTree->fieldArray = ['uid'];
115
116
117
118
119
120
            $pageTree->getTree($constraint->getPageId(), $constraint->getDepth());
            $pageIds = $pageTree->ids;
        }
        $pageIds[] = $constraint->getPageId();
        $queryConstraints[] = $query->in('eventPid', $pageIds);
    }
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    /**
     * Adds users and groups to the query constraints.
     *
     * @param \TYPO3\CMS\Belog\Domain\Model\Constraint $constraint
     * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
     * @param array &$queryConstraints the query constraints to add to, will be modified
     */
    protected function addUsersAndGroupsToQueryConstraints(\TYPO3\CMS\Belog\Domain\Model\Constraint $constraint, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$queryConstraints)
    {
        $userOrGroup = $constraint->getUserOrGroup();
        if ($userOrGroup === '') {
            return;
        }
        // Constraint for a group
        if (substr($userOrGroup, 0, 3) === 'gr-') {
            $groupId = (int)substr($userOrGroup, 3);
138
            $userIds = [];
139
140
141
142
143
144
145
146
147
            foreach ($this->beUserList as $userId => $userData) {
                if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($userData['usergroup_cached_list'], $groupId)) {
                    $userIds[] = $userId;
                }
            }
            if (!empty($userIds)) {
                $queryConstraints[] = $query->in('userid', $userIds);
            } else {
                // If there are no group members -> use -1 as constraint to not find anything
148
                $queryConstraints[] = $query->in('userid', [-1]);
149
150
151
152
153
154
155
            }
        } elseif (substr($userOrGroup, 0, 3) === 'us-') {
            $queryConstraints[] = $query->equals('userid', (int)substr($userOrGroup, 3));
        } elseif ($userOrGroup === '-1') {
            $queryConstraints[] = $query->equals('userid', (int)$GLOBALS['BE_USER']->user['uid']);
        }
    }
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    /**
     * Deletes all messages which have the same message details
     *
     * @param LogEntry $logEntry
     * @return int
     */
    public function deleteByMessageDetails(LogEntry $logEntry): int
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getQueryBuilderForTable('sys_log');
        $constraints = [];
        $constraints[] = $queryBuilder->expr()->eq('details', $queryBuilder->createNamedParameter($logEntry->getDetails()));
        // If the detailsNo is 11 or 12 we got messages that are heavily using placeholders. In this case
        // we need to compare both the message and the actual log data to not remove too many log entries.
        if (GeneralUtility::inList('11,12', $logEntry->getDetailsNumber())) {
            $constraints[] = $queryBuilder->expr()->eq('log_data', $queryBuilder->createNamedParameter($logEntry->getLogData()));
        }
        return $queryBuilder->delete('sys_log')
            ->where(...$constraints)
            ->execute();
    }

179
180
181
182
183
184
185
186
187
    /**
     * Get a list of all backend users that are not deleted
     *
     * @return array
     */
    protected function getBackendUsers()
    {
        return \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames();
    }
188
}