['table' => 'question_translation', 'pk' => 'questionID'], 'answer_option' => ['table' => 'answer_option_translation', 'pk' => 'answerOptionID'], 'string' => ['table' => 'string_translation', 'pk' => 'stringKey'], ]; /** * @return list */ public static function listLanguages(PDO $pdo): array { return $pdo->query( "SELECT languageCode, name FROM language ORDER BY languageCode" )->fetchAll(PDO::FETCH_ASSOC); } public static function upsertLanguage(PDO $pdo, string $code, string $name): void { $pdo->prepare(" INSERT INTO language (languageCode, name) VALUES (:lc, :n) ON CONFLICT(languageCode) DO UPDATE SET name = excluded.name ")->execute([':lc' => $code, ':n' => $name]); } /** * Delete a language and all its translations across all three tables. */ public static function deleteLanguage(PDO $pdo, string $code): void { $pdo->prepare("DELETE FROM language WHERE languageCode = :lc") ->execute([':lc' => $code]); $pdo->prepare("DELETE FROM question_translation WHERE languageCode = :lc") ->execute([':lc' => $code]); $pdo->prepare("DELETE FROM answer_option_translation WHERE languageCode = :lc") ->execute([':lc' => $code]); $pdo->prepare("DELETE FROM string_translation WHERE languageCode = :lc") ->execute([':lc' => $code]); } /** * Get all translations for a given entity. * * @param string $type question|answer_option|string * @return list */ public static function getForEntity(PDO $pdo, string $type, string $id): array { $meta = self::meta($type); $stmt = $pdo->prepare( "SELECT languageCode, text FROM {$meta['table']} WHERE {$meta['pk']} = :id" ); $stmt->execute([':id' => $id]); return $stmt->fetchAll(PDO::FETCH_ASSOC); } /** * Insert or update a single translation. * * @param string $type question|answer_option|string */ public static function upsert(PDO $pdo, string $type, string $id, string $lang, string $text): void { $meta = self::meta($type); $pdo->prepare(" INSERT INTO {$meta['table']} ({$meta['pk']}, languageCode, text) VALUES (:id, :lang, :t) ON CONFLICT({$meta['pk']}, languageCode) DO UPDATE SET text = excluded.text ")->execute([':id' => $id, ':lang' => $lang, ':t' => $text]); } /** * Delete a single translation. * * @param string $type question|answer_option|string */ public static function delete(PDO $pdo, string $type, string $id, string $lang): void { $meta = self::meta($type); $pdo->prepare( "DELETE FROM {$meta['table']} WHERE {$meta['pk']} = :id AND languageCode = :lang" )->execute([':id' => $id, ':lang' => $lang]); } /** * @return array{table: string, pk: string} */ private static function meta(string $type): array { if (!isset(self::TABLE_MAP[$type])) { throw new InvalidArgumentException("Unknown translation type: $type"); } return self::TABLE_MAP[$type]; } }