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.
This commit is contained in:
116
api/Router.php
Normal file
116
api/Router.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?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'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user