blob: 7f83d965bc0af2fd5f4deeaf2a229aa3fc0dccf0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
<?php
// Nextcloud - Social Support
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: AGPL-3.0-or-later
namespace OCA\Social\Service;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use OCA\Social\Entity\Mention;
use OCA\Social\Entity\Status;
use OCP\IRequest;
class ProcessMentionsService {
private Collection $previousMentions;
private Collection $currentMentions;
private IRequest $request;
private AccountFinder $accountFinder;
private ResolveAccountService $resolveAccountService;
public function __construct(IRequest $request, AccountFinder $accountFinder, ResolveAccountService $resolveAccountService) {
$this->previousMentions = new ArrayCollection();
$this->currentMentions = new ArrayCollection();
$this->request = $request;
$this->accountFinder = $accountFinder;
$this->resolveAccountService = $resolveAccountService;
}
public function run(Status $status) {
if (!$status->isLocal()) {
return;
}
$this->previousMentions = $status->getActiveMentions();
$this->currentMentions = new ArrayCollection();
if (preg_match('/@(([a-z0-9_]([a-z0-9_\.-]+[a-z0-9_]+)+)(@[[:word:]\.\-]+[[:word:]]+)?)/i', $status->getText(), $matches)) {
$host = $this->request->getServerHost();
for ($i = 0; $i < count($matches[0]); $i++) {
$completeMatch = $matches[0][$i];
$userName = $matches[2][$i];
$domain = $matches[2][$i] === '' ? '' : substr($matches[2][$i], 1);
$isLocal = $domain === '' || $host === $domain;
if ($isLocal) {
$domain = null;
} else {
// normalize domain name
$domain = parse_url('https://' . $domain, PHP_URL_HOST);
}
$mentionnedAccount = $this->accountFinder->findRemote($userName, $domain);
assert($mentionnedAccount !== null);
if (!$mentionnedAccount) {
// try to resolve it
$mentionnedAccount = $this->resolveAccountService->resolveMention($userName, $domain, AccountResolverOption::default());
}
if (!$mentionnedAccount) {
// give up
continue;
}
$mentions = $this->previousMentions->filter(fn (Mention $mention) => $mention->getAccount()->getId() === $mentionnedAccount->getId());
if ($mentions->isEmpty()) {
$mention = new Mention();
$mention->setStatus($status);
$mention->setAccount($mentionnedAccount);
} else {
$mention = $mentions->first();
}
$this->currentMentions->add($mention);
str_replace($completeMatch, $mentionnedAccount->getAccountName(), $status->getText());
}
}
}
}
|