OpenXE/classes/Modules/Calendar/CalendarService.php
2021-05-21 08:49:41 +02:00

297 lines
8.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Xentral\Modules\Calendar;
use Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\Calendar\Data\CalendarEvent;
use Xentral\Modules\Calendar\Data\CalendarEventUser;
use Xentral\Modules\Calendar\Exception\CalendarEventDeleteException;
use Xentral\Modules\Calendar\Exception\CalendarEventSaveException;
use Xentral\Modules\GoogleCalendar\Exception\GoogleCalendarException;
final class CalendarService
{
/** @var Database $db */
private $db;
/**
* @param Database $database
*/
public function __construct(Database $database)
{
$this->db = $database;
}
/**
* @param $eventId
*
* @return CalendarEvent|null
*/
public function tryGetEvent(int $eventId): ?CalendarEvent
{
$event = $this->tryGetEventWithoutUsers($eventId);
if ($event !== null) {
$users = $this->tryGetEventUsers($eventId);
foreach ($users as $user) {
$event->addAttendee($user);
}
}
return $event;
}
/**
* @param $eventId
*
* @return CalendarEvent|null
*/
public function tryGetEventWithoutUsers(int $eventId): ?CalendarEvent
{
if($eventId < 1) {
return null;
}
$sql = 'SELECT e.id, e.kalender as `calendar_id`, e.bezeichnung as `title`, e.beschreibung as `description`,
e.von as `start`, e.bis as `end`, e.allDay as `all_day`, e.color, e.public,
e.ort as `location`, e.typ as `type`, e.angelegtvon as `creator_id`,
e.adresseintern as `organizer_id`, e.adresse as `attendee_id`
FROM kalender_event AS e
WHERE e.id = :idValue';
$values = ['idValue' => $eventId];
$result = $this->db->fetchRow($sql, $values);
if (!empty($result)) {
return CalendarEvent::fromDbState($result);
}
return null;
}
/**
* @param int $eventId
*
* @return CalendarEventUser[]
*/
public function tryGetEventUsers(int $eventId): array
{
$sql = 'SELECT ku.id, ku.event as `event_id`, ku.userid as `user_id`, ku.gruppe as `group_id`,
u.adresse as `address_id`, a.email as `email`
FROM `kalender_user` AS ku
LEFT JOIN `user` AS u ON ku.userid = u.id
LEFT JOIN `adresse` AS a ON u.adresse = a.id
WHERE ku.event = :eventId';
$values = ['eventId' => $eventId];
$rows = $this->db->fetchAll($sql, $values);
if (empty($rows)) {
return [];
}
$users = [];
foreach ($rows as $row) {
$users[] = CalendarEventUser::fromDbState($row);
}
return $users;
}
/**
* @param CalendarEvent $event
*
* @return int
*/
public function saveEvent(CalendarEvent $event): int
{
if ($event->getId() > 0 && $this->eventExists($event->getId())) {
return $this->updateEvent($event);
}
return $this->insertEvent($event);
}
/**
* @param int $eventId
*
* @throws CalendarEventDeleteException
*
* @return void
*/
public function deleteEvent(int $eventId): void
{
$this->db->beginTransaction();
try {
$sql = 'DELETE FROM `kalender_event` WHERE id = :eventId';
$values = ['eventId' => $eventId];
$this->db->perform($sql, $values);
$deleteUser = 'DELETE FROM `kalender_user` WHERE event = :eventId';
$this->db->perform($deleteUser, $values);
} catch (Exception $e) {
$this->db->rollBack();
throw new CalendarEventDeleteException($e->getMessage(), $e->getCode(), $e);
}
$this->db->commit();
}
/**
* @param int $eventId
* @param int $userId
*
* @return void
*/
public function removeUserFromEvent(int $eventId, int $userId): void
{
$sql = 'DELETE FROM `kalender_user` WHERE event = :eventId AND userid = :userId';
$values = ['eventId' => $eventId, 'userId' => $userId];
$this->db->perform($sql, $values);
}
/**
* @param $eventId
*
* @return bool
*/
public function eventExists(int $eventId): bool
{
if ($eventId < 1) {
return false;
}
$sql = 'SELECT e.id FROM `kalender_event` AS e WHERE e.id = :idValue';
$values = ['idValue' => (int)$eventId];
$result = $this->db->fetchRow($sql, $values);
return (isset($result['id']) && $result['id'] === $eventId);
}
/**
* @param CalendarEvent $event
*
* @throws CalendarEventSaveException
*
* @return int
*/
private function insertEvent(CalendarEvent $event): int
{
$this->db->beginTransaction();
try {
$insertEvent = 'INSERT INTO kalender_event
(kalender, bezeichnung, beschreibung, von, bis, allDay, color,
public, ort, typ, angelegtvon, adresseintern, adresse)
VALUES
(:calendar_id, :title, :description, :start, :end, :all_day, :color,
:public, :location,:type, :creator_id, :organizer_id, :attendee_id)';
$values = $this->getBindValuesFromEvent($event);
$this->db->perform($insertEvent, $values);
$newId = $this->db->lastInsertId();
$users = $event->getAllUsers();
$this->insertEventUsers($users, $newId);
} catch (Exception $e) {
$this->db->rollBack();
throw new CalendarEventSaveException($e->getMessage(), $e->getCode(), $e);
}
$this->db->commit();
return $newId;
}
/**
* @param CalendarEvent $event
*
* @throws CalendarEventSaveException
*
* @return int
*/
private function updateEvent(CalendarEvent $event): int
{
$this->db->beginTransaction();
try {
$sql = 'UPDATE kalender_event SET
kalender = :calendar_id,
bezeichnung = :title,
beschreibung = :description,
von = :start,
bis = :end,
allDay = :all_day,
color = :color,
public = :public,
ort = :location,
angelegtvon = :creator_id,
adresseintern = :organizer_id,
adresse = :attendee_id,
typ = :type
WHERE id = :id';
$values = $this->getBindValuesFromEvent($event);
$this->db->perform($sql, $values);
$this->deleteEventUsers($event->getId());
$users = $event->getAllUsers();
$this->insertEventUsers($users, $event->getId());
} catch (Exception $e) {
$this->db->rollBack();
throw new CalendarEventSaveException($e->getMessage(), $e->getCode(), $e);
}
$this->db->commit();
return $event->getId();
}
/**
* @param $users
* @param $eventId
*
* @return void
*/
private function insertEventUsers($users, $eventId): void
{
if (!is_array($users) || count($users) < 1) {
return;
}
$insert = $this->db->insert();
$insert->into('kalender_user');
foreach ($users as $user) {
$insert->addRow()
->cols([
'event' => $eventId,
'userid' => $user->getUserId(),
'gruppe' => $user->getGroupId(),
]);
}
$insertSql = $insert->getStatement();
$values = $insert->getBindValues();
$this->db->perform($insertSql, $values);
}
/**
* @param $eventId
*
* @return void
*/
private function deleteEventUsers($eventId): void
{
$sql = 'DELETE FROM kalender_user WHERE event = :eventId';
$this->db->perform($sql, ['eventId' => $eventId]);
}
/**
* @param CalendarEvent $event
*
* @return array
*/
private function getBindValuesFromEvent(CalendarEvent $event): array
{
$values = $event->toArray();
if (empty($values['start'])) {
$values['start'] = null;
}
if (empty($values['end'])) {
$values['end'] = null;
}
return $values;
}
}