web - refactor core modules, harden authorization, simplify endpoints

This commit is contained in:
2026-08-29 11:15:54 +02:00
parent e1109a07ef
commit 79d857d686
71 changed files with 8269 additions and 9119 deletions
@@ -1,79 +0,0 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/ini/database.php");
// Eingaben
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// Pflichtfelder
if ($last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern (robust gegen +49/Leerzeichen)
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') {
$phone = null; // phone darf NULL sein (laut Tabelle)
}
// WICHTIG: diese Spalten sind NOT NULL in deiner Tabelle -> niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = ''; // pr_bezirk ist NOT NULL (varchar)
$sql = "INSERT INTO seelsorge_besuchsstellen
(last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw
]);
$newId = $pdo->lastInsertId();
echo json_encode(['status' => 'success', 'besuch_id' => $newId], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
@@ -4,6 +4,7 @@
?>
<?php
require_once('util/seelsorge_helpers.php');
require_once('util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
@@ -16,9 +17,3 @@
</div>
<?php include "content/calendar_help.php"; ?>
<?php
// Profiloverlay für Kalenderbereich
$isPageCalendar = true;
include "content/profile.php";
?>
@@ -1,98 +1,113 @@
<?php
/* Name: content/calendar_day.php
Beschreibung: AJAX-Endpoint: Liefert Inhalt fuer das Tages-Modal
Aufgerufen per fetch() aus seelsorge.js */
/* AJAX-Fragment für Tagesdetails und Änderungen der eigenen Verfügbarkeit. */
// CWD auf seelsorge/ setzen (Connector nutzt relative Pfade wie data/)
chdir(dirname(__DIR__));
require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/initialise.php';
require_once __DIR__ . '/../util/seelsorge_helpers.php';
require_once __DIR__ . '/../util/connector_feiertage.php';
require_once __DIR__ . '/../util/connector_kalendertage.php';
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
$selectedDate = trim((string) ($_POST['date'] ?? $_GET['date'] ?? ''));
$dateObject = DateTime::createFromFormat('!Y-m-d', $selectedDate);
if (!$dateObject || $dateObject->format('Y-m-d') !== $selectedDate) {
http_response_code(400);
exit('Ungültiges Datum.');
}
if (isset($_POST['calendarDate'])):
$p_selectedDate = $_POST['calendarDate'];
$action = trim((string) ($_POST['action'] ?? 'view'));
if (!in_array($action, ['view', 'toggle'], true)) {
http_response_code(400);
exit('Ungültige Aktion.');
}
require_once($g_projectsPath . 'seelsorge/util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
require_once($g_projectsPath . 'seelsorge/util/connector_kalendertage.php');
$connector_kalendertage = lib_Kalendertage_Connector::getInstance();
// Tagesinformationen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_selectedDate);
$p_calendarWeekdayName = $connector_kalendertage->get_KalenderWochentag($p_selectedDate);
$p_dayNumber = date("j", strtotime($p_selectedDate));
$p_year = date("Y", strtotime($p_selectedDate));
$p_kw = date("W", strtotime($p_selectedDate));
$feiertagsname = $connector_feiertage->get_feiertagsname($p_selectedDate);
$p_dateTitle = $p_calendarWeekdayName . ", " . $p_dayNumber . ". " . $p_calendarMonthName . " " . $p_year;
// Verfuegbare Diakon*innen laden
$sql = "SELECT u.*, p.\"DiakonIn\" FROM user_general_information u
LEFT JOIN user_permissions p ON u.user_id = p.user_id
ORDER BY RANDOM()";
$result = $pdo->query($sql);
$availableUsers = [];
$allRows = $result->fetchAll();
if (count($allRows) > 0) {
foreach($allRows as $row) {
$userId = $row['user_id'];
$name = $row['first_name'] . " " . $row['last_name'];
if ($row['first_name'] != null && $row['last_name'] != null && $row['DiakonIn'] == 1) {
$stmt_av = $pdo->prepare("SELECT * FROM verfuegbarkeiten WHERE user_id = ? AND datum = ?");
$stmt_av->execute([$userId, $p_selectedDate]);
if ($stmt_av->rowCount() > 0) {
$availableUsers[$userId] = $name;
}
}
}
if ($action === 'toggle') {
try {
seelsorge_verify_csrf($_POST);
} catch (InvalidArgumentException $e) {
http_response_code(400);
exit($e->getMessage());
}
if ($selectedDate < date('Y-m-d')) {
http_response_code(400);
exit('Vergangene Tage können nicht geändert werden.');
}
try {
$nowAvailable = seelsorge_toggle_availability($pdo, $selectedDate, (int) $_SESSION['user_id']);
} catch (Throwable $e) {
error_log('Seelsorge availability toggle failed: ' . $e->getMessage());
http_response_code(500);
exit('Verfügbarkeit konnte nicht geändert werden.');
}
}
// Pruefe ob aktueller User eingetragen ist
$stmt_self = $pdo->prepare("SELECT COUNT(*) AS count FROM verfuegbarkeiten WHERE datum=? AND user_id=?");
$stmt_self->execute([$p_selectedDate, $_SESSION["user_id"]]);
$selfResult = $stmt_self->fetch();
$selfAvailable = $selfResult['count'] > 0;
$holidayConnector = lib_Feiertage_Connector::getInstance();
$calendarConnector = lib_Kalendertage_Connector::getInstance();
$weekdayName = $calendarConnector->get_KalenderWochentag($selectedDate);
$monthName = $calendarConnector->get_KalenderMonatsname($selectedDate);
$dateTitle = sprintf('%s, %d. %s %s', $weekdayName, (int) $dateObject->format('j'), $monthName, $dateObject->format('Y'));
$holidayName = $holidayConnector->get_feiertagsname($selectedDate);
// JSON-Metadaten fuer JS
echo '<script type="application/json" id="modal-meta">';
echo json_encode([
'title' => $p_dateTitle,
'kw' => $p_kw,
'feiertag' => $feiertagsname,
'selfAvailable' => $selfAvailable,
'date' => $p_selectedDate
], JSON_UNESCAPED_UNICODE);
echo '</script>';
try {
$stmt = $pdo->prepare(
'SELECT v.user_id, u.first_name, u.last_name, u.mail AS email, COALESCE(p."DiakonIn", 0) AS "DiakonIn"
FROM verfuegbarkeiten v
LEFT JOIN user_general_information u ON u.user_id = v.user_id
LEFT JOIN user_permissions p ON p.user_id = v.user_id
WHERE v.datum = ?
ORDER BY RANDOM()'
);
$stmt->execute([$selectedDate]);
$availabilityRows = $stmt->fetchAll();
} catch (Throwable $e) {
error_log('Seelsorge calendar day load failed: ' . $e->getMessage());
http_response_code(500);
exit('Tagesdaten konnten nicht geladen werden.');
}
$selfAvailable = false;
$availableUsers = [];
foreach ($availabilityRows as $row) {
$userId = (int) $row['user_id'];
if ($userId === (int) $_SESSION['user_id']) {
$selfAvailable = true;
}
if ((int) $row['DiakonIn'] === 1 && !empty($row['first_name']) && !empty($row['last_name'])) {
$availableUsers[$userId] = trim($row['first_name'] . ' ' . $row['last_name']);
}
}
if ($action === 'toggle' && !empty($nowAvailable) && count($availabilityRows) > 1) {
try {
seelsorge_notify_match_by_mail($availabilityRows, $dateObject);
} catch (Throwable $e) {
error_log('Seelsorge match notification failed: ' . $e->getMessage());
}
}
?>
<script type="application/json" id="modal-meta"><?= json_encode([
'title' => $dateTitle,
'kw' => $dateObject->format('W'),
'feiertag' => $holidayName,
'selfAvailable' => $selfAvailable,
'date' => $selectedDate,
'availCount' => count($availabilityRows),
], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?></script>
<!-- Tagesinformationen -->
<?php if ($holidayName): ?>
<div class="seelsorge-modal-section">
<?php if ($feiertagsname): ?>
<div class="seelsorge-modal-field">
<div class="seelsorge-modal-field-label">Feiertag</div>
<div class="seelsorge-modal-field-value"><?= htmlspecialchars($feiertagsname) ?></div>
<div class="seelsorge-modal-field-value"><?= htmlspecialchars($holidayName) ?></div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- Verfuegbare Diakon*innen -->
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Verf&uuml;gbare Personen</div>
<?php if (count($availableUsers) > 0): ?>
<?php if ($availableUsers): ?>
<div class="diakon-grid" id="modal-galery">
<?php foreach ($availableUsers as $userId => $name):
$profileImg = glob($_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/profile_pictures/' . $userId . '-*.jpg');
if (!empty($profileImg)) {
usort($profileImg, function($a, $b) { return filemtime($b) - filemtime($a); });
$imgPath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $profileImg[0]);
} else {
$imgPath = '/intranet_repo/general_files/profile_pictures/default.jpg';
}
?>
<div class="diakon-card" onclick="openCalendarProfile(<?= (int)$userId ?>)" title="Profil anzeigen">
<img class="diakon-card-img" src="<?= htmlspecialchars($imgPath) ?>" alt="<?= htmlspecialchars($name) ?>">
<?php foreach ($availableUsers as $userId => $name): ?>
<div class="diakon-card" onclick="openCalendarProfile(<?= $userId ?>)" title="Profil anzeigen">
<img class="diakon-card-img" src="<?= htmlspecialchars(seelsorge_profile_image_url($userId)) ?>" alt="<?= htmlspecialchars($name) ?>">
<div class="diakon-card-info">
<div class="diakon-card-name"><?= htmlspecialchars($name) ?></div>
<div class="diakon-card-role">Verfügbar</div>
@@ -108,17 +123,11 @@ if (isset($_POST['calendarDate'])):
<?php endif; ?>
</div>
<!-- Eintragen / Austragen -->
<div class="seelsorge-modal-actions">
<button type="button"
class="seelsorge-action-button <?= $selfAvailable ? 'seelsorge-remove-button' : 'seelsorge-add-button' ?>"
id="modal-toggle-btn"
onclick="toggleAvailabilityModal('<?= $p_selectedDate ?>')">
onclick="toggleAvailabilityModal('<?= $selectedDate ?>')">
<?= $selfAvailable ? 'Verf&uuml;gbarkeit entfernen' : 'Als verf&uuml;gbar eintragen' ?>
</button>
</div>
<?php
$pdo = null;
endif;
?>
@@ -1,138 +0,0 @@
<?php /* Name: content/calendar_edit.php
Beschreibung: Kalenderblatt zum Bearbeiten der Verfügbarkeit des jeweiligen Users
Aufgerufen über calendar.php
*/
?>
<div class="calendar_title_modus">Bearbeitung der eigenen Verfügbarkeit</div>
<div id="toggleViewEdit" class="button tooltip borderradius_round" onclick="toggleViewEdit()">
<?php display_button('calendar', null, 'right'); ?>
<span class="tooltiptext">Kalender anzeigen</span>
</div>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
// Startdatum und Stile festlegen
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
// Monatsnamen und Titel holen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
// Kalenderkopf ausgeben
?>
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_edit_header_<?= $t ?>">
<div class="arrow_item" onclick="switchCalendarEdit('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="arrow_item" onclick="switchCalendarEdit('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
</div>
<?php
}
?>
<div class="calendar_content">
<table>
<thead>
<tr>
<th class="calendar_head">MO</th>
<th class="calendar_head">DI</th>
<th class="calendar_head">MI</th>
<th class="calendar_head">DO</th>
<th class="calendar_head">FR</th>
<th class="calendar_head_sat">SA</th>
<th class="calendar_head_sun">SO</th>
</tr>
</thead>
<tbody>
<?php
for ($c = 1; $c <= 2; $c++) { // Zwei Monatsansichten laden
$p_startDate = $c === 1 ? date("Y-m-d", strtotime("first day of this month")) : date("Y-m-d", strtotime("first day of next month"));
$p_endDate = $c === 1 ? date("Y-m-d", strtotime("last day of this month")) : date("Y-m-d", strtotime("last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
// Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$wochennr = (int)date("W o", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum); // Nur Berlin
$feiertagsname = $connector_feiertage->get_feiertagsname($datum); // (alle Bundesländer)
if ($i % 7 === 0) { // Beginn der Tabellenzeile
echo "<tr name='calendar_edit_$c' style='$p_style'>";
}
// Sichtbarkeit
if ($datum < date("Y-m-d")) { // vor Heute - nicht anklickbar
echo "<td class='calendar_day_area' style='filter:brightness(60%);opacity:0.3;'>";
echo "<div class='calendar_day'>$tag</div>";
} elseif ($datum < $p_startDate || $datum > $p_endDate) { // außerhalb des Monats
echo "<td class='calendar_day_area' style='filter:brightness(100%);opacity:0.5;'>";
echo "<div class='calendar_day'>$tag</div>";
} else {
echo "<td class='calendar_day_area'>";
echo "<div class='calendar_day'>";
// Verfügbarkeit des Users nur für zukünftige Tage
$sql = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=? and user_id=?";
$stmt = $pdo->prepare($sql);
if ($stmt) {
$stmt->execute([$datum, $_SESSION["user_id"]]);
$row = $stmt->fetch();
if ($row) {
$count = $row['count'];
} else {
echo "Error retrieving result";
}
} else {
echo "Error preparing statement";
}
// Falls das Datum heute oder in der Zukunft liegt
$Id_cDayItem = "id='calendar_day_item'";
if ($count > 0) { // User ist schon eingetragen
echo "<div $Id_cDayItem class='calendar_day_item availableday editmode' title='Verfügbar' onclick='toggleAvailability(\"$datum\", this)'>";
} else { // User ist noch nicht eingetragen
echo "<div $Id_cDayItem class='calendar_day_item normalday editmode' onclick='toggleAvailability(\"$datum\", this)'>";
}
echo $tag;
if ($feiertagsname != null) {
echo "<div class='feiertagsname'>$feiertagsname</div>";
}
echo "</div>"; // END: calendar_day
}
echo "</td>"; // END: calendar_day_area
if ($i % 7 === 6) { // Ende der Tabellenzeile
echo "</tr>";
}
// Reset der Variablen
$feiertagsname = null;
}
} // Schleifenende: Zwei Monatsansichten laden
?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
@@ -59,7 +59,7 @@
<div class="seelsorge-section-title">Benachrichtigungen</div>
<p style="font-size:0.9em;line-height:1.6;color:#374151;margin:0;">
Sobald sich zwei oder mehr Personen am selben Tag eintragen, werden alle
Beteiligten automatisch per SMS und E-Mail benachrichtigt.
Beteiligten automatisch per E-Mail benachrichtigt.
</p>
</div>
</div>
@@ -1,139 +1,115 @@
<?php /* Name: content/calendar_view.php
Beschreibung: Kalenderblatt mit Übersicht und Interaktion per Modal
Aufgerufen über calendar.php */
?>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
?>
/* Kalenderblatt mit Übersicht und Interaktion per Modal. */
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_header_<?= $t ?>">
$today = date('Y-m-d');
$monthStarts = [
1 => date('Y-m-d', strtotime('first day of this month')),
2 => date('Y-m-d', strtotime('first day of next month')),
];
$monthEnds = [
1 => date('Y-m-d', strtotime('last day of this month')),
2 => date('Y-m-d', strtotime('last day of next month')),
];
$calendarStarts = [
1 => $connector_kalendertage->get_KalenderStart($monthStarts[1]),
2 => $connector_kalendertage->get_KalenderStart($monthStarts[2]),
];
$availabilityEnd = date('Y-m-d', strtotime($calendarStarts[2] . ' +41 days'));
$availability = seelsorge_calendar_availability_map($pdo, $calendarStarts[1], $availabilityEnd, (int) $_SESSION['user_id']);
for ($month = 1; $month <= 2; $month++):
$startDate = $monthStarts[$month];
$isFirst = $month === 1;
$title = $connector_kalendertage->get_KalenderMonatsname($startDate) . ' ' . date('Y', strtotime($startDate));
?>
<div class="calendar_header" style="display:<?= $isFirst ? 'flex' : 'none' ?>" id="calendar_header_<?= $month ?>">
<div class="arrow_item" onclick="switchCalendar('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<div class="<?= $isFirst ? 'arrow_light' : 'arrow_dark' ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="calendar_title"><?= htmlspecialchars($title) ?></div>
<div class="arrow_item" onclick="switchCalendar('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<div class="<?= $isFirst ? 'arrow_dark' : 'arrow_light' ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
<button class="calendar-help-btn" onclick="openCalendarHelp()" aria-label="Hilfe" title="Hilfe">?</button>
</div>
<?php } ?>
<?php endfor; ?>
<div class="calendar_content">
<table>
<thead>
<tr>
<td class="calendar_head">MO</td>
<td class="calendar_head">DI</td>
<td class="calendar_head">MI</td>
<td class="calendar_head">DO</td>
<td class="calendar_head">FR</td>
<td class="calendar_head_sat">SA</td>
<td class="calendar_head_sun">SO</td>
</tr>
</thead>
<thead><tr>
<td class="calendar_head">MO</td><td class="calendar_head">DI</td><td class="calendar_head">MI</td>
<td class="calendar_head">DO</td><td class="calendar_head">FR</td>
<td class="calendar_head_sat">SA</td><td class="calendar_head_sun">SO</td>
</tr></thead>
<tbody>
<?php for ($calendar = 1; $calendar <= 2; $calendar++):
$startDate = $monthStarts[$calendar];
$endDate = $monthEnds[$calendar];
$calendarStart = $calendarStarts[$calendar];
$rowStyle = $calendar === 1 ? 'visibility:visible' : 'visibility:collapse';
<?php
// Zwei Monatsansichten laden
for ($c = 1; $c <= 2; $c++) {
$p_startDate = date("Y-m-d", strtotime($c === 1 ? "first day of this month" : "first day of next month"));
$p_endDate = date("Y-m-d", strtotime($c === 1 ? "last day of this month" : "last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
for ($i = 0; $i < 42; $i++):
$date = date('Y-m-d', strtotime($calendarStart . " +{$i} days"));
$day = date('j', strtotime($date));
$weekday = (int) date('w', strtotime($date));
$isBerlinHoliday = $connector_feiertage->isFeiertagInBerlin($date);
$holidayName = $connector_feiertage->get_feiertagsname($date);
$dayAvailability = $availability[$date] ?? ['count' => 0, 'self' => false];
$count = $dayAvailability['count'];
$userAvailable = $dayAvailability['self'];
//Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum);
$feiertagsname = $connector_feiertage->get_feiertagsname($datum);
if ($i % 7 === 0): ?>
<tr name="calendar_<?= $calendar ?>" style="<?= $rowStyle ?>">
<?php endif;
if ($i % 7 === 0) echo "<tr name='calendar_$c' style='$p_style'>";
$class = 'calendar_day_area';
$style = '';
if ($datum < $p_startDate || $datum > $p_endDate) {
$style = 'filter:brightness(100%);opacity:0.5;';
}
echo "<td class='$class' style='$style'><div class='calendar_day'>";
$Id_cDayItem = $datum >= date("Y-m-d") ? 'id="calendar_day_item" onclick="openDayModal(\'' . $datum . '\')"' : '';
$sql_count = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=?";
$stmt_count = $pdo->prepare($sql_count);
$count = 0;
if ($stmt_count) {
$stmt_count->execute([$datum]);
$row_count = $stmt_count->fetch();
if ($row_count) {
$count = $row_count['count'];
} else {
echo "Fehler beim Abrufen des Ergebnisses";
}
} else {
echo "Fehler beim Vorbereiten der Anweisung";
}
$sql_user_check = "SELECT user_id FROM verfuegbarkeiten WHERE datum=? AND user_id=?";
$stmt_user_check = $pdo->prepare($sql_user_check);
$userAvailable = false;
if ($stmt_user_check) {
$stmt_user_check->execute([$datum, $_SESSION["user_id"]]);
if ($stmt_user_check->fetch()) {
$userAvailable = true;
}
}
$class = 'calendar_day_item';
$outsideMonth = $date < $startDate || $date > $endDate;
$classes = ['calendar_day_item'];
$title = '';
if ($datum < date("Y-m-d")) {
$class .= ' past';
} elseif ($count >= 2 && $datum >= date("Y-m-d")) {
$class .= ' available_multiple';
$title = $userAvailable ? "It&acute;s a Match!" : "$count Personen verfügbar";
} elseif ($count == 1 && $datum >= date("Y-m-d")) {
$class .= ' available_single';
$title = 'Eine Person verfügbar';
} elseif ($datum == date("Y-m-d")) {
$class .= ' today';
$title = 'Heute';
} elseif ($isFeiertagInBerlin) {
$class .= ' sunday';
} elseif ($feiertagsname != null) {
$class .= ' localholiday';
$title = 'Regionaler Feiertag';
} elseif ($wochentag == 0) {
$class .= ' sunday';
} elseif ($wochentag == 6) {
$class .= ' saturday';
if ($date < $today) {
$emptyClass = 'past';
} elseif ($date === $today) {
$emptyClass = 'today';
} elseif ($isBerlinHoliday) {
$emptyClass = 'sunday';
} elseif ($holidayName !== null) {
$emptyClass = 'localholiday';
} elseif ($weekday === 0) {
$emptyClass = 'sunday';
} elseif ($weekday === 6) {
$emptyClass = 'saturday';
} else {
$class .= ' normalday';
$emptyClass = 'normalday';
}
echo "<div $Id_cDayItem class='$class' title='$title'>$tag</div>";
// Feiertagsbezeichnungen im Kalenderblatt ausgeblendet
echo "</div></td>";
if ($i % 7 === 6) echo "</tr>";
}
}
//Schleifenende: Zwei Monatsansichten laden
?>
if ($date < $today) {
$classes[] = 'past';
} elseif ($count >= 2) {
$classes[] = 'available_multiple';
$title = $userAvailable ? "It's a Match!" : "{$count} Personen verfügbar";
} elseif ($count === 1) {
$classes[] = 'available_single';
$title = 'Eine Person verfügbar';
} else {
$classes[] = $emptyClass;
if ($emptyClass === 'today') $title = 'Heute';
if ($emptyClass === 'localholiday') $title = 'Regionaler Feiertag';
}
?>
<td class="calendar_day_area"<?= $outsideMonth ? ' style="filter:brightness(100%);opacity:0.5;"' : '' ?>>
<div class="calendar_day">
<div class="<?= implode(' ', $classes) ?>"
<?= $date >= $today ? 'data-calendar-date="' . $date . '" data-empty-class="' . $emptyClass . '" onclick="openDayModal(\'' . $date . '\')"' : '' ?>
title="<?= htmlspecialchars($title, ENT_QUOTES) ?>"><?= $day ?></div>
</div>
</td>
<?php if ($i % 7 === 6): ?></tr><?php endif; ?>
<?php endfor;
endfor; ?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
</table>
</div>
@@ -1,28 +0,0 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
header('Content-Type: application/json; charset=utf-8');
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.']);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
try {
$stmt = $pdo->prepare("DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
echo json_encode(['status' => 'success']);
} catch (PDOException $e) {
echo json_encode(['status' => 'error', 'message' => 'Löschen fehlgeschlagen: ' . $e->getMessage()]);
}
@@ -1,161 +0,0 @@
<?php
/* Name: manage_visits.php
Beschreibung: Verwaltung der Seelsorge-Besuchsstellen
- Hinzufügen, Bearbeiten und Löschen von Einträgen
*/
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
// Eintrag hinzufügen
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['add_entry'])) {
$last_name = $_POST['last_name'];
$first_name = $_POST['first_name'];
$birth_date = $_POST['birth_date'];
$address_street = $_POST['address_street'];
$address_plz = $_POST['address_plz'];
$address_link = $_POST['address_link'];
$phone = $_POST['phone'];
$comment = $_POST['comment'];
$letzter_besuch = $_POST['letzter_besuch'];
$priority = $_POST['priority'];
$pr_bezirk = $_POST['pr_bezirk'];
$reservation = $_POST['reservation'];
$sql = "INSERT INTO seelsorge_besuchsstellen (last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$last_name, $first_name, $birth_date, $address_street, $address_plz, $address_link, $phone, $comment, $letzter_besuch, $priority, $pr_bezirk, $reservation])) {
echo "Neuer Eintrag hinzugefügt.";
} else {
echo "Fehler: " . implode(', ', $stmt->errorInfo());
}
}
// Eintrag löschen
if (isset($_GET['delete_id'])) {
$delete_id = $_GET['delete_id'];
$sql = "DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$delete_id])) {
echo "Eintrag gelöscht.";
} else {
echo "Fehler beim Löschen des Eintrags: " . implode(', ', $stmt->errorInfo());
}
}
// Daten abrufen
$sql = "SELECT * FROM seelsorge_besuchsstellen";
$result = $pdo->query($sql);
?>
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
<script src="/intranet_repo/projects/_central/scripts/seelsorge.js"></script>
<link rel="stylesheet" href="/intranet_repo/projects/_central/layouts/seelsorge.css">
</head>
<body class="theme-purple">
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
<div class="header_title ht_pastoral text_white" id="header_title">
<span class="header_title_text">Besuchsstellen Verwaltung</span>
</div>
<h1>Seelsorge Besuchsstellen Verwaltung</h1>
<!-- Formular zum Hinzufügen eines neuen Eintrags -->
<h2>Neuen Eintrag hinzufügen</h2>
<form method="POST" action="">
<label>Nachname:</label>
<input type="text" name="last_name" required><br>
<label>Vorname:</label>
<input type="text" name="first_name" required><br>
<label>Geburtsdatum:</label>
<input type="date" name="birth_date" required><br>
<label>Straße:</label>
<input type="text" name="address_street" required><br>
<label>PLZ:</label>
<input type="text" name="address_plz" required><br>
<label>Link zur Adresse:</label>
<input type="text" name="address_link"><br>
<label>Telefonnummer:</label>
<input type="number" name="phone"><br>
<label>Kommentar:</label>
<input type="text" name="comment"><br>
<label>Letzter Besuch:</label>
<input type="date" name="letzter_besuch"><br>
<label>Priorität:</label>
<input type="number" name="priority" required><br>
<label>Bezirk:</label>
<input type="text" name="pr_bezirk"><br>
<label>Reservierung:</label>
<input type="number" name="reservation"><br>
<input type="submit" name="add_entry" value="Eintrag hinzufügen">
</form>
<!-- Tabelle der vorhandenen Einträge -->
<h2>Vorhandene Einträge</h2>
<table border="1">
<tr>
<th>ID</th>
<th>Nachname</th>
<th>Vorname</th>
<th>Geburtsdatum</th>
<th>Adresse</th>
<th>PLZ</th>
<th>Link zur Adresse</th>
<th>Telefonnummer</th>
<th>Kommentar</th>
<th>Letzter Besuch</th>
<th>Priorität</th>
<th>Bezirk</th>
<th>Reservierung</th>
<th>Aktionen</th>
</tr>
<?php while ($row = $result->fetch()) { ?>
<tr>
<td><?php echo $row['besuch_id']; ?></td>
<td><?php echo $row['last_name']; ?></td>
<td><?php echo $row['first_name']; ?></td>
<td><?php echo $row['birth_date']; ?></td>
<td><?php echo $row['address_street']; ?></td>
<td><?php echo $row['address_plz']; ?></td>
<td><?php echo $row['address_link']; ?></td>
<td><?php echo $row['phone']; ?></td>
<td><?php echo $row['comment']; ?></td>
<td><?php echo $row['letzter_besuch']; ?></td>
<td><?php echo $row['priority']; ?></td>
<td><?php echo $row['pr_bezirk']; ?></td>
<td><?php echo $row['reservation']; ?></td>
<td>
<a href="manage_visits.php?delete_id=<?php echo $row['besuch_id']; ?>" onclick="return confirm('Eintrag wirklich löschen?');">Löschen</a>
</td>
</tr>
<?php } ?>
</table>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
</body>
</html>
<?php
$pdo = null;
?>
@@ -1,13 +0,0 @@
<?php /* Name: menue.php
Beschreibung: Seitenmenü des Seelsorgeplaners */
?>
<div class="menue" id="seelsorge">
<div class="list">
<div class="menu-item unselectable active" data-target="content_calendar">Kalendarium</div>
<div class="menu-item unselectable" data-target="content_visit">Besuchsstellen</div>
<div class="indicator" id="indicator"></div>
</div>
</div>
@@ -1,33 +0,0 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = $_GET['besuch_id'];
// SQL query to update priority to 2
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET priority = 2 WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
if ($stmt->rowCount() >= 0) {
// Berechne die Monate seit dem letzten Besuch, um sie in der Antwort zurückzugeben
$stmtQ = $pdo->prepare("SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor($row['days_since_last_visit'] / 30);
// Gib die aktualisierten Daten als JSON zurück
echo json_encode([
'status' => 'success',
'priority' => 2,
'months_since_last_visit' => $monthsSinceLastVisit
]);
} else {
// Fehlerbehandlung
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Priorität"
]);
}
$pdo = null;
?>
@@ -1,38 +1,62 @@
<?php
/*
Name: content/profile.php
Beschreibung: Popup innerhalb von Kalendertag bzw. Besuchsstellen: Profilanzeige
Zur Verwendung ist die nachfolgende Unterscheidung zu treffen/erweitern
*/
/* Profil-Overlay für Kalender und Besuchsstellen. */
require_once dirname(__DIR__) . '/util/seelsorge_helpers.php';
// Unterscheidung zwischen den aufrufenden Seitenbereichen
// --> Name ist außerdem beim Aufruf der JS-Funktion openCloseProfile(id, name, overlay) zu bilden!
// --> Bei einem neuen Seitenbereich ist zusätzlich der Listener (Escape-Taste) zu erweitern!
// --> In overlay_profile.php wird bei Escape-Taste bzw. Klick auf Exit mit id=0 sowie den entsprechenden name und overlay weggeblendet!
if (($isPageVisit ?? false) === true) {
$profile_container_name = "profile_visit";
$profile_overlay_id = "profile_visit_overlay";
$isPageVisit = false;
} elseif (($isPageCalendar ?? false) === true) {
$profile_container_name = "profile_calendar";
$profile_overlay_id = "profile_calendar_overlay";
$isPageCalendar = false;
}
$profile_container_name = 'profile_seelsorge';
$profile_overlay_id = 'profile_seelsorge_overlay';
// Statement für alle Profile vorbereiten
$stmt_all_profiles = $pdo->prepare("SELECT * FROM user_general_information");
$stmt_all_profiles->execute();
$profileRecords = seelsorge_profile_records($pdo);
?>
<div class="standard_overlay" id="<?= $profile_overlay_id ?>"> <!-- Overlay: Profile -->
<div class="bg_blur"></div>
<?php
while ($profile_all = $stmt_all_profiles->fetch()) {
?>
<div class="profile_container" name="<?= $profile_container_name ?>" id="<?= $profile_all['user_id'] ?>">
<?php $_SESSION["profile_id"] = $profile_all['user_id'];
include $g_phpSnippetsPath. "overlay_profile.php"; ?>
</div>
<?php } ?>
</div>
<div class="standard_overlay" id="<?= $profile_overlay_id ?>">
<div class="bg_blur"></div>
<?php foreach ($profileRecords as $record):
$partner = $record['user'];
$userId = (int) $partner['user_id'];
$fullName = trim(($partner['first_name'] ?? '') . ' ' . ($partner['last_name'] ?? ''));
$isRegistered = !empty($partner['first_name']);
$groups = $record['permissions'];
?>
<div class="profile_container" name="<?= $profile_container_name ?>" id="<?= $userId ?>">
<div class="profile-modal-card">
<button type="button" class="exit" aria-label="Schließen" onclick="openCloseProfile(0, '<?= $profile_container_name ?>', '<?= $profile_overlay_id ?>');">×</button>
<div class="profile-modal-hero">
<img class="profile-modal-img" src="<?= htmlspecialchars($record['image']) ?>" alt="Profilbild">
<div>
<?php if ($isRegistered): ?>
<div class="profile-modal-title"><?= htmlspecialchars($fullName) ?></div>
<?php else: ?>
<div class="profile-modal-title" style="color:rgba(255,255,255,0.7);">Nicht registriert</div>
<?php endif; ?>
<div class="profile-modal-subtitle">
<span><?= htmlspecialchars($partner['mail'] ?? '') ?></span>
</div>
</div>
</div>
<div class="profile-modal-body">
<?php if (!empty($partner['phone'])): ?>
<div class="profile-modal-field">
<div class="profile-modal-field-label">Telefon</div>
<div class="profile-modal-field-value">
<a href="tel:0<?= htmlspecialchars($partner['phone']) ?>">0<?= htmlspecialchars($partner['phone']) ?></a>
</div>
</div>
<?php endif; ?>
<?php $activeGroups = array_filter($groups, static fn($value, $key) => $key !== 'user_id' && (int) $value === 1, ARRAY_FILTER_USE_BOTH); ?>
<?php if ($activeGroups): ?>
<div class="profile-modal-field">
<div class="profile-modal-field-label">Gruppen</div>
<div class="profile-modal-chips">
<?php foreach (array_keys($activeGroups) as $groupName): ?>
<span class="profile-modal-chip"><?= htmlspecialchars($groupName) ?></span>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
@@ -1,48 +0,0 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Reservation für alle im Haushalt entfernen
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = NULL WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode(['status' => 'success', 'household_ids' => $householdIds]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Entfernen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -1,56 +0,0 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Hole die ID des aktuell angemeldeten Benutzers aus der Session
$user_id = $_SESSION['user_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Alle Personen im Haushalt reservieren
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = ? WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$user_id, $current['address_street'], $current['address_plz']])) {
// Alle betroffenen IDs zurückgeben
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'reservation_user_id' => $user_id,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -1,24 +0,0 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Überprüfen, ob die erforderlichen Parameter übergeben wurden
if (isset($_GET['besuch_id']) && isset($_GET['comment'])) {
$besuch_id = $_GET['besuch_id'];
$comment = $_GET['comment'];
// SQL-Update-Statement vorbereiten und ausführen
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET comment = ? WHERE besuch_id = ?");
if ($stmt->execute([$comment, $besuch_id])) {
// Erfolgreich aktualisiert
echo "Hinweis erfolgreich aktualisiert";
} else {
// Fehler beim Aktualisieren
echo "Fehler beim Aktualisieren des Hinweises";
}
} else {
// Fehler: Fehlende Parameter
echo "Fehler: Nicht alle erforderlichen Parameter wurden übergeben";
}
$pdo = null;
?>
@@ -1,57 +0,0 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = (int)($_GET['besuch_id'] ?? 0);
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
// Adresse der aktuellen Besuchsstelle laden
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if (!$current) {
echo json_encode(['status' => 'error', 'message' => 'Eintrag nicht gefunden.']);
exit;
}
// Alle Personen im gleichen Haushalt (gleiche Adresse) aktualisieren
$sql = "UPDATE seelsorge_besuchsstellen SET letzter_besuch = CURRENT_DATE, priority = 0 WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
// Monate seit letztem Besuch berechnen (für den angefragten Eintrag)
$query = "SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmtQ = $pdo->prepare($query);
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor(($row['days_since_last_visit'] ?? 0) / 30);
// Alle IDs im Haushalt zurückgeben für Frontend-Aktualisierung
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'last_visit' => date('Y-m-d'),
'months_since_last_visit' => $monthsSinceLastVisit,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Aktualisieren des Besuchsdatums"
]);
}
$pdo = null;
?>
@@ -1,132 +0,0 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// einfache Validierung
if ($besuch_id <= 0 || $last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') $phone = null; // phone darf NULL sein
// NOT NULL Spalten: niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = '';
// Alten Eintrag laden, um Änderungen zu erkennen
$stmtOld = $pdo->prepare("SELECT last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtOld->execute([$besuch_id]);
$oldEntry = $stmtOld->fetch();
$sql = "UPDATE seelsorge_besuchsstellen
SET last_name = ?, first_name = ?, birth_date = ?, address_street = ?, address_plz = ?,
address_link = ?, phone = ?, comment = ?, letzter_besuch = ?, priority = ?, pr_bezirk = ?
WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw,
$besuch_id
]);
// Vermerk in erledigte Tasks wenn sich irgendein Feld geändert hat
if ($oldEntry) {
$newValues = [
'last_name' => $last_name,
'first_name' => $first_name,
'birth_date' => $birth_date,
'address_street' => $address_street,
'address_plz' => $address_plz,
'address_link' => $address_link,
'phone' => $phone,
'comment' => $comment,
'letzter_besuch' => $letzter_besuch,
'priority' => $priority,
'pr_bezirk' => $pr_bezirk_raw,
];
$fieldLabels = [
'last_name' => 'Nachname',
'first_name' => 'Vorname',
'birth_date' => 'Geburtsdatum',
'address_street' => 'Adresse',
'address_plz' => 'PLZ/Ort',
'address_link' => 'Karten-Link',
'phone' => 'Telefon',
'comment' => 'Kommentar',
'letzter_besuch' => 'Letzter Besuch',
'priority' => 'Priorität',
'pr_bezirk' => 'Priester-Bezirk',
];
$changedFields = [];
foreach ($newValues as $key => $newVal) {
$oldVal = $oldEntry[$key] ?? '';
if ((string)$oldVal !== (string)$newVal) {
$changedFields[] = $fieldLabels[$key];
}
}
if (!empty($changedFields)) {
$personName = ($oldEntry['last_name'] ?? $last_name) . ", " . ($oldEntry['first_name'] ?? $first_name);
$changedList = implode(', ', $changedFields);
$taskSubject = "Besuchsstelle geändert: {$personName}";
$taskMessage = "Besuchsstelle #{$besuch_id} ({$personName}) wurde geändert. Geänderte Felder: {$changedList}.";
$senderName = "Seelsorgeplaner";
$stmtLog = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', ?, '', ?, ?, 'done', NOW(), NOW())");
$stmtLog->execute([$senderName, $taskSubject, $taskMessage]);
}
}
echo json_encode(['status' => 'success', 'besuch_id' => $besuch_id], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
File diff suppressed because it is too large Load Diff