174 lines
4.9 KiB
PHP
174 lines
4.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2025 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Mail\Service;
|
|
|
|
use OCA\Mail\Db\Actions;
|
|
use OCA\Mail\Db\ActionsMapper;
|
|
use OCA\Mail\Db\ActionStep;
|
|
use OCA\Mail\Db\ActionStepMapper;
|
|
use OCA\Mail\Exception\ServiceException;
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
|
|
|
class QuickActionsService {
|
|
|
|
public const AVAILABLE_ACTION_STEPS = [
|
|
'markAsSpam',
|
|
'applyTag',
|
|
'snooze',
|
|
'moveThread',
|
|
'deleteThread',
|
|
'markAsRead',
|
|
'markAsUnread',
|
|
'markAsImportant',
|
|
'markAsFavorite'
|
|
];
|
|
|
|
public function __construct(
|
|
private ActionsMapper $actionsMapper,
|
|
private ActionStepMapper $actionStepMapper,
|
|
) {
|
|
}
|
|
/**
|
|
* @param string $userId
|
|
* @return Actions[]
|
|
*/
|
|
public function findAll(string $userId): array {
|
|
$actions = $this->actionsMapper->findAll($userId);
|
|
$actionIds = array_map(fn (Actions $action) => $action->getId(), $actions);
|
|
$actionSteps = $this->actionStepMapper->findStepsByActionIds($actionIds, $userId);
|
|
return array_map(function (Actions $action) use ($actionSteps) {
|
|
$steps = array_values(array_filter($actionSteps, function (ActionStep $step) use ($action) {
|
|
return $step->getActionId() === $action->getId();
|
|
}));
|
|
$action->setActionSteps($steps);
|
|
if (!empty($steps)) {
|
|
$action->setIcon($steps[0]->getName());
|
|
}
|
|
return $action;
|
|
}, $actions);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function find(int $actionId, string $userId): ?Actions {
|
|
return $this->actionsMapper->find($actionId, $userId);
|
|
}
|
|
|
|
public function create(string $name, int $accountId): Actions {
|
|
$action = new Actions();
|
|
$action->setName($name);
|
|
$action->setAccountId($accountId);
|
|
return $this->actionsMapper->insert($action);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function update(Actions $action, string $name): Actions {
|
|
$action->setName($name);
|
|
return $this->actionsMapper->update($action);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function delete(int $actionId, string $userId): void {
|
|
$action = $this->actionsMapper->find($actionId, $userId);
|
|
$this->actionsMapper->delete($action);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function findActionStep(int $stepId, string $userId): ActionStep {
|
|
return $this->actionStepMapper->find($stepId, $userId);
|
|
}
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param int $order
|
|
* @param int $actionId
|
|
* @param string $parameter If the steps needs a parameter
|
|
* @return ActionStep
|
|
* @throws ServiceException
|
|
*/
|
|
public function createActionStep(string $name, int $order, int $actionId, ?int $tagId = null, ?int $mailboxId = null): ActionStep {
|
|
$this->validateActionStep($name, $order, $actionId, $tagId, $mailboxId);
|
|
$action = new ActionStep();
|
|
$action->setName($name);
|
|
$action->setOrder($order);
|
|
$action->setActionId($actionId);
|
|
$action->setTagId($tagId);
|
|
$action->setMailboxId($mailboxId);
|
|
return $this->actionStepMapper->insert($action);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function updateActionStep(ActionStep $action, string $name, int $order, ?int $tagId, ?int $mailboxId): ActionStep {
|
|
$action->setName($name);
|
|
$action->setOrder($order);
|
|
if ($tagId !== null) {
|
|
$action->setTagId($tagId);
|
|
}
|
|
if ($mailboxId !== null) {
|
|
$action->setMailboxId($mailboxId);
|
|
}
|
|
return $this->actionStepMapper->update($action);
|
|
}
|
|
|
|
/**
|
|
* @throws DoesNotExistException
|
|
*/
|
|
public function deleteActionStep(int $actionId, string $userId): void {
|
|
$action = $this->actionStepMapper->find($actionId, $userId);
|
|
$this->actionStepMapper->delete($action);
|
|
}
|
|
|
|
/**
|
|
* @throws ServiceException
|
|
*/
|
|
private function validateActionStep(string $name, int $order, int $actionId, ?int $tagId, ?int $mailboxId): void {
|
|
if (!in_array($name, self::AVAILABLE_ACTION_STEPS, true)) {
|
|
throw new ServiceException('Invalid action step');
|
|
}
|
|
try {
|
|
$highestOrderForAction = $this->actionStepMapper->findHighestOrderStep($actionId);
|
|
|
|
if ($highestOrderForAction === null && $order > 1) {
|
|
throw new ServiceException('Invalid action step order');
|
|
}
|
|
|
|
if ($highestOrderForAction && in_array($highestOrderForAction->getName(), ['deleteThread', 'moveThread', 'markAsSpam'], true)) {
|
|
throw new ServiceException('Cant perform actions after ' . $highestOrderForAction->getName());
|
|
}
|
|
|
|
if ($highestOrderForAction !== null && $order !== $highestOrderForAction->getOrder() + 1) {
|
|
throw new ServiceException('Invalid action step order');
|
|
}
|
|
} catch (DoesNotExistException $th) {
|
|
if ($order > 1) {
|
|
throw new ServiceException('Invalid action step order');
|
|
}
|
|
}
|
|
|
|
if ($name === 'applyTag' && $tagId === null) {
|
|
throw new ServiceException('TagId is required for applyTag action step');
|
|
}
|
|
|
|
if ($name === 'moveThread' && $mailboxId === null) {
|
|
throw new ServiceException('MailboxId is required for moveThread action step');
|
|
}
|
|
|
|
}
|
|
}
|