171 lines
5.2 KiB
PHP
171 lines
5.2 KiB
PHP
<?php
|
|
include_once(__DIR__ . '/../../controller/DatabaseController.php');
|
|
|
|
header('Content-Type: application/json');
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', '0');
|
|
|
|
$deniedTables = [];
|
|
|
|
$validOperations = ['=', '!=', '<', '>', '<=', '>=', 'LIKE'];
|
|
|
|
function isValidEntry(string $name): bool {
|
|
return (bool) preg_match('/^[a-zA-Z0-9_]+$/', $name);
|
|
}
|
|
|
|
function PermittedSchemas(array $deniedTables): array {
|
|
static $cache = null;
|
|
if ($cache !== null) {
|
|
return $cache;
|
|
}
|
|
|
|
$alleSchemas = DatabaseShowAllSchemas(); // 1 Query statt N+1
|
|
$schema = [];
|
|
|
|
foreach ($alleSchemas as $table => $columns) {
|
|
if (!isValidEntry($table)) {
|
|
continue;
|
|
}
|
|
if (in_array($table, $deniedTables, true)) {
|
|
continue;
|
|
}
|
|
$schema[$table] = $columns;
|
|
}
|
|
|
|
$cache = $schema;
|
|
return $schema;
|
|
}
|
|
|
|
$erlaubteSchema = PermittedSchemas($deniedTables);
|
|
|
|
function isValidTable(string $table, array $schema): void {
|
|
if (!isValidEntry($table) || !isset($schema[$table])) {
|
|
throw new InvalidArgumentException("Tabelle nicht erlaubt: $table");
|
|
}
|
|
}
|
|
|
|
function isValidColumn(string $table, array $columns, array $schema): void {
|
|
foreach ($columns as $col) {
|
|
if (!isValidEntry($col) || !in_array($col, $schema[$table], true)) {
|
|
throw new InvalidArgumentException("Spalte nicht erlaubt: $col");
|
|
}
|
|
}
|
|
}
|
|
|
|
function buildWhere(array $conditions, string $table, array $schema, array $validOperations): array {
|
|
$parts = [];
|
|
$values = [];
|
|
|
|
foreach ($conditions as $cond) {
|
|
$col = $cond['column'] ?? '';
|
|
$op = $cond['operator'] ?? '=';
|
|
$val = $cond['value'] ?? null;
|
|
|
|
isValidColumn($table, [$col], $schema);
|
|
|
|
if (!in_array($op, $validOperations, true)) {
|
|
throw new InvalidArgumentException("Ungültiger Operator: $op");
|
|
}
|
|
|
|
$parts[] = "`$col` $op ?";
|
|
$values[] = $val;
|
|
}
|
|
|
|
return [implode(' AND ', $parts), $values];
|
|
}
|
|
|
|
// Request einlesen
|
|
$daten = json_decode(file_get_contents('php://input'), true) ?? [];
|
|
$action = $daten['action'] ?? '';
|
|
$table = $daten['table'] ?? '';
|
|
|
|
try {
|
|
isValidTable($table, $erlaubteSchema);
|
|
|
|
switch ($action) {
|
|
|
|
case 'insert': {
|
|
$columns = $daten['columns'] ?? [];
|
|
$values = $daten['values'] ?? [];
|
|
|
|
isValidColumn($table, $columns, $erlaubteSchema);
|
|
|
|
if (count($columns) !== count($values)) {
|
|
throw new InvalidArgumentException('Anzahl der Werte passt nicht zu den Spalten');
|
|
}
|
|
|
|
$columnsSql = implode(', ', array_map(fn($c) => "`$c`", $columns));
|
|
$result = DatabaseInsert($table, $columnsSql, ...$values);
|
|
echo json_encode(['success' => $result]);
|
|
break;
|
|
}
|
|
|
|
case 'show': {
|
|
$columns = $daten['columns'] ?? [];
|
|
$conditions = $daten['conditions'] ?? [];
|
|
|
|
if (empty($columns)) {
|
|
$columns = $erlaubteSchema[$table];
|
|
} else {
|
|
isValidColumn($table, $columns, $erlaubteSchema);
|
|
}
|
|
|
|
$columnsSql = implode(', ', array_map(fn($c) => "`$c`", $columns));
|
|
[$whereSql, $values] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations);
|
|
|
|
$result = DatabaseShow($table, $columnsSql, $whereSql, ...$values);
|
|
echo json_encode(['success' => true, 'entries' => array_values($result ?? [])]);
|
|
break;
|
|
}
|
|
|
|
case 'update': {
|
|
$updates = $daten['updates'] ?? [];
|
|
$conditions = $daten['conditions'] ?? [];
|
|
|
|
if (empty($conditions)) {
|
|
throw new InvalidArgumentException('WHERE-Bedingung ist bei UPDATE Pflicht');
|
|
}
|
|
|
|
isValidColumn($table, array_keys($updates), $erlaubteSchema);
|
|
|
|
$setParts = [];
|
|
$setValues = [];
|
|
foreach ($updates as $col => $val) {
|
|
$setParts[] = "`$col` = ?";
|
|
$setValues[] = $val;
|
|
}
|
|
$setSql = implode(', ', $setParts);
|
|
|
|
[$whereSql, $whereValues] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations);
|
|
|
|
$result = DatabaseUpdate($table, $setSql, $whereSql, ...array_merge($setValues, $whereValues));
|
|
echo json_encode(['success' => $result]);
|
|
break;
|
|
}
|
|
|
|
case 'delete': {
|
|
$conditions = $daten['conditions'] ?? [];
|
|
|
|
if (empty($conditions)) {
|
|
throw new InvalidArgumentException('WHERE-Bedingung ist bei DELETE Pflicht');
|
|
}
|
|
|
|
[$whereSql, $values] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations);
|
|
|
|
$result = DatabaseDelete($table, $whereSql, ...$values);
|
|
echo json_encode(['success' => $result]);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
throw new InvalidArgumentException("Unbekannte Aktion: $action");
|
|
}
|
|
|
|
} catch (InvalidArgumentException $e) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => $e->getMessage()]);
|
|
} catch (Throwable $e) {
|
|
http_response_code(500);
|
|
error_log($e->getMessage());
|
|
echo json_encode(['error' => 'Serverfehler']);
|
|
} |