Audit Logs - who did what, when and from where: every change, * sign-in, look at a secret and export logAudit() writes. Searched, filtered * by date, who, client, type and action, and in views - changes, deletions, * sign-ins, security and data out - each counted for the filters picked. * Each entry links to the record it is about while that still exists, and * opens a quick look with all of it (modals/audit_log/audit_log.php). What is * shown can be exported (export_audit_logs). The work is in * functions/audit_log.php. */ // Default Column Sortby Filter $sort = "log_id"; $order = "DESC"; require_once "includes/inc_all_admin.php"; // Tab title - the file is named for the table, the page for what it holds $page_title = 'Audit Logs'; // Only these sort - an unknown column would take the page down $sortable_columns = [ 'log_id' => "log_id $order", 'log_created_at' => "log_created_at $order, log_id $order", 'user_name' => "user_name IS NULL, user_name $order, log_id DESC", 'client_name' => "client_name IS NULL, client_name $order, log_id DESC", 'log_type' => "log_type $order, log_action $order, log_id DESC", 'log_action' => "log_action $order, log_id DESC", 'log_ip' => "log_ip IS NULL, log_ip $order, log_id DESC", ]; if (!isset($sortable_columns[$sort])) { $sort = 'log_id'; } $views = auditLogViews(); $view = isset($_GET['view']) && is_string($_GET['view']) && isset($views[$_GET['view']]) ? $_GET['view'] : ''; $filter_src = array_merge($_GET, ['dtf' => $dtf, 'dtt' => $dtt, 'view' => $view]); $joins = auditLogJoinsSql(); $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS log_id, log_type, log_action, log_description, log_ip, log_user_agent, log_created_at, log_client_id, log_user_id, log_entity_id, user_name, user_avatar, user_type, client_name FROM logs $joins WHERE " . auditLogFiltersSql($filter_src) . " ORDER BY {$sortable_columns[$sort]} LIMIT $record_from, $record_to"); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $rows = []; while ($row = mysqli_fetch_assoc($sql)) { $rows[] = $row; } $records = auditLogRecords($rows); $new_ips = signInNewIpIds($rows); $kinds = auditLogKinds(); // Each view counted for the rest of the filters $count_sql = []; foreach ($views as $definition) { $count_sql[] = 'COALESCE(SUM(' . ($definition['where'] === '' ? '1' : $definition['where']) . '), 0)'; } $counts = array_combine(array_keys($views), array_map('intval', mysqli_fetch_row(mysqli_query($mysqli, "SELECT " . implode(', ', $count_sql) . " FROM logs $joins WHERE " . auditLogFiltersSql(array_merge($filter_src, ['view' => ''])))))); $client_filter = is_scalar($_GET['client'] ?? null) ? intval($_GET['client']) : 0; $user_filter = is_string($_GET['user'] ?? null) ? $_GET['user'] : ''; $type_filter = is_string($_GET['type'] ?? null) ? $_GET['type'] : ''; $action_filter = is_string($_GET['action'] ?? null) ? $_GET['action'] : ''; $entity_filter = is_scalar($_GET['entity'] ?? null) ? intval($_GET['entity']) : 0; $more_filters = $action_filter !== '' || $entity_filter; $any_filter = $q !== '' || $client_filter || $user_filter !== '' || $type_filter !== '' || $action_filter !== '' || $entity_filter || $dtf !== '1970-01-01' || $dtt !== '2099-12-31'; $sort_link = function ($column, $label) use ($url_query_strings_sort, $sort, $disp, $order_icon) { return '' . $label . ($sort === $column ? " $order_icon" : '') . ''; }; // A view keeps the filters, and starts from its first page $view_url = function ($key) { $query = $_GET; unset($query['page']); $query['view'] = $key; return '?' . http_build_query(array_filter($query, function ($value) { return $value !== '' && $value !== null && $value !== []; })); }; // When a view has nothing in it, and there are no filters to blame $view_empty = [ 'changes' => 'No changes yet', 'deletions' => 'Nothing deleted yet', 'signins' => 'No sign-ins yet', 'security' => 'Nothing to do with security yet', 'data' => 'Nothing looked at or taken out yet', ]; ?>

Audit Logs

Just one record: # Every record
"> 0 && isset($kinds[$type]['table']); $device = auditLogDevice($row['log_user_agent']); $from = implode(' ยท ', array_filter([(string) $row['log_ip'], $device])); ?>
Description
-
No longer here
'audit log entries', 'icon' => 'fa-history', 'filtered' => $any_filter, 'views' => ['view'], 'view' => $view !== '' ? ['icon' => $views[$view]['icon'], 'title' => $view_empty[$view], 'text' => escapeHtml($views[$view]['title']) . ' show here.'] : null, 'text' => 'Who changed what, signed in, looked at a password or exported something - when, and from where - shows here.', ]; require_once "../includes/filter_footer.php"; ?>