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.
117 lines
5.0 KiB
PHP
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'
|
|
]
|
|
];
|
|
}
|
|
}
|