edu-senex/edu/api/decks.php

63 Zeilen
2,3 KiB
PHP

<?php
$user_id = require_auth();
// GET /api/decks
if (get_method() === 'GET' && empty($segments[1])) {
$stmt = $pdo->prepare("
SELECT d.id, d.slug, d.name, d.description, d.card_count,
COUNT(cp.id) AS reviewed,
COUNT(cp.id) FILTER (WHERE cp.last_rating IN ('easy','medium')) AS correct,
COUNT(cp.id) FILTER (WHERE cp.next_review <= CURRENT_DATE) AS due
FROM decks d
LEFT JOIN cards c ON c.deck_id = d.id
LEFT JOIN card_progress cp ON cp.card_id = c.id AND cp.user_id = :uid
GROUP BY d.id
ORDER BY d.sort_order, d.name
");
$stmt->execute([':uid' => $user_id]);
json_ok(['decks' => $stmt->fetchAll()]);
}
// GET /api/decks/export-anki — download all cards as Anki TSV
if (get_method() === 'GET' && ($segments[1] ?? '') === 'export-anki') {
$stmt = $pdo->query("
SELECT d.name AS deck_name, c.question, c.answer, c.level
FROM cards c JOIN decks d ON d.id = c.deck_id
ORDER BY d.sort_order, d.name, c.sort_order
");
$cards = $stmt->fetchAll();
header('Content-Type: text/tab-separated-values; charset=utf-8');
header('Content-Disposition: attachment; filename="sol2_training_anki_' . date('Y-m-d') . '.txt"');
header('Cache-Control: no-cache');
// Clean markdown formatting for Anki: backticks -> <code>, ** -> <b>
function anki_format($text) {
$t = $text;
$t = preg_replace('/```(\w*)\n(.*?)```/s', '<pre><code>$2</code></pre>', $t);
$t = str_replace('`', '', $t);
$t = preg_replace('/\*\*(.+?)\*\*/', '<b>$1</b>', $t);
$t = str_replace("\n", '<br>', $t);
$t = str_replace("\t", ' ', $t);
return $t;
}
foreach ($cards as $c) {
$q = anki_format($c['question']);
$a = anki_format($c['answer']);
echo $q . "\t" . $a . "\t" . 'Sol2-Training::' . $c['deck_name'] . "\t" . $c['level'] . "\n";
}
exit;
}
// GET /api/decks/{slug}
if (get_method() === 'GET' && !empty($segments[1])) {
$stmt = $pdo->prepare("SELECT * FROM decks WHERE slug = :s");
$stmt->execute([':s' => $segments[1]]);
$deck = $stmt->fetch();
if (!$deck) json_error('Deck nicht gefunden', 404);
json_ok(['deck' => $deck]);
}
json_error('Methode nicht erlaubt', 405);