First pass of features

This commit is contained in:
2026-03-30 14:53:13 -05:00
parent 1a65e69d25
commit 6353f9c9b4
54 changed files with 5409 additions and 128 deletions
+59 -17
View File
@@ -1,23 +1,65 @@
<?php
function readJsonFile($filename) {
$filepath = __DIR__ . '/../data/' . $filename;
function getDataDirectory(): string {
return __DIR__ . '/../data';
}
function getDataFilePath(string $filename): string {
return getDataDirectory() . '/' . $filename;
}
function ensureDataDirectory(): void {
$dataDir = getDataDirectory();
if (!is_dir($dataDir)) {
mkdir($dataDir, 0755, true);
}
}
function readJsonFile(string $filename) {
$filepath = getDataFilePath($filename);
if (!file_exists($filepath)) {
return [];
}
$content = file_get_contents($filepath);
return json_decode($content, true) ?? [];
}
function writeJsonFile($filename, $data) {
$filepath = __DIR__ . '/../data/' . $filename;
$json = json_encode($data, JSON_PRETTY_PRINT);
return file_put_contents($filepath, $json);
}
function ensureDataDirectory() {
$dataDir = __DIR__ . '/../data';
if (!file_exists($dataDir)) {
mkdir($dataDir, 0755, true);
$fp = fopen($filepath, 'rb');
if ($fp === false) {
return [];
}
}
if (!flock($fp, LOCK_SH)) {
fclose($fp);
return [];
}
$content = stream_get_contents($fp);
flock($fp, LOCK_UN);
fclose($fp);
if ($content === false || $content === '') {
return [];
}
$decoded = json_decode($content, true);
return $decoded ?? [];
}
function writeJsonFile(string $filename, $data): bool {
ensureDataDirectory();
$filepath = getDataFilePath($filename);
$fp = fopen($filepath, 'c+');
if ($fp === false) {
return false;
}
if (!flock($fp, LOCK_EX)) {
fclose($fp);
return false;
}
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if ($json === false) {
flock($fp, LOCK_UN);
fclose($fp);
return false;
}
ftruncate($fp, 0);
rewind($fp);
$written = fwrite($fp, $json);
fflush($fp);
flock($fp, LOCK_UN);
fclose($fp);
return $written !== false;
}