needlogin = true; $me = new User(); $me->loadMe(); $this->me = $me; $this->layout()->set("me", $me); if (!$me->is(["Admin"]) && !$me->is(["employee"])) { $this->redirect("Dashboard"); } } protected function detailAction() { $this->layout()->setTemplate("Calendar/Detail"); } protected function apiAction() { if (!$this->me->is(["Admin"])) { $return = false; } $do = $this->request->do; switch ($do) { case "getCalendarEvents": $r = $this->request; $calendarEvents = CalendarModel::getCalendarEvents($this->me->id, 0, $r); return $calendarEvents; die(); case "getCalendarEvent": $r = $this->request; $id = ($r->id); $calendarEvents = CalendarModel::getCalendarEvent($id); return $calendarEvents; die(); case "searchCalendarEvents" : $r = $this->request; $calendarEvents = CalendarModel::searchCalendarEvents($r); return $calendarEvents; die(); case "generateCalendarEventsXlsx" : $r = $this->request; $this->generateXlsx($r); return $calendarEvents; die(); case "getCalendarEventAttachment" : $r = $this->request; $id = ($r->id); $this->getCalendarAttachment($id); die(); case "getCalendarEventAttachmentTmp" : $r = $this->request; $id = ($r->id); $name = ($r->name); $this->getCalendarAttachmentTmp($id, $name); die(); case "updateCalendarEvent": $r = $this->request; $calendarEvents = CalendarModel::updateCalendarEvent($r, $this->me); if ($r->customer_info_check) { if ($r->customer_info_type == 1) { $body = $r->customer_info_text; $email = new Emailnotification(); $email->setSubject('Inbetriebnahme'); $email->setBody($body); $email->setFrom('termin@xinon.at', 'Terminbestätigung'); $email->setTo($r->customer_info_type_text); $email->send(); } else if ($r->customer_info_type == 2) { $sms = new SmsNotification(); $customerText = trim($r->customer_info_text); $body = "Xinon Terminbestätigung:" . PHP_EOL . $customerText; $sms->setBody($body); $customerNumber = trim($r->customer_info_type_text); $customerNumber = str_replace(" ", "", $customerNumber); $customerNumber = str_replace("(", "", $customerNumber); $customerNumber = str_replace(")", "", $customerNumber); $customerNumber = str_replace("-", "", $customerNumber); $customerNumber = str_replace("/", "", $customerNumber); $customerNumber = str_replace(".", "", $customerNumber); $customerNumber = str_replace(",", "", $customerNumber); $customerNumber = str_replace(";", "", $customerNumber); $customerNumber = str_replace(":", "", $customerNumber); if (preg_match('/^0/', $customerNumber)) { $customerNumber = "+43" . substr($customerNumber, 1); } $sms->setRecipient($customerNumber); if (!empty($customerNumber) && !empty($customerText)) { $sms->send(); } } } die(); case "updateCalendarEventState" : $r = $this->request; $calendarEvents = CalendarModel::updateCalendarEventState($r, $this->me); die(); case "getAddress": $r = $this->request; $this->getAddress($r); die(); case "getAddressSbidi": $r = $this->request; $this->getAddressSbidi($r); die(); case "getTicket"; $r = $this->request; $this->getTicket($r); die(); case "insertCalendarEvent": $r = $this->request; if ($r->rruleData) { $rrules = json_encode($this->generateGraphRecurrence($r->rruleData, $r->start)); } $calendarEvents = CalendarModel::insertCalendarEvent($r, $this->me, $rrules); if ($r->customer_info_check) { if ($r->customer_info_type == 1) { $body = $r->customer_info_text; $email = new Emailnotification(); $email->setSubject('Technikertermin Xinon'); $email->setBody($body); $email->setFrom('termin@xinon.at', 'Terminbestätigung'); $email->setTo($r->customer_info_type_text); $email->send(); } else if ($r->customer_info_type == 2) { $sms = new SmsNotification(); $customerText = trim($r->customer_info_text); $body = "Xinon Terminbestätigung:" . PHP_EOL . $customerText; $sms->setBody($body); $customerNumber = trim($r->customer_info_type_text); $customerNumber = str_replace(" ", "", $customerNumber); $customerNumber = str_replace("(", "", $customerNumber); $customerNumber = str_replace(")", "", $customerNumber); $customerNumber = str_replace("-", "", $customerNumber); $customerNumber = str_replace("/", "", $customerNumber); $customerNumber = str_replace(".", "", $customerNumber); $customerNumber = str_replace(",", "", $customerNumber); $customerNumber = str_replace(";", "", $customerNumber); $customerNumber = str_replace(":", "", $customerNumber); if (preg_match('/^0/', $customerNumber)) { $customerNumber = "+43" . substr($customerNumber, 1); } $sms->setRecipient($customerNumber); if (!empty($customerNumber) && !empty($customerText)) { $sms->send(); } } } die(); case "deleteCalendarEvent": $r = $this->request; $id = ($r->id); CalendarModel::deleteCalendarEvent($r); die(); case "cancelCalendarEvent": $r = $this->request; $id = ($r->id); if ($r->customer_info_check) { if ($r->customer_info_type == 1) { $body = $r->customer_info_text; $email = new Emailnotification(); $email->setSubject('Technikertermin Xinon Absage'); $email->setBody($body); $email->setFrom('termin@xinon.at', 'Terminbestätigung'); $email->setTo($r->customer_info_type_text); $email->send(); } else if ($r->customer_info_type == 2) { $sms = new SmsNotification(); $customerText = trim($r->customer_info_text); $body = "Xinon Terminabsage:" . PHP_EOL . $customerText; $sms->setBody($body); $customerNumber = trim($r->customer_info_type_text); $customerNumber = str_replace(" ", "", $customerNumber); $customerNumber = str_replace("(", "", $customerNumber); $customerNumber = str_replace(")", "", $customerNumber); $customerNumber = str_replace("-", "", $customerNumber); $customerNumber = str_replace("/", "", $customerNumber); $customerNumber = str_replace(".", "", $customerNumber); $customerNumber = str_replace(",", "", $customerNumber); $customerNumber = str_replace(";", "", $customerNumber); $customerNumber = str_replace(":", "", $customerNumber); if (preg_match('/^0/', $customerNumber)) { $customerNumber = "+43" . substr($customerNumber, 1); } $sms->setRecipient($customerNumber); if (!empty($customerNumber) && !empty($customerText)) { $sms->send(); } } } CalendarModel::cancelCalendarEvent($r, $this->me); die(); case "updateCalendarColor": $r = $this->request; $calendar_id = ($r->calendar_id); $bgcolors = ($r->bgcolors); $txtcolors = ($r->txtcolors); $id = ($r->id); $this->updateCalendarColor($id, $calendar_id, $bgcolors, $txtcolors); die(); case "uploadCalendarEventAttachment": $r = $this->request; $filename = $_FILES['upload_file']['name']; $filesize = $_FILES['upload_file']['size']; $file_content = file_get_contents($_FILES['upload_file']['tmp_name']); $filetype = $_FILES['upload_file']['type']; $file_content = base64_encode($file_content); $newkey = $r->newkey; $id = CalendarModel::insertCalendarEventAttachmentTemp($filename, $filetype, $file_content, $filesize, $newkey); if ($id) { $json['success'] = true; $json['id'] = $id; } $json = json_encode($json); echo $json; die(); case "deleteCalendarEventAttachmentTmp": $r = $this->request; $newkey = ($r->newkey); $name = ($r->name); CalendarModel::deleteCalendarEventAttachmentTemp($newkey, $name); die(); default: $return = false; } } protected function encryptString($plainText, $password, $salt) { $cipher = "aes-256-cbc"; $ivlen = openssl_cipher_iv_length($cipher); $iv = openssl_random_pseudo_bytes($ivlen); $key = hash_pbkdf2("sha256", $password, $salt, 1000, 32, true); $cipherText = openssl_encrypt($plainText, $cipher, $key, 0, $iv); $cipherText = base64_encode($iv . $cipherText); return $cipherText; } protected function updateCalendarColor($id, $calendar_id, $bgcolors, $txtcolors) { $r = $this->request; $groups = $r->groups; $redis = new Redis(); //Connecting to Redis $redis->connect('172.16.5.5', '6379'); //$redis->auth('password'); $Calendar = new Calendar($id); foreach ($bgcolors as $key => $value) { $colordata[$calendar_id[$key]]['bgcolor'] = $value; $colordata[$calendar_id[$key]]['txtcolor'] = $txtcolors[$key]; } $Calendar->colors = json_encode($colordata); if ($groups) { $Calendar->groups = $groups; } $redis->set('thetool_calendar_usercolors_' . $this->me->id, json_encode($colordata)); $Calendar->save(); die(); } protected function viewAction() { $Calendar = CalendarModel::search(array("user_id" => $this->me->id)); $CalendarAll = CalendarModel::getAll(); $encryptedUser = $this->encryptString($this->me->id, "testpw", "testsalt"); $this->layout()->set("Calendar", $Calendar); $this->layout()->set("CalendarAll", $CalendarAll); $this->layout()->set("encryptedUser", $encryptedUser); $timerecordingholidays = TimerecordingHolidayModel::getAll(); $this->layout()->set("timerecordingholidays", $timerecordingholidays); $timerecordingemployees = TimerecordingEmployeeModel::getAll(); $standardCalendarColors = CalendarModel::$standardCalendarColors; $specialCalendarColors = CalendarModel::$specialCalendarColors; $this->layout()->set("timerecordingemployees", $timerecordingemployees); $this->layout()->set("standardCalendarColors", $standardCalendarColors); $this->layout()->set("specialCalendarColors", $specialCalendarColors); $this->layout()->setTemplate("Calendar/View"); } private function getCalendarAttachment($id) { $content = CalendarModel::getCalendarEventAttachment($id); // // header('Content-Type: application/octet-stream'); header('Content-Type: ' . $content['contentType']); header('Content-disposition: attachment; filename="' . $content['name'] . '"'); echo base64_decode($content['content']); exit; } private function getCalendarAttachmentTmp($id, $name) { $content = CalendarModel::getCalendarEventAttachmentTmp($id, $name); // // header('Content-Type: application/octet-stream'); header('Content-Type: ' . $content['contentType']); header('Content-disposition: attachment; filename="' . $content['name'] . '"'); echo base64_decode($content['content']); exit; } private function getAddress($r) { $xinon = $r->xinon; $address = AddressModel::search(array("Controller!" => 'Calendar', "search_term!" => $r->term, "xinon" => $xinon), array('count' => '20')); $mobiles = CalendarModel::$austrian_mobile_prefixes; $prefixes = array('0043', '43 ', '43', '0'); foreach ($address as $key => $value) { unset($mobilenumber); $id = $value->id; if ($value->company) { $text = "(F) " . $value->company; } else { $text = "(P) " . $value->firstname . " " . $value->lastname; } if ($value->mobile) { foreach ($mobiles as $mobile) { foreach ($prefixes as $prefix) { if (strpos($value->mobile, $prefix . $mobile) !== false) { $mobilenumber = str_replace($prefix . $mobile, '+43' . $mobile, $value->mobile); $found = 1; break; } } if ($found) { break; } } } if ($value->phone) { foreach ($mobiles as $mobile) { foreach ($prefixes as $prefix) { if (strpos($value->phone, $prefix . $mobile) !== false) { $mobilenumber = str_replace($prefix . $mobile, '+43' . $mobile, $value->phone); $found = 1; break; } } if ($found) { break; } } } if ($mobilenumber) { if (strlen($mobilenumber) > 0 && strlen($mobilenumber) < 22) { $mobilenumber = str_replace(" ", "", $mobilenumber); $mobilenumber = str_replace("(", "", $mobilenumber); $mobilenumber = str_replace(")", "", $mobilenumber); $mobilenumber = str_replace("-", "", $mobilenumber); $mobilenumber = str_replace("/", "", $mobilenumber); $mobilenumber = str_replace(".", "", $mobilenumber); $mobilenumber = str_replace(",", "", $mobilenumber); $mobilenumber = str_replace(";", "", $mobilenumber); $mobilenumber = str_replace(":", "", $mobilenumber); } } else if ($value->mobile) { $mobilenumber = $value->mobile; } else if ($value->phone) { $mobilenumber = $value->phone; } else { $mobilenumber = ""; } $rows[] = array( 'id' => $id, 'text' => $value->customer_number . " " . $text . " - " . $value->street . ", " . $value->zip . " " . $value->city, 'mail' => $value->email, 'mobilenumber' => $mobilenumber, 'spin' => $value->spin, 'location' => $value->street . ", " . $value->zip . " " . $value->city, 'name' => $value->customer_number . " " . $text ); } $json['incomplete_results'] = false; $json['total_count'] = count($rows); $json['items'] = $rows; $json = json_encode($json); echo trim($json); die(); } private function getAddressSbidi($r) { $address = CalendarModel::getAddressSbidi($r->term); $mobiles = CalendarModel::$austrian_mobile_prefixes; $prefixes = array('0043', '43 ', '43', '0'); foreach ($address as $key => $value) { unset($mobilenumber); if ($value->phone) { foreach ($mobiles as $mobile) { $found = 0; foreach ($prefixes as $prefix) { if (strpos($value->phone, $prefix . $mobile) !== false) { $mobilenumber = str_replace($prefix . $mobile, '+43' . $mobile, $value->phone); $found = 1; break; } else if (substr($value->phone, 0, 3) == $mobile) { $mobilenumber = "+43" . $value->phone; $found = 1; break; } } if ($found) { break; } } } if ($mobilenumber) { if (strlen($mobilenumber) > 0 && strlen($mobilenumber) < 22) { $mobilenumber = str_replace(" ", "", $mobilenumber); $mobilenumber = str_replace("(", "", $mobilenumber); $mobilenumber = str_replace(")", "", $mobilenumber); $mobilenumber = str_replace("-", "", $mobilenumber); $mobilenumber = str_replace("/", "", $mobilenumber); $mobilenumber = str_replace(".", "", $mobilenumber); $mobilenumber = str_replace(",", "", $mobilenumber); $mobilenumber = str_replace(";", "", $mobilenumber); $mobilenumber = str_replace(":", "", $mobilenumber); $mobilenumber = str_replace("++", "+", $mobilenumber); } } else if ($value->phone) { $mobilenumber = $value->phone; } else { $mobilenumber = ""; } $rows[] = array( 'id' => $value->id, 'text' => $value->lastname . " " . $value->firstname . " - " . $value->street . ", " . $value->zip . " " . $value->city, 'mail' => $value->email, 'mobilenumber' => $mobilenumber, 'location' => $value->street . " " . $value->number . ", " . $value->zip . " " . $value->city, 'name' => $value->lastname . " " . $value->firstname ); } $json['incomplete_results'] = false; $json['total_count'] = count($rows); $json['items'] = $rows; $json = json_encode($json); echo trim($json); die(); } private function getTicket($r) { $project = new XinonProject(); $data = $project->searchSupportTickets($r->term); foreach ($data as $key => $value) { $rows[] = array( 'id' => $value['id'], 'text' => 'Ticket: ' . $value['id'] . " " . $value['subject'], 'subject' => $value['subject'], 'mail' => $value['customField5'], 'mobilenumber' => $value['customField4'], 'location' => $value['customField3'], 'name' => $value['customField2'] ); } $json['incomplete_results'] = false; $json['total_count'] = count($rows); $json['items'] = $rows; $json = json_encode($json); echo trim($json); die(); } private function generateGraphRecurrence($data, $startDate) { $graph = [ 'pattern' => [], 'range' => [] ]; $freq = strtoupper($data['rrule_frequency']); switch ($freq) { case 'DAILY': $graph['pattern']['type'] = 'daily'; break; case 'WEEKLY': $graph['pattern']['type'] = 'weekly'; break; case 'MONTHLY': if (!empty($data['monthly_type']) && $data['monthly_type'] === 'BYMONTHDAY') { $graph['pattern']['type'] = 'absoluteMonthly'; $graph['pattern']['dayOfMonth'] = intval($data['rrule_bymonthday']); } elseif (!empty($data['monthly_type']) && $data['monthly_type'] === 'BYSETPOS') { $graph['pattern']['type'] = 'relativeMonthly'; // Mapping: 1 => first, 2 => second, 3 => third, 4 => fourth, -1 => last $setpos = intval($data['rrule_setpos']); $indexMapping = [ 1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', -1 => 'last' ]; $graph['pattern']['index'] = isset($indexMapping[$setpos]) ? $indexMapping[$setpos] : 'first'; if (!empty($data['rrule_bynweekday'])) { $graph['pattern']['daysOfWeek'] = [$this->convertDayToGraph(strtoupper($data['rrule_bynweekday']))]; } } break; case 'YEARLY': $graph['pattern']['type'] = 'absoluteYearly'; break; default: $graph['pattern']['type'] = 'daily'; } $graph['pattern']['interval'] = 1; if ($freq === 'WEEKLY' && !empty($data['rrule-byweekday'])) { $days = is_array($data['rrule-byweekday']) ? $data['rrule-byweekday'] : [$data['rrule-byweekday']]; $graphDays = []; foreach ($days as $day) { $graphDays[] = $this->convertDayToGraph(strtoupper($day)); } $graph['pattern']['daysOfWeek'] = $graphDays; } $graph['range']['startDate'] = $startDate; if (!empty($data['rrule_until'])) { $graph['range']['endDate'] = $data['rrule_until']; $graph['range']['type'] = 'endDate'; } elseif (!empty($data['rrule_count'])) { $graph['range']['numberOfOccurrences'] = intval($data['rrule_count']); $graph['range']['type'] = 'numbered'; } else { $graph['range']['type'] = 'noEnd'; } return $graph; } private function convertDayToGraph($dayAbbrev) { $mapping = [ 'MO' => 'monday', 'TU' => 'tuesday', 'WE' => 'wednesday', 'TH' => 'thursday', 'FR' => 'friday', 'SA' => 'saturday', 'SU' => 'sunday' ]; return isset($mapping[$dayAbbrev]) ? $mapping[$dayAbbrev] : $dayAbbrev; } private function generateXlsx($r) { $calendarEvents = json_decode(CalendarModel::getCalendarEvents($this->me->id, 0, $r, true), true); $eventTypes = CalendarModel::$eventTypes; $xls = new Spreadsheet(); $sheet = $xls->getActiveSheet(); $writer = new Xlsx($xls); $sheet->getStyle('A1:AN1')->getFont()->setBold(true); $sheet->getStyle('A:E')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $sheet->getStyle('I:L')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $sheet->getColumnDimension('A')->setWidth(25); $sheet->getColumnDimension('B')->setWidth(15); $sheet->getColumnDimension('C')->setWidth(10); $sheet->getColumnDimension('D')->setWidth(15); $sheet->getColumnDimension('E')->setWidth(10); $sheet->getColumnDimension('F')->setWidth(40); $sheet->getColumnDimension('G')->setWidth(40); $sheet->getColumnDimension('H')->setWidth(20); $sheet->getColumnDimension('I')->setWidth(10); $sheet->getColumnDimension('J')->setWidth(10); $sheet->getColumnDimension('K')->setWidth(15); $sheet->getColumnDimension('L')->setWidth(15); $sheet->setCellValue([1, 1], 'Kalender') ->setCellValue([2, 1], 'Startdatum') ->setCellValue([3, 1], 'Startzeit') ->setCellValue([4, 1], 'Enddatum') ->setCellValue([5, 1], 'Endzeit') ->setCellValue([6, 1], 'Betreff') ->setCellValue([7, 1], 'Ort') ->setCellValue([8, 1], 'Beschreibung') ->setCellValue([9, 1], 'Termintyp') ->setCellValue([10, 1], 'Privat') ->setCellValue([11, 1], 'Sichtbarkeit') ->setCellValue([12, 1], 'Organisator'); $counter = 2; foreach ($calendarEvents['data'] as $event) { if ($event['privateflag']['privateflag']) { $event['privateflag']['privateflag'] = "Ja"; } else { $event['privateflag']['privateflag'] = "Nein"; } if ($event['isorganizer']['isorganizer']) { $event['isorganizer']['isorganizer'] = "Ja"; } else { $event['isorganizer']['isorganizer'] = "Nein"; } if ($event['busy']['busy'] == 1) { $event['busy']['busy'] = "gebucht"; } else if ($event['busy']['busy'] == 2) { $event['busy']['busy'] = "mit Vorbehalt"; } else { $event['busy']['busy'] = "frei"; } if ($event['allDay']['allDay'] == 0) { $starttime = date("H:i", strtotime($event['cstart']['cstart'])); $endtime = date("H:i", strtotime($event['cend']['cend'])); $startdate = date("d.m.Y", strtotime($event['cstart']['cstart'])); $enddate = date("d.m.Y", strtotime($event['cend']['cend'])); } else { $starttime = ""; $startdate = date("d.m.Y", strtotime($event['cstart']['cstart'])); $endtime = ""; $enddate = date("d.m.Y", strtotime($event['cend']['cend']) - 7500); } if ($event['event_type']['event_type'] != "") { $helper = new Html(); $richText = $helper->toRichTextObject($event['description']['description']); $calendarType = $eventTypes[$event['event_type']['event_type']]; $sheet->setCellValue([1, $counter], $event['calendar_name']['calendar_name']) ->setCellValue([2, $counter], $startdate) ->setCellValue([3, $counter], $starttime) ->setCellValue([4, $counter], $enddate) ->setCellValue([5, $counter], $endtime) ->setCellValue([6, $counter], $event['ccategory']['ccategory']) ->setCellValue([7, $counter], $event['location']['location']) ->setCellValue([8, $counter], $richText) ->setCellValue([9, $counter], $calendarType) ->setCellValue([10, $counter], $event['privateflag']['privateflag']) ->setCellValue([11, $counter], $event['busy']['busy']) ->setCellValue([12, $counter], $event['isorganizer']['isorganizer']); $counter++; } } header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); header('Content-disposition: attachment; filename="Kalender-' . date('Y-m-d_H-i-s') . '-' . uniqid() . '.xlsx"'); $writer->save('php://output'); exit; } protected function indexAction() { $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(); $this->layout()->set("calendartemplates", $calendartemplates); $this->layout()->set("calendars", $calendars); } protected function addAction() { $users = UserModel::getAll(); $this->layout()->set("users", $users); $this->layout()->setTemplate("Calendar/Form"); } protected function editAction() { $id = $this->request->id; if (!is_numeric($id) || !$id) { $this->layout()->setFlash("Kalender Verwaltung nicht gefunden", "error"); $this->redirect("Calendar"); } $calendars = new Calendar($id); if ($calendars->id != $id) { $this->layout()->setFlash("Kalender Verwaltung nicht gefunden", "error"); $this->redirect("Calendar"); } $this->layout()->set("calendars", $calendars); return $this->addAction(); } protected function saveAction() { $r = $this->request; $id = $r->id; //var_dump($r->get());exit; if (is_numeric($id) && $id > 0) { $mode = "edit"; $calendars = new Calendar($id); if (!$calendars->id) { $this->layout()->setFlash("Kalender Verwaltung nicht gefunden", "error"); $this->redirect("Calendar"); } } else { $mode = "add"; } $data = []; if ($mode == "add") { $userType = trim($r->user_type); if ($userType === 'system') { $userId = intval($r->user_id); if (!$userId) { $this->layout()->setFlash("Bitte wählen Sie einen Benutzer aus", "error"); $this->redirect("Calendar", "add"); } $user = new User($userId); if (!$user->id) { $this->layout()->setFlash("Benutzer nicht gefunden", "error"); $this->redirect("Calendar", "add"); } $data['user_id'] = $userId; $data['calendar_name'] = $user->name; if (trim($r->calendar_email)) { $data['calendar_email'] = trim($r->calendar_email); } else { $data['calendar_email'] = $user->email; } } else { $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", "add"); } $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['active'] = trim($r->active); $data['calendar_admin'] = trim($r->calendar_admin) ? 1 : 0; if (!$data['go_calendar_id']) { $data['go_calendar_id'] = NULL; } if (!$data['microsoft_id']) { $data['microsoft_id'] = NULL; } if (!$data['active']) { $data['active'] = '0'; } if ($mode == "edit") { 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); } $id = $calendars->save(); if (!$id) { $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") { $this->layout()->setFlash("Kalender Verwaltung erfolgreich angelegt", "success"); } $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; $calendars = new Calendar($id); if (!$calendars->id || $calendars->id != $id) { $this->layout()->setFlash("Kalender Verwaltung nicht gefunden.", "error"); $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->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"); } } }