mirror of
https://github.com/chenasraf/cospend-nc.git
synced 2026-05-17 17:38:10 +00:00
271 lines
8.4 KiB
PHP
271 lines
8.4 KiB
PHP
<?php
|
|
/**
|
|
* @copyright Copyright (c) 2019 Julien Veyssier <julien-nc@posteo.net>
|
|
*
|
|
* @author Julien Veyssier <julien-nc@posteo.net>
|
|
*
|
|
* @license GNU AGPL version 3 or any later version
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
namespace OCA\Cospend\Activity;
|
|
|
|
use Exception;
|
|
use InvalidArgumentException;
|
|
use OCA\Cospend\Db\Bill;
|
|
use OCA\Cospend\Db\BillMapper;
|
|
use OCA\Cospend\Db\Project;
|
|
use OCA\Cospend\Db\ProjectMapper;
|
|
use OCA\Cospend\Service\UserService;
|
|
|
|
use OCP\Activity\IEvent;
|
|
use OCP\Activity\IManager;
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
|
use OCP\AppFramework\Db\Entity;
|
|
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
|
use OCP\IL10N;
|
|
use Psr\Log\LoggerInterface;
|
|
use function get_class;
|
|
|
|
class ActivityManager {
|
|
|
|
public const COSPEND_OBJECT_BILL = 'cospend_bill';
|
|
public const COSPEND_OBJECT_PROJECT = 'cospend_project';
|
|
|
|
public const SUBJECT_BILL_CREATE = 'bill_create';
|
|
public const SUBJECT_BILL_UPDATE = 'bill_update';
|
|
public const SUBJECT_BILL_DELETE = 'bill_delete';
|
|
|
|
public const SUBJECT_PROJECT_SHARE = 'project_share';
|
|
public const SUBJECT_PROJECT_UNSHARE = 'project_unshare';
|
|
|
|
public function __construct(
|
|
private IManager $manager,
|
|
private UserService $userService,
|
|
private ProjectMapper $projectMapper,
|
|
private BillMapper $billMapper,
|
|
private IL10N $l10n,
|
|
private LoggerInterface $logger,
|
|
private ?string $userId,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @param string $subjectIdentifier
|
|
* @param array $subjectParams
|
|
* @param bool $ownActivity
|
|
* @return string
|
|
*/
|
|
public function getActivityFormat(string $subjectIdentifier, array $subjectParams = [], bool $ownActivity = false): string {
|
|
$subject = '';
|
|
switch ($subjectIdentifier) {
|
|
case self::SUBJECT_BILL_CREATE:
|
|
$subject = $ownActivity ? $this->l10n->t('You have created a new bill {bill} in project {project}'): $this->l10n->t('{user} has created a new bill {bill} in project {project}');
|
|
break;
|
|
case self::SUBJECT_BILL_DELETE:
|
|
$subject = $ownActivity ? $this->l10n->t('You have deleted the bill {bill} of project {project}') : $this->l10n->t('{user} has deleted the bill {bill} of project {project}');
|
|
break;
|
|
case self::SUBJECT_PROJECT_SHARE:
|
|
$subject = $ownActivity ? $this->l10n->t('You have shared the project {project} with {who}') : $this->l10n->t('{user} has shared the project {project} with {who}');
|
|
break;
|
|
case self::SUBJECT_PROJECT_UNSHARE:
|
|
$subject = $ownActivity ? $this->l10n->t('You have removed {who} from the project {project}') : $this->l10n->t('{user} has removed {who} from the project {project}');
|
|
break;
|
|
case self::SUBJECT_BILL_UPDATE:
|
|
$subject = $ownActivity ? $this->l10n->t('You have updated the bill {bill} of project {project}') : $this->l10n->t('{user} has updated the bill {bill} of project {project}');
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return $subject;
|
|
}
|
|
|
|
/**
|
|
* @param string $objectType
|
|
* @param Entity $entity
|
|
* @param string $subject
|
|
* @param array $additionalParams
|
|
* @param string|null $author
|
|
*/
|
|
public function triggerEvent(string $objectType, Entity $entity, string $subject, array $additionalParams = [], ?string $author = null) {
|
|
try {
|
|
$event = $this->createEvent($objectType, $entity, $subject, $additionalParams, $author);
|
|
if ($event !== null) {
|
|
$this->sendToUsers($event);
|
|
}
|
|
} catch (Exception $e) {
|
|
// Ignore exception for undefined activities on update events
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $objectType
|
|
* @param Entity $entity
|
|
* @param string $subject
|
|
* @param array $additionalParams
|
|
* @param string|null $author
|
|
* @return IEvent|null
|
|
* @throws Exception
|
|
*/
|
|
private function createEvent(string $objectType, Entity $entity, string $subject, array $additionalParams = [], ?string $author = null): ?IEvent {
|
|
if ($subject === self::SUBJECT_BILL_DELETE) {
|
|
$object = $entity;
|
|
} else {
|
|
try {
|
|
$object = $this->findObjectForEntity($objectType, $entity);
|
|
} catch (DoesNotExistException $e) {
|
|
$this->logger->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity);
|
|
return null;
|
|
} catch (MultipleObjectsReturnedException $e) {
|
|
$this->logger->error('Could not create activity entry for ' . $subject . '. Entity not found.', (array)$entity);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Automatically fetch related details for subject parameters
|
|
* depending on the subject
|
|
*/
|
|
$eventType = 'cospend';
|
|
$subjectParams = [];
|
|
$message = null;
|
|
$objectName = null;
|
|
switch ($subject) {
|
|
// No need to enhance parameters since entity already contains the required data
|
|
case self::SUBJECT_BILL_CREATE:
|
|
case self::SUBJECT_BILL_UPDATE:
|
|
case self::SUBJECT_BILL_DELETE:
|
|
$subjectParams = $this->findDetailsForBill($object);
|
|
/** @var Bill $object */
|
|
$objectName = $object->getWhat();
|
|
$eventType = 'cospend_bill_event';
|
|
break;
|
|
case self::SUBJECT_PROJECT_SHARE:
|
|
case self::SUBJECT_PROJECT_UNSHARE:
|
|
$subjectParams = $this->findDetailsForProject((string) $entity->getId());
|
|
$objectName = $object->getId();
|
|
break;
|
|
default:
|
|
throw new Exception('Unknown subject for activity.');
|
|
}
|
|
$subjectParams['author'] = $this->l10n->t('A guest user');
|
|
|
|
$event = $this->manager->generateEvent();
|
|
$event->setApp('cospend')
|
|
->setType($eventType)
|
|
->setAuthor($author === null ? $this->userId ?? '' : $author)
|
|
->setObject($objectType, (int)$object->getId(), (string) $objectName)
|
|
->setSubject($subject, array_merge($subjectParams, $additionalParams))
|
|
->setTimestamp(time());
|
|
|
|
/*
|
|
if ($message !== null) {
|
|
$event->setMessage($message);
|
|
}
|
|
*/
|
|
return $event;
|
|
}
|
|
|
|
/**
|
|
* Publish activity to all users that are part of the project of a given object
|
|
*
|
|
* @param IEvent $event
|
|
*/
|
|
private function sendToUsers(IEvent $event) {
|
|
$projectId = '';
|
|
switch ($event->getObjectType()) {
|
|
case self::COSPEND_OBJECT_BILL:
|
|
$projectId = $event->getSubjectParameters()['project']['id'];
|
|
break;
|
|
case self::COSPEND_OBJECT_PROJECT:
|
|
$projectId = $event->getObjectName();
|
|
break;
|
|
}
|
|
foreach ($this->userService->findUsers($projectId) as $user) {
|
|
$event->setAffectedUser($user);
|
|
/** @noinspection DisconnectedForeachInstructionInspection */
|
|
$this->manager->publish($event);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $objectType
|
|
* @param $entity
|
|
* @return Entity
|
|
*/
|
|
private function findObjectForEntity($objectType, $entity): Entity {
|
|
$className = get_class($entity);
|
|
if ($objectType === self::COSPEND_OBJECT_BILL) {
|
|
switch ($className) {
|
|
case Bill::class:
|
|
$objectId = $entity->getId();
|
|
break;
|
|
default:
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
|
|
}
|
|
return $this->billMapper->find($objectId);
|
|
}
|
|
if ($objectType === self::COSPEND_OBJECT_PROJECT) {
|
|
switch ($className) {
|
|
case Project::class:
|
|
$objectId = $entity->getId();
|
|
break;
|
|
default:
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
|
|
}
|
|
return $this->projectMapper->find($objectId);
|
|
}
|
|
throw new InvalidArgumentException('No entity relation present for '. $className . ' to ' . $objectType);
|
|
}
|
|
|
|
/**
|
|
* @param object $bill
|
|
* @return array[]
|
|
*/
|
|
private function findDetailsForBill(object $bill): array {
|
|
$project = $this->projectMapper->find($bill->getProjectid());
|
|
$bill = [
|
|
'id' => $bill->getId(),
|
|
'name' => $bill->getWhat(),
|
|
'amount' => $bill->getAmount()
|
|
];
|
|
$project = [
|
|
'id' => $project->getId(),
|
|
'name' => $project->getName()
|
|
];
|
|
return [
|
|
'bill' => $bill,
|
|
'project' => $project
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param string $projectId
|
|
* @return array[]
|
|
*/
|
|
private function findDetailsForProject(string $projectId): array {
|
|
$project = $this->projectMapper->find($projectId);
|
|
$project = [
|
|
'id' => $project->getId(),
|
|
'name' => $project->getName()
|
|
];
|
|
return [
|
|
'project' => $project
|
|
];
|
|
}
|
|
|
|
}
|