Subversion Repositories oidplus

Rev

Rev 1207 | Rev 1268 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1207 Rev 1267
Line 24... Line 24...
24
// phpcs:enable PSR1.Files.SideEffects
24
// phpcs:enable PSR1.Files.SideEffects
25
 
25
 
26
class OIDplusLogger extends OIDplusBaseClass {
26
class OIDplusLogger extends OIDplusBaseClass {
27
 
27
 
28
        /**
28
        /**
29
         * This function splits a mask code containing multiple components
29
         * This method splits a mask code containing multiple components (delimited by '+') into single components
30
         * (delimited by '+' or '/') in single components
-
 
31
         * It takes care that '+' and '/' inside brackets won't be used to split the codes
30
         * It takes care that '+' inside brackets isn't be used to split the codes
32
         * Also, brackets can be escaped.
31
         * Also, brackets can be escaped.
33
         * The severity block (optional, must be standing in front of a component)
32
         * The severity block (optional, must be standing in front of a component)
34
         * is handled too. Inside the severity block, you may only use '/' to split components.
33
         * is handled too. Inside the severity block, you may only use '/' to split components.
35
         * The severity block will be implicitly repeated from the previous components if a component
34
         * The severity block will be implicitly repeated from the previous components if a component
36
         * does not feature one.
35
         * does not feature one.
-
 
36
         * @param string $maskcode A maskcode, e.g. [INFO]OID(2.999)
-
 
37
         * @return array|false An array of [$severity,$target],
-
 
38
         * where $severity is 'INFO' or [$online,$offline] like ['INFO','INFO']
-
 
39
         * and $target is like ['A'], ['OID', '2.999'], etc.
37
         *
40
         */
-
 
41
        public static function parse_maskcode(string $maskcode) {
-
 
42
                $out = array();
-
 
43
                $sevs = array(); // Note: The severity block will repeat for the next components if not changed explicitly
-
 
44
 
-
 
45
                if (!str_starts_with($maskcode,'V2:')) {
-
 
46
                        return false;
-
 
47
                } else {
-
 
48
                        $maskcode = substr($maskcode, 3);
-
 
49
                }
-
 
50
 
-
 
51
                // Step 1: Split severities from the rest of the maskcodes
-
 
52
                /*
38
         * "[ERR]AAA(BBB)+CCC(DDD)"   ==> array(
53
                 * "[ERR]AAA(BBB)+CCC(DDD)"   ==> array(
39
         *                                 array(array("ERR"),"AAA(BBB)"),
54
                 *                                 array(array("ERR"),"AAA(BBB)"),
40
         *                                 array(array("ERR"),"CCC(DDD)")
55
                 *                                 array(array("ERR"),"CCC(DDD)")
41
         *                              )
56
                 *                              )
42
         * "[INFO]AAA(B+BB)+[WARN]CCC(DDD)"  ==> array(
57
                 * "[INFO]AAA(B+BB)+[WARN]CCC(DDD)"  ==> array(
43
         *                                 array(array("INFO"),"AAA(B+BB)"),
58
                 *                                 array(array("INFO"),"AAA(B+BB)"),
44
         *                                 array(array("WARN"),"CCC(DDD)")
59
                 *                                 array(array("WARN"),"CCC(DDD)")
45
         *                              )
60
                 *                              )
46
         * "[?WARN/!OK] AAA(B\)BB)+CCC(DDD)" ==> array(
61
                 * "[OK/WARN] AAA(B\)BB)+CCC(DDD)" ==> array(
47
         *                                 array(array("?WARN", "!OK"),"AAA(B\)BB)"),
62
                 *                                 array(array("OK", "WARN"),"AAA(B\)BB)"),
48
         *                                 array(array("?WARN", "!OK"),"CCC(DDD)")
63
                 *                                 array(array("OK", "WARN"),"CCC(DDD)")
49
         *                              )
64
                 *                              )
50
         * @param string $maskcodes
-
 
51
         * @return array|false
-
 
52
         */
65
                 */
53
        private function split_maskcodes(string $maskcodes) {
-
 
54
                $out = array();
-
 
55
                $sevs = array(); // Note: The severity block will repeat for the next components if not changed explicitly
-
 
56
 
-
 
57
                $code = '';
66
                $code = '';
58
                $sev = '';
67
                $sev = '';
59
                $bracket_level = 0;
68
                $bracket_level = 0;
60
                $is_escaping = false;
69
                $is_escaping = false;
61
                $inside_severity_block = false;
70
                $inside_severity_block = false;
62
                for ($i=0; $i<strlen($maskcodes); $i++) {
71
                for ($i=0; $i<strlen($maskcode); $i++) {
63
                        $char = $maskcodes[$i];
72
                        $char = $maskcode[$i];
64
 
73
 
65
                        if ($inside_severity_block) {
74
                        if ($inside_severity_block) {
66
                                // Severity block (optional)
75
                                // Severity block (optional)
67
                                // e.g.  [?WARN/!OK] ==> $sevs = array("?WARN", "!OK")
76
                                // e.g.  [OK/WARN] ==> $sevs = array("OK", "WARN")
68
                                if ($char == '\\') {
77
                                if ($char == '\\') {
69
                                        if ($is_escaping) {
78
                                        if ($is_escaping) {
70
                                                $is_escaping = false;
79
                                                $is_escaping = false;
71
                                                $sev .= $char;
80
                                                $sev .= $char;
72
                                        } else {
81
                                        } else {
Line 144... Line 153...
144
                                                $bracket_level--;
153
                                                $bracket_level--;
145
                                                if ($bracket_level < 0) return false;
154
                                                if ($bracket_level < 0) return false;
146
                                        }
155
                                        }
147
                                        $code .= $char;
156
                                        $code .= $char;
148
                                }
157
                                }
149
                                else if ((($char == '+') || ($char == '/')) && ($bracket_level == 0)) {
158
                                else if (($char == '+') && ($bracket_level == 0)) {
150
                                        if ($is_escaping) {
159
                                        if ($is_escaping) {
151
                                                $is_escaping = false;
160
                                                $is_escaping = false;
152
                                                $code .= $char;
161
                                                $code .= $char;
153
                                        } else {
162
                                        } else {
154
                                                if ($code != '') $out[] = array($sevs,$code);
163
                                                if ($code != '') $out[] = array($sevs,$code);
Line 165... Line 174...
165
                                }
174
                                }
166
                        }
175
                        }
167
                }
176
                }
168
                if ($code != '') $out[] = array($sevs,$code);
177
                if ($code != '') $out[] = array($sevs,$code);
169
                if ($inside_severity_block) return false;
178
                if ($inside_severity_block) return false;
-
 
179
                unset($sevs);
-
 
180
 
-
 
181
                // Step 2: Process severities (split to online/offline)
-
 
182
                // Allowed:  ['INFO'] or ['INFO', 'INFO']
-
 
183
                // Disallow: ['NONE'] and ['NONE', 'NONE']
-
 
184
                foreach ($out as &$component) {
-
 
185
                        $sev_fixed = null;
-
 
186
                        $sevs = $component[0];
-
 
187
                        if (count($sevs) == 1) {
-
 
188
                                if ($sevs[0] == 'NONE') return false; // meaningless component
-
 
189
                                try { self::convertSeverity($sevs[0]); } catch (\Exception $e) { return false; } // just checking for valid value
-
 
190
                                $sev_fixed = $sevs[0];
-
 
191
                        } else if (count($sevs) == 2) {
-
 
192
                                $sev_online = $sevs[0];
-
 
193
                                $sev_offline = $sevs[1];
-
 
194
                                if (($sev_online == 'NONE') && ($sev_offline == 'NONE')) return false; // meaningless component
-
 
195
                                try { self::convertSeverity($sev_online); } catch (\Exception $e) { return false; } // just checking for valid value
-
 
196
                                try { self::convertSeverity($sev_offline); } catch (\Exception $e) { return false; } // just checking for valid value
-
 
197
                                $sev_fixed = [$sev_online, $sev_offline];
-
 
198
                        } else {
-
 
199
                                return false;
-
 
200
                        }
-
 
201
                        $component[0] = $sev_fixed;
-
 
202
                }
-
 
203
 
-
 
204
                // Step 3: Process target (split to type and value)
-
 
205
                // 'OID(2.999)' becomes ['OID', '2.999']
-
 
206
                // 'A' becomes ['A']
-
 
207
                foreach ($out as &$component) {
-
 
208
                        $m = array();
-
 
209
                        if (preg_match('@^([^()]+)\((.+)\)$@ismU', $component[1], $m)) {
-
 
210
                                $type = $m[1];
-
 
211
                                $value = $m[2];
-
 
212
                                $component[1] = [$type, $value];
-
 
213
                        } else {
-
 
214
                                $component[1] = [$component[1]];
-
 
215
                        }
-
 
216
                }
-
 
217
 
-
 
218
                // Some other checks (it makes it easier to validate the maskcodes with dev tools)
-
 
219
                foreach ($out as list($severity,$target)) {
-
 
220
                        if (($target[0] == 'OID') || ($target[0] == 'SUPOID')) {
-
 
221
                                if (is_array($severity)) return false; // OID and SUPOID logger mask cannot have online/offline severity
-
 
222
                                if (empty($target[1])) return false; /** @phpstan-ignore-line */
-
 
223
                        } else if (($target[0] == 'OIDRA') || ($target[0] == 'SUPOIDRA') || ($target[0] == 'RA')) {
-
 
224
                                if (empty($target[1])) return false;
-
 
225
                        } else if ($target[0] == 'A') {
-
 
226
                                if (!empty($target[1])) return false;
-
 
227
                        } else {
-
 
228
                                return false;
-
 
229
                        }
-
 
230
                }
170
 
231
 
171
                return $out;
232
                return $out;
172
        }
233
        }
173
 
234
 
174
        private $missing_plugin_queue = array();
235
        private $missing_plugin_queue = array();
Line 185... Line 246...
185
                }
246
                }
186
                return true;
247
                return true;
187
        }
248
        }
188
 
249
 
189
        /**
250
        /**
190
         * @param string $maskcodes A description of the mask-codes can be found in doc/developer_notes/logger_maskcodes.md
251
         * @param string $maskcode A description of the mask-codes can be found in doc/developer_notes/logger_maskcodes.md
191
         * @param string $message The message of the event
252
         * @param string $message The message of the event
192
         * @param mixed ...$sprintfArgs If used, %1..%n in $maskcodes and $message will be replaced, like _L() does.
253
         * @param mixed ...$sprintfArgs If used, %1..%n in $maskcode and $message will be replaced, like _L() does.
193
         * @return bool
254
         * @return bool
194
         * @throws OIDplusException
255
         * @throws OIDplusException
195
         */
256
         */
196
        public function log(string $maskcodes, string $message, ...$sprintfArgs): bool {
257
        public function log(string $maskcode, string $message, ...$sprintfArgs): bool {
197
                $this->reLogMissing(); // try to re-log failed requests
258
                $this->reLogMissing(); // try to re-log failed requests
198
 
259
 
-
 
260
                $sprintfArgs_Escaped = array();
-
 
261
                foreach ($sprintfArgs as $arg) {
-
 
262
                        // Inside an severity block, e.g. INFO of [INFO], we would need to escape []/\
-
 
263
                        // In the value, e.g. 2.999 of OID(2.999), we would need to escape ()+\
-
 
264
                        // Since there seems to be no meaningful use-case for parametrized severities, we only escape the value
-
 
265
                        $sprintfArgs_Escaped[] = str_replace(array('(',')','+','\\'), array('\\(', '\\)', '\\+', '\\\\'), $arg);
-
 
266
                }
-
 
267
 
199
                $maskcodes = my_vsprintf($maskcodes, $sprintfArgs);
268
                $maskcode = my_vsprintf($maskcode, $sprintfArgs_Escaped);
200
                $message = my_vsprintf($message, $sprintfArgs);
269
                $message = my_vsprintf($message, $sprintfArgs);
201
 
270
 
202
                if (strpos(str_replace('%%','',$maskcodes),'%') !== false) {
271
                if (strpos(str_replace('%%','',$maskcode),'%') !== false) {
203
                        throw new OIDplusException(_L('Unresolved wildcards in logging maskcode'));
272
                        throw new OIDplusException(_L('Unresolved wildcards in logging maskcode'));
204
                }
273
                }
205
 
274
 
206
                return $this->log_internal($maskcodes, $message, true);
275
                return $this->log_internal($maskcode, $message, true);
207
        }
276
        }
208
 
277
 
209
        /**
278
        /**
210
         * @param string $maskcodes
279
         * @param string $sev_name
211
         * @param string $message
280
         * @return int
212
         * @param bool $allow_delayed_log
281
         * @throws OIDplusConfigInitializationException
213
         * @return bool
-
 
214
         * @throws OIDplusException
282
         * @throws OIDplusException
215
         */
283
         */
216
        private function log_internal(string $maskcodes, string $message, bool $allow_delayed_log): bool {
284
        private static function convertSeverity(string $sev_name): int {
217
                $loggerPlugins = OIDplus::getLoggerPlugins();
285
                //$sev_name = strtoupper($sev_name);
218
                if (count($loggerPlugins) == 0) {
-
 
219
                        // The plugin might not be initialized in OIDplus::init()
-
 
220
                        // yet. Remember the log entries for later submission during
-
 
221
                        // OIDplus::init();
-
 
222
                        if ($allow_delayed_log) $this->missing_plugin_queue[] = array($maskcodes, $message);
-
 
223
                        return false;
-
 
224
                }
-
 
225
 
-
 
226
                // What is a mask code?
-
 
227
                // A mask code gives information about the log event:
-
 
228
                // 1. The severity (info, warning, error)
-
 
229
                // 2. In which logbook(s) the event shall be placed
-
 
230
                // Example:
-
 
231
                // The event would be:
-
 
232
                // "Person 'X' moves from house 'A' to house 'B'"
-
 
233
                // This event would affect the person X and the two houses,
-
 
234
                // so, instead of logging into 3 logbooks separately,
-
 
235
                // you would create a mask code that tells the system
-
 
236
                // to put the message into the logbooks of person X,
-
 
237
                // house A, and house B.
-
 
238
 
286
 
-
 
287
                switch ($sev_name) {
-
 
288
                        case 'NONE':
239
                $logEvent = new OIDplusLogEvent($message);
289
                                // Do not log anything. Used for online/offline severity pairs
-
 
290
                                return -1;
240
 
291
 
241
                // A mask code with multiple components is split into single codes
-
 
242
                // using '+' or '/', e.g. "OID(x)+RA(x)" would be split to "OID(x)" and "RA(x)"
-
 
243
                // which would result in the message being placed in the logbook of OID x,
-
 
244
                // and the logbook of the RA owning OID x.
-
 
245
                $maskcodes_ary = $this->split_maskcodes($maskcodes);
-
 
246
                if ($maskcodes_ary === false) {
-
 
247
                        throw new OIDplusException(_L('Invalid maskcode "%1" (failed to split)',$maskcodes));
-
 
248
                }
-
 
249
                foreach ($maskcodes_ary as list($sevs,$maskcode)) {
-
 
250
                        // At the beginning of each mask code, you must define a severity.
-
 
251
                        // If you have a mask code with multiple components, you don't have to place the
-
 
252
                        // severity for each component. You can just leave it at the beginning.
-
 
253
                        // e.g. "[WARN]OID(x)+RA(x)" is equal to "[WARN]OID(x)+[WARN]RA(x)"
-
 
254
                        // You can also put different severities for the components:
-
 
255
                        // e.g. "[INFO]OID(x)+[WARN]RA(x)" would be a info for the OID, but a warning for the RA.
-
 
256
                        // If you want to make the severity dependent on wheather the user is logged in or not,
-
 
257
                        // prepend "?" or "!" and use '/' as delimiter
-
 
258
                        // Example: "[?WARN/!OK]RA(x)" means: If RA is not logged in, it is a warning; if it is logged in, it is an success
-
 
259
                        $severity = 0; // default severity = none
-
 
260
                        $severity_online = 0;
-
 
261
                        foreach ($sevs as $sev) {
-
 
262
                                switch (strtoupper($sev)) {
-
 
263
                                        // [OK]   = Success
292
                        // [OK]   = Success
264
                                        //          Numeric value: 1
293
                        //          Numeric value: 1
265
                                        //          Rule of thumb: YOU have done something and it was successful
294
                        //          Rule of thumb: YOU have done something and it was successful
266
                                        case '?OK':
-
 
267
                                                $severity_online = 1;
-
 
268
                                                break;
-
 
269
                                        case '!OK':
-
 
270
                                        case  'OK':
295
                        case  'OK':
271
                                                $severity = 1;
-
 
272
                                                break;
296
                                return 1;
-
 
297
 
273
                                        // [INFO] = Informational
298
                        // [INFO] = Informational
274
                                        //          Numeric value: 2
299
                        //          Numeric value: 2
275
                                        //          Rule of thumb: Someone else has done something (that affects you) and it was successful
300
                        //          Rule of thumb: Someone else has done something (that affects you) and it was successful
276
                                        case '?INFO':
-
 
277
                                                $severity_online = 2;
-
 
278
                                                break;
-
 
279
                                        case '!INFO':
-
 
280
                                        case  'INFO':
301
                        case 'INFO':
281
                                                $severity = 2;
-
 
282
                                                break;
302
                                return 2;
-
 
303
 
283
                                        // [WARN] = Warning
304
                        // [WARN] = Warning
284
                                        //          Numeric value: 3
305
                        //          Numeric value: 3
285
                                        //          Rule of thumb: Something happened (probably someone did something) and it affects you
306
                        //          Rule of thumb: Something happened (probably someone did something) and it affects you
286
                                        case '?WARN':
-
 
287
                                                $severity_online = 3;
-
 
288
                                                break;
-
 
289
                                        case '!WARN':
-
 
290
                                        case  'WARN':
307
                        case 'WARN':
291
                                                $severity = 3;
-
 
292
                                                break;
308
                                return 3;
-
 
309
 
293
                                        // [ERR]  = Error
310
                        // [ERR]  = Error
294
                                        //          Numeric value: 4
311
                        //          Numeric value: 4
295
                                        //          Rule of thumb: Something failed (probably someone did something) and it affects you
312
                        //          Rule of thumb: Something failed (probably someone did something) and it affects you
296
                                        case '?ERR':
-
 
297
                                                $severity_online = 4;
-
 
298
                                                break;
-
 
299
                                        case '!ERR':
-
 
300
                                        case  'ERR':
313
                        case 'ERR':
301
                                                $severity = 4;
-
 
302
                                                break;
314
                                return 4;
-
 
315
 
303
                                        // [CRIT] = Critical
316
                        // [CRIT] = Critical
304
                                        //          Numeric value: 5
317
                        //          Numeric value: 5
305
                                        //          Rule of thumb: Something happened (probably someone did something) which is not an error,
318
                        //          Rule of thumb: Something happened (probably someone did something) which is not an error,
306
                                        //          but some critical situation (e.g. hardware failure), and it affects you
319
                        //          but some critical situation (e.g. hardware failure), and it affects you
307
                                        case '?CRIT':
-
 
308
                                                $severity_online = 5;
-
 
309
                                                break;
-
 
310
                                        case '!CRIT':
-
 
311
                                        case  'CRIT':
320
                        case 'CRIT':
312
                                                $severity = 5;
-
 
313
                                                break;
321
                                return 5;
-
 
322
 
314
                                        default:
323
                        default:
315
                                                throw new OIDplusException(_L('Invalid maskcode "%1" (Unknown severity "%2")',$maskcodes,$sev));
324
                                throw new OIDplusException(_L('Unknown severity "%1" in logger maskcode',$sev_name));
316
                                }
325
                }
317
                        }
326
        }
318
 
327
 
-
 
328
        /**
-
 
329
         * @param string $maskcode
-
 
330
         * @param string $message
-
 
331
         * @param bool $allow_delayed_log
-
 
332
         * @return bool
-
 
333
         * @throws OIDplusException
-
 
334
         */
-
 
335
        private function log_internal(string $maskcode, string $message, bool $allow_delayed_log): bool {
-
 
336
                $loggerPlugins = OIDplus::getLoggerPlugins();
-
 
337
                if (count($loggerPlugins) == 0) {
-
 
338
                        // The plugin might not be initialized in OIDplus::init()
-
 
339
                        // yet. Remember the log entries for later submission during
-
 
340
                        // OIDplus::init();
-
 
341
                        if ($allow_delayed_log) $this->missing_plugin_queue[] = array($maskcode, $message);
-
 
342
                        return false;
-
 
343
                }
-
 
344
 
-
 
345
                $logEvent = new OIDplusLogEvent($message);
-
 
346
 
-
 
347
                $maskcode_ary = self::parse_maskcode($maskcode);
-
 
348
                if ($maskcode_ary === false) {
-
 
349
                        throw new OIDplusException(_L('Invalid maskcode "%1" (failed to parse or has invalid data)',$maskcode));
-
 
350
                }
-
 
351
                foreach ($maskcode_ary as list($severity,$target)) {
-
 
352
                        if ($target[0] == 'OID') {
319
                        // OID(x)       Save log entry into the logbook of: Object "x"
353
                                // OID(x)       Save log entry into the logbook of: Object "x"
320
                        $m = array();
354
                                $object_id = $target[1];
321
                        if (preg_match('@^OID\((.+)\)$@ismU', $maskcode, $m)) {
355
                                assert(!is_array($severity));
322
                                $object_id = $m[1];
356
                                $obj = OIDplusObject::parse($object_id);
323
                                $logEvent->addTarget(new OIDplusLogTargetObject($severity, $object_id));
357
                                if (!$obj) throw new OIDplusException(_L('OID logger mask: Invalid object %1',$object_id));
-
 
358
                                if (($severity_int = self::convertSeverity($severity)) >= 0) {
324
                                if ($object_id == '') throw new OIDplusException(_L('OID logger mask requires OID'));
359
                                        $logEvent->addTarget(new OIDplusLogTargetObject($severity_int, $object_id));
-
 
360
                                }
325
                        }
361
                        }
326
 
362
 
-
 
363
                        else if ($target[0] == 'SUPOID') {
327
                        // SUPOID(x)    Save log entry into the logbook of: Parent of object "x"
364
                                // SUPOID(x)    Save log entry into the logbook of: Parent of object "x"
328
                        else if (preg_match('@^SUPOID\((.+)\)$@ismU', $maskcode, $m)) {
-
 
329
                                $object_id         = $m[1];
365
                                $object_id = $target[1];
330
                                if ($object_id == '') throw new OIDplusException(_L('SUPOID logger mask requires OID'));
366
                                assert(!is_array($severity));
331
                                $obj = OIDplusObject::parse($object_id);
367
                                $obj = OIDplusObject::parse($object_id);
332
                                if ($obj) {
368
                                if (!$obj) throw new OIDplusException(_L('SUPOID logger mask: Invalid object %1',$object_id));
333
                                        if ($objParent = $obj->getParent()) {
369
                                if ($objParent = $obj->getParent()) {
334
                                                $parent = $objParent->nodeId();
370
                                        $parent = $objParent->nodeId();
335
                                                $logEvent->addTarget(new OIDplusLogTargetObject($severity, $parent));
371
                                        if (($severity_int = self::convertSeverity($severity)) >= 0) {
336
                                        } else {
-
 
337
                                                //throw new OIDplusException(_L('%1 has no parent',$object_id));
372
                                                $logEvent->addTarget(new OIDplusLogTargetObject($severity_int, $parent));
338
                                        }
373
                                        }
339
                                } else {
374
                                } else {
340
                                        throw new OIDplusException(_L('SUPOID logger mask: Invalid object %1',$object_id));
375
                                        //throw new OIDplusException(_L('%1 has no parent',$object_id));
341
                                }
376
                                }
342
                        }
377
                        }
343
 
378
 
-
 
379
                        else if ($target[0] == 'OIDRA') {
344
                        // OIDRA(x)?    Save log entry into the logbook of: Logged in RA of object "x"
380
                                // OIDRA(x)     Save log entry into the logbook of: Logged in RA of object "x"
345
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
-
 
346
                        else if (preg_match('@^OIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
-
 
347
                                $object_id         = $m[1];
381
                                $object_id = $target[1];
348
                                $ra_need_login     = $m[2] == '?';
-
 
349
                                if ($object_id == '') throw new OIDplusException(_L('OIDRA logger mask requires OID'));
-
 
350
                                $obj = OIDplusObject::parse($object_id);
382
                                $obj = OIDplusObject::parse($object_id);
-
 
383
                                if (!$obj) throw new OIDplusException(_L('OIDRA logger mask: Invalid object "%1"', $object_id));
351
                                if ($obj) {
384
                                if (!is_array($severity)) {
352
                                        if ($ra_need_login) {
385
                                        $severity_online = $severity;
353
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
386
                                        $severity_offline = $severity;
354
                                                        if ($obj->userHasWriteRights($ra)) $logEvent->addTarget(new OIDplusLogTargetUser($severity_online, $ra->raEmail()));
-
 
355
                                                }
-
 
356
                                        } else {
387
                                } else {
357
                                                // $logEvent->addTarget(new OIDplusLogTargetUser($severity, $obj->getRa()->raEmail()));
388
                                        $severity_online = $severity[0];
358
                                                foreach (OIDplusRA::getAllRAs() as $ra) {
389
                                        $severity_offline = $severity[1];
359
                                                        if ($obj->userHasWriteRights($ra)) $logEvent->addTarget(new OIDplusLogTargetUser($severity, $ra->raEmail()));
-
 
360
                                                }
390
                                }
-
 
391
                                foreach (OIDplusRA::getAllRAs() as $ra) {
-
 
392
                                        if ($obj->userHasWriteRights($ra)) {
-
 
393
                                                if (OIDplus::authUtils()->isRaLoggedIn($ra)) {
-
 
394
                                                        if (($severity_online_int = self::convertSeverity($severity_online)) >= 0) {
-
 
395
                                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_online_int, $ra->raEmail()));
361
                                        }
396
                                                        }
362
                                } else {
397
                                                } else {
-
 
398
                                                        if (($severity_offline_int = self::convertSeverity($severity_offline)) >= 0) {
363
                                        throw new OIDplusException(_L('OIDRA logger mask: Invalid object "%1"',$object_id));
399
                                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_offline_int, $ra->raEmail()));
-
 
400
                                                        }
-
 
401
                                                }
-
 
402
                                        }
364
                                }
403
                                }
365
                        }
404
                        }
366
 
405
 
-
 
406
                        else if ($target[0] == 'SUPOIDRA') {
367
                        // SUPOIDRA(x)? Save log entry into the logbook of: Logged in RA that owns the superior object of "x"
407
                                // SUPOIDRA(x)  Save log entry into the logbook of: Logged in RA that owns the superior object of "x"
368
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
-
 
369
                        else if (preg_match('@^SUPOIDRA\((.+)\)([\?\!])$@ismU', $maskcode, $m)) {
-
 
370
                                $object_id         = $m[1];
408
                                $object_id = $target[1];
371
                                $ra_need_login     = $m[2] == '?';
-
 
372
                                if ($object_id == '') throw new OIDplusException(_L('SUPOIDRA logger mask requires OID'));
-
 
373
                                $obj = OIDplusObject::parse($object_id);
409
                                $obj = OIDplusObject::parse($object_id);
-
 
410
                                if (!$obj) throw new OIDplusException(_L('SUPOIDRA logger mask: Invalid object "%1"',$object_id));
374
                                if ($obj) {
411
                                if (!is_array($severity)) {
375
                                        if ($ra_need_login) {
412
                                        $severity_online = $severity;
376
                                                foreach (OIDplus::authUtils()->loggedInRaList() as $ra) {
413
                                        $severity_offline = $severity;
377
                                                        if ($obj->userHasParentalWriteRights($ra)) $logEvent->addTarget(new OIDplusLogTargetUser($severity_online, $ra->raEmail()));
-
 
378
                                                }
-
 
379
                                        } else {
414
                                } else {
380
                                                if ($objParent = $obj->getParent()) {
415
                                        $severity_online = $severity[0];
381
                                                        // $logEvent->addTarget(new OIDplusLogTargetUser($severity, $objParent->getRa()->raEmail()));
416
                                        $severity_offline = $severity[1];
-
 
417
                                }
382
                                                        foreach (OIDplusRA::getAllRAs() as $ra) {
418
                                foreach (OIDplusRA::getAllRAs() as $ra) {
-
 
419
                                        if ($obj->userHasParentalWriteRights($ra)) {
-
 
420
                                                if (OIDplus::authUtils()->isRaLoggedIn($ra)) {
-
 
421
                                                        if (($severity_online_int = self::convertSeverity($severity_online)) >= 0) {
383
                                                                if ($obj->userHasParentalWriteRights($ra)) $logEvent->addTarget(new OIDplusLogTargetUser($severity, $ra->raEmail()));
422
                                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_online_int, $ra->raEmail()));
384
                                                        }
423
                                                        }
385
                                                } else {
424
                                                } else {
-
 
425
                                                        if (($severity_offline_int = self::convertSeverity($severity_offline)) >= 0) {
386
                                                        //throw new OIDplusException(_L('%1 has no parent, therefore also no parent RA',$object_id));
426
                                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_offline_int, $ra->raEmail()));
-
 
427
                                                        }
387
                                                }
428
                                                }
388
                                        }
429
                                        }
389
                                } else {
-
 
390
                                        throw new OIDplusException(_L('SUPOIDRA logger mask: Invalid object "%1"',$object_id));
-
 
391
                                }
430
                                }
392
                        }
431
                        }
393
 
432
 
-
 
433
                        else if ($target[0] == 'RA') {
394
                        // RA(x)?       Save log entry into the logbook of: Logged in RA "x"
434
                                // RA(x)        Save log entry into the logbook of: Logged in RA "x"
395
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
435
                                $ra_email = $target[1];
396
                        else if (preg_match('@^RA\((.*)\)([\?\!])$@ismU', $maskcode, $m)) {
436
                                if (!is_array($severity)) {
-
 
437
                                        $severity_online = $severity;
397
                                $ra_email          = $m[1];
438
                                        $severity_offline = $severity;
-
 
439
                                } else {
398
                                $ra_need_login     = $m[2] == '?';
440
                                        $severity_online = $severity[0];
399
                                if (!empty($ra_email)) {
441
                                        $severity_offline = $severity[1];
-
 
442
                                }
400
                                        if ($ra_need_login && OIDplus::authUtils()->isRaLoggedIn($ra_email)) {
443
                                if (OIDplus::authUtils()->isRaLoggedIn($ra_email)) {
-
 
444
                                        if (($severity_online_int = self::convertSeverity($severity_online)) >= 0) {
401
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_online, $ra_email));
445
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_online_int, $ra_email));
-
 
446
                                        }
402
                                        } else if (!$ra_need_login) {
447
                                } else {
-
 
448
                                        if (($severity_offline_int = self::convertSeverity($severity_offline)) >= 0) {
403
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity, $ra_email));
449
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_offline_int, $ra_email));
404
                                        }
450
                                        }
405
                                }
451
                                }
406
                        }
452
                        }
407
 
453
 
-
 
454
                        else if ($target[0] == 'A') {
408
                        // A?   Save log entry into the logbook of: A logged in admin
455
                                // A    Save log entry into the logbook of: A logged in admin
-
 
456
                                if (!is_array($severity)) {
409
                        // Remove or replace "?" by "!" if the entity does not need to be logged in
457
                                        $severity_online = $severity;
-
 
458
                                        $severity_offline = $severity;
-
 
459
                                } else {
410
                        else if (preg_match('@^A([\?\!])$@imU', $maskcode, $m)) {
460
                                        $severity_online = $severity[0];
411
                                $admin_need_login = $m[1] == '?';
461
                                        $severity_offline = $severity[1];
-
 
462
                                }
412
                                if ($admin_need_login && OIDplus::authUtils()->isAdminLoggedIn()) {
463
                                if (OIDplus::authUtils()->isAdminLoggedIn()) {
-
 
464
                                        if (($severity_online_int = self::convertSeverity($severity_online)) >= 0) {
413
                                        $logEvent->addTarget(new OIDplusLogTargetUser($severity_online, 'admin'));
465
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_online_int, 'admin'));
-
 
466
                                        }
414
                                } else if (!$admin_need_login) {
467
                                } else {
-
 
468
                                        if (($severity_offline_int = self::convertSeverity($severity_offline)) >= 0) {
415
                                        $logEvent->addTarget(new OIDplusLogTargetUser($severity, 'admin'));
469
                                                $logEvent->addTarget(new OIDplusLogTargetUser($severity_offline_int, 'admin'));
-
 
470
                                        }
416
                                }
471
                                }
417
                        }
472
                        }
418
 
473
 
419
                        // Unexpected
474
                        // Unexpected
420
                        else {
475
                        else {
421
                                throw new OIDplusException(_L('Unexpected logger component "%1" in mask code "%2"',$maskcode,$maskcodes));
476
                                throw new OIDplusException(_L('Unexpected logger component type "%1" in mask code "%2"',$target[0],$maskcode));
422
                        }
477
                        }
423
                }
478
                }
424
 
479
 
425
                // Now write the log message
480
                // Now write the log message
426
 
481