ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilRbacLog.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
31{
32 private const LOG_TABLE_NAME = 'rbac_log';
33 public const EDIT_PERMISSIONS = 1;
34 public const MOVE_OBJECT = 2;
35 public const LINK_OBJECT = 3;
36 public const COPY_OBJECT = 4;
37 public const CREATE_OBJECT = 5;
38 public const EDIT_TEMPLATE = 6;
39 public const EDIT_TEMPLATE_EXISTING = 7;
40 public const CHANGE_OWNER = 8;
41
42 public function __construct(
43 private readonly ilDBInterface $db
44 ) {
45 }
46
47 public function getLogItems(
48 int $ref_id,
50 Order $order,
51 ?array $filter
52 ): array {
53 $this->db->setLimit($range->getLength(), $range->getStart());
54 $set = $this->db->query(
55 'SELECT * FROM ' . self::LOG_TABLE_NAME
56 . ' WHERE ref_id = ' . $this->db->quote($ref_id, ilDBConstants::T_INTEGER)
57 . $this->getWhereForFilter($filter)
58 . $order->join(
59 ' ORDER BY ',
60 static fn(string $ret, string $key, string $value): string =>
61 $ret === ' ORDER BY ' ? "{$ret} {$key} {$value}" : "{$ret}, {$key} {$value} "
62 )
63 );
64 $result = [];
65 while ($row = $this->db->fetchAssoc($set)) {
66 $row['data'] = unserialize($row['data'], [false]);
67 $result[] = $row;
68 }
69 return $result;
70 }
71
72 public function getLogItemsCount(
73 int $ref_id,
74 array $filter
75 ): int {
76 $result = $this->db->fetchObject(
77 $this->db->query(
78 'SELECT COUNT(*) as cnt FROM ' . self::LOG_TABLE_NAME . ' WHERE ref_id = '
79 . $this->db->quote(
80 $ref_id,
81 ilDBConstants::T_INTEGER
82 ) . $this->getWhereForFilter($filter)
83 )
84 );
85 return $result->cnt;
86 }
87
88 private function getWhereForFilter(?array $filter): string
89 {
90 if ($filter === null) {
91 return '';
92 }
93
94 $where = [];
95 if (isset($filter['action'])) {
96 $where[] = ' ' . $this->db->in(
97 'action',
98 $filter['action'],
99 false,
101 );
102 }
103 if (isset($filter['from'])) {
104 $where[] = ' created >= ' . $this->db->quote(
105 $filter['from'],
107 );
108 }
109 if (isset($filter['to'])) {
110 $where[] = ' created <= ' . $this->db->quote(
111 $filter['to'],
113 );
114 }
115
116 if (count($where) > 0) {
117 $where = array_merge([' AND '], [implode(' AND ', $where)]);
118 }
119 return implode('', $where);
120 }
121
122 public static function isActive(): bool
123 {
124 return ilPrivacySettings::getInstance()->enabledRbacLog();
125 }
126
127 public static function gatherFaPa(int $ref_id, array $role_ids, bool $add_action = false): array
128 {
129 global $DIC;
130
131 $rbacreview = $DIC->rbac()->review();
132 $result = [];
133
134 // #10946 - if result is written to log directly we need to add an "action" dimension
135 // if result is used as input to diffFaPa() we need "raw" data
136
137 // roles
138 foreach ($role_ids as $role_id) {
139 if ($role_id != SYSTEM_ROLE_ID) {
140 if ($add_action) {
141 $result["ops"][$role_id]["add"] = $rbacreview->getRoleOperationsOnObject($role_id, $ref_id);
142 } else {
143 $result["ops"][$role_id] = $rbacreview->getRoleOperationsOnObject($role_id, $ref_id);
144 }
145 }
146 }
147
148 // inheritance
149 if ($ref_id && $ref_id != ROLE_FOLDER_ID) {
150 if ($add_action) {
151 $result["inht"]["add"] = $rbacreview->getRolesOfRoleFolder($ref_id);
152 } else {
153 $result["inht"] = $rbacreview->getRolesOfRoleFolder($ref_id);
154 }
155 }
156
157 return $result;
158 }
159
160 public static function diffFaPa(array $old, array $new): array
161 {
162 $result = [];
163
164 // roles
165 foreach ((array) $old["ops"] as $role_id => $ops) {
166 $diff = array_diff($ops, $new["ops"][$role_id]);
167 if ($diff !== []) {
168 $result["ops"][$role_id]["rmv"] = array_values($diff);
169 }
170 $diff = array_diff($new["ops"][$role_id], $ops);
171 if ($diff !== []) {
172 $result["ops"][$role_id]["add"] = array_values($diff);
173 }
174 }
175
176 if (isset($old["inht"]) || isset($new["inht"])) {
177 if (isset($old["inht"]) && !isset($new["inht"])) {
178 $result["inht"]["rmv"] = $old["inht"];
179 } elseif (!isset($old["inht"]) && isset($new["inht"])) {
180 $result["inht"]["add"] = $new["inht"];
181 } else {
182 $diff = array_diff($old["inht"], $new["inht"]);
183 if ($diff !== []) {
184 $result["inht"]["rmv"] = array_values($diff);
185 }
186 $diff = array_diff($new["inht"], $old["inht"]);
187 if ($diff !== []) {
188 $result["inht"]["add"] = array_values($diff);
189 }
190 }
191 }
192 return $result;
193 }
194
195 public static function gatherTemplate(int $role_ref_id, int $role_id): array
196 {
197 global $DIC;
198
199 $rbacreview = $DIC->rbac()->review();
200 return $rbacreview->getAllOperationsOfRole($role_id, $role_ref_id);
201 }
202
203 public static function diffTemplate(array $old, array $new): array
204 {
205 $result = [];
206 $types = array_unique(array_merge(array_keys($old), array_keys($new)));
207 foreach ($types as $type) {
208 if (!isset($old[$type])) {
209 $result[$type]["add"] = $new[$type];
210 } elseif (!isset($new[$type])) {
211 $result[$type]["rmv"] = $old[$type];
212 } else {
213 $diff = array_diff($old[$type], $new[$type]);
214 if ($diff !== []) {
215 $result[$type]["rmv"] = array_values($diff);
216 }
217 $diff = array_diff($new[$type], $old[$type]);
218 if ($diff !== []) {
219 $result[$type]["add"] = array_values($diff);
220 }
221 }
222 }
223 return $result;
224 }
225
226 public static function add(int $action, int $ref_id, array $diff, bool $source_ref_id = false): bool
227 {
228 global $DIC;
229
230 $ilUser = $DIC->user();
231 $ilDB = $DIC->database();
232
233 if (self::isValidAction($action) && count($diff)) {
234 if ($source_ref_id) {
235 $diff["src"] = $source_ref_id;
236 }
237 $id = $ilDB->nextId(self::LOG_TABLE_NAME);
238
239 $ilDB->query('INSERT INTO ' . self::LOG_TABLE_NAME . ' (log_id, user_id, created, ref_id, action, data)' .
240 " VALUES (" . $ilDB->quote($id, "integer") . "," . $ilDB->quote($ilUser->getId(), "integer") .
241 "," . $ilDB->quote(time(), "integer") .
242 "," . $ilDB->quote($ref_id, "integer") . "," . $ilDB->quote($action, "integer") .
243 "," . $ilDB->quote(serialize($diff), "text") . ")");
244 return true;
245 }
246 return false;
247 }
248
249 protected static function isValidAction(int $action): bool
250 {
251 if (in_array(
252 $action,
253 [
254 self::EDIT_PERMISSIONS,
255 self::MOVE_OBJECT,
256 self::LINK_OBJECT,
257 self::COPY_OBJECT,
258 self::CREATE_OBJECT,
259 self::EDIT_TEMPLATE,
260 self::EDIT_TEMPLATE_EXISTING,
261 self::CHANGE_OWNER
262 ]
263 )) {
264 return true;
265 }
266 return false;
267 }
268
269 public static function delete(int $ref_id): void
270 {
271 global $DIC;
272
273 $ilDB = $DIC->database();
274 $ilDB->query('DELETE FROM ' . self::LOG_TABLE_NAME . ' WHERE ref_id = ' . $ilDB->quote($ref_id, 'integer'));
275 self::garbageCollection();
276 }
277
278 public static function garbageCollection(): void
279 {
280 global $DIC;
281
282 $ilDB = $DIC->database();
283
284 $settings = ilPrivacySettings::getInstance();
285 $max = $settings->getRbacLogAge();
286
287 $ilDB->query('DELETE FROM ' . self::LOG_TABLE_NAME . ' WHERE created < ' . $ilDB->quote(
288 strtotime("-" . $max . "months"),
289 "integer"
290 ));
291 }
292}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:29
join($init, callable $fn)
Definition: Order.php:75
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:29
Class ilDBConstants.
class ilRbacLog Log changes in Rbac-related settings
const EDIT_PERMISSIONS
const COPY_OBJECT
static diffTemplate(array $old, array $new)
getLogItems(int $ref_id, Range $range, Order $order, ?array $filter)
static add(int $action, int $ref_id, array $diff, bool $source_ref_id=false)
__construct(private readonly ilDBInterface $db)
const MOVE_OBJECT
static isValidAction(int $action)
const EDIT_TEMPLATE_EXISTING
static gatherTemplate(int $role_ref_id, int $role_id)
const CHANGE_OWNER
getLogItemsCount(int $ref_id, array $filter)
const LOG_TABLE_NAME
static gatherFaPa(int $ref_id, array $role_ids, bool $add_action=false)
static garbageCollection()
const LINK_OBJECT
static diffFaPa(array $old, array $new)
const EDIT_TEMPLATE
getWhereForFilter(?array $filter)
static isActive()
const CREATE_OBJECT
const SYSTEM_ROLE_ID
Definition: constants.php:29
const ROLE_FOLDER_ID
Definition: constants.php:34
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:66
global $DIC
Definition: shib_login.php:26