116 lines
3.1 KiB
PHP
116 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\JobApi;
|
|
|
|
use App\Models\JobSource;
|
|
use App\Services\JobApi\Clients\AdzunaClient;
|
|
use App\Services\JobApi\Clients\JobApiClient;
|
|
use App\Services\JobApi\Clients\RemotiveClient;
|
|
use App\Services\JobApi\Clients\TheMuseClient;
|
|
use App\Services\JobApi\Exceptions\ApiException;
|
|
|
|
class JobApiClientFactory
|
|
{
|
|
/**
|
|
* Client class mappings
|
|
*/
|
|
private const CLIENT_MAP = [
|
|
'remotive' => 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<JobApiClient>
|
|
*/
|
|
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;
|
|
}
|
|
}
|