351 lines
16 KiB
PHP
351 lines
16 KiB
PHP
<?php
|
|
add_shortcode('konficastle_workshopwahl', function($atts) {
|
|
$atts = shortcode_atts(['wahl'=>null], $atts);
|
|
$wahl_id = intval($atts['wahl']);
|
|
|
|
global $wpdb;
|
|
|
|
// Optionales Debug-Ausgabe-Fragment (standardmäßig leer, um Warnungen zu vermeiden)
|
|
$debug_output = '';
|
|
|
|
$wahl = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}kc_wahlen WHERE id=%d", $wahl_id));
|
|
if(!$wahl || !$wahl->freigegeben) {
|
|
// Keine Fehlermeldung im Frontend anzeigen; Formular ausblenden
|
|
return '';
|
|
}
|
|
|
|
// Ermittle erlaubte Workshops pro Phase für diese Wahl.
|
|
$phasen = (int)$wahl->anzahl_einheiten;
|
|
$workshops_by_phase = [];
|
|
$mapping_candidates = [
|
|
"{$wpdb->prefix}kc_wahl_workshops",
|
|
"{$wpdb->prefix}kc_workshop_wahlen",
|
|
"{$wpdb->prefix}kc_wahl_workshop"
|
|
];
|
|
$mapping_table = null;
|
|
foreach ($mapping_candidates as $t) {
|
|
$found = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $t));
|
|
if ($found === $t) { $mapping_table = $t; break; }
|
|
}
|
|
if ($mapping_table) {
|
|
$has_phase_col = (bool) $wpdb->get_var("SHOW COLUMNS FROM {$mapping_table} LIKE 'phase'");
|
|
for ($phase = 1; $phase <= $phasen; $phase++) {
|
|
if ($has_phase_col) {
|
|
$workshops_by_phase[$phase] = $wpdb->get_results($wpdb->prepare(
|
|
"SELECT w.* FROM {$wpdb->prefix}kc_workshops w
|
|
JOIN {$mapping_table} m ON w.id = m.workshop_id
|
|
WHERE m.wahl_id = %d AND m.phase = %d
|
|
ORDER BY w.name",
|
|
$wahl_id, $phase
|
|
));
|
|
} else {
|
|
$workshops_by_phase[$phase] = $wpdb->get_results($wpdb->prepare(
|
|
"SELECT w.* FROM {$wpdb->prefix}kc_workshops w
|
|
JOIN {$mapping_table} m ON w.id = m.workshop_id
|
|
WHERE m.wahl_id = %d
|
|
ORDER BY w.name",
|
|
$wahl_id
|
|
));
|
|
}
|
|
}
|
|
} else {
|
|
$all = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}kc_workshops ORDER BY name");
|
|
for ($phase = 1; $phase <= $phasen; $phase++) $workshops_by_phase[$phase] = $all;
|
|
}
|
|
|
|
// POST Verarbeitung
|
|
$error_message = null;
|
|
$success_redirect = false;
|
|
|
|
if($_SERVER['REQUEST_METHOD']=='POST' && isset($_POST['kc_workshop_submit'])) {
|
|
//$debug_output .= '<div style="background:lime;padding:10px;">POST WIRD VERARBEITET!</div>';
|
|
|
|
if(empty($_POST['vorname']) || empty($_POST['nachname'])) {
|
|
$error_message = 'Bitte Vor- und Nachname ausfüllen.';
|
|
} else {
|
|
$inserted_ids = [];
|
|
$vorname = sanitize_text_field($_POST['vorname']);
|
|
$nachname = sanitize_text_field($_POST['nachname']);
|
|
$norm_v = mb_strtolower(trim($vorname));
|
|
$norm_n = mb_strtolower(trim($nachname));
|
|
|
|
// Duplikatsprüfung
|
|
$exists = $wpdb->get_var($wpdb->prepare(
|
|
"SELECT COUNT(*) FROM {$wpdb->prefix}kc_teilnehmer WHERE LOWER(TRIM(vorname))=%s AND LOWER(TRIM(nachname))=%s AND wahl_id=%d",
|
|
$norm_v, $norm_n, $wahl_id
|
|
));
|
|
|
|
if ($exists && $exists > 0) {
|
|
$error_message = 'Diese Kombination aus Vorname und Nachname existiert bereits für diese Wahl.';
|
|
} else {
|
|
// Validierung und Insert
|
|
$validation_passed = true;
|
|
|
|
for ($phase = 1; $phase <= $phasen; $phase++) {
|
|
$allowed = array_map('intval', wp_list_pluck($workshops_by_phase[$phase] ?? [], 'id'));
|
|
$w1 = intval($_POST["phase{$phase}_wunsch1"] ?? 0);
|
|
$w2 = intval($_POST["phase{$phase}_wunsch2"] ?? 0);
|
|
$w3 = intval($_POST["phase{$phase}_wunsch3"] ?? 0);
|
|
|
|
if (empty($allowed) || !in_array($w1, $allowed, true) || !in_array($w2, $allowed, true) || !in_array($w3, $allowed, true)) {
|
|
$error_message = "Ungültige Workshop-Auswahl für Phase {$phase}.";
|
|
$validation_passed = false;
|
|
break;
|
|
}
|
|
// Ensure the three wishes in this phase are not duplicates
|
|
$selected = [$w1, $w2, $w3];
|
|
if (count(array_unique($selected)) !== count($selected)) {
|
|
$error_message = "Bitte wähle in Phase {$phase} drei verschiedene Workshops (keine Duplikate).";
|
|
$validation_passed = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($validation_passed) {
|
|
for ($phase = 1; $phase <= $phasen; $phase++) {
|
|
$w1 = intval($_POST["phase{$phase}_wunsch1"]);
|
|
$w2 = intval($_POST["phase{$phase}_wunsch2"]);
|
|
$w3 = intval($_POST["phase{$phase}_wunsch3"]);
|
|
|
|
$result = $wpdb->insert("{$wpdb->prefix}kc_teilnehmer", [
|
|
'vorname' => $vorname,
|
|
'nachname' => $nachname,
|
|
'wahl_id' => $wahl_id,
|
|
'phase' => $phase,
|
|
'wunsch1' => $w1,
|
|
'wunsch2' => $w2,
|
|
'wunsch3' => $w3,
|
|
'deleted' => 0
|
|
]);
|
|
|
|
if ($result === false) {
|
|
$error_message = 'Datenbankfehler: ' . $wpdb->last_error;
|
|
break;
|
|
} else {
|
|
$inserted_ids[] = intval($wpdb->insert_id);
|
|
}
|
|
}
|
|
|
|
if (empty($error_message)) {
|
|
// Cookie setzen
|
|
$cookie_name = 'kc_my_part_' . intval($wahl_id);
|
|
$existing = [];
|
|
if (!empty($_COOKIE[$cookie_name])) {
|
|
$dec = json_decode(stripslashes($_COOKIE[$cookie_name]), true);
|
|
if (is_array($dec)) $existing = array_map('intval', $dec);
|
|
}
|
|
$all_ids = array_values(array_unique(array_merge($existing, $inserted_ids)));
|
|
@setcookie($cookie_name, wp_json_encode($all_ids), time() + 30*24*3600, '/');
|
|
|
|
// Erfolg
|
|
$success_redirect = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ob_start();
|
|
?>
|
|
<style>
|
|
.kc-form-container {background:#f8fbe7; border-left:8px solid #b6d333; max-width:600px; margin:40px auto; padding:32px 28px; border-radius:14px; box-shadow:0 2px 8px #b6d33322;}
|
|
.kc-form-container h2 {margin-top:0; font-size:2em; font-weight:700;}
|
|
.kc-form-container label {font-weight:600;}
|
|
.kc-form-row {margin-bottom:20px;}
|
|
.kc-form-row input[type="text"], .kc-form-row select {
|
|
width:100%; padding:10px 12px; border-radius:7px; border:1.2px solid #aac484; background:#fafcf6; font-size:1.09em;
|
|
transition:border 0.17s;
|
|
}
|
|
.kc-form-row input[type="text"]:focus, .kc-form-row select:focus {border:1.8px solid #b6d333;}
|
|
.kc-form-row input[type="submit"] {
|
|
background:#326dd2; color:#fff; font-weight:600; font-size:1.15em;
|
|
padding:11px 30px; border:0; border-radius:8px; cursor:pointer; margin-top:5px; box-shadow:0 2px 6px #aac48422;
|
|
}
|
|
.kc-form-row input[type="submit"]:hover {background:#2559a2;}
|
|
.kc-required {color:#d82626; font-weight:bold;}
|
|
.kc-success-msg {color:#21952c; background:#e3f7e4; padding:16px 20px; border-radius:8px; font-weight:600; margin-bottom:15px; text-align:center;}
|
|
.kc-error-msg {color:#a80000; background:#ffeaea; padding:16px 20px; border-radius:8px; font-weight:600; margin-bottom:15px; text-align:center;}
|
|
@media (max-width: 700px) {.kc-form-container {padding:17px 7px;}}
|
|
</style>
|
|
|
|
<?php echo $debug_output; ?>
|
|
|
|
<div class="kc-form-container">
|
|
<h2><?= esc_html($wahl->name) ?></h2>
|
|
<?php if($wahl->beschreibung): ?>
|
|
<div style="margin-bottom:12px; color:#3b3b3b;"><?= nl2br(esc_html($wahl->beschreibung)) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($error_message): ?>
|
|
<div class="kc-error-msg"><?= esc_html($error_message) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($success_redirect): ?>
|
|
<div class="kc-success-msg">
|
|
Danke! Deine Wünsche wurden gespeichert.<br>
|
|
Erfolgreich eingefügte IDs: <?= implode(', ', $inserted_ids) ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<form method="post" autocomplete="off">
|
|
<input type="hidden" name="kc_workshop_submit" value="1">
|
|
<div class="kc-form-row">
|
|
<label>Vorname <span class="kc-required">*</span></label>
|
|
<input type="text" name="vorname" required>
|
|
</div>
|
|
<div class="kc-form-row">
|
|
<label>Nachname <span class="kc-required">*</span></label>
|
|
<input type="text" name="nachname" required>
|
|
</div>
|
|
<?php for($phase=1; $phase<=$phasen; $phase++): ?>
|
|
<div class="kc-form-row"><b>
|
|
<?php if($phasen>1): ?>Phase <?= $phase ?><?php endif; ?>
|
|
</b></div>
|
|
<?php for($w=1; $w<=3; $w++): ?>
|
|
<div class="kc-form-row">
|
|
<label>
|
|
<span style="font-weight:bold;color:#2355be;"><?= $phase ?>. Phase; <?= $w ?>. Wunsch</span> <span class="kc-required">*</span>
|
|
</label>
|
|
<select name="phase<?= $phase ?>_wunsch<?= $w ?>" required>
|
|
<option value="">Bitte wähle einen Workshop aus</option>
|
|
<?php foreach(($workshops_by_phase[$phase] ?? []) as $ws): ?>
|
|
<option value="<?= esc_attr($ws->id) ?>"><?= esc_html($ws->name) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<?php endfor; ?>
|
|
<script>
|
|
(function(){
|
|
// Disable already selected options within this phase and validate on submit
|
|
var phase = <?= json_encode($phase) ?>;
|
|
document.addEventListener('DOMContentLoaded', function(){
|
|
var selector = 'select[name^="phase' + phase + '_wunsch"]';
|
|
var selects = Array.prototype.slice.call(document.querySelectorAll(selector));
|
|
if (!selects.length) return;
|
|
function refresh(){
|
|
var values = selects.map(function(s){ return s.value; }).filter(function(v){ return v !== ''; });
|
|
selects.forEach(function(s){
|
|
Array.prototype.slice.call(s.options).forEach(function(opt){
|
|
if (opt.value === '') { opt.disabled = false; return; }
|
|
// disable option if selected in another select
|
|
var usedElsewhere = values.indexOf(opt.value) !== -1 && s.value !== opt.value;
|
|
opt.disabled = usedElsewhere;
|
|
});
|
|
});
|
|
}
|
|
selects.forEach(function(s){ s.addEventListener('change', refresh); });
|
|
// initial
|
|
refresh();
|
|
// Add submit-time validation to prevent duplicates (safety)
|
|
var form = selects[0] && selects[0].form;
|
|
if (form) {
|
|
form.addEventListener('submit', function(e){
|
|
var vals = selects.map(function(s){ return s.value; }).filter(function(v){ return v !== ''; });
|
|
var unique = vals.filter(function(v,i,a){ return a.indexOf(v) === i; });
|
|
if (vals.length !== unique.length) {
|
|
e.preventDefault();
|
|
alert('Bitte wähle in Phase ' + phase + ' drei verschiedene Workshops (keine Duplikate).');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
<?php endfor; ?>
|
|
<div class="kc-form-row">
|
|
<input type="submit" name="submit_finish" value="Senden" />
|
|
</div>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
return ob_get_clean();
|
|
});
|
|
|
|
// Shortcode: allow teamers to create a workshop after entering password
|
|
add_shortcode('konficastle_teamer_create', function($atts) {
|
|
global $wpdb;
|
|
$prefix = $wpdb->prefix;
|
|
$msg = '';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['kc_teamer_create_nonce'])) {
|
|
if (empty($_POST['kc_teamer_create_nonce']) || !wp_verify_nonce($_POST['kc_teamer_create_nonce'], 'kc_teamer_create_action')) {
|
|
$msg = '<div class="kc-error-msg">Ungültiger Request.</div>';
|
|
} else {
|
|
$pw = trim($_POST['kc_teamer_pw'] ?? '');
|
|
$saved_hash = get_option('kc_teamer_password_hash', '');
|
|
if (empty($saved_hash) || !wp_check_password($pw, $saved_hash)) {
|
|
$msg = '<div class="kc-error-msg">Falsches Passwort.</div>';
|
|
} else {
|
|
$vorname = sanitize_text_field($_POST['vorname'] ?? '');
|
|
$nachname = sanitize_text_field($_POST['nachname'] ?? '');
|
|
$ws_name = sanitize_text_field($_POST['workshop_name'] ?? '');
|
|
if ($vorname === '' || $nachname === '' || $ws_name === '') {
|
|
$msg = '<div class="kc-error-msg">Bitte alle Felder ausfüllen.</div>';
|
|
} else {
|
|
$existing = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$prefix}kc_teamer WHERE vorname=%s AND nachname=%s", $vorname, $nachname));
|
|
if ($existing) {
|
|
$tid = intval($existing->id);
|
|
} else {
|
|
$wpdb->insert("{$prefix}kc_teamer", ['vorname'=>$vorname,'nachname'=>$nachname]);
|
|
$tid = intval($wpdb->insert_id);
|
|
}
|
|
$min_t = max(0, intval($_POST['min_teilnehmer'] ?? 0));
|
|
$max_t = max(1, intval($_POST['max_teilnehmer'] ?? 10));
|
|
if ($min_t > $max_t) {
|
|
$msg = '<div class="kc-error-msg">Die minimale Teilnehmerzahl darf nicht größer als die maximale sein.</div>';
|
|
} else {
|
|
$col = $wpdb->get_var("SHOW COLUMNS FROM {$prefix}kc_workshops LIKE 'min_teilnehmer'");
|
|
if (empty($col)) {
|
|
$wpdb->query("ALTER TABLE {$prefix}kc_workshops ADD COLUMN min_teilnehmer INT NOT NULL DEFAULT 0");
|
|
}
|
|
$wpdb->insert("{$prefix}kc_workshops", ['name'=>$ws_name, 'beschreibung'=>'', 'max_teilnehmer'=>$max_t, 'min_teilnehmer'=>$min_t]);
|
|
$wid = intval($wpdb->insert_id);
|
|
|
|
if ($wid) {
|
|
$wpdb->insert("{$prefix}kc_workshop_teamer", ['workshop_id'=>$wid, 'teamer_id'=>$tid]);
|
|
$msg = '<div class="kc-success-msg">Workshop angelegt und Teamer zugeordnet.</div>';
|
|
} else {
|
|
$msg = '<div class="kc-error-msg">Fehler beim Anlegen des Workshops.</div>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ob_start();
|
|
$nonce = wp_create_nonce('kc_teamer_create_action');
|
|
?>
|
|
<div class="kc-form-container">
|
|
<h2>Teamer: Workshop erstellen</h2>
|
|
<?php echo $msg; ?>
|
|
<form method="post">
|
|
<input type="hidden" name="kc_teamer_create_nonce" value="<?= esc_attr($nonce) ?>">
|
|
<div class="kc-form-row">
|
|
<label>Passwort</label>
|
|
<input type="password" name="kc_teamer_pw" required />
|
|
</div>
|
|
<div class="kc-form-row">
|
|
<label>Vorname</label>
|
|
<input type="text" name="vorname" required />
|
|
</div>
|
|
<div class="kc-form-row">
|
|
<label>Nachname</label>
|
|
<input type="text" name="nachname" required />
|
|
</div>
|
|
<div class="kc-form-row">
|
|
<label>Workshop-Name</label>
|
|
<input type="text" name="workshop_name" required />
|
|
</div>
|
|
<div class="kc-form-row" style="display:flex;gap:8px;">
|
|
<div style="flex:1"><label>Min. Teilnehmer</label><input type="number" name="min_teilnehmer" value="0" required /></div>
|
|
<div style="flex:1"><label>Max. Teilnehmer</label><input type="number" name="max_teilnehmer" value="10" required /></div>
|
|
</div>
|
|
<div class="kc-form-row">
|
|
<input type="submit" value="Erstellen" />
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
return ob_get_clean();
|
|
});
|