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:
218
pathvector-admin/lib/FlatFileDB.php
Normal file
218
pathvector-admin/lib/FlatFileDB.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* FlatFileDB Class
|
||||
*
|
||||
* Handles all flat-file JSON storage operations for the Pathvector admin dashboard
|
||||
*/
|
||||
|
||||
class FlatFileDB {
|
||||
private string $filePath;
|
||||
private array $data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $filePath Path to the JSON file
|
||||
*/
|
||||
public function __construct(string $filePath) {
|
||||
$this->filePath = $filePath;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data from JSON file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function load(): void {
|
||||
if (file_exists($this->filePath)) {
|
||||
$content = file_get_contents($this->filePath);
|
||||
$this->data = json_decode($content, true) ?? [];
|
||||
} else {
|
||||
$this->data = [];
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data to JSON file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(): bool {
|
||||
$dir = dirname($this->filePath);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
$json = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
return file_put_contents($this->filePath, $json) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data by key
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(string $key) {
|
||||
return $this->data[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data by key
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function set(string $key, $value): bool {
|
||||
$this->data[$key] = $value;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete data by key
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(string $key): bool {
|
||||
if (isset($this->data[$key])) {
|
||||
unset($this->data[$key]);
|
||||
return $this->save();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if key exists
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(string $key): bool {
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function keys(): array {
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all entries
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int {
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(): bool {
|
||||
$this->data = [];
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search data by callback function
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return array
|
||||
*/
|
||||
public function search(callable $callback): array {
|
||||
return array_filter($this->data, $callback, ARRAY_FILTER_USE_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data by key with callback
|
||||
*
|
||||
* @param string $key
|
||||
* @param callable $callback
|
||||
* @return bool
|
||||
*/
|
||||
public function update(string $key, callable $callback): bool {
|
||||
if (isset($this->data[$key])) {
|
||||
$this->data[$key] = $callback($this->data[$key]);
|
||||
return $this->save();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilePath(): string {
|
||||
return $this->filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload data from file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reload(): void {
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup current data
|
||||
*
|
||||
* @param string $backupDir
|
||||
* @return string|false Returns backup file path on success, false on failure
|
||||
*/
|
||||
public function backup(string $backupDir): string|false {
|
||||
if (!is_dir($backupDir)) {
|
||||
mkdir($backupDir, 0755, true);
|
||||
}
|
||||
|
||||
$timestamp = date('Y-m-d_H-i-s');
|
||||
$filename = basename($this->filePath, '.json');
|
||||
$backupPath = $backupDir . '/' . $filename . '_' . $timestamp . '.json';
|
||||
|
||||
$json = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
return file_put_contents($backupPath, $json) !== false ? $backupPath : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore data from backup file
|
||||
*
|
||||
* @param string $backupPath
|
||||
* @return bool
|
||||
*/
|
||||
public function restore(string $backupPath): bool {
|
||||
if (!file_exists($backupPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = file_get_contents($backupPath);
|
||||
$data = json_decode($content, true);
|
||||
|
||||
if ($data === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
return $this->save();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user