prefix;
kc_admin_tabs('kc_teilnehmer');
// Alle Wahlen + Workshops für Dropdowns und Validierung
$all_wahlen = $wpdb->get_results("SELECT id, name, anzahl_einheiten FROM {$prefix}kc_wahlen WHERE deleted=0 ORDER BY id DESC");
$all_workshops = $wpdb->get_results("SELECT id, name FROM {$prefix}kc_workshops ORDER BY name");
// Map of wahl id => name for quick lookup
$wahl_name_map = [];
if (!empty($all_wahlen)) {
foreach ($all_wahlen as $w) {
$wahl_name_map[intval($w->id)] = $w->name;
}
}
// Map of workshop id => name for quick lookup in overview
$workshops_map = [];
if (!empty($all_workshops)) {
foreach ($all_workshops as $ws) {
$workshops_map[intval($ws->id)] = $ws->name;
}
}
// CSV-Export (alle Teilnehmer oder gefiltert nach Wahl/Phase)
if (isset($_GET['export_teilnehmer_csv']) && current_user_can('manage_options')) {
$export_wahl_id = isset($_GET['wahl_id']) ? intval($_GET['wahl_id']) : 0;
$export_phase = isset($_GET['phase']) ? intval($_GET['phase']) : 0;
$sql = "SELECT * FROM {$prefix}kc_teilnehmer";
if ($export_wahl_id > 0 && $export_phase > 0) {
$sql .= $wpdb->prepare(" WHERE wahl_id=%d AND phase=%d", $export_wahl_id, $export_phase);
} elseif ($export_wahl_id > 0) {
$sql .= $wpdb->prepare(" WHERE wahl_id=%d", $export_wahl_id);
} elseif ($export_phase > 0) {
$sql .= $wpdb->prepare(" WHERE phase=%d", $export_phase);
}
$sql .= " ORDER BY wahl_id, phase, nachname, vorname";
$export_rows = $wpdb->get_results($sql);
$filename_suffix = '_alle';
if ($export_wahl_id > 0) {
$wahl_name_for_file = isset($wahl_name_map[$export_wahl_id]) ? $wahl_name_map[$export_wahl_id] : ('wahl_'.$export_wahl_id);
$wahl_slug = sanitize_title($wahl_name_for_file);
if ($wahl_slug === '') {
$wahl_slug = 'wahl_'.$export_wahl_id;
}
$filename_suffix = '_'.$wahl_slug;
if ($export_phase > 0) {
$filename_suffix .= '_phase_'.$export_phase;
}
} elseif ($export_phase > 0) {
$filename_suffix = '_phase_'.$export_phase;
}
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="kc_teilnehmer'.$filename_suffix.'.csv"');
echo "\xEF\xBB\xBF";
$output = fopen('php://output', 'w');
$delimiter = ';';
fputcsv($output, ['Vorname','Nachname','Wahl','Phase','Wunsch 1','Wunsch 2','Wunsch 3'], $delimiter);
$csv_clean = function($value) {
$text = html_entity_decode((string)$value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
$text = wp_strip_all_tags($text, true);
$text = preg_replace('/\s+/u', ' ', $text);
return trim($text);
};
foreach ($export_rows as $tn) {
$w1_id = intval($tn->wunsch1);
$w2_id = intval($tn->wunsch2);
$w3_id = intval($tn->wunsch3);
$w1_disp = $w1_id && isset($workshops_map[$w1_id]) ? $workshops_map[$w1_id] : ($w1_id ? strval($w1_id) : '');
$w2_disp = $w2_id && isset($workshops_map[$w2_id]) ? $workshops_map[$w2_id] : ($w2_id ? strval($w2_id) : '');
$w3_disp = $w3_id && isset($workshops_map[$w3_id]) ? $workshops_map[$w3_id] : ($w3_id ? strval($w3_id) : '');
$wahl_name = isset($wahl_name_map[intval($tn->wahl_id)]) ? $wahl_name_map[intval($tn->wahl_id)] : '';
$vorname = $csv_clean($tn->vorname);
$nachname = $csv_clean($tn->nachname);
$wahl_name_clean = $csv_clean($wahl_name);
$w1_clean = $csv_clean($w1_disp);
$w2_clean = $csv_clean($w2_disp);
$w3_clean = $csv_clean($w3_disp);
fputcsv($output, [
$vorname,
$nachname,
$wahl_name_clean,
intval($tn->phase),
$w1_clean,
$w2_clean,
$w3_clean
], $delimiter);
}
fclose($output);
exit;
}
// Build map of wahl -> phases + workshops (for JS)
$wahl_map = [];
foreach($all_wahlen as $w) {
$wahl_map[intval($w->id)] = ['phases' => max(1,intval($w->anzahl_einheiten)), 'workshops' => []];
}
if (!empty($all_workshops)) {
foreach($all_workshops as $ws) {
$ww = $wpdb->get_col($wpdb->prepare("SELECT wahl_id FROM {$prefix}kc_wahl_workshops WHERE workshop_id=%d", $ws->id));
if (!empty($ww)) {
foreach($ww as $wid) {
if (isset($wahl_map[intval($wid)])) {
$wahl_map[intval($wid)]['workshops'][] = ['id'=>intval($ws->id),'name'=>$ws->name];
}
}
}
}
}
// Teilnehmer l�schen
if (isset($_GET['delete_teilnehmer'])) {
$tid = intval($_GET['delete_teilnehmer']);
$wpdb->delete("{$prefix}kc_teilnehmer", ['id' => $tid]);
echo '
Teilnehmer gel�scht!
';
}
// Teilnehmer speichern (neu/�ndern)
if (isset($_POST['kc_teilnehmer_save'])) {
// sanitize inputs
$vorname = sanitize_text_field($_POST['vorname']);
$nachname = sanitize_text_field($_POST['nachname']);
$wahl_id_post = intval($_POST['wahl_id']);
$phase_post = intval($_POST['phase']);
$w1 = intval($_POST['wunsch1']);
$w2 = intval($_POST['wunsch2']);
$w3 = intval($_POST['wunsch3']);
// Server-side validation: duplicate name in same Wahl (exclude self on edit)
$norm_v = mb_strtolower(trim($vorname));
$norm_n = mb_strtolower(trim($nachname));
if (!empty($_POST['tid'])) {
$exclude_id = intval($_POST['tid']);
$exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$prefix}kc_teilnehmer WHERE LOWER(TRIM(vorname))=%s AND LOWER(TRIM(nachname))=%s AND wahl_id=%d AND id<>%d", $norm_v, $norm_n, $wahl_id_post, $exclude_id));
} else {
$exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$prefix}kc_teilnehmer WHERE LOWER(TRIM(vorname))=%s AND LOWER(TRIM(nachname))=%s AND wahl_id=%d", $norm_v, $norm_n, $wahl_id_post));
}
if ($exists && $exists > 0) {
echo 'Diese Kombination aus Vorname und Nachname existiert bereits für diese Wahl.
';
} else {
// validate phase within wahl
$wahl_row = $wpdb->get_row($wpdb->prepare("SELECT anzahl_einheiten FROM {$prefix}kc_wahlen WHERE id=%d", $wahl_id_post));
$max_ph = $wahl_row ? max(1,intval($wahl_row->anzahl_einheiten)) : 1;
if ($phase_post < 1 || $phase_post > $max_ph) {
echo 'Ungültige Phase für die gewählte Wahl.
';
} else {
// validate that selected workshops belong to the chosen wahl (if mapping exists)
$valid_ws = [];
$ww_rows = $wpdb->get_col($wpdb->prepare("SELECT workshop_id FROM {$prefix}kc_wahl_workshops WHERE wahl_id=%d", $wahl_id_post));
if (!empty($ww_rows)) foreach($ww_rows as $r) $valid_ws[] = intval($r);
// if mapping exists, enforce membership
$check_membership = function($wid) use ($valid_ws) {
if (empty($valid_ws)) return true; // no mapping -> allow
return in_array(intval($wid), $valid_ws);
};
if (!$check_membership($w1) || !$check_membership($w2) || !$check_membership($w3)) {
echo 'Einer oder mehrere ausgewählte Workshops gehören nicht zur gewählten Wahl.
';
} else {
$data = [
'vorname' => $vorname,
'nachname' => $nachname,
'wahl_id' => $wahl_id_post,
'phase' => $phase_post,
'wunsch1' => $w1,
'wunsch2' => $w2,
'wunsch3' => $w3
];
if (!empty($_POST['tid'])) {
$wpdb->update("{$prefix}kc_teilnehmer", $data, ['id'=>intval($_POST['tid'])]);
echo 'Teilnehmer aktualisiert!
';
} else {
$wpdb->insert("{$prefix}kc_teilnehmer", $data);
echo 'Teilnehmer angelegt!
';
}
}
}
}
}
// Teilnehmer bearbeiten
if (isset($_GET['edit_teilnehmer'])) {
$tid = intval($_GET['edit_teilnehmer']);
$tn = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$prefix}kc_teilnehmer WHERE id=%d", $tid));
echo '';
echo '
Teilnehmer bearbeiten
';
echo '
';
// Provide JS map and init JS: restrict phases/workshops based on Wahl and init Select2
echo '';
echo '';
echo '
';
return;
}
// Neuer Teilnehmer anlegen
if (isset($_GET['new'])) {
echo '';
echo '
Neuen Teilnehmer anlegen
';
echo '
';
// Init Select2 for nicer selects if available
echo '';
echo '
';
return;
}
// Übersicht
// Map für Wahl-ID => Name ist bereits oben aufgebaut
echo '';
echo '
Alle Teilnehmer
';
echo '
Teilnehmer-Export (Ansicht)';
echo '
+ Neuer Teilnehmer';
// Wahl-Filter-Buttons sortiert nach KC1, KC2, KC3, dann Rest
$kc_buttons = [];
$rest_buttons = [];
foreach($all_wahlen as $w) {
$name = strtoupper($w->name);
if ($name === 'KC1' || $name === 'KC2' || $name === 'KC3') {
$kc_buttons[$name] = $w;
} else {
$rest_buttons[] = $w;
}
}
echo '
'
.'';
echo '';
foreach(["KC1","KC2","KC3"] as $kc) {
if(isset($kc_buttons[$kc])) {
$w = $kc_buttons[$kc];
echo '';
}
}
foreach($rest_buttons as $w) {
echo '';
}
echo 'Alle anzeigen';
echo '
';
// Platzhalter für Phasen-Filter
echo '
';
// Teilnehmer laden und gruppieren nach Wahl und Phase
$teilnehmer = $wpdb->get_results("SELECT * FROM {$prefix}kc_teilnehmer ORDER BY wahl_id, phase, nachname, vorname");
$gruppen = [];
foreach ($teilnehmer as $tn) {
$wid = intval($tn->wahl_id);
$ph = intval($tn->phase);
$gruppen[$wid][$ph][] = $tn;
}
foreach ($gruppen as $wid => $phasen) {
$wahl_disp = isset($wahl_name_map[$wid]) ? esc_html($wahl_name_map[$wid]) : $wid;
$csv_wahl_url = add_query_arg([
'page' => 'kc_teilnehmer',
'export_teilnehmer_csv' => 1,
'wahl_id' => intval($wid)
], admin_url('admin.php'));
// Gesamtanzahl Teilnehmer für diese Wahl berechnen
$gesamt = 0;
foreach ($phasen as $tns) $gesamt += count($tns);
echo '
';
echo ''. $wahl_disp . ' (' . $gesamt . ' TN)
';
echo '';
foreach ($phasen as $phase => $tns) {
echo '';
echo 'Phase '.intval($phase).' ('.count($tns).' TN)
';
echo '';
echo '| Vorname | Nachname | Wahl | Phase | Wunsch 1 | Wunsch 2 | Wunsch 3 | Aktion |
';
foreach ($tns as $tn) {
$w1_id = intval($tn->wunsch1);
$w2_id = intval($tn->wunsch2);
$w3_id = intval($tn->wunsch3);
$w1_disp = $w1_id && isset($workshops_map[$w1_id]) ? esc_html($workshops_map[$w1_id]) : ($w1_id ? intval($w1_id) : 'Keine');
$w2_disp = $w2_id && isset($workshops_map[$w2_id]) ? esc_html($workshops_map[$w2_id]) : ($w2_id ? intval($w2_id) : 'Keine');
$w3_disp = $w3_id && isset($workshops_map[$w3_id]) ? esc_html($workshops_map[$w3_id]) : ($w3_id ? intval($w3_id) : 'Keine');
$wahl_disp = isset($wahl_name_map[intval($tn->wahl_id)]) ? esc_html($wahl_name_map[intval($tn->wahl_id)]) : intval($tn->wahl_id);
echo "
| ".esc_html($tn->vorname)." |
".esc_html($tn->nachname)." |
".$wahl_disp." |
".intval($tn->phase)." |
".$w1_disp." |
".$w2_disp." |
".$w3_disp." |
Bearbeiten
Löschen
|
";
}
echo '
';
echo ' ';
}
echo ' ';
}
// JS für Wahl- und Phasen-Filter
echo '';
echo '';
echo '
';
}
?>