[ 'type' => 'literal', 'value' => 'logs', ], 'action' => [ 'type' => 'enum', 'allowed' => ['list'], 'omit_if' => 'list', ], 'tab' => [ 'type' => 'enum', 'allowed' => ['user', 'system'], 'omit_if' => 'user', ], 'page_num' => [ 'type' => 'int', 'min' => 1, 'omit_if' => 1, ], 'from_time' => [ 'type' => 'string', 'validator' => static function ($value): bool { return trim((string)$value) !== ''; }, ], 'until_time' => [ 'type' => 'string', 'validator' => static function ($value): bool { return trim((string)$value) !== ''; }, ], 'message' => [ 'type' => 'string', 'validator' => static function ($value): bool { return trim((string)$value) !== ''; }, ], 'id' => [ 'type' => 'int', 'min' => 1, 'include_if' => static function (array $sourceQuery): bool { return (($sourceQuery['tab'] ?? '') === 'system'); }, ], ]; $canonicalQuery = app_url_build_query_from_policy($_GET, $canonicalPolicy); // Keep logs URLs constrained to supported list filters and pagination state. app_url_redirect_to_canonical_query((string)$app_root, $_GET, $canonicalQuery); } switch ($action) { case 'list': default: logs_plugin_render_list($logObject, $db, $userId, $validSession, $app_root); return true; } } function logs_plugin_render_list($logObject, $db, int $userId, bool $validSession, string $app_root): void { // Load User class for permissions check $userObject = new \User($db); // Check for rights; user or system $has_system_access = ($userObject->hasRight($userId, 'superuser') || $userObject->hasRight($userId, 'view app logs')); // Get current page for pagination $currentPage = $_REQUEST['page_num'] ?? 1; $currentPage = (int)$currentPage; // Get selected tab $selected_tab = $_REQUEST['tab'] ?? 'user'; if ($selected_tab === 'system' && !$has_system_access) { $selected_tab = 'user'; } // Set scope based on selected tab $scope = ($selected_tab === 'system') ? 'system' : 'user'; // Specify time range include APP_PATH . 'helpers/time_range.php'; // Prepare search filters $filters = []; if (isset($_REQUEST['from_time']) && !empty($_REQUEST['from_time'])) { $filters['from_time'] = $_REQUEST['from_time']; } if (isset($_REQUEST['until_time']) && !empty($_REQUEST['until_time'])) { $filters['until_time'] = $_REQUEST['until_time']; } if (isset($_REQUEST['message']) && !empty($_REQUEST['message'])) { $filters['message'] = $_REQUEST['message']; } if ($scope === 'system' && isset($_REQUEST['id']) && !empty($_REQUEST['id'])) { $filters['id'] = $_REQUEST['id']; } // Pagination variables $items_per_page = 15; $offset = ($currentPage - 1) * $items_per_page; // Build params for pagination $params = ''; if (!empty($_REQUEST['from_time'])) { $params .= '&from_time=' . urlencode($_REQUEST['from_time']); } if (!empty($_REQUEST['until_time'])) { $params .= '&until_time=' . urlencode($_REQUEST['until_time']); } if (!empty($_REQUEST['message'])) { $params .= '&message=' . urlencode($_REQUEST['message']); } if (!empty($_REQUEST['id'])) { $params .= '&id=' . urlencode($_REQUEST['id']); } if (isset($_REQUEST['tab'])) { $params .= '&tab=' . urlencode($_REQUEST['tab']); } // Prepare the result $search = $logObject->readLog($userId, $scope, $offset, $items_per_page, $filters); $search_all = $logObject->readLog($userId, $scope, 0, 0, $filters); $logs = []; $totalPages = 0; $item_count = 0; if (!empty($search)) { // Get total items and number of pages $item_count = count($search_all); $totalPages = ceil($item_count / $items_per_page); $logs = []; $logs['records'] = []; foreach ($search as $item) { // When we show only user's logs, omit user_id column if ($scope === 'user') { // assign title to the field $log_record = [ 'time' => $item['time'], 'log level' => $item['level'], 'log message' => $item['message'] ]; } else { // assign title to the field $log_record = [ 'userID' => $item['user_id'], 'username' => $item['username'], 'time' => $item['time'], 'log level' => $item['level'], 'log message' => $item['message'] ]; } $logs['records'][] = $log_record; } } $username = $userObject->getUserDetails($userId)[0]['username']; $page = 'logs'; // For pagination template // Get any new feedback messages include_once APP_PATH . 'helpers/feedback.php'; require_once PLUGIN_LOGS_PATH . 'helpers/logs_view_helper.php'; // Load the view include PLUGIN_LOGS_PATH . 'views/logs.php'; }