feat: controller liens avec validation et export json
This commit is contained in:
1 parent
a2324d2307
commit
a7003886da
1 file changed
+185
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
final class LinkController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LinkRepository $repository,
|
||||
private readonly JsonExporter $exporter,
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(string $method, string $path): void
|
||||
{
|
||||
if ($path === '/links' || $path === '/links/') {
|
||||
match ($method) {
|
||||
'GET' => $this->listLinks(),
|
||||
'POST' => $this->createLink(),
|
||||
default => $this->methodNotAllowed(),
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (preg_match('#^/links/(\d+)$#', $path, $matches)) {
|
||||
$id = (int) $matches[1];
|
||||
|
||||
match ($method) {
|
||||
'GET' => $this->showLink($id),
|
||||
'PUT' => $this->updateLink($id),
|
||||
'DELETE' => $this->deleteLink($id),
|
||||
default => $this->methodNotAllowed(),
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->routeNotFound();
|
||||
}
|
||||
|
||||
private function listLinks(): void
|
||||
{
|
||||
$this->json($this->repository->all());
|
||||
}
|
||||
|
||||
private function showLink(int $id): void
|
||||
{
|
||||
$link = $this->repository->find($id);
|
||||
|
||||
if ($link === null) {
|
||||
$this->json(['error' => 'Lien introuvable.'], 404);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->json($link);
|
||||
}
|
||||
|
||||
private function createLink(): void
|
||||
{
|
||||
$data = $this->body();
|
||||
$errors = $this->validate($data);
|
||||
|
||||
if ($errors !== []) {
|
||||
$this->json(['errors' => $errors], 422);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$id = $this->repository->create(
|
||||
trim($data['title']),
|
||||
trim((string) ($data['description'] ?? '')),
|
||||
trim($data['link_url']),
|
||||
$this->nullable($data['thumbnail'] ?? null),
|
||||
);
|
||||
} catch (PDOException) {
|
||||
$this->json(['error' => 'Cette URL de vidéo existe déjà.'], 409);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->exporter->export();
|
||||
$this->json($this->repository->find($id), 201);
|
||||
}
|
||||
|
||||
private function updateLink(int $id): void
|
||||
{
|
||||
if ($this->repository->find($id) === null) {
|
||||
$this->json(['error' => 'Lien introuvable.'], 404);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->body();
|
||||
$errors = $this->validate($data);
|
||||
|
||||
if ($errors !== []) {
|
||||
$this->json(['errors' => $errors], 422);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->update(
|
||||
$id,
|
||||
trim($data['title']),
|
||||
trim((string) ($data['description'] ?? '')),
|
||||
trim($data['link_url']),
|
||||
$this->nullable($data['thumbnail'] ?? null),
|
||||
);
|
||||
} catch (PDOException) {
|
||||
$this->json(['error' => 'Cette URL de vidéo existe déjà.'], 409);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->exporter->export();
|
||||
$this->json($this->repository->find($id));
|
||||
}
|
||||
|
||||
private function deleteLink(int $id): void
|
||||
{
|
||||
if ($this->repository->find($id) === null) {
|
||||
$this->json(['error' => 'Lien introuvable.'], 404);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->repository->delete($id);
|
||||
$this->exporter->export();
|
||||
http_response_code(204);
|
||||
}
|
||||
|
||||
private function body(): array
|
||||
{
|
||||
$decoded = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
private function validate(array $data): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
$title = trim((string) ($data['title'] ?? ''));
|
||||
$linkUrl = trim((string) ($data['link_url'] ?? ''));
|
||||
|
||||
if ($title === '') {
|
||||
$errors[] = 'Le champ title est requis.';
|
||||
}
|
||||
|
||||
if ($linkUrl === '') {
|
||||
$errors[] = 'Le champ link_url est requis.';
|
||||
} elseif (!filter_var($linkUrl, FILTER_VALIDATE_URL)) {
|
||||
$errors[] = 'Le champ link_url doit être une URL valide.';
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private function nullable(?string $value): ?string
|
||||
{
|
||||
$value = trim((string) $value);
|
||||
|
||||
return $value === '' ? null : $value;
|
||||
}
|
||||
|
||||
private function json(mixed $data, int $status = 200): void
|
||||
{
|
||||
http_response_code($status);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
private function routeNotFound(): void
|
||||
{
|
||||
$this->json(['error' => 'Route introuvable.'], 404);
|
||||
}
|
||||
|
||||
private function methodNotAllowed(): void
|
||||
{
|
||||
$this->json(['error' => 'Méthode non autorisée.'], 405);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user