Excluir api.php
This commit is contained in:
238
api.php
238
api.php
@@ -1,238 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Cardix Admin - MySQL Proxy API
|
|
||||||
* =========================================================
|
|
||||||
* INSTRUÇÕES DE DEPLOY:
|
|
||||||
* 1. Copie este arquivo para o seu servidor em 31.97.64.165
|
|
||||||
* 2. Coloque em um diretório acessível pelo Apache/Nginx
|
|
||||||
* Ex: /var/www/html/cardix-api/api.php
|
|
||||||
* 3. Acesse pelo browser: http://31.97.64.165/cardix-api/api.php?action=tables
|
|
||||||
* 4. Atualize a variável API_URL em src/lib/config.ts com a URL correta
|
|
||||||
* =========================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ---- Configurações ----
|
|
||||||
define('API_SECRET', 'cardix-admin-2024');
|
|
||||||
define('DB_HOST', 'localhost'); // Use 'localhost' se MySQL está no mesmo servidor
|
|
||||||
define('DB_NAME', 'cardix');
|
|
||||||
define('DB_USER', 'wander');
|
|
||||||
define('DB_PASS', 'DIpIYIp25O');
|
|
||||||
define('DB_PORT', 3306);
|
|
||||||
|
|
||||||
// ---- CORS Headers ----
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
header('Access-Control-Allow-Origin: *');
|
|
||||||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
|
||||||
header('Access-Control-Allow-Headers: Content-Type, X-API-Key');
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
||||||
http_response_code(204);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Autenticação por API Key ----
|
|
||||||
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
|
||||||
if ($apiKey !== API_SECRET) {
|
|
||||||
http_response_code(401);
|
|
||||||
echo json_encode(['error' => 'Não autorizado. Forneça o header X-API-Key.']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Conexão PDO ----
|
|
||||||
try {
|
|
||||||
$pdo = new PDO(
|
|
||||||
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";port=" . DB_PORT . ";charset=utf8mb4",
|
|
||||||
DB_USER,
|
|
||||||
DB_PASS,
|
|
||||||
[
|
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
||||||
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode(['error' => 'Falha na conexão com o banco de dados: ' . $e->getMessage()]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Helpers ----
|
|
||||||
function sanitizeIdentifier(string $name): string {
|
|
||||||
return preg_replace('/[^a-zA-Z0-9_]/', '', $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPrimaryKey(PDO $pdo, string $table): string {
|
|
||||||
$stmt = $pdo->query("SHOW KEYS FROM `{$table}` WHERE Key_name = 'PRIMARY'");
|
|
||||||
$row = $stmt->fetch();
|
|
||||||
return $row ? $row['Column_name'] : 'id';
|
|
||||||
}
|
|
||||||
|
|
||||||
function jsonResponse(mixed $data, int $status = 200): void {
|
|
||||||
http_response_code($status);
|
|
||||||
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Roteamento ----
|
|
||||||
$method = $_SERVER['REQUEST_METHOD'];
|
|
||||||
$action = $_GET['action'] ?? null;
|
|
||||||
$table = isset($_GET['table']) ? sanitizeIdentifier($_GET['table']) : null;
|
|
||||||
$id = $_GET['id'] ?? null;
|
|
||||||
|
|
||||||
// ACTION: Listar todas as tabelas
|
|
||||||
if ($action === 'tables') {
|
|
||||||
$stmt = $pdo->query("SHOW TABLES");
|
|
||||||
jsonResponse($stmt->fetchAll(PDO::FETCH_COLUMN));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACTION: Schema de uma tabela (colunas + FKs)
|
|
||||||
if ($action === 'schema' && $table) {
|
|
||||||
$stmt = $pdo->query("DESCRIBE `{$table}`");
|
|
||||||
$columns = $stmt->fetchAll();
|
|
||||||
|
|
||||||
$fkStmt = $pdo->prepare("
|
|
||||||
SELECT COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
|
|
||||||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
|
||||||
WHERE TABLE_SCHEMA = DATABASE()
|
|
||||||
AND TABLE_NAME = ?
|
|
||||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
||||||
");
|
|
||||||
$fkStmt->execute([$table]);
|
|
||||||
$fks = $fkStmt->fetchAll();
|
|
||||||
|
|
||||||
// Para cada FK, detecta a melhor coluna de exibição
|
|
||||||
$fkDisplay = [];
|
|
||||||
foreach ($fks as $fk) {
|
|
||||||
$refTable = $fk['REFERENCED_TABLE_NAME'];
|
|
||||||
$descStmt = $pdo->query("DESCRIBE `{$refTable}`");
|
|
||||||
$refCols = $descStmt->fetchAll();
|
|
||||||
|
|
||||||
$displayCol = null;
|
|
||||||
foreach ($refCols as $col) {
|
|
||||||
if ($col['Field'] !== $fk['REFERENCED_COLUMN_NAME'] &&
|
|
||||||
(strpos($col['Type'], 'varchar') !== false || strpos($col['Type'], 'text') !== false)) {
|
|
||||||
$displayCol = $col['Field'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$fkDisplay[$fk['COLUMN_NAME']] = [
|
|
||||||
'table' => $refTable,
|
|
||||||
'keyCol' => $fk['REFERENCED_COLUMN_NAME'],
|
|
||||||
'displayCol' => $displayCol ?? $fk['REFERENCED_COLUMN_NAME'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonResponse(['columns' => $columns, 'foreignKeys' => $fks, 'fkDisplay' => $fkDisplay]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACTION: Opções para campo FK (select dropdown)
|
|
||||||
if ($action === 'fk_options' && $table) {
|
|
||||||
$pkCol = sanitizeIdentifier($_GET['pk'] ?? 'id');
|
|
||||||
$labelCol = sanitizeIdentifier($_GET['label'] ?? $pkCol);
|
|
||||||
|
|
||||||
$stmt = $pdo->query(
|
|
||||||
"SELECT `{$pkCol}` AS `value`, `{$labelCol}` AS `label` FROM `{$table}` ORDER BY `{$labelCol}` LIMIT 500"
|
|
||||||
);
|
|
||||||
jsonResponse($stmt->fetchAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- CRUD ----
|
|
||||||
if (!$table) {
|
|
||||||
jsonResponse(['error' => 'Parâmetro "table" obrigatório'], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = getPrimaryKey($pdo, $table);
|
|
||||||
|
|
||||||
switch ($method) {
|
|
||||||
|
|
||||||
// READ (listagem paginada ou registro único)
|
|
||||||
case 'GET':
|
|
||||||
if ($id !== null) {
|
|
||||||
$stmt = $pdo->prepare("SELECT * FROM `{$table}` WHERE `{$pk}` = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
$row = $stmt->fetch();
|
|
||||||
jsonResponse($row !== false ? $row : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page = max(1, intval($_GET['page'] ?? 1));
|
|
||||||
$limit = min(100, max(5, intval($_GET['limit'] ?? 10)));
|
|
||||||
$offset = ($page - 1) * $limit;
|
|
||||||
$search = trim($_GET['search'] ?? '');
|
|
||||||
|
|
||||||
// Busca simples em todas as colunas varchar
|
|
||||||
$whereClause = '';
|
|
||||||
$searchParams = [];
|
|
||||||
if ($search !== '') {
|
|
||||||
$descStmt = $pdo->query("DESCRIBE `{$table}`");
|
|
||||||
$cols = $descStmt->fetchAll(PDO::FETCH_COLUMN, 0);
|
|
||||||
$conditions = [];
|
|
||||||
foreach ($cols as $col) {
|
|
||||||
$conditions[] = "`{$col}` LIKE ?";
|
|
||||||
$searchParams[] = "%{$search}%";
|
|
||||||
}
|
|
||||||
$whereClause = 'WHERE ' . implode(' OR ', $conditions);
|
|
||||||
}
|
|
||||||
|
|
||||||
$countStmt = $pdo->query("SELECT COUNT(*) FROM `{$table}` {$whereClause}");
|
|
||||||
if ($searchParams) {
|
|
||||||
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM `{$table}` {$whereClause}");
|
|
||||||
$countStmt->execute($searchParams);
|
|
||||||
}
|
|
||||||
$total = (int) $countStmt->fetchColumn();
|
|
||||||
|
|
||||||
$dataStmt = $pdo->prepare("SELECT * FROM `{$table}` {$whereClause} LIMIT ? OFFSET ?");
|
|
||||||
$params = array_merge($searchParams, [$limit, $offset]);
|
|
||||||
$dataStmt->execute($params);
|
|
||||||
$data = $dataStmt->fetchAll();
|
|
||||||
|
|
||||||
jsonResponse([
|
|
||||||
'data' => $data,
|
|
||||||
'total' => $total,
|
|
||||||
'page' => $page,
|
|
||||||
'limit' => $limit,
|
|
||||||
'totalPages' => (int) ceil($total / $limit),
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// CREATE
|
|
||||||
case 'POST':
|
|
||||||
$body = json_decode(file_get_contents('php://input'), true);
|
|
||||||
if (!$body || !is_array($body)) {
|
|
||||||
jsonResponse(['error' => 'Body JSON inválido'], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$cols = array_keys($body);
|
|
||||||
$placeholders = implode(', ', array_fill(0, count($cols), '?'));
|
|
||||||
$colNames = '`' . implode('`, `', $cols) . '`';
|
|
||||||
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO `{$table}` ({$colNames}) VALUES ({$placeholders})");
|
|
||||||
$stmt->execute(array_values($body));
|
|
||||||
jsonResponse(['id' => $pdo->lastInsertId(), 'message' => 'Registro criado com sucesso!']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// UPDATE
|
|
||||||
case 'PUT':
|
|
||||||
if ($id === null) jsonResponse(['error' => 'ID obrigatório para atualização'], 400);
|
|
||||||
|
|
||||||
$body = json_decode(file_get_contents('php://input'), true);
|
|
||||||
if (!$body || !is_array($body)) {
|
|
||||||
jsonResponse(['error' => 'Body JSON inválido'], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sets = implode(', ', array_map(fn($col) => "`{$col}` = ?", array_keys($body)));
|
|
||||||
$stmt = $pdo->prepare("UPDATE `{$table}` SET {$sets} WHERE `{$pk}` = ?");
|
|
||||||
$stmt->execute([...array_values($body), $id]);
|
|
||||||
jsonResponse(['message' => 'Registro atualizado com sucesso!']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DELETE
|
|
||||||
case 'DELETE':
|
|
||||||
if ($id === null) jsonResponse(['error' => 'ID obrigatório para exclusão'], 400);
|
|
||||||
$stmt = $pdo->prepare("DELETE FROM `{$table}` WHERE `{$pk}` = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
jsonResponse(['message' => 'Registro excluído com sucesso!']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
jsonResponse(['error' => 'Método não permitido'], 405);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user