Add nodes management and initial setup pages

- Implemented nodes management functionality in `nodes.php` including create, update, and delete actions.
- Added form validation and error handling for node operations.
- Created a new setup page in `setup.php` for initial administrator account creation.
- Included user feedback messages for successful operations and errors.
- Designed user interface for both nodes management and setup processes.
This commit is contained in:
2025-12-14 01:33:12 -05:00
parent cf0ec74888
commit d8b76233c0
19 changed files with 8800 additions and 0 deletions

View File

@@ -0,0 +1,285 @@
<?php
/**
* Logger Class
*
* Handles audit logging for the Pathvector admin dashboard
*/
require_once __DIR__ . '/FlatFileDB.php';
class Logger {
private FlatFileDB $db;
private int $maxEntries;
private array $validLevels = ['info', 'warning', 'error', 'success'];
/**
* Constructor
*
* @param string $logFile Path to the log file
* @param int $maxEntries Maximum number of log entries to keep
*/
public function __construct(string $logFile, int $maxEntries = 1000) {
$this->db = new FlatFileDB($logFile);
$this->maxEntries = $maxEntries;
// Initialize logs array if not exists
if (!$this->db->exists('logs')) {
$this->db->set('logs', []);
}
}
/**
* Add a log entry
*
* @param string $level Log level (info, warning, error, success)
* @param string $action Action performed
* @param string $message Log message
* @param string|null $user User who performed the action
* @param array $context Additional context data
* @return bool
*/
public function log(string $level, string $action, string $message, ?string $user = null, array $context = []): bool {
if (!in_array($level, $this->validLevels)) {
$level = 'info';
}
$logs = $this->db->get('logs') ?? [];
$entry = [
'id' => uniqid('log_'),
'timestamp' => date('c'),
'level' => $level,
'action' => $action,
'message' => $message,
'user' => $user ?? ($_SESSION['user']['username'] ?? 'system'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
'context' => $context,
];
array_unshift($logs, $entry);
// Trim logs to max entries
if (count($logs) > $this->maxEntries) {
$logs = array_slice($logs, 0, $this->maxEntries);
}
return $this->db->set('logs', $logs);
}
/**
* Log info level message
*
* @param string $action
* @param string $message
* @param array $context
* @return bool
*/
public function info(string $action, string $message, array $context = []): bool {
return $this->log('info', $action, $message, null, $context);
}
/**
* Log warning level message
*
* @param string $action
* @param string $message
* @param array $context
* @return bool
*/
public function warning(string $action, string $message, array $context = []): bool {
return $this->log('warning', $action, $message, null, $context);
}
/**
* Log error level message
*
* @param string $action
* @param string $message
* @param array $context
* @return bool
*/
public function error(string $action, string $message, array $context = []): bool {
return $this->log('error', $action, $message, null, $context);
}
/**
* Log success level message
*
* @param string $action
* @param string $message
* @param array $context
* @return bool
*/
public function success(string $action, string $message, array $context = []): bool {
return $this->log('success', $action, $message, null, $context);
}
/**
* Get all logs
*
* @param int|null $limit
* @param int $offset
* @return array
*/
public function getLogs(?int $limit = null, int $offset = 0): array {
$logs = $this->db->get('logs') ?? [];
if ($limit !== null) {
return array_slice($logs, $offset, $limit);
}
return $logs;
}
/**
* Get logs by level
*
* @param string $level
* @param int|null $limit
* @return array
*/
public function getByLevel(string $level, ?int $limit = null): array {
$logs = $this->db->get('logs') ?? [];
$filtered = array_filter($logs, fn($log) => $log['level'] === $level);
if ($limit !== null) {
return array_slice($filtered, 0, $limit);
}
return array_values($filtered);
}
/**
* Get logs by user
*
* @param string $user
* @param int|null $limit
* @return array
*/
public function getByUser(string $user, ?int $limit = null): array {
$logs = $this->db->get('logs') ?? [];
$filtered = array_filter($logs, fn($log) => $log['user'] === $user);
if ($limit !== null) {
return array_slice($filtered, 0, $limit);
}
return array_values($filtered);
}
/**
* Get logs by action
*
* @param string $action
* @param int|null $limit
* @return array
*/
public function getByAction(string $action, ?int $limit = null): array {
$logs = $this->db->get('logs') ?? [];
$filtered = array_filter($logs, fn($log) => strpos($log['action'], $action) !== false);
if ($limit !== null) {
return array_slice($filtered, 0, $limit);
}
return array_values($filtered);
}
/**
* Get logs by date range
*
* @param string $startDate
* @param string $endDate
* @return array
*/
public function getByDateRange(string $startDate, string $endDate): array {
$logs = $this->db->get('logs') ?? [];
$start = strtotime($startDate);
$end = strtotime($endDate);
return array_values(array_filter($logs, function($log) use ($start, $end) {
$logTime = strtotime($log['timestamp']);
return $logTime >= $start && $logTime <= $end;
}));
}
/**
* Search logs
*
* @param string $query
* @param int|null $limit
* @return array
*/
public function search(string $query, ?int $limit = null): array {
$logs = $this->db->get('logs') ?? [];
$query = strtolower($query);
$filtered = array_filter($logs, function($log) use ($query) {
return strpos(strtolower($log['message']), $query) !== false ||
strpos(strtolower($log['action']), $query) !== false ||
strpos(strtolower($log['user']), $query) !== false;
});
if ($limit !== null) {
return array_slice($filtered, 0, $limit);
}
return array_values($filtered);
}
/**
* Get total log count
*
* @return int
*/
public function count(): int {
$logs = $this->db->get('logs') ?? [];
return count($logs);
}
/**
* Clear all logs
*
* @return bool
*/
public function clear(): bool {
return $this->db->set('logs', []);
}
/**
* Export logs to JSON
*
* @return string
*/
public function exportJson(): string {
$logs = $this->db->get('logs') ?? [];
return json_encode($logs, JSON_PRETTY_PRINT);
}
/**
* Export logs to CSV
*
* @return string
*/
public function exportCsv(): string {
$logs = $this->db->get('logs') ?? [];
$output = "ID,Timestamp,Level,Action,Message,User,IP\n";
foreach ($logs as $log) {
$output .= sprintf(
'"%s","%s","%s","%s","%s","%s","%s"' . "\n",
$log['id'],
$log['timestamp'],
$log['level'],
str_replace('"', '""', $log['action']),
str_replace('"', '""', $log['message']),
$log['user'],
$log['ip']
);
}
return $output;
}
}