0) { $adopters[(int) $r['OWNERID']] = true; } } foreach ($source['animal'] ?? [] as $r) { foreach (['BROUGHTINBYOWNERID', 'ORIGINALOWNERID'] as $field) { if ((int) ($r[$field] ?? 0) > 0) { $depositors[(int) $r[$field]] = true; } } foreach (['CURRENTVETID', 'OWNERSVETID'] as $field) { if ((int) ($r[$field] ?? 0) > 0) { $vets[(int) $r[$field]] = true; } } } foreach ($source['animalvaccination'] ?? [] as $r) { if ((int) ($r['ADMINISTERINGVETID'] ?? 0) > 0) { $vets[(int) $r['ADMINISTERINGVETID']] = true; } } $existing = $db ->query('SELECT id,kind,name,phone,email,city FROM directory_contacts WHERE deleted_at IS NULL') ->fetchAll(PDO::FETCH_ASSOC); $items = []; $summary = ['create' => 0, 'match' => 0, 'review' => 0]; foreach ($source['owner'] ?? [] as $row) { $mapped = self::map( $row, isset($adopters[(int) $row['ID']]), isset($depositors[(int) $row['ID']]), isset($vets[(int) $row['ID']]), ); $strong = []; $weak = []; $reasons = []; foreach ($existing as $contact) { $email = self::text($mapped['email']); $phone = self::phone($mapped['phone']); $sameEmail = $email !== '' && $email === self::text($contact['email']); $samePhone = $phone !== '' && $phone === self::phone($contact['phone']); $sameIdentity = self::text($mapped['name']) === self::text($contact['name']) && self::text($mapped['city']) === self::text($contact['city']); if ($sameEmail || $samePhone || $sameIdentity) { $strong[(int) $contact['id']] = $contact; if ($sameEmail) { $reasons[] = 'même adresse e-mail'; } if ($samePhone) { $reasons[] = 'même téléphone'; } if ($sameIdentity) { $reasons[] = 'même nom et ville'; } } elseif ( self::text($mapped['name']) !== '' && self::text($mapped['name']) === self::text($contact['name']) ) { $weak[(int) $contact['id']] = $contact; } } if (count($strong) === 1) { $action = 'match'; $candidates = $strong; } elseif (count($strong) > 1) { $action = 'review'; $candidates = $strong; } elseif ($weak) { $action = 'review'; $candidates = $weak; $reasons[] = 'même nom uniquement'; } else { $action = 'create'; $candidates = []; } $summary[$action]++; $items[] = [ 'asm3_id' => (int) $row['ID'], 'action' => $action, 'match_reasons' => array_values(array_unique($reasons)), 'globinours_candidates' => array_values( array_map( static fn($c) => ['id' => (int) $c['id'], 'name' => $c['name'], 'city' => $c['city']], $candidates, ), ), 'mapped' => $mapped, ]; } return ['source' => basename($path), 'read_only' => true, 'summary' => $summary, 'items' => $items]; } private static function map(array $r, bool $adopter, bool $depositor, bool $vetReferenced): array { $yes = static fn($v) => (string) $v === '1'; $name = trim( (string) ($r['OWNERNAME'] ?? '' ?: trim((string) ($r['OWNERFORENAMES'] ?? '') . ' ' . (string) ($r['OWNERSURNAME'] ?? ''))), ); $organization = (bool) preg_match('/\b(cabinet|clinique|cr[eé]matorium|association|refuge|fourri[eè]re)\b/iu', $name) || $yes($r['ISSHELTER'] ?? 0) || $yes($r['ISSUPPLIER'] ?? 0); $roles = []; if ($adopter || $yes($r['ISADOPTER'] ?? 0)) { $roles[] = 'adoptant'; } if ($yes($r['ISFOSTERER'] ?? 0)) { $roles[] = 'fa'; } if ($yes($r['ISVOLUNTEER'] ?? 0)) { $roles[] = 'benevole'; } if ($depositor) { $roles[] = 'deposant'; } if ($vetReferenced || $yes($r['ISVET'] ?? 0)) { $roles[] = $organization ? 'cabinet' : 'veterinaire'; } if (preg_match('/cr[eé]matorium/iu', $name)) { $roles[] = 'crematorium'; } $phones = array_values( array_filter([ trim((string) ($r['MOBILETELEPHONE'] ?? '')), trim((string) ($r['HOMETELEPHONE'] ?? '')), trim((string) ($r['WORKTELEPHONE'] ?? '')), ]), ); return [ 'kind' => $organization ? 'organization' : 'person', 'name' => $name ?: 'Contact ASM3 ' . (int) $r['ID'], 'phone' => $phones[0] ?? null, 'email' => trim((string) ($r['EMAILADDRESS'] ?? '')) ?: null, 'address' => trim((string) ($r['OWNERADDRESS'] ?? '')) ?: null, 'postal_code' => trim((string) ($r['OWNERPOSTCODE'] ?? '')) ?: null, 'city' => trim((string) ($r['OWNERTOWN'] ?? '')) ?: null, 'country' => trim((string) ($r['OWNERCOUNTRY'] ?? '')) ?: 'France', 'notes' => trim((string) ($r['COMMENTS'] ?? '')) ?: null, 'roles' => array_values(array_unique($roles)), ]; } private static function text(mixed $v): string { return mb_strtolower(trim((string) $v)); } private static function phone(mixed $v): string { return (string) preg_replace('/\D+/', '', (string) $v); } }