From 5f2e78637a097db1c6f5ed132b41ddc33f45c98c Mon Sep 17 00:00:00 2001 From: bernardhanna Date: Tue, 27 Jan 2026 17:30:50 +0000 Subject: [PATCH] matchmalking bulk --- .../Controllers/MatchMakingToolController.php | 17 ++++++++ app/Imports/MatchmakingProfileImport.php | 43 ++++++++++++++++--- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/MatchMakingToolController.php b/app/Http/Controllers/MatchMakingToolController.php index 7a3bd7095..1cc97101e 100644 --- a/app/Http/Controllers/MatchMakingToolController.php +++ b/app/Http/Controllers/MatchMakingToolController.php @@ -9,6 +9,7 @@ use Illuminate\View\View; use App\Filters\MatchmakingProfileFilters; use Symfony\Component\HttpFoundation\StreamedResponse; +use Illuminate\Support\Str; class MatchMakingToolController extends Controller { @@ -77,6 +78,22 @@ public function show(Request $request, string $slug): View $profile = MatchmakingProfile::where('slug', $slug)->first(); if (! $profile) { + // Fallback: try to match by computed slug from name or organisation name + $search = str_replace('-', ' ', $slug); + $candidates = MatchmakingProfile::query() + ->where('organisation_name', 'like', "%{$search}%") + ->orWhereRaw("CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) LIKE ?", ["%{$search}%"]) + ->get(['id', 'slug', 'first_name', 'last_name', 'organisation_name']); + + foreach ($candidates as $candidate) { + $orgSlug = $candidate->organisation_name ? Str::slug($candidate->organisation_name) : null; + $nameSlug = Str::slug(trim("{$candidate->first_name} {$candidate->last_name}")); + + if ($slug === $orgSlug || $slug === $nameSlug) { + return redirect()->route('matchmaking_tool_detail', ['slug' => $candidate->slug], 301); + } + } + abort(404); } diff --git a/app/Imports/MatchmakingProfileImport.php b/app/Imports/MatchmakingProfileImport.php index e2a00ad60..38af2c6e0 100644 --- a/app/Imports/MatchmakingProfileImport.php +++ b/app/Imports/MatchmakingProfileImport.php @@ -27,9 +27,13 @@ protected function parseArray($value): array if (empty($value)) { return []; } - // Handle semicolon-separated values (common in CSV exports) - $separator = strpos($value, ';') !== false ? ';' : ','; - return array_filter(array_map('trim', explode($separator, $value))); + // Handle semicolon/comma/pipe separated values (common in CSV exports) + $parts = preg_split('/[;,|]/', (string) $value); + return array_filter(array_map(function ($item) { + $item = trim((string) $item); + $item = trim($item, " \t\n\r\0\x0B."); + return $item; + }, $parts)); } /** @@ -551,11 +555,36 @@ public function model(array $row): ?Model 'Organization type', ]); if (!empty($orgTypeValue)) { - $orgType = trim($orgTypeValue); - // Check if it's a valid organisation type $validTypes = MatchmakingProfile::getValidOrganizationTypeOptions(); - if (in_array($orgType, $validTypes)) { - $organisationType = [$orgType]; + $validMap = []; + foreach ($validTypes as $typeOption) { + $validMap[mb_strtolower(trim($typeOption))] = $typeOption; + } + + $orgTypeValues = $this->parseArray($orgTypeValue); + $normalized = []; + foreach ($orgTypeValues as $value) { + $value = trim((string) $value); + $value = trim($value, " \t\n\r\0\x0B,."); + $key = mb_strtolower($value); + if (isset($validMap[$key])) { + $normalized[] = $validMap[$key]; + continue; + } + // Try collapsing multiple spaces and normalizing case + $collapsed = preg_replace('/\s+/', ' ', $key); + if (isset($validMap[$collapsed])) { + $normalized[] = $validMap[$collapsed]; + continue; + } + // Allow raw value if no valid match (keeps data for volunteers) + if ($value !== '') { + $normalized[] = $value; + } + } + + if (!empty($normalized)) { + $organisationType = array_values(array_unique($normalized)); } }