web - refactor core modules, harden authorization, simplify endpoints
This commit is contained in:
@@ -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ü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ügbarkeit entfernen' : 'Als verfü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´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
@@ -4,6 +4,36 @@
|
||||
|
||||
// Initialisierung
|
||||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
|
||||
require_once __DIR__ . '/util/seelsorge_helpers.php';
|
||||
|
||||
$seelsorgeCsrfToken = seelsorge_csrf_token();
|
||||
$activeTab = ($_GET['tab'] ?? '') === 'visit' ? 'visit' : 'calendar';
|
||||
$visitFormError = $_SESSION['seelsorge_visit_form_error'] ?? null;
|
||||
unset($_SESSION['seelsorge_visit_form_error']);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['visit_command'])) {
|
||||
$isVisitSave = $_POST['visit_command'] === 'save';
|
||||
$submittedVisitForm = $isVisitSave ? array_diff_key($_POST, ['visit_command' => true, 'csrf_token' => true]) : null;
|
||||
|
||||
try {
|
||||
seelsorge_verify_csrf($_POST);
|
||||
seelsorge_process_visit_command($pdo, $_POST, (int) $_SESSION['user_id']);
|
||||
} catch (InvalidArgumentException | RuntimeException $e) {
|
||||
$_SESSION['seelsorge_visit_form_error'] = [
|
||||
'message' => $e->getMessage(),
|
||||
'form' => $submittedVisitForm,
|
||||
];
|
||||
} catch (Throwable $e) {
|
||||
error_log('Seelsorge visit command failed: ' . $e->getMessage());
|
||||
$_SESSION['seelsorge_visit_form_error'] = [
|
||||
'message' => 'Aktion fehlgeschlagen.',
|
||||
'form' => $submittedVisitForm,
|
||||
];
|
||||
}
|
||||
|
||||
header('Location: /intranet_repo/projects/seelsorge/seelsorge.php?tab=visit', true, 303);
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" dir="ltr">
|
||||
@@ -27,15 +57,15 @@
|
||||
|
||||
<div class="content" id="fullsize">
|
||||
<div class="content-tab-bar" id="seelsorge-tabs">
|
||||
<div class="content-tab-bar__item active" data-target="content_calendar">Kalendarium</div>
|
||||
<div class="content-tab-bar__item" data-target="content_visit">Besuchsstellen</div>
|
||||
<div class="content-tab-bar__item<?= $activeTab === 'calendar' ? ' active' : '' ?>" data-target="content_calendar">Kalendarium</div>
|
||||
<div class="content-tab-bar__item<?= $activeTab === 'visit' ? ' active' : '' ?>" data-target="content_visit">Besuchsstellen</div>
|
||||
</div>
|
||||
<div class="content_seelsorge active" id="content_calendar">
|
||||
<div class="content_seelsorge<?= $activeTab === 'calendar' ? ' active' : '' ?>" id="content_calendar">
|
||||
<?php // Kalendarium:
|
||||
include 'content/calendar.php'; ?>
|
||||
</div>
|
||||
|
||||
<div class="content_seelsorge" id="content_visit">
|
||||
<div class="content_seelsorge<?= $activeTab === 'visit' ? ' active' : '' ?>" id="content_visit">
|
||||
|
||||
<?php // Besuchsstellen:
|
||||
include 'content/visit.php'; ?>
|
||||
@@ -61,6 +91,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include __DIR__ . '/content/profile.php'; ?>
|
||||
|
||||
<script type="application/json" id="seelsorge-config"><?= json_encode([
|
||||
'csrfToken' => $seelsorgeCsrfToken,
|
||||
], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?></script>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
/* Name: toggle_availability.php
|
||||
Beschreibung: Verfuegbarkeit eintragen/entfernen (AJAX-Endpoint)
|
||||
Liefert JSON-Response, sendet SMS+Mail bei Match */
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION["user_id"]) || !isset($_POST["date"])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['ok' => false, 'error' => 'Fehlende Parameter']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$date = $_POST["date"];
|
||||
$formattedDate = date("d.m.Y", strtotime($date));
|
||||
$userId = (int) $_SESSION["user_id"];
|
||||
|
||||
$pdo = require($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/ini/database.php");
|
||||
|
||||
// Pruefen ob Verfuegbarkeit bereits besteht
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS count FROM verfuegbarkeiten WHERE datum = ? AND user_id = ?");
|
||||
$stmt->execute([$date, $userId]);
|
||||
$wasAvailable = $stmt->fetch()['count'] > 0;
|
||||
|
||||
// Eintragen oder Austragen
|
||||
if ($wasAvailable) {
|
||||
$stmt = $pdo->prepare("DELETE FROM verfuegbarkeiten WHERE datum = ? AND user_id = ?");
|
||||
} else {
|
||||
$stmt = $pdo->prepare("INSERT INTO verfuegbarkeiten (datum, user_id) VALUES (?, ?)");
|
||||
}
|
||||
|
||||
if (!$stmt->execute([$date, $userId])) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['ok' => false, 'error' => 'Datenbankfehler']);
|
||||
$pdo = null;
|
||||
exit;
|
||||
}
|
||||
|
||||
$nowAvailable = !$wasAvailable;
|
||||
$notifications = [];
|
||||
|
||||
// Bei neuem Eintrag: Match pruefen und benachrichtigen
|
||||
if ($nowAvailable) {
|
||||
// E-Mail-Spalte dynamisch ermitteln
|
||||
$emailCol = null;
|
||||
$emailCandidates = ['email', 'mail', 'email_address', 'e_mail', 'user_email'];
|
||||
$inList = "'" . implode("','", $emailCandidates) . "'";
|
||||
$res = $pdo->query("SELECT column_name FROM information_schema.columns WHERE table_name = 'user_general_information' AND column_name IN ($inList) LIMIT 1");
|
||||
if ($res && $r = $res->fetch()) { $emailCol = $r['column_name']; }
|
||||
|
||||
$emailSelect = $emailCol ? ", u.\"{$emailCol}\" AS email" : ", '' AS email";
|
||||
$sql = "SELECT u.user_id, u.first_name, u.last_name, u.phone{$emailSelect}
|
||||
FROM verfuegbarkeiten v
|
||||
JOIN user_general_information u ON v.user_id = u.user_id
|
||||
WHERE v.datum = ?";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$date]);
|
||||
|
||||
$matchUsers = $stmt->fetchAll();
|
||||
|
||||
if (count($matchUsers) > 1) {
|
||||
$nameList = implode(', ', array_map(fn($u) => trim($u['first_name'] . ' ' . $u['last_name']), $matchUsers));
|
||||
$smsText = mb_convert_encoding(
|
||||
"Intranet NAK Reinickendorf\n\nIt's a match!\n\n{$nameList} haben am {$formattedDate} fuer einen Seelsorgebesuch Zeit!",
|
||||
'UTF-8', 'auto'
|
||||
);
|
||||
|
||||
// SMS an alle Beteiligten
|
||||
foreach ($matchUsers as $u) {
|
||||
if (!empty($u['phone'])) {
|
||||
$smsData = json_encode([
|
||||
'phone' => '+49' . $u['phone'],
|
||||
'message' => $smsText
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
$ctx = stream_context_create(['http' => [
|
||||
'header' => "Content-Type: application/json; charset=utf-8",
|
||||
'method' => 'POST',
|
||||
'content' => $smsData,
|
||||
'timeout' => 5
|
||||
]]);
|
||||
@file_get_contents(rtrim(intranet_env('SMS_GATEWAY_URL'), '/') . '/send_sms', false, $ctx);
|
||||
$notifications[] = "SMS → " . $u['first_name'];
|
||||
}
|
||||
}
|
||||
|
||||
// E-Mail an alle Beteiligten
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php';
|
||||
$mailBetreff = "Seelsorge-Match am {$formattedDate}";
|
||||
$mailNachricht = "It's a match!\n\n{$nameList} haben am {$formattedDate} für einen Seelsorgebesuch Zeit.\n\nBitte stimmt euch untereinander ab.";
|
||||
$host = $_SERVER['HTTP_HOST'] ?? intranet_env('INTRANET_FQDN');
|
||||
$btnUrl = "https://{$host}/intranet_repo/projects/seelsorge/seelsorge.php";
|
||||
|
||||
foreach ($matchUsers as $u) {
|
||||
$email = trim($u['email'] ?? '');
|
||||
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
@send_intranet_mail($email, $mailBetreff, $mailNachricht, null, 'intranet@nak-reinickendorf.de', 'Zum Seelsorgeplaner', $btnUrl);
|
||||
$notifications[] = "Mail → " . $u['first_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aktuellen Count der verfuegbaren Diakon*innen fuer diesen Tag zurueckgeben
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) AS cnt FROM verfuegbarkeiten WHERE datum = ?");
|
||||
$stmt->execute([$date]);
|
||||
$availCount = $stmt->fetch()['cnt'];
|
||||
|
||||
$pdo = null;
|
||||
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
'nowAvailable' => $nowAvailable,
|
||||
'availCount' => (int) $availCount,
|
||||
'notifications' => $notifications
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
?>
|
||||
@@ -33,7 +33,7 @@ class lib_Feiertage_Connector
|
||||
return $wert === $datum;
|
||||
});
|
||||
|
||||
if ($filter !== null) {
|
||||
if (!empty($filter)) {
|
||||
|
||||
$feiertagsname = implode(" ",array_keys($filter));
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class lib_Feiertage_Connector
|
||||
if(isset(self::$cache['c0-'.$jahr]))
|
||||
return self::$cache['c0-'.$jahr];
|
||||
|
||||
$file = "data/feiertage_$jahr.json";
|
||||
$file = __DIR__ . "/../data/feiertage_$jahr.json";
|
||||
|
||||
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
|
||||
|
||||
@@ -63,7 +63,7 @@ class lib_Feiertage_Connector
|
||||
if(isset(self::$cache['c0-'.$jahr.$land]))
|
||||
return self::$cache['c0-'.$jahr.$land];
|
||||
|
||||
$file = "data/feiertage_" . $jahr . "_" . $land . ".json";
|
||||
$file = __DIR__ . "/../data/feiertage_" . $jahr . "_" . $land . ".json";
|
||||
|
||||
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
|
||||
|
||||
@@ -99,7 +99,7 @@ class lib_Feiertage_Connector
|
||||
if(isset(self::$cache['c1-'.$jahr]))
|
||||
return self::$cache['c1-'.$jahr];
|
||||
|
||||
$file = "data/ferientage_berlin_$jahr.json";
|
||||
$file = __DIR__ . "/../data/ferientage_berlin_$jahr.json";
|
||||
|
||||
if (!file_exists($file)) { //Ggf. Datei von externer API speichern
|
||||
|
||||
|
||||
@@ -0,0 +1,446 @@
|
||||
<?php
|
||||
/* Gemeinsame, seiteneffektarme Hilfsfunktionen des Seelsorgeplaners. */
|
||||
|
||||
if (!defined('SEELSORGE_INITIAL_VISIT_DATE')) {
|
||||
define('SEELSORGE_INITIAL_VISIT_DATE', '2024-07-11');
|
||||
}
|
||||
|
||||
function seelsorge_csrf_token(): string
|
||||
{
|
||||
if (empty($_SESSION['seelsorge_csrf'])) {
|
||||
$_SESSION['seelsorge_csrf'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
return (string) $_SESSION['seelsorge_csrf'];
|
||||
}
|
||||
|
||||
function seelsorge_verify_csrf(array $input): void
|
||||
{
|
||||
$postedToken = $input['csrf_token'] ?? '';
|
||||
$sessionToken = $_SESSION['seelsorge_csrf'] ?? '';
|
||||
if (!is_string($postedToken) || !is_string($sessionToken) || $sessionToken === '' || !hash_equals($sessionToken, $postedToken)) {
|
||||
throw new InvalidArgumentException('Ungültige Anfrage. Bitte laden Sie die Seite neu.');
|
||||
}
|
||||
}
|
||||
|
||||
function seelsorge_profile_image_url(int $userId): string
|
||||
{
|
||||
$default = '/intranet_repo/general_files/profile_pictures/default.jpg';
|
||||
if ($userId <= 0 || empty($_SERVER['DOCUMENT_ROOT'])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$images = glob($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/profile_pictures/{$userId}-*.jpg") ?: [];
|
||||
if (!$images) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
usort($images, static fn($a, $b) => filemtime($b) <=> filemtime($a));
|
||||
return str_replace($_SERVER['DOCUMENT_ROOT'], '', $images[0]);
|
||||
}
|
||||
|
||||
function seelsorge_load_priests(PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query(
|
||||
'SELECT u.user_id, u.first_name, u.last_name, u.mail AS email
|
||||
FROM user_general_information u
|
||||
JOIN user_permissions p ON p.user_id = u.user_id
|
||||
WHERE p."PriesterIn" = 1
|
||||
ORDER BY u.last_name ASC, u.first_name ASC'
|
||||
);
|
||||
|
||||
return $stmt ? $stmt->fetchAll() : [];
|
||||
}
|
||||
|
||||
function seelsorge_priest_options(array $priests): string
|
||||
{
|
||||
$options = [];
|
||||
foreach ($priests as $priest) {
|
||||
$userId = (int) ($priest['user_id'] ?? 0);
|
||||
$firstName = trim((string) ($priest['first_name'] ?? ''));
|
||||
$lastName = trim((string) ($priest['last_name'] ?? ''));
|
||||
$email = trim((string) ($priest['email'] ?? ''));
|
||||
|
||||
if ($firstName !== '' && $lastName !== '') {
|
||||
$label = $lastName . ', ' . $firstName;
|
||||
} elseif ($lastName !== '' || $firstName !== '') {
|
||||
$label = $lastName !== '' ? $lastName : $firstName;
|
||||
} else {
|
||||
$label = $email !== '' ? $email : "User #{$userId}";
|
||||
}
|
||||
|
||||
$options[] = sprintf(
|
||||
'<option value="%d">%s</option>',
|
||||
$userId,
|
||||
htmlspecialchars($label, ENT_QUOTES, 'UTF-8')
|
||||
);
|
||||
}
|
||||
|
||||
return implode('', $options);
|
||||
}
|
||||
|
||||
function seelsorge_parse_visit_entry(array $input): array
|
||||
{
|
||||
$priestId = trim((string) ($input['pr_bezirk'] ?? ''));
|
||||
$entry = [
|
||||
'besuch_id' => max(0, (int) ($input['besuch_id'] ?? 0)),
|
||||
'last_name' => trim((string) ($input['last_name'] ?? '')),
|
||||
'first_name' => trim((string) ($input['first_name'] ?? '')),
|
||||
'birth_date' => trim((string) ($input['birth_date'] ?? '')),
|
||||
'address_street' => trim((string) ($input['address_street'] ?? '')),
|
||||
'address_plz' => trim((string) ($input['address_plz'] ?? '')),
|
||||
'address_link' => trim((string) ($input['address_link'] ?? '')),
|
||||
'phone' => preg_replace('/\D+/', '', trim((string) ($input['phone'] ?? ''))) ?: null,
|
||||
'comment' => trim((string) ($input['comment'] ?? '')),
|
||||
'letzter_besuch' => trim((string) ($input['letzter_besuch'] ?? '')) ?: SEELSORGE_INITIAL_VISIT_DATE,
|
||||
'priority' => (int) ($input['priority'] ?? 0),
|
||||
'pr_bezirk' => ctype_digit($priestId) ? (int) $priestId : 0,
|
||||
];
|
||||
|
||||
if ($entry['last_name'] === '' || $entry['first_name'] === '' || $entry['address_street'] === ''
|
||||
|| $entry['address_plz'] === '' || $entry['address_link'] === '' || $entry['pr_bezirk'] <= 0) {
|
||||
throw new InvalidArgumentException('Pflichtfelder fehlen.');
|
||||
}
|
||||
|
||||
foreach (['birth_date', 'letzter_besuch'] as $field) {
|
||||
$date = DateTime::createFromFormat('!Y-m-d', $entry[$field]);
|
||||
if (!$date || $date->format('Y-m-d') !== $entry[$field]) {
|
||||
throw new InvalidArgumentException('Ungültiges Datum.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($entry['priority'] < 0 || $entry['priority'] > 2) {
|
||||
throw new InvalidArgumentException('Ungültige Priorität.');
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
function seelsorge_visit_entry_client_data(array $row): array
|
||||
{
|
||||
return [
|
||||
'besuch_id' => (int) ($row['besuch_id'] ?? 0),
|
||||
'last_name' => $row['last_name'] ?? '',
|
||||
'first_name' => $row['first_name'] ?? '',
|
||||
'birth_date' => $row['birth_date'] ?? '',
|
||||
'address_street' => $row['address_street'] ?? '',
|
||||
'address_plz' => $row['address_plz'] ?? '',
|
||||
'address_link' => $row['address_link'] ?? '',
|
||||
'phone' => $row['phone'] ?? '',
|
||||
'comment' => $row['comment'] ?? '',
|
||||
'letzter_besuch' => $row['letzter_besuch'] ?? '',
|
||||
'priority' => (int) ($row['priority'] ?? 0),
|
||||
'pr_bezirk' => $row['pr_bezirk'] === null ? '' : (int) $row['pr_bezirk'],
|
||||
'reservation' => $row['reservation'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
function seelsorge_changed_visit_fields(array $oldEntry, array $newEntry): array
|
||||
{
|
||||
$labels = [
|
||||
'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',
|
||||
];
|
||||
|
||||
$changed = [];
|
||||
foreach ($labels as $field => $label) {
|
||||
if ((string) ($oldEntry[$field] ?? '') !== (string) ($newEntry[$field] ?? '')) {
|
||||
$changed[] = $label;
|
||||
}
|
||||
}
|
||||
return $changed;
|
||||
}
|
||||
|
||||
function seelsorge_save_visit_entry(PDO $pdo, array $entry): void
|
||||
{
|
||||
$fields = [
|
||||
'last_name', 'first_name', 'birth_date', 'address_street', 'address_plz',
|
||||
'address_link', 'phone', 'comment', 'letzter_besuch', 'priority', 'pr_bezirk',
|
||||
];
|
||||
$values = array_map(static fn($field) => $entry[$field], $fields);
|
||||
$visitId = (int) $entry['besuch_id'];
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
if ($visitId === 0) {
|
||||
$stmt = $pdo->prepare(
|
||||
'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->execute($values);
|
||||
$pdo->commit();
|
||||
return;
|
||||
}
|
||||
|
||||
$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([$visitId]);
|
||||
$oldEntry = $stmtOld->fetch();
|
||||
if (!$oldEntry) {
|
||||
throw new RuntimeException('Eintrag nicht gefunden.');
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'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->execute(array_merge($values, [$visitId]));
|
||||
|
||||
$changedFields = seelsorge_changed_visit_fields($oldEntry, $entry);
|
||||
if ($changedFields) {
|
||||
$personName = ($oldEntry['last_name'] ?? $entry['last_name']) . ', ' . ($oldEntry['first_name'] ?? $entry['first_name']);
|
||||
$stmtLog = $pdo->prepare(
|
||||
"INSERT INTO admin_messages
|
||||
(type, sender_name, sender_email, subject, message, status, processed_at, created_at)
|
||||
VALUES ('system', 'Seelsorgeplaner', '', ?, ?, 'done', NOW(), NOW())"
|
||||
);
|
||||
$stmtLog->execute([
|
||||
"Besuchsstelle geändert: {$personName}",
|
||||
"Besuchsstelle #{$visitId} ({$personName}) wurde geändert. Geänderte Felder: " . implode(', ', $changedFields) . '.',
|
||||
]);
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
function seelsorge_visit_action(PDO $pdo, string $action, int $visitId, int $userId): void
|
||||
{
|
||||
if ($visitId <= 0) {
|
||||
throw new InvalidArgumentException('Ungültige Besuchs-ID.');
|
||||
}
|
||||
|
||||
if ($action === 'delete') {
|
||||
$stmt = $pdo->prepare('DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?');
|
||||
$stmt->execute([$visitId]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
throw new RuntimeException('Eintrag nicht gefunden.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'prioritize') {
|
||||
$stmt = $pdo->prepare('UPDATE seelsorge_besuchsstellen SET priority = 2 WHERE besuch_id = ?');
|
||||
$stmt->execute([$visitId]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
throw new RuntimeException('Eintrag nicht gefunden.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?');
|
||||
$stmt->execute([$visitId]);
|
||||
$address = $stmt->fetch();
|
||||
if (!$address) {
|
||||
throw new RuntimeException('Eintrag nicht gefunden.');
|
||||
}
|
||||
|
||||
$params = [];
|
||||
switch ($action) {
|
||||
case 'reserve':
|
||||
$sql = 'UPDATE seelsorge_besuchsstellen SET reservation = ? WHERE address_street = ? AND address_plz = ?';
|
||||
$params[] = $userId;
|
||||
break;
|
||||
case 'unreserve':
|
||||
$sql = 'UPDATE seelsorge_besuchsstellen SET reservation = NULL WHERE address_street = ? AND address_plz = ?';
|
||||
break;
|
||||
case 'complete':
|
||||
$sql = 'UPDATE seelsorge_besuchsstellen SET letzter_besuch = CURRENT_DATE, priority = 0, reservation = NULL WHERE address_street = ? AND address_plz = ?';
|
||||
break;
|
||||
case 'update_date':
|
||||
$sql = 'UPDATE seelsorge_besuchsstellen SET letzter_besuch = CURRENT_DATE, priority = 0 WHERE address_street = ? AND address_plz = ?';
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException('Unbekannte Aktion.');
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute(array_merge($params, [$address['address_street'], $address['address_plz']]));
|
||||
}
|
||||
|
||||
function seelsorge_process_visit_command(PDO $pdo, array $input, int $userId): void
|
||||
{
|
||||
$command = trim((string) ($input['visit_command'] ?? ''));
|
||||
if ($command === 'save') {
|
||||
seelsorge_save_visit_entry($pdo, seelsorge_parse_visit_entry($input));
|
||||
return;
|
||||
}
|
||||
|
||||
seelsorge_visit_action($pdo, $command, (int) ($input['besuch_id'] ?? 0), $userId);
|
||||
}
|
||||
|
||||
function seelsorge_toggle_availability(PDO $pdo, string $date, int $userId): bool
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'WITH deleted AS (
|
||||
DELETE FROM verfuegbarkeiten WHERE datum = ? AND user_id = ? RETURNING user_id
|
||||
)
|
||||
INSERT INTO verfuegbarkeiten (datum, user_id)
|
||||
SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM deleted)
|
||||
RETURNING user_id'
|
||||
);
|
||||
$stmt->execute([$date, $userId, $date, $userId]);
|
||||
return $stmt->fetchColumn() !== false;
|
||||
}
|
||||
|
||||
function seelsorge_notify_match_by_mail(array $users, DateTimeInterface $date): void
|
||||
{
|
||||
if (count($users) < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
$names = array_values(array_filter(array_map(
|
||||
static fn($user) => trim(($user['first_name'] ?? '') . ' ' . ($user['last_name'] ?? '')),
|
||||
$users
|
||||
)));
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php';
|
||||
|
||||
$formattedDate = $date->format('d.m.Y');
|
||||
$subject = "Seelsorge-Match am {$formattedDate}";
|
||||
$message = "It's a match!\n\n" . implode(', ', $names) . " haben am {$formattedDate} für einen Seelsorgebesuch Zeit.\n\nBitte stimmt euch untereinander ab.";
|
||||
$host = $_SERVER['HTTP_HOST'] ?? intranet_env('INTRANET_FQDN');
|
||||
$plannerUrl = "https://{$host}/intranet_repo/projects/seelsorge/seelsorge.php";
|
||||
|
||||
foreach ($users as $user) {
|
||||
$email = trim((string) ($user['email'] ?? ''));
|
||||
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
continue;
|
||||
}
|
||||
if (!send_intranet_mail($email, $subject, $message, null, 'intranet@nak-reinickendorf.de', 'Zum Seelsorgeplaner', $plannerUrl)) {
|
||||
error_log("Seelsorge match mail failed for user " . (int) ($user['user_id'] ?? 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function seelsorge_calendar_availability_map(PDO $pdo, string $startDate, string $endDate, int $userId): array
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT datum, COUNT(*) AS count,
|
||||
SUM(CASE WHEN user_id = ? THEN 1 ELSE 0 END) AS self_count
|
||||
FROM verfuegbarkeiten
|
||||
WHERE datum BETWEEN ? AND ?
|
||||
GROUP BY datum'
|
||||
);
|
||||
$stmt->execute([$userId, $startDate, $endDate]);
|
||||
|
||||
$map = [];
|
||||
foreach ($stmt->fetchAll() as $row) {
|
||||
$date = (string) $row['datum'];
|
||||
$map[$date] = [
|
||||
'count' => (int) $row['count'],
|
||||
'self' => (int) $row['self_count'] > 0,
|
||||
];
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
function seelsorge_group_households(array $entries): array
|
||||
{
|
||||
$households = [];
|
||||
foreach ($entries as $entry) {
|
||||
$key = ($entry['address_street'] ?? '') . '||' . ($entry['address_plz'] ?? '');
|
||||
if (!isset($households[$key])) {
|
||||
$households[$key] = [
|
||||
'members' => [],
|
||||
'address_street' => $entry['address_street'] ?? '',
|
||||
'address_plz' => $entry['address_plz'] ?? '',
|
||||
'address_link' => $entry['address_link'] ?? '',
|
||||
'phone' => $entry['phone'] ?? '',
|
||||
'reservation' => null,
|
||||
];
|
||||
}
|
||||
$households[$key]['members'][] = $entry;
|
||||
if (($entry['reservation'] ?? null) !== null) {
|
||||
$households[$key]['reservation'] = $entry['reservation'];
|
||||
}
|
||||
}
|
||||
return $households;
|
||||
}
|
||||
|
||||
function seelsorge_household_status(array $members, bool $isReserved, ?int $todayTimestamp = null): array
|
||||
{
|
||||
if ($isReserved) {
|
||||
return ['key' => 'blue', 'label' => 'Geplant'];
|
||||
}
|
||||
|
||||
$todayTimestamp = $todayTimestamp ?? strtotime(date('Y-m-d'));
|
||||
$status = 'green';
|
||||
foreach ($members as $member) {
|
||||
$lastVisit = strtotime((string) ($member['letzter_besuch'] ?? SEELSORGE_INITIAL_VISIT_DATE));
|
||||
$months = (int) floor(($todayTimestamp - $lastVisit) / (86400 * 30));
|
||||
$priority = (int) ($member['priority'] ?? 0);
|
||||
if ($priority === 2 || $months >= 6) {
|
||||
$status = 'red';
|
||||
break;
|
||||
}
|
||||
if ($priority === 1 || $months >= 2) {
|
||||
$status = 'orange';
|
||||
}
|
||||
}
|
||||
|
||||
$labels = ['red' => 'Dringend', 'orange' => 'Fällig', 'green' => 'Aktuell'];
|
||||
return ['key' => $status, 'label' => $labels[$status]];
|
||||
}
|
||||
|
||||
function seelsorge_relative_visit_text(string $lastVisit, ?int $todayTimestamp = null): string
|
||||
{
|
||||
if ($lastVisit === SEELSORGE_INITIAL_VISIT_DATE) {
|
||||
return 'Initialer Eintrag';
|
||||
}
|
||||
|
||||
$todayTimestamp = $todayTimestamp ?? strtotime(date('Y-m-d'));
|
||||
$days = max(0, (int) floor(($todayTimestamp - strtotime($lastVisit)) / 86400));
|
||||
if ($days >= 25) {
|
||||
$months = (int) floor($days / 30);
|
||||
return $months === 1 ? 'vor einem Monat' : "vor {$months} Monaten";
|
||||
}
|
||||
if ($days >= 7) {
|
||||
$weeks = (int) floor($days / 7);
|
||||
return $weeks === 1 ? 'vor einer Woche' : "vor {$weeks} Wochen";
|
||||
}
|
||||
return $days === 1 ? 'vor einem Tag' : "vor {$days} Tagen";
|
||||
}
|
||||
|
||||
function seelsorge_profile_records(PDO $pdo): array
|
||||
{
|
||||
static $cache = null;
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$users = $pdo->query('SELECT * FROM user_general_information ORDER BY user_id')->fetchAll();
|
||||
$permissionRows = $pdo->query('SELECT * FROM user_permissions')->fetchAll();
|
||||
$permissionsByUser = [];
|
||||
foreach ($permissionRows as $permissions) {
|
||||
$permissionsByUser[(int) $permissions['user_id']] = $permissions;
|
||||
}
|
||||
|
||||
$cache = [];
|
||||
foreach ($users as $user) {
|
||||
$userId = (int) $user['user_id'];
|
||||
$cache[] = [
|
||||
'user' => $user,
|
||||
'permissions' => $permissionsByUser[$userId] ?? [],
|
||||
'image' => seelsorge_profile_image_url($userId),
|
||||
];
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
Reference in New Issue
Block a user