diff --git a/api/endpoints/sites.php b/api/endpoints/sites.php index 6c29e98..62fc249 100644 --- a/api/endpoints/sites.php +++ b/api/endpoints/sites.php @@ -1,123 +1,132 @@ [ - 'name' => "Tom's Java Jive", - 'url' => 'https://tomsjavajive.com', - 'type' => 'db', - 'db' => ['host'=>'localhost','name'=>'toms_tjj_db','user'=>'toms_tjj_user','pass'=>'+60wlPc+55e@gFq4'], - 'keys' => ['api_key'=>'cybermail_api_key','from_email'=>'cybermail_from_email','from_name'=>'cybermail_from_name','admin_email'=>'smtp_admin_email'], + 'name' => "Tom's Java Jive", + 'url' => 'https://tomsjavajive.com', + // Also sync to TJJ's own settings table + 'sync_db' => ['host'=>'localhost','name'=>'toms_tjj_db','user'=>'toms_tjj_user','pass'=>'+60wlPc+55e@gFq4'], + 'sync_keys' => ['api_key'=>'cybermail_api_key','from_email'=>'cybermail_from_email','from_name'=>'cybermail_from_name','admin_email'=>'smtp_admin_email'], ], 'tomtomgames' => [ - 'name' => 'TomTomGames', - 'url' => 'https://tomtomgames.com', - 'type' => 'file', - 'file' => '/home/tomtomgames.com/includes/config.php', - 'keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'SMTP_FROM','from_name'=>'SMTP_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], + 'name' => 'TomTomGames', + 'url' => 'https://tomtomgames.com', + // Also try to push to file + 'file' => '/home/tomtomgames.com/includes/config.php', + 'file_keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'SMTP_FROM','from_name'=>'SMTP_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], ], 'epictravelexpeditions' => [ - 'name' => 'Epic Travel Expeditions', - 'url' => 'https://epictravelexpeditions.com', - 'type' => 'file', - 'file' => '/home/epictravelexpeditions.com/public_html/api/config.php', - 'keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], + 'name' => 'Epic Travel Expeditions', + 'url' => 'https://epictravelexpeditions.com', + 'file' => '/home/epictravelexpeditions.com/public_html/api/config.php', + 'file_keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], ], 'parkerslingshot' => [ - 'name' => 'Parker Slingshot', - 'url' => 'https://parkerslingshot.epictravelexpeditions.com', - 'type' => 'file', - 'file' => '/home/epictravelexpeditions.com/parkerslingshot/db.php', - 'keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], + 'name' => 'Parker Slingshot', + 'url' => 'https://parkerslingshot.epictravelexpeditions.com', + 'file' => '/home/epictravelexpeditions.com/parkerslingshot/db.php', + 'file_keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], ], 'parkerslingshotrentals' => [ - 'name' => 'Parker Slingshot Rentals', - 'url' => 'https://parkerslingshotrentals.com', - 'type' => 'file', - 'file' => '/home/parkerslingshotrentals.com/public_html/db.php', - 'keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], + 'name' => 'Parker Slingshot Rentals', + 'url' => 'https://parkerslingshotrentals.com', + 'file' => '/home/parkerslingshotrentals.com/public_html/db.php', + 'file_keys' => ['api_key'=>'CYBERMAIL_API_KEY','from_email'=>'MAIL_FROM','from_name'=>'MAIL_FROM_NAME','admin_email'=>'ADMIN_EMAIL'], ], ]; -// ── Helpers ────────────────────────────────────────────────────────── -function fileGet(string $file, string $constant): string { - if (!file_exists($file)) return ''; - $content = file_get_contents($file); - if (preg_match("/define\s*\(\s*['\"]" . preg_quote($constant, '/') . "['\"],\s*['\"]([^'\"]*)['\"].*?\)/s", $content, $m)) - return $m[1]; - return ''; +// ── Primary storage: jarvis_db site_settings table ────────────────── +function ssGet(string $siteId, string $field): string { + $row = JarvisDB::single( + 'SELECT setting_value FROM site_settings WHERE site_id=? AND setting_key=?', + [$siteId, $field] + ); + return $row['setting_value'] ?? ''; } -function fileSet(string $file, string $constant, string $value): bool { - if (!file_exists($file)) return false; +function ssSet(string $siteId, string $field, string $value): bool { + JarvisDB::execute( + 'INSERT INTO site_settings (site_id, setting_key, setting_value) VALUES (?,?,?) + ON DUPLICATE KEY UPDATE setting_value=VALUES(setting_value), updated_at=NOW()', + [$siteId, $field, $value] + ); + return true; +} + +// ── Secondary sync: TJJ own DB ─────────────────────────────────────── +function tjjSync(array $syncDb, array $syncKeys, string $field, string $value): void { + $key = $syncKeys[$field] ?? null; + if (!$key) return; + try { + $pdo = new PDO("mysql:host={$syncDb['host']};dbname={$syncDb['name']};charset=utf8mb4", + $syncDb['user'], $syncDb['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + $exists = $pdo->prepare('SELECT id FROM settings WHERE setting_key=?'); + $exists->execute([$key]); + if ($exists->fetch()) { + $pdo->prepare('UPDATE settings SET setting_value=? WHERE setting_key=?') + ->execute([json_encode($value), $key]); + } else { + $pdo->prepare('INSERT INTO settings (setting_key, setting_value) VALUES (?,?)') + ->execute([$key, json_encode($value)]); + } + } catch (Exception $e) { /* best-effort */ } +} + +// ── File push: best-effort write to config file ────────────────────── +function filePush(string $file, string $constant, string $value): void { + if (!file_exists($file) || !is_writable($file)) return; $content = file_get_contents($file); - $safe = str_replace("'", "\\'", $value); - $new = preg_replace( + $safe = str_replace("'", "\\'", $value); + $new = preg_replace( "/define\s*\(\s*['\"]" . preg_quote($constant, '/') . "['\"],\s*['\"][^'\"]*['\"](\s*)\)/", "define('" . $constant . "', '" . $safe . "'$1)", $content ); - if ($new === null) return false; // regex error - if ($new === $content) return true; // already correct value - return file_put_contents($file, $new) !== false; + if ($new && $new !== $content) { + file_put_contents($file, $new); + } } -function dbGet(array $db, string $key): string { - try { - $pdo = new PDO("mysql:host={$db['host']};dbname={$db['name']};charset=utf8mb4", - $db['user'], $db['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); - $s = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key=?"); - $s->execute([$key]); - $row = $s->fetch(PDO::FETCH_ASSOC); - if (!$row) return ''; - $decoded = json_decode($row['setting_value'], true); - return $decoded ?? $row['setting_value']; - } catch (Exception $e) { return ''; } -} - -function dbSet(array $db, string $key, string $value): bool { - try { - $pdo = new PDO("mysql:host={$db['host']};dbname={$db['name']};charset=utf8mb4", - $db['user'], $db['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); - $existing = $pdo->prepare("SELECT id FROM settings WHERE setting_key=?"); - $existing->execute([$key]); - if ($existing->fetch()) { - $pdo->prepare("UPDATE settings SET setting_value=? WHERE setting_key=?")->execute([json_encode($value), $key]); - } else { - $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?,?)")->execute([$key, json_encode($value)]); - } - return true; - } catch (Exception $e) { return false; } -} - -function siteGet(array $site, string $field): string { - $constant = $site['keys'][$field] ?? ''; - if (!$constant) return ''; - if ($site['type'] === 'db') return dbGet($site['db'], $constant); - return fileGet($site['file'], $constant); -} - -function siteSet(array $site, string $field, string $value): bool { - $constant = $site['keys'][$field] ?? ''; - if (!$constant) return false; - if ($site['type'] === 'db') return dbSet($site['db'], $constant, $value); - return fileSet($site['file'], $constant, $value); +// ── Initial population: seed jarvis_db from TJJ DB on first access ── +function seedFromTjjDb(string $siteId, array $syncDb, array $syncKeys): void { + foreach ($syncKeys as $field => $key) { + if (ssGet($siteId, $field) !== '') continue; // already have it + try { + $pdo = new PDO("mysql:host={$syncDb['host']};dbname={$syncDb['name']};charset=utf8mb4", + $syncDb['user'], $syncDb['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + $s = $pdo->prepare('SELECT setting_value FROM settings WHERE setting_key=?'); + $s->execute([$key]); + $row = $s->fetch(PDO::FETCH_ASSOC); + if ($row) { + $v = json_decode($row['setting_value'], true) ?? $row['setting_value']; + ssSet($siteId, $field, $v); + } + } catch (Exception $e) { /* best-effort */ } + } } // ── Router ─────────────────────────────────────────────────────────── if ($method === 'GET') { + // Seed TJJ from its own DB if not yet in jarvis_db + if (isset($SITES['tomsjavajive']['sync_db'])) { + seedFromTjjDb('tomsjavajive', $SITES['tomsjavajive']['sync_db'], $SITES['tomsjavajive']['sync_keys']); + } + $result = []; foreach ($SITES as $id => $site) { $result[$id] = [ - 'name' => $site['name'], - 'url' => $site['url'], - 'api_key' => siteGet($site, 'api_key'), - 'from_email' => siteGet($site, 'from_email'), - 'from_name' => siteGet($site, 'from_name'), - 'admin_email'=> siteGet($site, 'admin_email'), + 'name' => $site['name'], + 'url' => $site['url'], + 'api_key' => ssGet($id, 'api_key'), + 'from_email' => ssGet($id, 'from_email'), + 'from_name' => ssGet($id, 'from_name'), + 'admin_email' => ssGet($id, 'admin_email'), ]; } echo json_encode(['success' => true, 'sites' => $result]); @@ -125,16 +134,18 @@ if ($method === 'GET') { } if ($method === 'POST') { - $action = $data['action'] ?? ''; - $siteId = $data['site'] ?? ''; - $results = []; + $action = $data['action'] ?? ''; + $siteId = $data['site'] ?? ''; if ($action === 'push_key') { - // Push API key to all sites at once $apiKey = trim($data['api_key'] ?? ''); if (!$apiKey) { echo json_encode(['success'=>false,'error'=>'API key required']); exit; } + $results = []; foreach ($SITES as $id => $site) { - $results[$id] = siteSet($site, 'api_key', $apiKey); + ssSet($id, 'api_key', $apiKey); + if (isset($site['sync_db'])) tjjSync($site['sync_db'], $site['sync_keys'], 'api_key', $apiKey); + if (isset($site['file'])) filePush($site['file'], $site['file_keys']['api_key'] ?? '', $apiKey); + $results[$id] = true; } echo json_encode(['success'=>true,'results'=>$results]); exit; @@ -142,13 +153,19 @@ if ($method === 'POST') { if ($action === 'save' && $siteId && isset($SITES[$siteId])) { $site = $SITES[$siteId]; - $fields = ['api_key', 'from_email', 'from_name', 'admin_email']; + $fields = ['api_key','from_email','from_name','admin_email']; foreach ($fields as $field) { - if (isset($data[$field])) { - $results[$field] = siteSet($site, $field, trim($data[$field])); - } + if (!isset($data[$field])) continue; + $value = trim($data[$field]); + // 1. Always save to jarvis_db + ssSet($siteId, $field, $value); + // 2. Sync to TJJ own DB if applicable + if (isset($site['sync_db'])) tjjSync($site['sync_db'], $site['sync_keys'], $field, $value); + // 3. Push to file if accessible + if (isset($site['file']) && isset($site['file_keys'][$field])) + filePush($site['file'], $site['file_keys'][$field], $value); } - echo json_encode(['success'=>true,'results'=>$results]); + echo json_encode(['success'=>true]); exit; }