RemotiveClient::class, 'the-muse' => TheMuseClient::class, 'adzuna' => AdzunaClient::class, ]; /** * Create an API client for the given source * * @param JobSource $source * @return JobApiClient * @throws ApiException */ public static function make(JobSource $source): JobApiClient { $sourceName = strtolower($source->name); $normalizedName = self::normalizeSourceName($sourceName); if (!isset(self::CLIENT_MAP[$normalizedName])) { throw new ApiException( "No client implementation found for source: {$source->name}", $source->name, ['available_clients' => array_keys(self::CLIENT_MAP)] ); } $clientClass = self::CLIENT_MAP[$normalizedName]; return new $clientClass($source); } /** * Create clients for all active sources * * @return array */ public static function makeAll(): array { $sources = JobSource::active()->get(); return $sources->map(function (JobSource $source) { try { return self::make($source); } catch (ApiException $e) { // Log the error but continue with other sources \Log::warning("Failed to create client for source: {$source->name}", [ 'error' => $e->getMessage(), ]); return null; } })->filter()->values()->all(); } /** * Create a client by source name * * @param string $sourceName * @return JobApiClient * @throws ApiException */ public static function makeByName(string $sourceName): JobApiClient { $source = JobSource::where('name', $sourceName) ->orWhere('name', 'LIKE', "%{$sourceName}%") ->firstOrFail(); return self::make($source); } /** * Get all available client types * * @return array */ public static function getAvailableClients(): array { return array_keys(self::CLIENT_MAP); } /** * Normalize source name for lookup */ private static function normalizeSourceName(string $name): string { // Convert "Remotive", "remotive.io", "Remotive.io" to "remotive" $name = strtolower($name); $name = str_replace(['.io', '.com', ' '], '', $name); // Handle special cases $name = match (true) { str_contains($name, 'muse') => 'the-muse', str_contains($name, 'remotive') => 'remotive', str_contains($name, 'adzuna') => 'adzuna', default => $name, }; return $name; } }