false, 'title' => 'Invalid request method', 'message' => 'Only POST requests are allowed.' ]); exit; } $apiKey = $_POST['api_key'] ?? $_POST['apiKey'] ?? null; // Authenticate user first if (!$apiKey) { echo json_encode([ 'success' => false, 'title' => 'Missing API key', 'message' => 'API key is required.' ]); exit; } $sql = "SELECT * FROM user WHERE api_key = :apiKey"; $stmt = $db->prepare($sql); $stmt->bindValue(':apiKey', $apiKey, SQLITE3_TEXT); $result = $stmt->execute(); $user = $result->fetchArray(SQLITE3_ASSOC); if (!$user) { echo json_encode([ 'success' => false, 'title' => 'Unauthorized', 'message' => 'Invalid API key.' ]); exit; } $userId = $user['id']; // 1. Process Custom CSS if (isset($_POST['css'])) { $customCss = $_POST['css']; $stmtDelCss = $db->prepare('DELETE FROM custom_css_style WHERE user_id = :userId'); $stmtDelCss->bindValue(':userId', $userId, SQLITE3_INTEGER); $stmtDelCss->execute(); $stmtInsCss = $db->prepare('INSERT INTO custom_css_style (css, user_id) VALUES (:customCss, :userId)'); $stmtInsCss->bindValue(':customCss', $customCss, SQLITE3_TEXT); $stmtInsCss->bindValue(':userId', $userId, SQLITE3_INTEGER); $stmtInsCss->execute(); } // 2. Process Custom Colors if (isset($_POST['main_color']) || isset($_POST['accent_color']) || isset($_POST['hover_color']) || isset($_POST['mainColor']) || isset($_POST['accentColor']) || isset($_POST['hoverColor'])) { // Fetch current custom colors to allow partial updates $colorSql = "SELECT * FROM custom_colors WHERE user_id = :userId"; $colorStmt = $db->prepare($colorSql); $colorStmt->bindValue(':userId', $userId, SQLITE3_INTEGER); $colorResult = $colorStmt->execute(); $currentColor = $colorResult->fetchArray(SQLITE3_ASSOC) ?: [ 'main_color' => '#0000ff', 'accent_color' => '#00ffff', 'hover_color' => '#00008b' ]; $main_color = $_POST['main_color'] ?? $_POST['mainColor'] ?? $currentColor['main_color']; $accent_color = $_POST['accent_color'] ?? $_POST['accentColor'] ?? $currentColor['accent_color']; $hover_color = $_POST['hover_color'] ?? $_POST['hoverColor'] ?? $currentColor['hover_color']; // Validate colors if (!preg_match('/^#[0-9A-Fa-f]{6}$/', $main_color) || !preg_match('/^#[0-9A-Fa-f]{6}$/', $accent_color) || !preg_match('/^#[0-9A-Fa-f]{6}$/', $hover_color)) { echo json_encode([ 'success' => false, 'title' => 'Invalid colors', 'message' => 'Custom colors must be in #RRGGBB format.' ]); exit; } if ($main_color === $accent_color) { echo json_encode([ 'success' => false, 'title' => 'Color validation failed', 'message' => 'Main color and accent color cannot be the same.' ]); exit; } // Delete & Insert $delColors = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId'); $delColors->bindValue(':userId', $userId, SQLITE3_INTEGER); $delColors->execute(); $insColors = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color, user_id) VALUES (:main_color, :accent_color, :hover_color, :userId)'); $insColors->bindValue(':main_color', $main_color, SQLITE3_TEXT); $insColors->bindValue(':accent_color', $accent_color, SQLITE3_TEXT); $insColors->bindValue(':hover_color', $hover_color, SQLITE3_TEXT); $insColors->bindValue(':userId', $userId, SQLITE3_INTEGER); $insColors->execute(); } // 3. Process Settings table updates $updateFields = []; $params = []; $binarySettings = [ 'monthly_price' => 'monthly_price', 'convert_currency' => 'convert_currency', 'remove_background' => 'remove_background', 'hide_disabled' => 'hide_disabled', 'disabled_to_bottom' => 'disabled_to_bottom', 'show_original_price' => 'show_original_price', 'mobile_nav' => 'mobile_nav', 'show_subscription_progress' => 'show_subscription_progress', 'week_starts_sunday' => 'week_starts_sunday', 'square_icons' => 'square_icons' ]; foreach ($binarySettings as $postKey => $dbCol) { if (isset($_POST[$postKey])) { $val = $_POST[$postKey]; if ($val === '1' || $val === '0' || $val === 1 || $val === 0) { $updateFields[] = "`$dbCol` = :$postKey"; $params[$postKey] = [ 'val' => ($val === '1' || $val === 1) ? 1 : 0, 'type' => SQLITE3_INTEGER ]; } else { echo json_encode([ 'success' => false, 'title' => 'Invalid parameter', 'message' => "Parameter '$postKey' must be 0 or 1." ]); exit; } } } if (isset($_POST['dark_theme'])) { $darkTheme = $_POST['dark_theme']; if (in_array($darkTheme, ['0', '1', '2', 0, 1, 2], true)) { $updateFields[] = "`dark_theme` = :dark_theme"; $params['dark_theme'] = [ 'val' => intval($darkTheme), 'type' => SQLITE3_INTEGER ]; } else { echo json_encode([ 'success' => false, 'title' => 'Invalid parameter', 'message' => "Parameter 'dark_theme' must be 0 (light), 1 (dark), or 2 (automatic)." ]); exit; } } if (isset($_POST['color_theme'])) { $colorTheme = $_POST['color_theme']; $allowedThemes = ['blue', 'green', 'red', 'yellow', 'purple', 'custom']; if (in_array($colorTheme, $allowedThemes, true)) { $updateFields[] = "`color_theme` = :color_theme"; $params['color_theme'] = [ 'val' => $colorTheme, 'type' => SQLITE3_TEXT ]; } else { echo json_encode([ 'success' => false, 'title' => 'Invalid parameter', 'message' => "Parameter 'color_theme' must be one of: " . implode(', ', $allowedThemes) . "." ]); exit; } } // Perform update if fields were specified if (!empty($updateFields)) { $sqlUpdate = "UPDATE settings SET " . implode(', ', $updateFields) . " WHERE user_id = :userId"; $stmtUpdate = $db->prepare($sqlUpdate); $stmtUpdate->bindValue(':userId', $userId, SQLITE3_INTEGER); foreach ($params as $paramKey => $paramData) { $stmtUpdate->bindValue(':' . $paramKey, $paramData['val'], $paramData['type']); } $resultUpdate = $stmtUpdate->execute(); if (!$resultUpdate) { echo json_encode([ 'success' => false, 'title' => 'Database error', 'message' => 'Failed to save settings to the database.' ]); exit; } } echo json_encode([ 'success' => true, 'title' => 'Settings updated', 'message' => 'User settings have been saved successfully.' ]); $db->close(); ?>