Bladeren bron

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>
tags/v27.0.0beta2
Christoph Wurst 1 jaar geleden
bovenliggende
commit
8f0025ced3
No account linked to committer's email address
1 gewijzigde bestanden met toevoegingen van 59 en 49 verwijderingen
  1. 59
    49
      apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php

+ 59
- 49
apps/contactsinteraction/lib/Listeners/ContactInteractionListener.php Bestand weergeven

@@ -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 {

Laden…
Annuleren
Opslaan