308 lines
8.7 KiB
PHP
308 lines
8.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
final class JeuService
|
|
{
|
|
private JsonStore $store;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->store = new JsonStore(Config::get("dataPath") . "/jeux.json");
|
|
}
|
|
|
|
public function listerPourUtilisateur(
|
|
string $utilisateurId,
|
|
?string $recherche = null,
|
|
?string $consoleId = null,
|
|
?string $etat = null,
|
|
?string $format = null
|
|
): array
|
|
{
|
|
$jeux = $this->store->filtrer(
|
|
static fn (array $jeu): bool => ($jeu["utilisateurId"] ?? "") === $utilisateurId
|
|
);
|
|
|
|
if ($consoleId !== null && $consoleId !== "")
|
|
{
|
|
$jeux = array_values(array_filter(
|
|
$jeux,
|
|
static fn (array $jeu): bool => ($jeu["consoleId"] ?? "") === $consoleId
|
|
));
|
|
}
|
|
|
|
if ($etat !== null && $etat !== "")
|
|
{
|
|
$jeux = array_values(array_filter(
|
|
$jeux,
|
|
static fn (array $jeu): bool => ($jeu["etat"] ?? "") === $etat
|
|
));
|
|
}
|
|
|
|
if ($format !== null && $format !== "")
|
|
{
|
|
$jeux = array_values(array_filter(
|
|
$jeux,
|
|
static function (array $jeu) use ($format): bool
|
|
{
|
|
$formats = $jeu["formats"] ?? [];
|
|
|
|
return is_array($formats) && in_array($format, $formats, true);
|
|
}
|
|
));
|
|
}
|
|
|
|
if ($recherche !== null && $recherche !== "")
|
|
{
|
|
$terme = mb_strtolower($recherche);
|
|
$jeux = array_values(array_filter(
|
|
$jeux,
|
|
static function (array $jeu) use ($terme): bool
|
|
{
|
|
$champs = [
|
|
$jeu["titre"] ?? "",
|
|
$jeu["description"] ?? "",
|
|
$jeu["editeur"] ?? "",
|
|
$jeu["developpeur"] ?? "",
|
|
implode(" ", $jeu["genres"] ?? []),
|
|
implode(" ", $jeu["formats"] ?? [])
|
|
];
|
|
|
|
return str_contains(mb_strtolower(implode(" ", $champs)), $terme);
|
|
}
|
|
));
|
|
}
|
|
|
|
usort(
|
|
$jeux,
|
|
static fn (array $a, array $b): int => strcmp($a["titre"] ?? "", $b["titre"] ?? "")
|
|
);
|
|
|
|
return $jeux;
|
|
}
|
|
|
|
public function trouverPourUtilisateur(string $id, string $utilisateurId): ?array
|
|
{
|
|
$jeu = $this->store->trouverParId($id);
|
|
|
|
if ($jeu === null || ($jeu["utilisateurId"] ?? "") !== $utilisateurId)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return $jeu;
|
|
}
|
|
|
|
public function listerParConsole(string $consoleId, string $utilisateurId): array
|
|
{
|
|
return $this->listerPourUtilisateur($utilisateurId, null, $consoleId, null);
|
|
}
|
|
|
|
public function derniersAjouts(string $utilisateurId, int $limite = 6): array
|
|
{
|
|
$jeux = $this->listerPourUtilisateur($utilisateurId);
|
|
|
|
usort(
|
|
$jeux,
|
|
static fn (array $a, array $b): int => strcmp($b["createdAt"] ?? "", $a["createdAt"] ?? "")
|
|
);
|
|
|
|
return array_slice($jeux, 0, $limite);
|
|
}
|
|
|
|
public function creer(string $utilisateurId, array $donnees): array
|
|
{
|
|
$jeu = $this->preparerDonnees($utilisateurId, $donnees);
|
|
$maintenant = Helpers::maintenant();
|
|
|
|
$jeu["id"] = Helpers::genererId();
|
|
$jeu["utilisateurId"] = $utilisateurId;
|
|
$jeu["createdAt"] = $maintenant;
|
|
$jeu["updatedAt"] = $maintenant;
|
|
|
|
return $this->store->ajouter($jeu);
|
|
}
|
|
|
|
public function modifier(string $id, string $utilisateurId, array $donnees): array
|
|
{
|
|
$existant = $this->trouverPourUtilisateur($id, $utilisateurId);
|
|
|
|
if ($existant === null)
|
|
{
|
|
throw new RuntimeException("Jeu introuvable.");
|
|
}
|
|
|
|
$ancienneJaquette = $existant["jaquette"] ?? null;
|
|
$jeu = $this->preparerDonnees($utilisateurId, $donnees, $existant);
|
|
$jeu["updatedAt"] = Helpers::maintenant();
|
|
|
|
$miseAJour = $this->store->mettreAJour($id, $jeu);
|
|
|
|
if ($miseAJour === null)
|
|
{
|
|
throw new RuntimeException("Échec de la mise à jour.");
|
|
}
|
|
|
|
$nouvelleJaquette = $miseAJour["jaquette"] ?? null;
|
|
|
|
if (
|
|
$ancienneJaquette !== null
|
|
&& $ancienneJaquette !== ""
|
|
&& $ancienneJaquette !== $nouvelleJaquette
|
|
)
|
|
{
|
|
$this->supprimerJaquetteLocale($ancienneJaquette);
|
|
}
|
|
|
|
return $miseAJour;
|
|
}
|
|
|
|
public function remplacerJaquette(string $id, string $utilisateurId, array $fichier): array
|
|
{
|
|
$jeu = $this->trouverPourUtilisateur($id, $utilisateurId);
|
|
|
|
if ($jeu === null)
|
|
{
|
|
throw new RuntimeException("Jeu introuvable.");
|
|
}
|
|
|
|
$nouvelleJaquette = ImageUpload::enregistrer(
|
|
$fichier,
|
|
Config::get("jaquettesPath")
|
|
);
|
|
|
|
$this->supprimerJaquetteLocale($jeu["jaquette"] ?? null);
|
|
|
|
$miseAJour = $this->store->mettreAJour($id, [
|
|
"jaquette" => $nouvelleJaquette,
|
|
"sourceEnrichissement" => "manuel",
|
|
"updatedAt" => Helpers::maintenant()
|
|
]);
|
|
|
|
if ($miseAJour === null)
|
|
{
|
|
throw new RuntimeException("Échec de la mise à jour de la jaquette.");
|
|
}
|
|
|
|
return $miseAJour;
|
|
}
|
|
|
|
public function supprimer(string $id, string $utilisateurId): bool
|
|
{
|
|
$jeu = $this->trouverPourUtilisateur($id, $utilisateurId);
|
|
|
|
if ($jeu === null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
$this->supprimerJaquetteLocale($jeu["jaquette"] ?? null);
|
|
|
|
return $this->store->supprimer($id);
|
|
}
|
|
|
|
public function compterPourUtilisateur(string $utilisateurId): int
|
|
{
|
|
return count($this->listerPourUtilisateur($utilisateurId));
|
|
}
|
|
|
|
public function supprimerParConsole(string $consoleId, string $utilisateurId): int
|
|
{
|
|
$jeux = $this->listerParConsole($consoleId, $utilisateurId);
|
|
$compteur = 0;
|
|
|
|
foreach ($jeux as $jeu)
|
|
{
|
|
if ($this->supprimer($jeu["id"], $utilisateurId))
|
|
{
|
|
$compteur++;
|
|
}
|
|
}
|
|
|
|
return $compteur;
|
|
}
|
|
|
|
private function preparerDonnees(string $utilisateurId, array $donnees, ?array $existant = null): array
|
|
{
|
|
$titre = trim((string) ($donnees["titre"] ?? ""));
|
|
$consoleId = trim((string) ($donnees["consoleId"] ?? ""));
|
|
$etat = trim((string) ($donnees["etat"] ?? "possede"));
|
|
|
|
if ($titre === "" || $consoleId === "")
|
|
{
|
|
throw new InvalidArgumentException("Le titre et la console sont obligatoires.");
|
|
}
|
|
|
|
if (!array_key_exists($etat, Helpers::etatsJeu()))
|
|
{
|
|
throw new InvalidArgumentException("État de jeu invalide.");
|
|
}
|
|
|
|
$genres = $donnees["genres"] ?? [];
|
|
|
|
if (is_string($genres))
|
|
{
|
|
$genres = array_values(array_filter(array_map("trim", explode(",", $genres))));
|
|
}
|
|
|
|
if (!is_array($genres))
|
|
{
|
|
$genres = [];
|
|
}
|
|
|
|
$jaquette = trim((string) ($donnees["jaquette"] ?? ($existant["jaquette"] ?? "")));
|
|
|
|
return [
|
|
"titre" => $titre,
|
|
"consoleId" => $consoleId,
|
|
"etat" => $etat,
|
|
"formats" => Helpers::normaliserFormats($donnees["formats"] ?? []),
|
|
"jaquette" => $jaquette,
|
|
"description" => trim((string) ($donnees["description"] ?? "")),
|
|
"dateSortie" => $this->normaliserDate($donnees["dateSortie"] ?? null),
|
|
"genres" => array_values($genres),
|
|
"editeur" => trim((string) ($donnees["editeur"] ?? "")),
|
|
"developpeur" => trim((string) ($donnees["developpeur"] ?? "")),
|
|
"notes" => trim((string) ($donnees["notes"] ?? "")),
|
|
"sourceEnrichissement" => trim((string) ($donnees["sourceEnrichissement"] ?? "manuel"))
|
|
];
|
|
}
|
|
|
|
private function normaliserDate(mixed $date): ?string
|
|
{
|
|
if ($date === null || $date === "")
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$date = (string) $date;
|
|
|
|
if (!preg_match("/^\d{4}-\d{2}-\d{2}$/", $date))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return $date;
|
|
}
|
|
|
|
private function supprimerJaquetteLocale(?string $chemin): void
|
|
{
|
|
if ($chemin === null || $chemin === "")
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (str_starts_with($chemin, "http://") || str_starts_with($chemin, "https://"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$fichier = Config::get("jaquettesPath") . "/" . basename($chemin);
|
|
|
|
if (is_file($fichier))
|
|
{
|
|
unlink($fichier);
|
|
}
|
|
}
|
|
}
|