diff --git a/AddOn/.DS_Store b/AddOn/.DS_Store new file mode 100644 index 00000000..99e69f7d Binary files /dev/null and b/AddOn/.DS_Store differ diff --git a/AddOn/Calender_Office365_User/OutlookCalendar.php b/AddOn/Calender_Office365_User/OutlookCalendar.php new file mode 100644 index 00000000..c0661afe --- /dev/null +++ b/AddOn/Calender_Office365_User/OutlookCalendar.php @@ -0,0 +1,102 @@ +clientId = $clientId; + $this->clientSecret = $clientSecret; + $this->redirectUri = $redirectUri; + $this->accessToken = $accessToken; + $this->refreshToken = $refreshToken; + } + + // ------------------------------------------ + // 🔁 Refresh Token verwenden + public function refreshAccessToken() { + $url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"; + + $data = [ + 'grant_type' => 'refresh_token', + 'refresh_token' => $this->refreshToken, + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'redirect_uri' => $this->redirectUri, + 'scope' => 'https://graph.microsoft.com/.default' + ]; + + $response = $this->sendRequest($url, $data, true); + if (isset($response['access_token'])) { + $this->accessToken = $response['access_token']; + $this->refreshToken = $response['refresh_token'] ?? $this->refreshToken; + } + + return $response; + } + + // ------------------------------------------ + // 📅 Termin erstellen + public function createEvent($eventData) { + $url = "https://graph.microsoft.com/v1.0/me/events"; + return $this->sendRequest($url, $eventData, false, 'POST'); + } + + // ✏️ Termin bearbeiten + public function updateEvent($eventId, $eventData) { + $url = "https://graph.microsoft.com/v1.0/me/events/{$eventId}"; + return $this->sendRequest($url, $eventData, false, 'PATCH'); + } + + // ❌ Termin löschen + public function deleteEvent($eventId) { + $url = "https://graph.microsoft.com/v1.0/me/events/{$eventId}"; + return $this->sendRequest($url, [], false, 'DELETE'); + } + + // ------------------------------------------ + // 🔧 API Request senden (intern) + private function sendRequest($url, $data = [], $isForm = false, $method = 'POST') { + $ch = curl_init($url); + $headers = [ + 'Authorization: Bearer ' . $this->accessToken, + ]; + + if ($isForm) { + $body = http_build_query($data); + $headers[] = 'Content-Type: application/x-www-form-urlencoded'; + } else { + $body = json_encode($data); + $headers[] = 'Content-Type: application/json'; + } + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + if ($method !== 'GET' && !empty($data)) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + + $response = curl_exec($ch); + $err = curl_error($ch); + curl_close($ch); + + if ($err) { + return ['error' => $err]; + } + + return json_decode($response, true); + } + + // 🔓 Getter für AccessToken + public function getAccessToken() { + return $this->accessToken; + } + + public function getRefreshToken() { + return $this->refreshToken; + } +} diff --git a/AddOn/Calender_Office365_User/auth.php b/AddOn/Calender_Office365_User/auth.php new file mode 100644 index 00000000..6b8814cd --- /dev/null +++ b/AddOn/Calender_Office365_User/auth.php @@ -0,0 +1,14 @@ + $config['client_id'], + 'response_type' => 'code', + 'redirect_uri' => $config['redirect_uri'], + 'response_mode' => 'query', + 'scope' => $config['scopes'], +]; + +$authUrl = $config['auth_url'] . '?' . http_build_query($params); +header("Location: $authUrl"); +exit; diff --git a/AddOn/Calender_Office365_User/calendar.php b/AddOn/Calender_Office365_User/calendar.php new file mode 100644 index 00000000..e7216c17 --- /dev/null +++ b/AddOn/Calender_Office365_User/calendar.php @@ -0,0 +1,56 @@ + ($data['time_saved'] + $data['expires_in'] - 60)) { + $calendar->refreshAccessToken(); + $tokens[$email]['access_token'] = $calendar->getAccessToken(); + $tokens[$email]['refresh_token'] = $calendar->getRefreshToken(); + $tokens[$email]['time_saved'] = time(); + file_put_contents($config['token_storage'], json_encode($tokens, JSON_PRETTY_PRINT)); +} + +// ➤ Beispiel: Termin anlegen +$event = [ + "subject" => "Test-Meeting via PHP", + "start" => [ + "dateTime" => "2025-06-25T10:00:00", + "timeZone" => "Europe/Berlin" + ], + "end" => [ + "dateTime" => "2025-06-25T11:00:00", + "timeZone" => "Europe/Berlin" + ], + "body" => [ + "contentType" => "HTML", + "content" => "Meeting von OutlookCalendar PHP" + ] +]; + +$response = $calendar->createEvent($event); + +echo "
";
+print_r($response);
+echo "
"; diff --git a/AddOn/Calender_Office365_User/callback.php b/AddOn/Calender_Office365_User/callback.php new file mode 100644 index 00000000..11598156 --- /dev/null +++ b/AddOn/Calender_Office365_User/callback.php @@ -0,0 +1,69 @@ + $config['client_id'], + 'scope' => $config['scopes'], + 'code' => $code, + 'redirect_uri' => $config['redirect_uri'], + 'grant_type' => 'authorization_code', + 'client_secret' => $config['client_secret'], +]; + +$ch = curl_init($config['token_url']); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); +curl_setopt($ch, CURLOPT_POST, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/x-www-form-urlencoded', +]); + +$response = curl_exec($ch); +curl_close($ch); + +$tokenData = json_decode($response, true); + +if (!isset($tokenData['access_token'])) { + die("Fehler beim Token-Abruf: " . $response); +} + +// ➤ E-Mail-Adresse vom User holen +$ch = curl_init($config['graph_url'] . '/me'); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $tokenData['access_token'], +]); +$userResponse = curl_exec($ch); +curl_close($ch); + +$userData = json_decode($userResponse, true); +$email = $userData['mail'] ?? $userData['userPrincipalName'] ?? null; + +if (!$email) { + die("Fehler beim Abrufen der E-Mail."); +} + +// ➤ Speichern in tokens.json +$tokens = []; +if (file_exists($config['token_storage'])) { + $tokens = json_decode(file_get_contents($config['token_storage']), true); +} + +$tokens[$email] = [ + 'access_token' => $tokenData['access_token'], + 'refresh_token' => $tokenData['refresh_token'], + 'expires_in' => $tokenData['expires_in'], + 'time_saved' => time() +]; + +file_put_contents($config['token_storage'], json_encode($tokens, JSON_PRETTY_PRINT)); + +echo "Erfolgreich verbunden mit: $email
"; +echo "Zum Kalender-Tool"; diff --git a/AddOn/Calender_Office365_User/config.php b/AddOn/Calender_Office365_User/config.php new file mode 100644 index 00000000..5003cd24 --- /dev/null +++ b/AddOn/Calender_Office365_User/config.php @@ -0,0 +1,11 @@ + '', + 'client_secret' => '', + 'redirect_uri' => 'https://servicebericht.isgus.de/calsync/callback.php', + 'scopes' => 'offline_access user.read calendars.readwrite', + 'auth_url' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', + 'token_url' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token', + 'graph_url' => 'https://graph.microsoft.com/v1.0', + 'token_storage' => __DIR__ . '/tokens.json', +];