Files
adsPRO/autoload/controls/class.Logs.php
Jacek Pyziak bc75eab439 feat: add logs page with filtering and data table
- Implemented a new logs page with filters for level, source, and date range.
- Added a data table to display logs with pagination and sorting capabilities.
- Created backend functionality to fetch logs data based on filters.
- Introduced a new Logs class for handling log data operations.
- Added a new database migration for the logs table.
- Enhanced UI with custom checkbox styles for better user experience.
- Updated navigation to include a link to the logs page.
2026-02-21 13:05:59 +01:00

152 lines
4.6 KiB
PHP

<?php
namespace controls;
class Logs
{
static public function main_view()
{
$sources = \factory\Logs::get_sources();
return \view\Logs::main_view( $sources );
}
static public function get_logs_data_table()
{
$start = (int) \S::get( 'start' );
$length = (int) \S::get( 'length' );
$draw = (int) \S::get( 'draw' );
$filters = [];
$level = trim( (string) \S::get( 'level' ) );
if ( $level !== '' && $level !== 'all' )
{
$filters['level'] = $level;
}
$source = trim( (string) \S::get( 'source' ) );
if ( $source !== '' && $source !== 'all' )
{
$filters['source'] = $source;
}
$date_from = trim( (string) \S::get( 'date_from' ) );
if ( $date_from !== '' )
{
$filters['date_from'] = $date_from;
}
$date_to = trim( (string) \S::get( 'date_to' ) );
if ( $date_to !== '' )
{
$filters['date_to'] = $date_to;
}
$rows = \factory\Logs::get_data( $start, $length, $filters );
$total = \factory\Logs::get_records_total( $filters );
$level_badges = [
'info' => '<span class="badge badge-success">info</span>',
'error' => '<span class="badge badge-danger">error</span>',
'warning' => '<span class="badge badge-warning">warning</span>'
];
$data = [];
foreach ( $rows as $row )
{
$message = (string) ( $row['message'] ?? '' );
if ( mb_strlen( $message ) > 120 )
{
$message = mb_substr( $message, 0, 120 ) . '...';
}
$client_label = '';
if ( !empty( $row['client_name'] ) )
{
$client_label = htmlspecialchars( (string) $row['client_name'], ENT_QUOTES, 'UTF-8' );
}
else if ( !empty( $row['client_id'] ) )
{
$client_label = 'ID: ' . (int) $row['client_id'];
}
else
{
$client_label = '-';
}
$data[] = [
(string) ( $row['date_add'] ?? '' ),
$level_badges[ $row['level'] ] ?? htmlspecialchars( (string) $row['level'], ENT_QUOTES, 'UTF-8' ),
htmlspecialchars( (string) ( $row['source'] ?? '' ), ENT_QUOTES, 'UTF-8' ),
$client_label,
htmlspecialchars( $message, ENT_QUOTES, 'UTF-8' ),
'<button type="button" class="btn btn-sm btn-outline-secondary log-detail-btn" data-id="' . (int) $row['id'] . '"><i class="fa-solid fa-eye"></i></button>'
];
}
echo json_encode( [
'draw' => $draw,
'recordsTotal' => $total,
'recordsFiltered' => $total,
'data' => $data
] );
exit;
}
static public function get_detail()
{
$id = (int) \S::get( 'id' );
if ( $id <= 0 )
{
echo json_encode( [ 'success' => false, 'message' => 'Nieprawidlowe ID.' ] );
exit;
}
$log = \factory\Logs::get_one( $id );
if ( !$log )
{
echo json_encode( [ 'success' => false, 'message' => 'Wpis nie znaleziony.' ] );
exit;
}
$context = null;
if ( !empty( $log['context_json'] ) )
{
$decoded = json_decode( $log['context_json'], true );
if ( $decoded !== null )
{
$context = json_encode( $decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_INVALID_UTF8_SUBSTITUTE );
}
else
{
$context = $log['context_json'];
}
}
$response = json_encode( [
'success' => true,
'log' => [
'id' => (int) $log['id'],
'level' => $log['level'],
'source' => $log['source'],
'client_name' => $log['client_name'] ?? '',
'client_id' => $log['client_id'],
'message' => $log['message'],
'context' => $context,
'date_add' => $log['date_add']
]
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR );
if ( $response === false )
{
echo json_encode( [ 'success' => false, 'message' => 'Blad kodowania JSON: ' . json_last_error_msg() ] );
exit;
}
echo $response;
exit;
}
}