Skip to content

Commit a11a0e9

Browse files
committed
Merge branch 'dev'
2 parents a2fc0d8 + eca85a3 commit a11a0e9

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

app/Services/Matchmaking/ProfileAvatarResolver.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public function resolve(
6767
}
6868
}
6969

70+
$fuzzyMatch = $this->resolveFuzzy($candidates, $index, $isOrganisation);
71+
if ($fuzzyMatch !== null) {
72+
return '/' . ltrim($fuzzyMatch, '/');
73+
}
74+
7075
return null;
7176
}
7277

@@ -133,5 +138,71 @@ private function normalize(string $value): string
133138
{
134139
return Str::slug(trim($value));
135140
}
141+
142+
/**
143+
* @param array<int, string> $candidates
144+
* @param array<string, string> $index
145+
*/
146+
private function resolveFuzzy(array $candidates, array $index, bool $isOrganisation): ?string
147+
{
148+
$normalizedCandidates = [];
149+
foreach ($candidates as $candidate) {
150+
$normalized = $this->normalize($candidate);
151+
if ($normalized !== '') {
152+
$normalizedCandidates[] = $normalized;
153+
}
154+
}
155+
156+
if (empty($normalizedCandidates)) {
157+
return null;
158+
}
159+
160+
$bestScore = 0;
161+
$bestPath = null;
162+
163+
foreach ($index as $key => $path) {
164+
foreach ($normalizedCandidates as $candidate) {
165+
$score = $this->scoreMatch($candidate, $key, $isOrganisation);
166+
if ($score > $bestScore) {
167+
$bestScore = $score;
168+
$bestPath = $path;
169+
}
170+
}
171+
}
172+
173+
return $bestScore >= 40 ? $bestPath : null;
174+
}
175+
176+
private function scoreMatch(string $candidate, string $indexKey, bool $isOrganisation): int
177+
{
178+
if ($candidate === $indexKey) {
179+
return 100;
180+
}
181+
182+
$candidateTokens = array_values(array_filter(explode('-', $candidate)));
183+
$indexTokens = array_values(array_filter(explode('-', $indexKey)));
184+
$tokenOverlap = count(array_intersect($candidateTokens, $indexTokens));
185+
186+
if ($tokenOverlap === 0) {
187+
return 0;
188+
}
189+
190+
$candidateContainsKey = str_contains($candidate, $indexKey);
191+
$keyContainsCandidate = str_contains($indexKey, $candidate);
192+
193+
if (($candidateContainsKey || $keyContainsCandidate) && mb_strlen($indexKey) >= 5) {
194+
return 70 + min($tokenOverlap, 5);
195+
}
196+
197+
if ($isOrganisation && $tokenOverlap >= 2) {
198+
return 45 + min($tokenOverlap, 5);
199+
}
200+
201+
if (!$isOrganisation && $tokenOverlap >= 2) {
202+
return 40 + min($tokenOverlap, 5);
203+
}
204+
205+
return 0;
206+
}
136207
}
137208

0 commit comments

Comments
 (0)