summaryrefslogtreecommitdiffstats
path: root/apps/contactsinteraction
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2023-04-26 11:41:47 +0200
committerChristoph Wurst <christoph@winzerhof-wurst.at>2023-04-26 11:41:47 +0200
commit8f0025ced304334689b6947acf21115e29e7abc3 (patch)
tree70ff8460dff3657ce727c561932b0a68e1d2fb33 /apps/contactsinteraction
parentc08026a92ab020ac327aa7b8d379fc26cfe447bd (diff)
downloadnextcloud-server-8f0025ced304334689b6947acf21115e29e7abc3.tar.gz
nextcloud-server-8f0025ced304334689b6947acf21115e29e7abc3.zip
fix(contactsinteraction): Read, update or insert in DB transaction
The transaction guarantees there are no two concurrent inserts for the same interaction. Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'apps/contactsinteraction')
-rw-r--r--apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php108
1 files changed, 59 insertions, 49 deletions
diff --git a/apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php b/apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php
index 0d776bb9fcc..ad98a75065f 100644
--- a/apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php
+++ b/apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php
@@ -28,10 +28,12 @@ namespace OCA\ContactsInteraction\Listeners;
use OCA\ContactsInteraction\Db\CardSearchDao;
use OCA\ContactsInteraction\Db\RecentContact;
use OCA\ContactsInteraction\Db\RecentContactMapper;
+use OCP\AppFramework\Db\TTransactional;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Contacts\Events\ContactInteractedWithEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
+use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
@@ -41,9 +43,13 @@ use Sabre\VObject\UUIDUtil;
use Throwable;
class ContactInteractionListener implements IEventListener {
+
+ use TTransactional;
+
private RecentContactMapper $mapper;
private CardSearchDao $cardSearchDao;
private IUserManager $userManager;
+ private IDBConnection $dbConnection;
private ITimeFactory $timeFactory;
private IL10N $l10n;
private LoggerInterface $logger;
@@ -51,12 +57,14 @@ class ContactInteractionListener implements IEventListener {
public function __construct(RecentContactMapper $mapper,
CardSearchDao $cardSearchDao,
IUserManager $userManager,
+ IDBConnection $connection,
ITimeFactory $timeFactory,
IL10N $l10nFactory,
LoggerInterface $logger) {
$this->mapper = $mapper;
$this->cardSearchDao = $cardSearchDao;
$this->userManager = $userManager;
+ $this->dbConnection = $connection;
$this->timeFactory = $timeFactory;
$this->l10n = $l10nFactory;
$this->logger = $logger;
@@ -77,58 +85,60 @@ class ContactInteractionListener implements IEventListener {
return;
}
- $existing = $this->mapper->findMatch(
- $event->getActor(),
- $event->getUid(),
- $event->getEmail(),
- $event->getFederatedCloudId()
- );
- if (!empty($existing)) {
- $now = $this->timeFactory->getTime();
- foreach ($existing as $c) {
- $c->setLastContact($now);
- $this->mapper->update($c);
+ $this->atomic(function () use ($event) {
+ $existing = $this->mapper->findMatch(
+ $event->getActor(),
+ $event->getUid(),
+ $event->getEmail(),
+ $event->getFederatedCloudId()
+ );
+ if (!empty($existing)) {
+ $now = $this->timeFactory->getTime();
+ foreach ($existing as $c) {
+ $c->setLastContact($now);
+ $this->mapper->update($c);
+ }
+
+ return;
}
- return;
- }
-
- $contact = new RecentContact();
- $contact->setActorUid($event->getActor()->getUID());
- if ($event->getUid() !== null) {
- $contact->setUid($event->getUid());
- }
- if ($event->getEmail() !== null) {
- $contact->setEmail($event->getEmail());
- }
- if ($event->getFederatedCloudId() !== null) {
- $contact->setFederatedCloudId($event->getFederatedCloudId());
- }
- $contact->setLastContact($this->timeFactory->getTime());
-
- $copy = $this->cardSearchDao->findExisting(
- $event->getActor(),
- $event->getUid(),
- $event->getEmail(),
- $event->getFederatedCloudId()
- );
- if ($copy !== null) {
- try {
- $parsed = Reader::read($copy, Reader::OPTION_FORGIVING);
- $parsed->CATEGORIES = $this->l10n->t('Recently contacted');
- $contact->setCard($parsed->serialize());
- } catch (Throwable $e) {
- $this->logger->warning(
- 'Could not parse card to add recent category: ' . $e->getMessage(),
- [
- 'exception' => $e,
- ]);
- $contact->setCard($copy);
+ $contact = new RecentContact();
+ $contact->setActorUid($event->getActor()->getUID());
+ if ($event->getUid() !== null) {
+ $contact->setUid($event->getUid());
}
- } else {
- $contact->setCard($this->generateCard($contact));
- }
- $this->mapper->insert($contact);
+ if ($event->getEmail() !== null) {
+ $contact->setEmail($event->getEmail());
+ }
+ if ($event->getFederatedCloudId() !== null) {
+ $contact->setFederatedCloudId($event->getFederatedCloudId());
+ }
+ $contact->setLastContact($this->timeFactory->getTime());
+
+ $copy = $this->cardSearchDao->findExisting(
+ $event->getActor(),
+ $event->getUid(),
+ $event->getEmail(),
+ $event->getFederatedCloudId()
+ );
+ if ($copy !== null) {
+ try {
+ $parsed = Reader::read($copy, Reader::OPTION_FORGIVING);
+ $parsed->CATEGORIES = $this->l10n->t('Recently contacted');
+ $contact->setCard($parsed->serialize());
+ } catch (Throwable $e) {
+ $this->logger->warning(
+ 'Could not parse card to add recent category: ' . $e->getMessage(),
+ [
+ 'exception' => $e,
+ ]);
+ $contact->setCard($copy);
+ }
+ } else {
+ $contact->setCard($this->generateCard($contact));
+ }
+ $this->mapper->insert($contact);
+ }, $this->dbConnection);
}
private function getDisplayName(?string $uid): ?string {