$maxLength) { $value = substr($value, 0, $maxLength); } return $value; } if ($_SERVER['REQUEST_METHOD'] !== 'POST') { translation_response(405, ['error' => 'Method not allowed']); } if ((int) ($_SERVER['CONTENT_LENGTH'] ?? 0) > 131072) { translation_response(413, ['error' => 'Request too large']); } $body = json_decode(file_get_contents('php://input'), true); if (!is_array($body) || !isset($body['lang'], $body['translations']) || !is_array($body['translations'])) { translation_response(400, ['error' => 'Missing lang or translations']); } $lang = preg_replace('/[^a-z]/', '', strtolower($body['lang'])); $translations = $body['translations']; if (strlen($lang) < 2 || strlen($lang) > 5) { translation_response(400, ['error' => 'Invalid lang code']); } $base = include __DIR__ . '/lang/en.php'; if (file_exists(__DIR__ . "/lang/$lang.php")) { translation_response(409, ['error' => 'Static language already exists']); } foreach ($translations as $key => $value) { if (is_string($key) && array_key_exists($key, $base) && (is_string($value) || is_numeric($value))) { $base[$key] = clean_translation_value((string) $value); } } $content = json_encode($base, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n"; if ($content === false) { translation_response(500, ['error' => 'Could not encode language file']); } $langDir = getenv('WEBSITE_LANG_WRITE_DIR') ?: (sys_get_temp_dir() . '/website-lang'); if (!is_dir($langDir) && !mkdir($langDir, 0755, true)) { translation_response(500, ['error' => 'Could not create language directory']); } $path = "$langDir/$lang.json"; $tmpPath = "$path.tmp." . bin2hex(random_bytes(6)); if (file_put_contents($tmpPath, $content, LOCK_EX) === false || !rename($tmpPath, $path)) { @unlink($tmpPath); translation_response(500, ['error' => 'Could not write language file']); } echo json_encode(['success' => true, 'lang' => $lang]);