projet par cursor
This commit is contained in:
1 parent
236f75ecdd
commit
b785db1b84
47 files changed
+3902
No files matched your search
@@ -0,0 +1,249 @@
|
||||
<?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
|
||||
): 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 ($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"] ?? [])
|
||||
];
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
$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.");
|
||||
}
|
||||
|
||||
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,
|
||||
"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);
|
||||
}
|
||||
}
|
||||
}
|
||||