Files
Workshop-Wahlen/includes/frontend-ergebnis.php
ProgrammGamer 9b2d7b77fd
All checks were successful
Deploy Workshop-Wahlen (DEV / PROD) / deploy (push) Successful in 13s
Frontend: Hinweis entfernt keine Freigeschaltet-Meldung mehr im Formular und Ergebnis; Inhalte bleiben sichtbar ohne Banner.
2026-01-30 21:33:29 +01:00

238 lines
11 KiB
PHP

<?php
add_shortcode('konficastle_workshop_ergebnis', function($atts) {
$atts = shortcode_atts(['wahl'=>null], $atts);
$wahl_id = intval($atts['wahl']);
global $wpdb;
$wahl = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}kc_wahlen WHERE id=$wahl_id");
if(!$wahl) return '';
// Keine Warnmeldung im Frontend anzeigen, Ergebnisse weiterhin darstellen
// Workshops für diese Wahl holen
$workshops = $wpdb->get_results(
"SELECT ws.id, ws.name
FROM {$wpdb->prefix}kc_workshops ws
JOIN {$wpdb->prefix}kc_wahl_workshops ww ON ws.id = ww.workshop_id
WHERE ww.wahl_id = ".intval($wahl_id)
);
$ws_names = [];
$ws_ids = [];
foreach($workshops as $ws) {
$ws_names[$ws->id] = $ws->name;
$ws_ids[] = intval($ws->id);
}
// Zuteilungen holen
$rows = $wpdb->get_results(
"SELECT * FROM {$wpdb->prefix}kc_zuteilung WHERE wahl_id=".intval($wahl_id)
);
// Gruppieren nach Workshop, sortieren nach Teilnehmerzahl
$workshop_groups = [];
$nicht_zugeteilt = [];
$phases = [];
foreach($rows as $row) {
// Einträge ohne Phase komplett ignorieren
if ($row->phase === null || $row->phase === '') {
continue;
}
$phaseNum = intval($row->phase);
$phases[$phaseNum] = true;
if ($row->workshop_id && isset($ws_names[$row->workshop_id])) {
$workshop_groups[$row->workshop_id][] = $row;
} else {
$nicht_zugeteilt[] = $row;
}
}
uasort($workshop_groups, function($a, $b) {
return count($a) - count($b);
});
$phases = array_keys($phases);
sort($phases, SORT_NUMERIC);
// Teamer pro Workshop und Phase laden (mit Hierarchie: Phase-spezifisch > Wahl-weit > Feste)
$ws_teamers = [];
if (!empty($ws_ids)) {
// Für JEDEN Workshop einzeln laden
foreach($ws_ids as $ws_id) {
foreach($phases as $phase) {
// 1. Versuche Phase-spezifische Teamer zu laden
$trows = $wpdb->get_results($wpdb->prepare(
"SELECT t.vorname, t.nachname FROM {$wpdb->prefix}kc_workshop_teamer wt
JOIN {$wpdb->prefix}kc_teamer t ON wt.teamer_id = t.id
WHERE wt.workshop_id = %d AND wt.wahl_id = %d AND wt.phase = %d",
$ws_id, $wahl_id, $phase
));
// 2. Falls nicht: Versuche Wahl-weite Teamer zu laden
if (empty($trows)) {
$trows = $wpdb->get_results($wpdb->prepare(
"SELECT t.vorname, t.nachname FROM {$wpdb->prefix}kc_workshop_teamer wt
JOIN {$wpdb->prefix}kc_teamer t ON wt.teamer_id = t.id
WHERE wt.workshop_id = %d AND wt.wahl_id = %d AND wt.phase IS NULL",
$ws_id, $wahl_id
));
}
// 3. Falls nicht: Lade Feste Teamer
if (empty($trows)) {
$trows = $wpdb->get_results($wpdb->prepare(
"SELECT t.vorname, t.nachname FROM {$wpdb->prefix}kc_workshop_teamer wt
JOIN {$wpdb->prefix}kc_teamer t ON wt.teamer_id = t.id
WHERE wt.workshop_id = %d AND wt.wahl_id IS NULL AND wt.phase IS NULL",
$ws_id
));
}
if (!empty($trows)) {
$key = intval($ws_id) . '_' . intval($phase);
$ws_teamers[$key] = [];
foreach ($trows as $tr) {
$ws_teamers[$key][] = trim($tr->vorname.' '.$tr->nachname);
}
}
}
}
}
// Versuche, Teilnehmer-IDs aus Cookie zu lesen (falls vorhanden)
$my_ids = [];
$cookie_name = 'kc_my_part_' . intval($wahl_id);
if (!empty($_COOKIE[$cookie_name])) {
$decoded = json_decode(stripslashes($_COOKIE[$cookie_name]), true);
if (is_array($decoded)) $my_ids = array_map('intval', $decoded);
}
ob_start();
// Inline styles, angepasst an konfi-castle.com Look (dezent, grün/türkis Akzent)
echo '<style>
.kc-result{font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;color:#222;}
.kc-result h3{margin-top:0;text-align:center;color:#154a3b;}
.kc-phase{margin:18px 0;padding:12px;border-radius:12px;background:#fbfffe;border:1px solid #e6f3ee;}
/* Responsive Kachel-Layout: auto-fit with minmax so cards wrap based on viewport */
.kc-result .kc-inner { max-width:1100px; margin:0 auto; padding:0 14px; box-sizing:border-box; }
.kc-workshops-grid{display:grid;grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));gap:14px;margin-top:12px;align-items:start;}
.kc-workshop-card{background:#ffffff;border-radius:12px;overflow:hidden;border:1px solid #e9f4f0;box-shadow:0 2px 6px rgba(8,38,28,0.04);width:100%;}
/* Zentrierter, prominenter Titelbereich in der Mitte oben der Kachel */
.kc-workshop-card .title{background:linear-gradient(90deg, rgba(45,166,106,0.04), rgba(13,89,71,0.02));display:flex;flex-wrap:wrap;align-items:center;justify-content:center;padding:18px 12px;font-weight:800;color:#0d5947;font-size:1.06rem;letter-spacing:0.2px;border-bottom:1px solid rgba(229,244,240,0.8);gap:12px;}
.kc-workshop-card .title .count{color:#6b6b6b;font-weight:600;font-size:0.9rem;margin-left:6px;}
.kc-workshop-card .title .teamers{font-weight:600;color:#145a47;font-size:0.9rem;opacity:0.92;}
.kc-workshop-card .title .teamers small{font-weight:500;color:#4c7a6a;opacity:0.9;font-size:0.85rem;margin-left:6px;}
/* Content-Bereich unter dem Titel mit etwas mehr Luft */
.kc-workshop-card .content{padding:12px 18px 18px 18px;}
.kc-participants{display:grid;grid-template-columns:1fr 1fr;gap:6px 12px;font-size:0.95rem;color:#2b2b2b;}
.kc-participant{padding:6px 8px;border-radius:6px;background:transparent;}
.kc-participant.me{background:#fffbe6;border:1px solid #ffeab2;}
.kc-notassigned{background:#fff6f6;border:1px solid #ffd2d2;padding:12px;border-radius:10px;margin-top:12px;}
/* Auf sehr kleinen Bildschirmen die Teilnehmer ebenfalls einspaltig */
@media(max-width:700px){ .kc-participants{grid-template-columns:1fr;} }
</style>';
echo '<div class="kc-result">';
echo '<h3>Ergebnis für diese Wahl</h3>';
// Falls persönliche IDs vorhanden: zeige persönliche Zuteilung oben
$personal_shown = false;
if (!empty($my_ids)) {
// Suche Zuteilungen für meine IDs
$my_rows = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}kc_zuteilung WHERE wahl_id=".intval($wahl_id)." AND id IN (" . implode(',', array_map('intval', $my_ids)) . ")");
if (!empty($my_rows)) {
// Entferntes <br> nach "Deine Zuteilung"
echo '<div style="background:#e8f9ef;border-left:6px solid #2da66a;padding:12px 14px;margin-bottom:12px;border-radius:8px;">';
echo '<b>Deine Zuteilung</b><ul style="margin:6px 0 0 16px;">';
foreach($my_rows as $mr) {
$wslabel = ($mr->workshop_id && isset($ws_names[$mr->workshop_id])) ? $ws_names[$mr->workshop_id] : ($mr->workshop_id ? 'ID '.$mr->workshop_id : 'Nicht zugeteilt');
echo '<li>'.esc_html($mr->vorname.' '.$mr->nachname).' (Phase '.intval($mr->phase).') — '.esc_html($wslabel).'</li>';
}
echo '</ul></div>';
$personal_shown = true;
}
}
// Für jede Phase: Workshops nebeneinander darstellen
foreach($phases as $phase) {
echo '<div class="kc-phase">';
echo '<h4 style="margin:6px 0;text-align:center;">Phase '.intval($phase).'</h4>';
echo '<div class="kc-workshops-grid">';
// Sammle nur Workshops mit Teilnehmern in dieser Phase
$display = [];
foreach($ws_names as $ws_id => $ws_name) {
$teilnehmer = [];
if (isset($workshop_groups[$ws_id])) {
foreach($workshop_groups[$ws_id] as $t) {
if (intval($t->phase) === intval($phase)) $teilnehmer[] = $t;
}
}
$count = count($teilnehmer);
if ($count === 0) continue; // nur Workshops mit TN anzeigen
$display[] = [
'id' => $ws_id,
'name' => $ws_name,
'teilnehmer' => $teilnehmer,
'count' => $count
];
}
// Nach Teilnehmerzahl aufsteigend sortieren (kleinste oben, größte unten)
usort($display, function($a, $b) {
return $a['count'] - $b['count'];
});
// Ausgabe der sortierten Kacheln
foreach($display as $d) {
$ws_name = $d['name'];
$teilnehmer = $d['teilnehmer'];
$count = $d['count'];
// Sortiere so, dass persönliche Teilnehmer zuerst kommen
if (!empty($my_ids) && !empty($teilnehmer)) {
usort($teilnehmer, function($a, $b) use ($my_ids) {
$a_my = in_array(intval($a->id), $my_ids);
$b_my = in_array(intval($b->id), $my_ids);
if ($a_my && !$b_my) return -1;
if (!$a_my && $b_my) return 1;
return 0;
});
}
echo '<div class="kc-workshop-card">';
// Teamernamen (falls vorhanden) anzeigen - mit Phase-Key
$teamer_html = '';
$teamer_key = intval($d['id']) . '_' . intval($phase);
if (!empty($ws_teamers[$teamer_key])) {
$teamer_html = '<span class="teamers">'.esc_html(implode(', ', $ws_teamers[$teamer_key])).'</span>';
}
echo '<div class="title">'.esc_html($ws_name).' '. $teamer_html .'<span class="count">('.$count.' TN)</span></div>';
echo '<div class="content">';
echo '<div class="kc-participants">';
foreach($teilnehmer as $t) {
$is_me = in_array(intval($t->id), $my_ids);
$name = esc_html($t->vorname.' '.$t->nachname);
$label = $name . ' <span style="color:#6b6b6b;font-size:85%;">('.intval($t->phase).')</span>';
echo '<div class="kc-participant'.($is_me ? ' me' : '').'">'. $label .'</div>';
}
echo '</div>'; // kc-participants
echo '</div>'; // content
echo '</div>';
}
echo '</div>'; // kc-workshops-grid
echo '</div>'; // kc-phase
}
// Extra: Nicht zugeteilt
if (!empty($nicht_zugeteilt)) {
echo '<div class="kc-notassigned">';
echo '<b>Nicht zugeteilt:</b><br>';
echo '<ul style="margin:6px 0 0 18px;">';
foreach($nicht_zugeteilt as $t) {
echo '<li>'.esc_html($t->vorname.' '.$t->nachname).' (Phase '.intval($t->phase).')</li>';
}
echo '</ul></div>';
}
echo '</div>'; // kc-result
return ob_get_clean();
});
?>