diff --git a/app/classes/log.php b/app/classes/log.php index cd1ca27..26c26b0 100644 --- a/app/classes/log.php +++ b/app/classes/log.php @@ -21,7 +21,6 @@ class Log { $this->db = $database->getConnection(); } - /** * Insert a log event into the database. * @@ -40,9 +39,9 @@ class Log { $query = $this->db->prepare($sql); $query->execute([ - ':user_id' => $user_id, - ':scope' => $scope, - ':message' => $message, + ':user_id' => $user_id, + ':scope' => $scope, + ':message' => $message, ]); return true; @@ -52,7 +51,6 @@ class Log { } } - /** * Retrieve log entries from the database. * @@ -60,36 +58,67 @@ class Log { * @param string $scope The scope of the logs ('user' or 'system'). * @param int $offset The offset for pagination. Default is 0. * @param int $items_per_page The number of log entries to retrieve per page. Default is no limit. + * @param array $filters Optional array of filters (from_time, until_time, message, id) * * @return array An array of log entries. */ - public function readLog($user_id, $scope, $offset=0, $items_per_page='') { + public function readLog($user_id, $scope, $offset=0, $items_per_page='', $filters=[]) { + $params = []; + $where_clauses = []; + + // Base query with user join + $base_sql = 'SELECT l.*, u.username + FROM logs l + LEFT JOIN users u ON l.user_id = u.id'; + + // Add scope condition if ($scope === 'user') { - $sql = 'SELECT * FROM logs WHERE user_id = :user_id ORDER BY time DESC'; - if ($items_per_page) { - $items_per_page = (int)$items_per_page; - $sql .= ' LIMIT ' . $offset . ',' . $items_per_page; - } - - $query = $this->db->prepare($sql); - $query->execute([ - ':user_id' => $user_id, - ]); + $where_clauses[] = 'l.user_id = :user_id'; + $params[':user_id'] = $user_id; } - if ($scope === 'system') { - $sql = 'SELECT * FROM logs ORDER BY time DESC'; - if ($items_per_page) { - $items_per_page = (int)$items_per_page; - $sql .= ' LIMIT ' . $offset . ',' . $items_per_page; - } - $query = $this->db->prepare($sql); - $query->execute(); + // Add time range filters if specified + if (!empty($filters['from_time'])) { + $where_clauses[] = 'l.time >= :from_time'; + $params[':from_time'] = $filters['from_time'] . ' 00:00:00'; } + if (!empty($filters['until_time'])) { + $where_clauses[] = 'l.time <= :until_time'; + $params[':until_time'] = $filters['until_time'] . ' 23:59:59'; + } + + // Add message search if specified + if (!empty($filters['message'])) { + $where_clauses[] = 'l.message LIKE :message'; + $params[':message'] = '%' . $filters['message'] . '%'; + } + + // Add user ID search if specified + if (!empty($filters['id'])) { + $where_clauses[] = 'l.user_id = :search_user_id'; + $params[':search_user_id'] = $filters['id']; + } + + // Combine WHERE clauses + $sql = $base_sql; + if (!empty($where_clauses)) { + $sql .= ' WHERE ' . implode(' AND ', $where_clauses); + } + + // Add ordering + $sql .= ' ORDER BY l.time DESC'; + + // Add pagination + if ($items_per_page) { + $items_per_page = (int)$items_per_page; + $sql .= ' LIMIT ' . $offset . ',' . $items_per_page; + } + + $query = $this->db->prepare($sql); + $query->execute($params); return $query->fetchAll(PDO::FETCH_ASSOC); } - } ?> diff --git a/app/pages/logs.php b/app/pages/logs.php index 9d1c69a..e00f4c0 100644 --- a/app/pages/logs.php +++ b/app/pages/logs.php @@ -12,16 +12,36 @@ include '../app/includes/messages.php'; include '../app/includes/messages-show.php'; // Check for rights; user or system -if (($userObject->hasRight($user_id, 'superuser') || - $userObject->hasRight($user_id, 'view app logs'))) { - $scope = 'system'; -} else { - $scope = 'user'; +$has_system_access = ($userObject->hasRight($user_id, 'superuser') || + $userObject->hasRight($user_id, 'view app logs')); + +// 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/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; $browse_page = $_REQUEST['p'] ?? 1; @@ -29,8 +49,8 @@ $browse_page = (int)$browse_page; $offset = ($browse_page -1) * $items_per_page; // prepare the result -$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page); -$search_all = $logObject->readLog($user_id, $scope); +$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page, $filters); +$search_all = $logObject->readLog($user_id, $scope, 0, '', $filters); if (!empty($search)) { // we get total items and number of pages @@ -41,20 +61,20 @@ if (!empty($search)) { $logs['records'] = array(); foreach ($search as $item) { - // when we show only user's logs, omit user_id column if ($scope === 'user') { $log_record = array( // assign title to the field in the array record - 'time' => $item['time'], - 'log message' => $item['message'] + 'time' => $item['time'], + 'log message' => $item['message'] ); } else { $log_record = array( // assign title to the field in the array record - 'userID' => $item['user_id'], - 'time' => $item['time'], - 'log message' => $item['message'] + 'userID' => $item['user_id'], + 'username' => $item['username'], + 'time' => $item['time'], + 'log message' => $item['message'] ); } @@ -68,8 +88,10 @@ $widget['full'] = false; $widget['collapsible'] = false; $widget['name'] = 'Logs'; $username = $userObject->getUserDetails($user_id)[0]['username']; -$widget['title'] = "Log events for user \"$username\""; +$widget['title'] = "Log events"; $widget['filter'] = true; +$widget['scope'] = $scope; +$widget['has_system_access'] = $has_system_access; if (!empty($logs['records'])) { $widget['full'] = true; $widget['table_headers'] = array_keys($logs['records'][0]); diff --git a/app/templates/logs-filter.php b/app/templates/logs-filter.php index 29c0082..b9c13ab 100644 --- a/app/templates/logs-filter.php +++ b/app/templates/logs-filter.php @@ -1,26 +1,41 @@ - -
-
- - /> - - /> - /> - /> - - -
- +
+
+
+ + + +
+ + +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ + + Clear + +
+
+
diff --git a/app/templates/logs-list.php b/app/templates/logs-list.php index 570af70..53f1443 100644 --- a/app/templates/logs-list.php +++ b/app/templates/logs-list.php @@ -1,57 +1,72 @@ - -
- - -
- -
- - - + +
+
+ + - -
+ + + +
-

time period: -

+
+ Time period: - +
-
+
- - +
+
+ - - - + + + + + - $column) { - if ($key === 'user ID' && isset($user_id) && $user_id === $column) { ?> - - - - + + + + +
Username (id)TimeLog message
()
- $items_per_page) { - $url = "$app_root?platform=$platform_id&page=$page"; - include '../app/helpers/pagination.php'; -} -?> - -

No matching records found.

-
+ $items_per_page) { + include '../app/helpers/pagination.php'; + } + } else { ?> +
+ No log entries found for the specified criteria. +
+
- +
+
+
+
+