251 lines
6.1 KiB
PHP
251 lines
6.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Enrichissement via l'API RAWG (https://rawg.io/apidocs).
|
|
* Si la clé API est absente ou l'API indisponible, renvoie une liste vide.
|
|
*/
|
|
final class EnrichissementService
|
|
{
|
|
private const BASE_URL = "https://api.rawg.io/api";
|
|
|
|
public function estDisponible(): bool
|
|
{
|
|
return Config::get("rawgApiKey", "") !== "";
|
|
}
|
|
|
|
public function rechercher(string $titre, int $limite = 8): array
|
|
{
|
|
$titre = trim($titre);
|
|
|
|
if ($titre === "" || !$this->estDisponible())
|
|
{
|
|
return [];
|
|
}
|
|
|
|
$cacheCle = "recherche_" . md5(mb_strtolower($titre));
|
|
$cache = $this->lireCache($cacheCle);
|
|
|
|
if ($cache !== null)
|
|
{
|
|
return array_slice($cache, 0, $limite);
|
|
}
|
|
|
|
$reponse = $this->appeler("/games", [
|
|
"search" => $titre,
|
|
"page_size" => $limite
|
|
]);
|
|
|
|
if ($reponse === null || !isset($reponse["results"]) || !is_array($reponse["results"]))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
$resultats = [];
|
|
|
|
foreach ($reponse["results"] as $jeu)
|
|
{
|
|
$resultats[] = $this->mapperResultatListe($jeu);
|
|
}
|
|
|
|
$this->ecrireCache($cacheCle, $resultats);
|
|
|
|
return $resultats;
|
|
}
|
|
|
|
public function detail(int $rawgId): ?array
|
|
{
|
|
if (!$this->estDisponible())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$cacheCle = "detail_" . $rawgId;
|
|
$cache = $this->lireCache($cacheCle);
|
|
|
|
if ($cache !== null)
|
|
{
|
|
return $cache;
|
|
}
|
|
|
|
$reponse = $this->appeler("/games/" . $rawgId);
|
|
|
|
if ($reponse === null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$detail = $this->mapperDetail($reponse);
|
|
$this->ecrireCache($cacheCle, $detail);
|
|
|
|
return $detail;
|
|
}
|
|
|
|
public function telechargerJaquette(?string $urlImage): ?string
|
|
{
|
|
if ($urlImage === null || $urlImage === "")
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$extension = pathinfo(parse_url($urlImage, PHP_URL_PATH) ?? "", PATHINFO_EXTENSION);
|
|
$extension = $extension !== "" ? strtolower($extension) : "jpg";
|
|
|
|
if (!in_array($extension, ["jpg", "jpeg", "png", "webp", "gif"], true))
|
|
{
|
|
$extension = "jpg";
|
|
}
|
|
|
|
$nomFichier = Helpers::genererId() . "." . $extension;
|
|
$cheminLocal = Config::get("jaquettesPath") . "/" . $nomFichier;
|
|
|
|
$contexte = stream_context_create([
|
|
"http" => [
|
|
"timeout" => 10,
|
|
"header" => "User-Agent: JeuxVideoTech/1.0\r\n"
|
|
]
|
|
]);
|
|
|
|
$contenu = @file_get_contents($urlImage, false, $contexte);
|
|
|
|
if ($contenu === false)
|
|
{
|
|
return $urlImage;
|
|
}
|
|
|
|
if (file_put_contents($cheminLocal, $contenu) === false)
|
|
{
|
|
return $urlImage;
|
|
}
|
|
|
|
return $nomFichier;
|
|
}
|
|
|
|
private function mapperResultatListe(array $jeu): array
|
|
{
|
|
$genres = [];
|
|
|
|
foreach ($jeu["genres"] ?? [] as $genre)
|
|
{
|
|
if (!empty($genre["name"]))
|
|
{
|
|
$genres[] = $genre["name"];
|
|
}
|
|
}
|
|
|
|
return [
|
|
"rawgId" => (int) ($jeu["id"] ?? 0),
|
|
"titre" => (string) ($jeu["name"] ?? ""),
|
|
"dateSortie" => $jeu["released"] ?? null,
|
|
"jaquetteUrl" => $jeu["background_image"] ?? null,
|
|
"genres" => $genres,
|
|
"note" => $jeu["rating"] ?? null
|
|
];
|
|
}
|
|
|
|
private function mapperDetail(array $jeu): array
|
|
{
|
|
$base = $this->mapperResultatListe($jeu);
|
|
|
|
$editeurs = [];
|
|
foreach ($jeu["publishers"] ?? [] as $editeur)
|
|
{
|
|
if (!empty($editeur["name"]))
|
|
{
|
|
$editeurs[] = $editeur["name"];
|
|
}
|
|
}
|
|
|
|
$developpeurs = [];
|
|
foreach ($jeu["developers"] ?? [] as $developpeur)
|
|
{
|
|
if (!empty($developpeur["name"]))
|
|
{
|
|
$developpeurs[] = $developpeur["name"];
|
|
}
|
|
}
|
|
|
|
$description = (string) ($jeu["description_raw"] ?? "");
|
|
|
|
if ($description === "" && !empty($jeu["description"]))
|
|
{
|
|
$description = trim(strip_tags((string) $jeu["description"]));
|
|
}
|
|
|
|
return array_merge($base, [
|
|
"description" => $description,
|
|
"editeur" => implode(", ", $editeurs),
|
|
"developpeur" => implode(", ", $developpeurs)
|
|
]);
|
|
}
|
|
|
|
private function appeler(string $chemin, array $params = []): ?array
|
|
{
|
|
$params["key"] = Config::get("rawgApiKey");
|
|
$url = self::BASE_URL . $chemin . "?" . http_build_query($params);
|
|
|
|
$contexte = stream_context_create([
|
|
"http" => [
|
|
"method" => "GET",
|
|
"timeout" => 8,
|
|
"header" => "User-Agent: JeuxVideoTech/1.0\r\nAccept: application/json\r\n"
|
|
]
|
|
]);
|
|
|
|
$reponse = @file_get_contents($url, false, $contexte);
|
|
|
|
if ($reponse === false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$donnees = json_decode($reponse, true);
|
|
|
|
return is_array($donnees) ? $donnees : null;
|
|
}
|
|
|
|
private function lireCache(string $cle): ?array
|
|
{
|
|
$fichier = Config::get("cachePath") . "/" . $cle . ".json";
|
|
|
|
if (!is_file($fichier))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (filemtime($fichier) < time() - 86400)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$contenu = file_get_contents($fichier);
|
|
|
|
if ($contenu === false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$donnees = json_decode($contenu, true);
|
|
|
|
return is_array($donnees) ? $donnees : null;
|
|
}
|
|
|
|
private function ecrireCache(string $cle, array $donnees): void
|
|
{
|
|
$dossier = Config::get("cachePath");
|
|
|
|
if (!is_dir($dossier))
|
|
{
|
|
mkdir($dossier, 0775, true);
|
|
}
|
|
|
|
$fichier = $dossier . "/" . $cle . ".json";
|
|
file_put_contents(
|
|
$fichier,
|
|
json_encode($donnees, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
|
LOCK_EX
|
|
);
|
|
}
|
|
}
|