Kalenderupdate

* Komplette Verwaltung von Kalender Rechte von internen und externen Mitarbeiteren
This commit is contained in:
Daniel Spitzer
2025-10-05 17:36:42 +02:00
parent c389477e05
commit 363dbd5436
5 changed files with 743 additions and 60 deletions
+375 -24
View File
@@ -244,22 +244,12 @@ class CalendarController extends mfBaseController
protected function encryptString($plainText, $password, $salt)
{
// Definiere den Algorithmus und die Länge des Initialisierungsvektors
$cipher = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($cipher);
// Generiere einen Initialisierungsvektor
$iv = openssl_random_pseudo_bytes($ivlen);
// Erzeuge einen Schlüssel aus dem Passwort und dem Salt
$key = hash_pbkdf2("sha256", $password, $salt, 1000, 32, true);
// Verschlüssele den String
$cipherText = openssl_encrypt($plainText, $cipher, $key, 0, $iv);
// Füge den IV an den verschlüsselten Text an, da dieser für die Entschlüsselung benötigt wird
$cipherText = base64_encode($iv . $cipherText);
return $cipherText;
}
@@ -691,6 +681,16 @@ class CalendarController extends mfBaseController
{
$this->layout()->setTemplate("Calendar/Index");
$calendars = CalendarModel::getAll();
// ÄNDERUNG: Erstelle assoziatives Array für Zugriff per go_calendar_id
$calendarsById = [];
foreach ($calendars as $cal) {
if ($cal->go_calendar_id) {
$calendarsById[$cal->go_calendar_id] = $cal;
}
}
$this->layout()->set("calendarsById", $calendarsById);
$calendarTemplateEventTypes = CalendarTemplateModel::$calendarTemplateEventTypes;
$this->layout()->set("calendarTemplateEventTypes", $calendarTemplateEventTypes);
$calendartemplates = CalendarTemplateModel::getAll();
@@ -700,8 +700,8 @@ class CalendarController extends mfBaseController
protected function addAction()
{
$users = UserModel::getAll();
$this->layout()->set("users", $users);
// $users = UserModel::getAll();
// $this->layout()->set("users", $users);
$this->layout()->setTemplate("Calendar/Form");
}
@@ -742,20 +742,42 @@ class CalendarController extends mfBaseController
$data = [];
if ($mode == "add") {
$data['user_id'] = trim($r->user_id);
if (!$data['user_id']) {
$this->layout()->setFlash("Name darf nicht leer sein", "error");
$data['calendar_firstname'] = trim($r->calendar_firstname);
$data['calendar_lastname'] = trim($r->calendar_lastname);
if (!$data['calendar_firstname'] || !$data['calendar_lastname']) {
$this->layout()->setFlash("Vor- und Nachname dürfen nicht leer sein", "error");
$this->redirect("Calendar");
}
$data['calendar_name'] = $data['calendar_firstname'] . ' ' . $data['calendar_lastname'];
if (trim($r->calendar_email)) {
$data['calendar_email'] = trim($r->calendar_email);
} else {
$data['calendar_email'] = strtolower($data['calendar_firstname']) . '.' .
strtolower($data['calendar_lastname']) . '@xinon.extern';
}
} elseif ($mode == "edit" && !$calendars->user_id) {
$data['calendar_firstname'] = trim($r->calendar_firstname);
$data['calendar_lastname'] = trim($r->calendar_lastname);
if (!$data['calendar_firstname'] || !$data['calendar_lastname']) {
$this->layout()->setFlash("Vor- und Nachname dürfen nicht leer sein", "error");
$this->redirect("Calendar", "edit", ["id" => $id]);
}
$data['calendar_name'] = $data['calendar_firstname'] . ' ' . $data['calendar_lastname'];
if (trim($r->calendar_email)) {
$data['calendar_email'] = trim($r->calendar_email);
} else {
$data['calendar_email'] = strtolower($data['calendar_firstname']) . '.' .
strtolower($data['calendar_lastname']) . '@xinon.extern';
}
}
$data['go_calendar_id'] = trim($r->go_calendar_id);
$data['microsoft_id'] = trim($r->microsoft_id);
// $data['rights'] = trim($r->rights);
// $data['colors'] = trim($r->colors);
// $data['subscription_id'] = trim($r->subscription_id);
// $data['expirationDateTime'] = trim($r->expirationDateTime);
$data['active'] = trim($r->active);
$data['calendar_admin'] = trim($r->calendar_admin) ? 1 : 0;
if (!$data['go_calendar_id']) {
$data['go_calendar_id'] = NULL;
@@ -766,12 +788,120 @@ class CalendarController extends mfBaseController
if (!$data['active']) {
$data['active'] = '0';
}
if ($mode == "edit") {
$calendars->update($data);
if (isset($r->rights) && is_array($r->rights)) {
$newRights = [];
if ($calendars->go_calendar_id) {
$newRights[$calendars->go_calendar_id] = "all";
}
$oldRights = json_decode($calendars->rights, true) ?: [];
foreach ($r->rights as $calendarId => $right) {
if ($right != 'none') {
$newRights[intval($calendarId)] = $right;
}
}
$data['rights'] = json_encode($newRights);
if ($calendars->groups && $calendars->go_calendar_id) {
$groups = json_decode($calendars->groups, true) ?: [];
$groupsUpdated = false;
foreach ($groups as &$group) {
if (!isset($group['calendars']) || !is_array($group['calendars'])) {
continue;
}
foreach ($group['calendars'] as $index => $calendar) {
if (!isset($calendar['calendar_id'])) {
continue;
}
$calId = $calendar['calendar_id'];
$hadRight = isset($oldRights[$calId]) && $oldRights[$calId] != 'none';
$hasRight = isset($newRights[$calId]) && $newRights[$calId] != 'none';
// Wenn Recht entfernt wurde (hatte Recht, hat jetzt keines mehr)
if ($hadRight && !$hasRight) {
unset($group['calendars'][$index]);
$groupsUpdated = true;
error_log("Removed calendar $calId from group '{$group['name']}' due to rights removal");
}
}
if ($groupsUpdated) {
$group['calendars'] = array_values($group['calendars']);
}
}
foreach ($newRights as $calId => $right) {
// Überspringe sich selbst
if ($calId == $calendars->go_calendar_id) {
continue;
}
$hadRight = isset($oldRights[$calId]) && $oldRights[$calId] != 'none';
$hasRight = true; // Ist in newRights
if (!$hadRight && $hasRight) {
foreach ($groups as &$group) {
if ($group['name'] === 'Persönlich' && $group['origin'] == 1) {
// Prüfe ob schon vorhanden
$alreadyExists = false;
foreach ($group['calendars'] as $cal) {
if ($cal['calendar_id'] == $calId) {
$alreadyExists = true;
break;
}
}
if (!$alreadyExists) {
$group['calendars'][] = [
'calendar_id' => (string)$calId,
'checked' => 0,
'origin' => 1
];
$groupsUpdated = true;
error_log("Added calendar $calId to group 'Persönlich' due to new rights");
}
break;
}
}
}
}
if ($groupsUpdated) {
$data['groups'] = json_encode($groups);
}
}
// ÄNDERUNG ENDE
}
$calendars->update($data);
} else {
if (!$data['go_calendar_id']) {
$tempCal = (object)[
'calendar_firstname' => $data['calendar_firstname'],
'calendar_lastname' => $data['calendar_lastname'],
'calendar_name' => $data['calendar_name'],
'calendar_email' => $data['calendar_email'],
'microsoft_id' => $data['microsoft_id']
];
$goUserId = $this->createGroupOfficeUser($tempCal);
if ($goUserId) {
$goCalendarId = $this->createGroupOfficeCalendar($goUserId, $tempCal);
if ($goCalendarId) {
$data['go_calendar_id'] = $goCalendarId;
} else {
$this->layout()->setFlash("Kalender konnte in GroupOffice nicht erstellt werden", "error");
$this->redirect("Calendar");
}
} else {
$this->layout()->setFlash("Benutzer konnte in GroupOffice nicht erstellt werden", "error");
$this->redirect("Calendar");
}
}
$calendars = CalendarModel::create($data);
}
@@ -781,7 +911,68 @@ class CalendarController extends mfBaseController
$this->layout()->setFlash("Kalender Verwaltung konnte nicht angelegt werden", "error");
$this->redirect("Calendar");
}
if ($mode == "add") {
$newCalendar = new Calendar($id);
$newGoCalendarId = $newCalendar->go_calendar_id;
if (!$newGoCalendarId) {
$goUserId = $this->createGroupOfficeUser($newCalendar);
if ($goUserId) {
$goCalendarId = $this->createGroupOfficeCalendar($goUserId, $newCalendar);
if ($goCalendarId) {
$newCalendar->go_calendar_id = $goCalendarId;
$newCalendar->save();
$newGoCalendarId = $goCalendarId;
}
}
}
$allCalendars = CalendarModel::getAll();
$newUserRights = [];
$newUserRights[$newGoCalendarId] = "all";
foreach ($allCalendars as $existingCal) {
if ($existingCal->id == $id || !$existingCal->go_calendar_id) {
continue;
}
$existingRights = json_decode($existingCal->rights, true) ?: [];
if ($existingCal->calendar_admin == 1) {
$existingRights[$newGoCalendarId] = "all";
} else {
$existingRights[$newGoCalendarId] = "read";
}
$existingCal->rights = json_encode($existingRights);
if ($existingCal->groups) {
$groups = json_decode($existingCal->groups, true) ?: [];
$groupUpdated = false;
foreach ($groups as &$group) {
if (isset($group['name']) && $group['name'] === 'Persönlich' && isset($group['origin']) && $group['origin'] == 1) {
// Füge neuen Kalender hinzu
$group['calendars'][] = [
'calendar_id' => (string)$newGoCalendarId,
'checked' => 0,
'origin' => 1
];
$groupUpdated = true;
break;
}
}
if ($groupUpdated) {
$existingCal->groups = json_encode($groups);
}
}
$existingCal->save();
$newUserRights[$existingCal->go_calendar_id] = "read";
}
$newCalendar->rights = json_encode($newUserRights);
$newCalendar->save();
}
if ($mode == "edit") {
$this->layout()->setFlash("Kalender Verwaltung erfolgreich geändert", "success");
} else if ($mode = "add") {
@@ -789,8 +980,89 @@ class CalendarController extends mfBaseController
}
$this->redirect("Calendar");
}
private function createGroupOfficeUser($calendar)
{
$dbcal = CalendarModel::dbKalender();
$username = $calendar->calendar_firstname . $calendar->calendar_lastname;
$data = [
'username' => $username,
'displayName' => $calendar->calendar_name,
'enabled' => 1,
'email' => $calendar->calendar_email,
'recoveryEmail' => $calendar->calendar_email,
'createdAt' => date('Y-m-d H:i:s'),
'modifiedAt' => date('Y-m-d H:i:s'),
'dateFormat' => 'd-m-Y',
'shortDateInList' => 1,
'timeFormat' => 'G:i',
'thousandsSeparator' => '.',
'decimalSeparator' => ',',
'currency' => '€',
'loginCount' => 0,
'max_rows_list' => 20,
'timezone' => 'Europe/Amsterdam',
'start_module' => 'summary',
'language' => 'de',
'theme' => 'Paper',
'themeColorScheme' => 'light',
'firstWeekday' => 1,
'sort_name' => 'first_name',
'homeDir' => 'users/' . $username,
'passwordModifiedAt' => date('Y-m-d H:i:s')
];
if ($dbcal->insert('core_user', $data)) {
$userId = $dbcal->insert_id;
error_log("Created GroupOffice User - ID: $userId, Username: $username");
return $userId;
}
error_log("Failed to create GroupOffice User for: $username");
return false;
}
private function createGroupOfficeCalendar($goUserId, $calendar)
{
$dbcal = CalendarModel::dbKalender();
error_log("Creating Calendar for GO User ID: $goUserId");
$data = [
'group_id' => 1,
'user_id' => intval($goUserId),
'acl_id' => 49,
'name' => $calendar->calendar_name,
'start_hour' => 0,
'end_hour' => 0,
'time_interval' => 1800,
'public' => 0,
'shared_acl' => 0,
'show_bdays' => 0,
'show_completed_tasks' => 1,
'comment' => '',
'show_holidays' => 1,
'enable_ics_import' => 0,
'ics_import_url' => '',
'tooltip' => '',
'version' => 1,
'tool_user_id' => 0,
'ms_user_id' => $calendar->microsoft_id ? $calendar->microsoft_id : NULL
];
if ($dbcal->insert('cal_calendars', $data, ['tool_user_id'])) {
$calendarId = $dbcal->insert_id;
error_log("Created GroupOffice Calendar - ID: $calendarId for User ID: $goUserId");
return $calendarId;
}
error_log("Failed to create GroupOffice Calendar for User ID: $goUserId");
return false;
}
protected function deleteAction()
{
$id = $this->request->id;
@@ -800,8 +1072,87 @@ class CalendarController extends mfBaseController
$this->redirect("Calendar");
}
if ($calendars->user_id) {
$this->layout()->setFlash("System-Benutzer können nicht gelöscht werden.", "error");
$this->redirect("Calendar");
}
$deletedGoCalendarId = $calendars->go_calendar_id;
if ($deletedGoCalendarId) {
$this->deleteGroupOfficeCalendar($deletedGoCalendarId);
$allCalendars = CalendarModel::getAll();
foreach ($allCalendars as $otherCal) {
if ($otherCal->id == $id) {
continue;
}
$otherRights = json_decode($otherCal->rights, true) ?: [];
if (isset($otherRights[$deletedGoCalendarId])) {
unset($otherRights[$deletedGoCalendarId]);
$otherCal->rights = json_encode($otherRights);
}
if ($otherCal->groups) {
$groups = json_decode($otherCal->groups, true) ?: [];
$groupUpdated = false;
foreach ($groups as &$group) {
if (isset($group['calendars']) && is_array($group['calendars'])) {
foreach ($group['calendars'] as $index => $calendar) {
if (isset($calendar['calendar_id']) && $calendar['calendar_id'] == $deletedGoCalendarId) {
unset($group['calendars'][$index]);
$groupUpdated = true;
}
}
if ($groupUpdated) {
$group['calendars'] = array_values($group['calendars']);
}
}
}
if ($groupUpdated) {
$otherCal->groups = json_encode($groups);
}
}
$otherCal->save();
}
}
$calendars->delete();
$this->redirect("Calendar");
$this->layout()->setFlash("Benutzer erfolgreich gelöscht.", "success");
$this->redirect("Calendar", "index", ["tab" => "user"]);
}
private function deleteGroupOfficeCalendar($goCalendarId)
{
$dbcal = CalendarModel::dbKalender();
$res = $dbcal->select('cal_calendars', 'user_id', "id = " . intval($goCalendarId));
if ($dbcal->num_rows($res) > 0) {
$row = $dbcal->fetch_array($res);
$goUserId = $row['user_id'];
if ($dbcal->delete('cal_calendars', "id = " . intval($goCalendarId))) {
error_log("Deleted GroupOffice Calendar ID: $goCalendarId");
$checkRes = $dbcal->select('cal_calendars', 'COUNT(*) as count', "user_id = " . intval($goUserId));
$checkRow = $dbcal->fetch_array($checkRes);
if ($checkRow['count'] == 0) {
if ($dbcal->delete('core_user', "id = " . intval($goUserId))) {
error_log("Deleted GroupOffice User ID: $goUserId (no calendars left)");
} else {
error_log("Failed to delete GroupOffice User ID: $goUserId - " . $dbcal->getLastError());
}
} else {
error_log("GroupOffice User ID: $goUserId has " . $checkRow['count'] . " calendar(s) left - not deleted");
}
} else {
error_log("Failed to delete GroupOffice Calendar ID: $goCalendarId - " . $dbcal->getLastError());
}
} else {
error_log("GroupOffice Calendar ID: $goCalendarId not found");
}
}
}
+6
View File
@@ -3,6 +3,11 @@
class CalendarModel
{
private $user_id;
private $calendar_name;
private $calendar_firstname;
private $calendar_lastname;
private $calendar_email;
private $go_calendar_id;
private $microsoft_id;
private $rights;
@@ -11,6 +16,7 @@ class CalendarModel
private $subscription_id;
private $expirationDateTime;
private $active;
private $calendar_admin;
public static $austrian_mobile_prefixes = array(
'650', // Tele2 / Magenta