Files
domili/verschiebung.php
Borgal 1b9ba22bb5 1.3.0
2025-11-16 21:13:04 +01:00

445 lines
22 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
define('APP_URL', 'https://domili.borgal.de');
// 🔒 Testmodus: true = nur User-ID 1, false = alle Benutzer
$test_mode = false;
function load_reschedule_data($conn, $meeting_id, $user_id)
{
$stmt = mysqli_prepare($conn, "
SELECT p.id, p.meeting_id, p.proposed_by_user_id, p.proposed_date, p.reason, p.created_at,
u.username as proposer_name
FROM meeting_reschedule_proposals p
LEFT JOIN users u ON p.proposed_by_user_id = u.id
WHERE p.meeting_id = ? AND p.status = 'pending'
ORDER BY p.created_at DESC
");
mysqli_stmt_bind_param($stmt, "i", $meeting_id);
mysqli_stmt_execute($stmt);
$active_proposals = mysqli_fetch_all(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC);
mysqli_stmt_close($stmt);
if (empty($active_proposals)) {
return ['active_proposals' => [], 'user_votes' => [], 'yes_voters' => [], 'no_voters' => []];
}
$proposal_ids = array_column($active_proposals, 'id');
$ids_list = implode(',', array_map('intval', $proposal_ids));
$vote_stmt = mysqli_prepare($conn, "SELECT proposal_id, user_id, vote FROM meeting_reschedule_votes WHERE proposal_id IN ($ids_list)");
mysqli_stmt_execute($vote_stmt);
$votes = mysqli_fetch_all(mysqli_stmt_get_result($vote_stmt), MYSQLI_ASSOC);
mysqli_stmt_close($vote_stmt);
$user_ids = array_unique(array_column($votes, 'user_id'));
$user_names = [];
if (!empty($user_ids)) {
$user_ids_list = implode(',', array_map('intval', $user_ids));
$user_stmt = mysqli_prepare($conn, "SELECT id, username FROM users WHERE id IN ($user_ids_list)");
mysqli_stmt_execute($user_stmt);
$users = mysqli_fetch_all(mysqli_stmt_get_result($user_stmt), MYSQLI_ASSOC);
mysqli_stmt_close($user_stmt);
foreach ($users as $u) {
$user_names[$u['id']] = htmlspecialchars($u['username']);
}
}
$user_votes = [];
$yes_voters = array_fill_keys($proposal_ids, []);
$no_voters = array_fill_keys($proposal_ids, []);
foreach ($votes as $v) {
if ($v['user_id'] == $user_id) {
$user_votes[$v['proposal_id']] = $v['vote'];
}
$username = $user_names[$v['user_id']] ?? 'Unbekannt';
if ($v['vote'] === 'yes') {
$yes_voters[$v['proposal_id']][] = $username;
} elseif ($v['vote'] === 'no') {
$no_voters[$v['proposal_id']][] = $username;
}
}
foreach ($active_proposals as &$p) {
$p['yes_votes'] = count($yes_voters[$p['id']] ?? []);
$p['no_votes'] = count($no_voters[$p['id']] ?? []);
}
return compact('active_proposals', 'user_votes', 'yes_voters', 'no_voters');
}
function handle_reschedule_actions($conn, $meeting_id, $user_id)
{
global $test_mode;
// Vorschlag einreichen
if (isset($_POST['propose_reschedule']) && isset($_POST['new_date']) && isset($_POST['reason'])) {
$new_date = $_POST['new_date'];
$reason = $_POST['reason'];
$check = mysqli_prepare($conn, "SELECT id FROM meeting_reschedule_proposals WHERE meeting_id = ? AND proposed_by_user_id = ? AND status = 'pending'");
mysqli_stmt_bind_param($check, "ii", $meeting_id, $user_id);
mysqli_stmt_execute($check);
$exists = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
mysqli_stmt_close($check);
if ($exists) {
$_SESSION['error_message'] = "Du hast bereits einen Verschiebungsvorschlag eingereicht.";
return;
}
$ins = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_proposals (meeting_id, proposed_by_user_id, proposed_date, reason) VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($ins, "iiss", $meeting_id, $user_id, $new_date, $reason);
mysqli_stmt_execute($ins);
$proposal_id = mysqli_insert_id($conn);
mysqli_stmt_close($ins);
// 🔥 Automatisch "Ja"-Stimme für den Ersteller
$auto_vote = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_votes (proposal_id, user_id, vote) VALUES (?, ?, 'yes')");
mysqli_stmt_bind_param($auto_vote, "ii", $proposal_id, $user_id);
mysqli_stmt_execute($auto_vote);
mysqli_stmt_close($auto_vote);
// ✉️ E-Mail bei Vorschlag
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
$mail->CharSet = 'UTF-8';
$orig_date = null;
$orig_stmt = mysqli_prepare($conn, "SELECT meeting_date FROM meetings WHERE id = ?");
mysqli_stmt_bind_param($orig_stmt, "i", $meeting_id);
mysqli_stmt_execute($orig_stmt);
$orig_row = mysqli_fetch_assoc(mysqli_stmt_get_result($orig_stmt));
mysqli_stmt_close($orig_stmt);
$orig_str = $orig_row ? date('d.m.Y', strtotime($orig_row['meeting_date'])) : 'einem Termin';
try {
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = SMTP_ENCRYPTION;
$mail->Port = SMTP_PORT;
$mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME);
$proposer = $_SESSION['username'] ?? 'Ein Benutzer';
$new_fmt = date('d.m.Y H:i', strtotime($new_date));
// 🔒 Empfängerliste Testmodus?
if ($test_mode) {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE id = 1 AND email IS NOT NULL AND email != ''");
} else {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
}
while ($u = mysqli_fetch_assoc($users_stmt)) {
// Überspringe den eigenen Vorschlag aber im Testmodus ggf. auskommentieren
if (isset($_SESSION['email']) && $u['email'] === $_SESSION['email']) continue;
$mail_body_html = '
<div style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', Arial, sans-serif; line-height: 1.6; color: #333; max-width: 700px; margin: 0 auto; padding: 20px; background: #f8f9fa;">
<div style="background: white; padding: 24px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.08);">
<h3 style="color: #0d6efd; margin-top: 0;">Neuer Terminvorschlag</h3>
<p>Hallo <strong>' . htmlspecialchars($u['username']) . '</strong>,</p>
<div style="background: #f0f7ff; border-left: 4px solid #0d6efd; padding: 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
<p><strong>' . htmlspecialchars($proposer) . '</strong> hat einen neuen Vorschlag zur Verschiebung des Termins eingereicht.</p>
<p><strong>Neuer vorgeschlagener Termin:</strong><br>
' . htmlspecialchars($new_fmt) . '</p>
<p><strong>Grund:</strong><br>
' . htmlspecialchars($reason) . '</p>
</div>
<p>Bitte stimme erneut ab, ob du teilnehmen möchtest.</p>
<p><a href="' . APP_URL . '/index.php" style="display: inline-block; background: #0d6efd; color: white; text-decoration: none; padding: 8px 16px; border-radius: 4px; font-weight: 500;">Zur Abstimmung</a></p>
<p style="margin-top: 24px; padding-top: 16px; border-top: 1px solid #eee; color: #6c757d; font-size: 0.875rem;">
Dein DoMiLi-Team
</p>
</div>
</div>';
$mail->isHTML(true);
$mail->addAddress($u['email']);
$mail->Subject = "DoMiLi: Neuer Terminvorschlag für den ursprünglichen Termin vom $orig_str";
$mail->Body = $mail_body_html;
$mail->AltBody = "Hallo " . $u['username'] . ",\n\n" . $proposer . " hat einen neuen Vorschlag zur Verschiebung eingereicht.\nNeuer Termin: " . $new_fmt . "\nGrund: " . $reason . "\n\nZur Abstimmung: " . APP_URL . "/index.php\n\nDein DoMiLi-Team";
$mail->send();
$mail->clearAddresses();
}
$_SESSION['success_message'] = "Vorschlag eingereicht! Alle Benutzer wurden benachrichtigt.";
} catch (Exception $e) {
$_SESSION['error_message'] = "Fehler beim Senden der E-Mails.";
error_log("PHPMailer Error: " . $mail->ErrorInfo);
}
} else {
$_SESSION['success_message'] = "Vorschlag eingereicht! (E-Mail nicht verfügbar)";
}
return;
}
// Abstimmen
if (isset($_POST['vote_proposal']) && isset($_POST['proposal_id'])) {
$pid = intval($_POST['proposal_id']);
$vote = $_POST['vote_proposal'];
if (!in_array($vote, ['yes', 'no', 'maybe'])) return;
$check = mysqli_prepare($conn, "SELECT id FROM meeting_reschedule_votes WHERE proposal_id = ? AND user_id = ?");
mysqli_stmt_bind_param($check, "ii", $pid, $user_id);
mysqli_stmt_execute($check);
$existing = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
mysqli_stmt_close($check);
if ($existing) {
$upd = mysqli_prepare($conn, "UPDATE meeting_reschedule_votes SET vote = ? WHERE id = ?");
mysqli_stmt_bind_param($upd, "si", $vote, $existing['id']);
mysqli_stmt_execute($upd);
mysqli_stmt_close($upd);
} else {
$ins = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_votes (proposal_id, user_id, vote) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($ins, "iis", $pid, $user_id, $vote);
mysqli_stmt_execute($ins);
mysqli_stmt_close($ins);
}
return;
}
// Löschen (nur Ersteller)
if (isset($_POST['delete_proposal']) && isset($_POST['proposal_id'])) {
$pid = intval($_POST['proposal_id']);
$check = mysqli_prepare($conn, "SELECT proposed_by_user_id FROM meeting_reschedule_proposals WHERE id = ? AND meeting_id = ?");
mysqli_stmt_bind_param($check, "ii", $pid, $meeting_id);
mysqli_stmt_execute($check);
$owner = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
mysqli_stmt_close($check);
if ($owner && $owner['proposed_by_user_id'] == $user_id) {
mysqli_query($conn, "DELETE FROM meeting_reschedule_votes WHERE proposal_id = $pid");
mysqli_query($conn, "DELETE FROM meeting_reschedule_proposals WHERE id = $pid");
}
return;
}
// Bearbeiten (nur Ersteller)
if (isset($_POST['edit_proposal']) && isset($_POST['proposal_id']) && isset($_POST['new_date']) && isset($_POST['reason'])) {
$pid = intval($_POST['proposal_id']);
$new_date = $_POST['new_date'];
$reason = $_POST['reason'];
$check = mysqli_prepare($conn, "SELECT proposed_by_user_id FROM meeting_reschedule_proposals WHERE id = ? AND meeting_id = ?");
mysqli_stmt_bind_param($check, "ii", $pid, $meeting_id);
mysqli_stmt_execute($check);
$owner = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
mysqli_stmt_close($check);
if ($owner && $owner['proposed_by_user_id'] == $user_id) {
mysqli_query($conn, "DELETE FROM meeting_reschedule_votes WHERE proposal_id = $pid");
$upd = mysqli_prepare($conn, "UPDATE meeting_reschedule_proposals SET proposed_date = ?, reason = ? WHERE id = ?");
mysqli_stmt_bind_param($upd, "ssi", $new_date, $reason, $pid);
mysqli_stmt_execute($upd);
mysqli_stmt_close($upd);
}
return;
}
// Admin: Vorschlag annehmen → MEETING AKTUALISIEREN + E-MAIL
if (isset($_SESSION['role']) && $_SESSION['role'] === 'admin') {
if (isset($_POST['accept_proposal']) && isset($_POST['proposal_id'])) {
$proposal_id = intval($_POST['proposal_id']);
$proposal_stmt = mysqli_prepare($conn, "
SELECT p.proposed_date, p.reason, p.meeting_id,
m.meeting_date AS original_date
FROM meeting_reschedule_proposals p
JOIN meetings m ON p.meeting_id = m.id
WHERE p.id = ?
");
mysqli_stmt_bind_param($proposal_stmt, "i", $proposal_id);
mysqli_stmt_execute($proposal_stmt);
$proposal = mysqli_fetch_assoc(mysqli_stmt_get_result($proposal_stmt));
mysqli_stmt_close($proposal_stmt);
if ($proposal) {
$new_date = $proposal['proposed_date'];
$new_reason = $proposal['reason'];
$meeting_id = $proposal['meeting_id'];
$original_date = $proposal['original_date'];
// Meeting aktualisieren ACHTUNG: nur meeting_date, kein reason hier
$update_meeting = mysqli_prepare($conn, "
UPDATE meetings
SET meeting_date = ?
WHERE id = ?
");
mysqli_stmt_bind_param($update_meeting, "si", $new_date, $meeting_id);
mysqli_stmt_execute($update_meeting);
mysqli_stmt_close($update_meeting);
// Vorschlag akzeptieren
$accept_stmt = mysqli_prepare($conn, "
UPDATE meeting_reschedule_proposals
SET status = 'accepted'
WHERE id = ?
");
mysqli_stmt_bind_param($accept_stmt, "i", $proposal_id);
mysqli_stmt_execute($accept_stmt);
mysqli_stmt_close($accept_stmt);
// Andere ablehnen
$reject_others = mysqli_prepare($conn, "
UPDATE meeting_reschedule_proposals
SET status = 'rejected'
WHERE meeting_id = ? AND id != ?
");
mysqli_stmt_bind_param($reject_others, "ii", $meeting_id, $proposal_id);
mysqli_stmt_execute($reject_others);
mysqli_stmt_close($reject_others);
// ✉️ E-Mail nach Akzeptanz
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
$mail->CharSet = 'UTF-8';
try {
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = SMTP_ENCRYPTION;
$mail->Port = SMTP_PORT;
$mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME);
$orig_fmt = date('d.m.Y H:i', strtotime($original_date));
$new_fmt = date('d.m.Y H:i', strtotime($new_date));
if ($test_mode) {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE id = 1 AND email IS NOT NULL AND email != ''");
} else {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
}
while ($u = mysqli_fetch_assoc($users_stmt)) {
$mail_body_html = '
<div style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', Arial, sans-serif; line-height: 1.6; color: #333; max-width: 700px; margin: 0 auto; padding: 20px; background: #f8f9fa;">
<div style="background: white; padding: 24px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.08);">
<h3 style="color: #0d6efd; margin-top: 0;">Termin wurde verschoben!</h3>
<p>Hallo <strong>' . htmlspecialchars($u['username']) . '</strong>,</p>
<div style="background: #f0f7ff; border-left: 4px solid #0d6efd; padding: 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
<p>Der Termin wurde vom Admin verschoben.</p>
<p><strong>Ursprünglicher Termin:</strong><br>
' . htmlspecialchars($orig_fmt) . '</p>
<p><strong>Neuer Termin:</strong><br>
' . htmlspecialchars($new_fmt) . '</p>
<p><strong>Grund:</strong><br>
' . htmlspecialchars($new_reason) . '</p>
</div>
<p>Bitte stimme erneut ab, ob du teilnehmen möchtest.</p>
<p><a href="' . APP_URL . '/index.php" style="display: inline-block; background: #0d6efd; color: white; text-decoration: none; padding: 8px 16px; border-radius: 4px; font-weight: 500;">Zur Abstimmung</a></p>
<p style="margin-top: 24px; padding-top: 16px; border-top: 1px solid #eee; color: #6c757d; font-size: 0.875rem;">
Dein DoMiLi-Team
</p>
</div>
</div>';
$mail->isHTML(true);
$mail->addAddress($u['email']);
$mail->Subject = "DoMiLi: Termin wurde verschoben!";
$mail->Body = $mail_body_html;
$mail->AltBody = "Hallo " . $u['username'] . ",\n\nDer Termin wurde verschoben.\nUrsprünglich: " . $orig_fmt . "\nNeu: " . $new_fmt . "\nGrund: " . $new_reason . "\n\nZur Abstimmung: " . APP_URL . "/index.php\n\nDein DoMiLi-Team";
$mail->send();
$mail->clearAddresses();
}
} catch (Exception $e) {
error_log("Fehler bei Akzeptanz-E-Mail: " . $mail->ErrorInfo);
}
}
}
header("Location: index.php");
exit;
}
// Admin: Vorschlag ablehnen → MIT KURZER E-MAIL
if (isset($_POST['reject_proposal']) && isset($_POST['proposal_id'])) {
$proposal_id = intval($_POST['proposal_id']);
$proposal_stmt = mysqli_prepare($conn, "
SELECT p.proposed_by_user_id, u.username AS proposer_name,
m.meeting_date AS original_date
FROM meeting_reschedule_proposals p
JOIN users u ON p.proposed_by_user_id = u.id
JOIN meetings m ON p.meeting_id = m.id
WHERE p.id = ?
");
mysqli_stmt_bind_param($proposal_stmt, "i", $proposal_id);
mysqli_stmt_execute($proposal_stmt);
$proposal = mysqli_fetch_assoc(mysqli_stmt_get_result($proposal_stmt));
mysqli_stmt_close($proposal_stmt);
$reject_stmt = mysqli_prepare($conn, "
UPDATE meeting_reschedule_proposals
SET status = 'rejected'
WHERE id = ?
");
mysqli_stmt_bind_param($reject_stmt, "i", $proposal_id);
mysqli_stmt_execute($reject_stmt);
mysqli_stmt_close($reject_stmt);
// ✉️ Kurze E-Mail nach Ablehnung
if ($proposal && file_exists(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
$mail->CharSet = 'UTF-8';
try {
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = SMTP_ENCRYPTION;
$mail->Port = SMTP_PORT;
$mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME);
$proposer = $proposal['proposer_name'];
$original_fmt = date('d.m.Y H:i', strtotime($proposal['original_date']));
if ($test_mode) {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE id = 1 AND email IS NOT NULL AND email != ''");
} else {
$users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
}
while ($u = mysqli_fetch_assoc($users_stmt)) {
$mail_body_html = '
<div style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', Arial, sans-serif; line-height: 1.6; color: #333; max-width: 700px; margin: 0 auto; padding: 20px; background: #f8f9fa;">
<div style="background: white; padding: 24px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.08);">
<h3 style="color: #dc3545; margin-top: 0;">Verschiebungsvorschlag abgelehnt</h3>
<p>Hallo <strong>' . htmlspecialchars($u['username']) . '</strong>,</p>
<div style="background: #fff5f5; border-left: 4px solid #dc3545; padding: 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
<p>Der Verschiebungsvorschlag von <strong>' . htmlspecialchars($proposer) . '</strong> wurde vom Admin abgelehnt.</p>
<p>Der Termin bleibt daher unverändert beim ursprünglichen Termin am <strong>' . htmlspecialchars($original_fmt) . '</strong>.</p>
</div>
<p style="margin-top: 24px; padding-top: 16px; border-top: 1px solid #eee; color: #6c757d; font-size: 0.875rem;">
Dein DoMiLi-Team
</p>
</div>
</div>';
$mail->isHTML(true);
$mail->addAddress($u['email']);
$mail->Subject = "DoMiLi: Verschiebungsvorschlag abgelehnt";
$mail->Body = $mail_body_html;
$mail->AltBody = "Hallo " . $u['username'] . ",\n\nDer Verschiebungsvorschlag von " . $proposer . " wurde abgelehnt.\nDer Termin bleibt beim ursprünglichen Termin am " . $original_fmt . ".\n\nDein DoMiLi-Team";
$mail->send();
$mail->clearAddresses();
}
} catch (Exception $e) {
error_log("Fehler bei Ablehnungs-E-Mail: " . $mail->ErrorInfo);
}
}
header("Location: index.php");
exit;
}
}
}