mail_calendar_sync/lib/Controller/SettingsController.php
2026-02-09 23:02:34 -05:00

216 lines
6.8 KiB
PHP

<?php
declare(strict_types=1);
namespace OCA\MailCalendarSync\Controller;
use OCA\MailCalendarSync\AppInfo\Application;
use OCA\MailCalendarSync\Db\Config;
use OCA\MailCalendarSync\Db\ConfigMapper;
use OCA\MailCalendarSync\Db\LogMapper;
use OCA\MailCalendarSync\Service\CalendarService;
use OCA\MailCalendarSync\Service\MailService;
use OCA\MailCalendarSync\Service\SyncService;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
class SettingsController extends ApiController {
private ConfigMapper $configMapper;
private LogMapper $logMapper;
private CalendarService $calendarService;
private MailService $mailService;
private SyncService $syncService;
private ?string $userId;
public function __construct(
IRequest $request,
ConfigMapper $configMapper,
LogMapper $logMapper,
CalendarService $calendarService,
MailService $mailService,
SyncService $syncService,
?string $userId,
) {
parent::__construct(
Application::APP_ID,
$request,
'PUT, GET, POST',
'Authorization, Content-Type, Accept, requesttoken',
86400
);
$this->configMapper = $configMapper;
$this->logMapper = $logMapper;
$this->calendarService = $calendarService;
$this->mailService = $mailService;
$this->syncService = $syncService;
$this->userId = $userId;
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getConfig(): JSONResponse {
try {
$config = $this->configMapper->findByUserId($this->userId);
return new JSONResponse($config->toArray());
} catch (DoesNotExistException $e) {
return new JSONResponse([
'enabled' => false,
'mailAccountId' => null,
'calendarUri' => null,
'autoAccept' => false,
'syncInterval' => 600,
]);
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Failed to load config: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function setConfig(): JSONResponse {
try {
// Parse JSON body
$body = file_get_contents('php://input');
$data = json_decode($body, true);
if (!is_array($data)) {
return new JSONResponse(
['error' => 'Invalid request body'],
Http::STATUS_BAD_REQUEST
);
}
$enabled = !empty($data['enabled']);
$mailAccountId = $data['mailAccountId'] ?? null;
$calendarUri = $data['calendarUri'] ?? null;
$autoAccept = !empty($data['autoAccept']);
$syncInterval = (int)($data['syncInterval'] ?? 600);
// Clamp sync interval to valid range (5 min to 24 hours)
$syncInterval = max(300, min(86400, $syncInterval));
// Normalize empty strings to null
if ($mailAccountId === '' || $mailAccountId === '0') {
$mailAccountId = null;
}
if ($calendarUri === '') {
$calendarUri = null;
}
try {
$config = $this->configMapper->findByUserId($this->userId);
} catch (DoesNotExistException $e) {
$config = new Config();
$config->setUserId($this->userId);
$config->setCreatedAt(date('Y-m-d H:i:s'));
}
$config->setEnabled($enabled ? 1 : 0);
$config->setMailAccountId($mailAccountId !== null ? (int)$mailAccountId : null);
$config->setCalendarUri($calendarUri);
$config->setAutoAccept($autoAccept ? 1 : 0);
$config->setSyncInterval($syncInterval);
$config->setUpdatedAt(date('Y-m-d H:i:s'));
if ($config->getId() === null) {
$config = $this->configMapper->insert($config);
} else {
$config = $this->configMapper->update($config);
}
return new JSONResponse($config->toArray());
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Failed to save: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getCalendars(): JSONResponse {
try {
$calendars = $this->calendarService->getWritableCalendars($this->userId);
return new JSONResponse($calendars);
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Failed to load calendars: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getMailAccounts(): JSONResponse {
try {
$accounts = $this->mailService->getMailAccounts($this->userId);
return new JSONResponse($accounts);
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Failed to load mail accounts: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getLog(): JSONResponse {
try {
$limit = (int)($this->request->getParam('limit', '50'));
$offset = (int)($this->request->getParam('offset', '0'));
$entries = $this->logMapper->findByUserId($this->userId, $limit, $offset);
$data = array_map(fn($entry) => $entry->toArray(), $entries);
return new JSONResponse($data);
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Failed to load log: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*
* Manually trigger a sync for the current user.
*/
public function triggerSync(): JSONResponse {
try {
$stats = $this->syncService->syncForUser($this->userId);
return new JSONResponse([
'status' => 'ok',
'stats' => $stats,
]);
} catch (\Throwable $e) {
return new JSONResponse(
['error' => 'Sync failed: ' . $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
}