Files
mystuff_backend/api/Router.php
Lars Behrends 66f69bc90d Add PHP Media API scaffold and Docker configs
Initial project scaffold for a PHP Media API including routing, controllers, models and services under api/ (Router, Media/Cast/Image/Settings controllers, models, database/bootstrap files and automatic docs service). Adds Docker support (Dockerfile, docker-compose.yml, DOCKER_README.md, php-custom.ini), .htaccess for pretty URLs, API documentation and example payloads (API_EXAMPLES.md, api/README.md, api_examples/*.json), image handling service and logging, plus a comprehensive .gitignore. This commit provides a runnable development environment and example requests to get the API up and tested quickly.
2026-04-12 00:46:30 +02:00

117 lines
5.0 KiB
PHP

<?php
require_once __DIR__ . '/controllers/MediaController.php';
require_once __DIR__ . '/controllers/CastController.php';
require_once __DIR__ . '/controllers/ImageController.php';
require_once __DIR__ . '/controllers/SettingsController.php';
require_once __DIR__ . '/services/DocumentationService.php';
require_once __DIR__ . '/services/ApiLogger.php';
class Router {
private $pdo;
private $mediaController;
private $castController;
private $imageController;
private $settingsController;
private $documentationService;
private $logger;
public function __construct($pdo) {
$this->pdo = $pdo;
$this->mediaController = new MediaController($pdo);
$this->castController = new CastController($pdo);
$this->imageController = new ImageController();
$this->settingsController = new SettingsController($pdo);
$this->documentationService = new DocumentationService();
$this->logger = ApiLogger::getInstance();
}
public function route($method, $pathSegments) {
$path = '/' . implode('/', $pathSegments);
$queryString = $_SERVER['QUERY_STRING'] ?? '';
$fullPath = $queryString ? $path . '?' . $queryString : $path;
// Request loggen
$body = null;
if ($method === 'POST' || $method === 'PUT') {
$body = json_decode(file_get_contents('php://input'), true);
}
$this->logger->logRequest($method, $fullPath, $_GET, $body);
if (empty($pathSegments)) {
$response = $this->getRoot();
$this->logger->logResponse($method, $fullPath, 200, $response);
return $response;
}
$resource = $pathSegments[0];
try {
switch ($resource) {
case 'images':
// Images are served directly, bypass JSON response
$this->imageController->handleRequest($method, $pathSegments);
exit;
case 'media':
$response = $this->mediaController->handleRequest($method, $pathSegments);
$statusCode = http_response_code();
$this->logger->logResponse($method, $fullPath, $statusCode, $response);
return $response;
case 'cast':
$response = $this->castController->handleRequest($method, $pathSegments);
$statusCode = http_response_code();
$this->logger->logResponse($method, $fullPath, $statusCode, $response);
return $response;
case 'settings':
$response = $this->settingsController->handleRequest($method, $pathSegments);
$statusCode = http_response_code();
$this->logger->logResponse($method, $fullPath, $statusCode, $response);
return $response;
case 'docs':
$response = $this->getDocumentation();
$this->logger->logResponse($method, $fullPath, 200, $response);
return $response;
default:
http_response_code(404);
$response = ['success' => false, 'error' => 'Endpoint not found'];
$this->logger->logResponse($method, $fullPath, 404, $response);
return $response;
}
} catch (Exception $e) {
http_response_code(500);
$response = ['success' => false, 'error' => $e->getMessage()];
$this->logger->logError($method, $fullPath, $e->getMessage());
return $response;
}
}
private function getDocumentation() {
$docs = $this->documentationService->generateDocumentation();
return ['success' => true, 'data' => $docs];
}
private function getRoot() {
return [
'success' => true,
'message' => 'Media API v1.0',
'endpoints' => [
'GET /api/docs' => 'Automatische API-Dokumentation',
'GET /api/images/*' => 'Bilder abrufen (z.B. /api/images/games/poster_xxx.webp)',
'GET /api/media' => 'Alle Medien abrufen',
'GET /api/media/:id' => 'Ein Medium abrufen',
'POST /api/media' => 'Neues Medium erstellen',
'PUT /api/media/:id' => 'Medium aktualisieren',
'DELETE /api/media/:id' => 'Medium löschen',
'GET /api/cast' => 'Alle Cast-Mitglieder abrufen',
'GET /api/cast/:id' => 'Cast-Mitglied abrufen',
'GET /api/cast/:id/media' => 'Alle Medien eines Cast-Mitglieds abrufen',
'POST /api/cast' => 'Neues Cast-Mitglied erstellen',
'PUT /api/cast/:id' => 'Cast-Mitglied aktualisieren',
'DELETE /api/cast/:id' => 'Cast-Mitglied löschen',
'GET /api/settings' => 'Einstellungen abrufen',
'PUT /api/settings' => 'Einstellungen aktualisieren'
]
];
}
}