131 lines
4.0 KiB
PHP
Executable File
131 lines
4.0 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* MSPE Services API
|
|
*/
|
|
|
|
require_once 'config.php';
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$id = $_GET['id'] ?? null;
|
|
|
|
// CSRF protection for write operations
|
|
if ($method !== 'GET') {
|
|
requireSameOriginRequest();
|
|
}
|
|
|
|
switch ($method) {
|
|
case 'GET':
|
|
if ($id) {
|
|
getService($id);
|
|
} else {
|
|
getServices();
|
|
}
|
|
break;
|
|
|
|
case 'POST':
|
|
requireAuth();
|
|
$postData = !empty($_POST) ? $_POST : getRequestBody();
|
|
if (!empty($postData['id'])) {
|
|
updateService($postData['id']);
|
|
} else {
|
|
createService();
|
|
}
|
|
break;
|
|
|
|
case 'PUT':
|
|
requireAuth();
|
|
if (!$id) {
|
|
jsonResponse(['success' => false, 'message' => 'Service ID required'], 400);
|
|
}
|
|
updateService($id);
|
|
break;
|
|
|
|
case 'DELETE':
|
|
requireAuth();
|
|
if (!$id) {
|
|
jsonResponse(['success' => false, 'message' => 'ID required'], 400);
|
|
}
|
|
deleteService($id);
|
|
break;
|
|
|
|
default:
|
|
jsonResponse(['success' => false, 'message' => 'Method not allowed'], 405);
|
|
}
|
|
|
|
function getServices() {
|
|
global $db;
|
|
$services = $db->getAll('services');
|
|
|
|
// Sort by order
|
|
usort($services, function($a, $b) {
|
|
return ($a['order'] ?? 99) - ($b['order'] ?? 99);
|
|
});
|
|
|
|
// Public view: only active
|
|
if (!checkAuth()) {
|
|
$services = array_filter($services, function($s) {
|
|
return ($s['active'] ?? true) === true;
|
|
});
|
|
}
|
|
|
|
jsonResponse(['success' => true, 'data' => array_values($services)]);
|
|
}
|
|
|
|
function getService($id) {
|
|
global $db;
|
|
$service = $db->get('services', $id);
|
|
if (!$service) jsonResponse(['success' => false, 'message' => 'Not found'], 404);
|
|
jsonResponse(['success' => true, 'data' => $service]);
|
|
}
|
|
|
|
function createService() {
|
|
global $db;
|
|
$data = !empty($_POST) ? $_POST : getRequestBody();
|
|
|
|
if (empty($data['name'])) {
|
|
jsonResponse(['success' => false, 'message' => 'Service name is required'], 400);
|
|
}
|
|
|
|
// Sanitize text fields
|
|
$data['name'] = sanitize($data['name']);
|
|
$data['icon'] = sanitize($data['icon'] ?? '');
|
|
$data['features'] = sanitize($data['features'] ?? '');
|
|
$data['price'] = sanitize($data['price'] ?? '');
|
|
// Sanitize description: allow only safe formatting tags (no <script>, <iframe>, event handlers etc.)
|
|
$data['description'] = sanitizeRichText($data['description'] ?? '');
|
|
|
|
$data['active'] = isset($data['active']) ? filter_var($data['active'], FILTER_VALIDATE_BOOLEAN) : true;
|
|
$data['order'] = (int)($data['order'] ?? 99);
|
|
|
|
$service = $db->insert('services', $data);
|
|
jsonResponse(['success' => true, 'message' => 'Service created', 'data' => $service]);
|
|
}
|
|
|
|
function updateService($id) {
|
|
global $db;
|
|
$existing = $db->get('services', $id);
|
|
if (!$existing) jsonResponse(['success' => false, 'message' => 'Not found'], 404);
|
|
|
|
$data = !empty($_POST) ? $_POST : getRequestBody();
|
|
// Sanitize editable text fields
|
|
if (isset($data['name'])) $data['name'] = sanitize($data['name']);
|
|
if (isset($data['icon'])) $data['icon'] = sanitize($data['icon']);
|
|
if (isset($data['features'])) $data['features'] = sanitize($data['features']);
|
|
if (isset($data['price'])) $data['price'] = sanitize($data['price']);
|
|
if (isset($data['description'])) $data['description'] = sanitizeRichText($data['description']);
|
|
$data['active'] = isset($data['active']) ? filter_var($data['active'], FILTER_VALIDATE_BOOLEAN) : ($existing['active'] ?? true);
|
|
|
|
$service = $db->update('services', $id, $data);
|
|
jsonResponse(['success' => true, 'message' => 'Service updated', 'data' => $service]);
|
|
}
|
|
|
|
function deleteService($id) {
|
|
global $db;
|
|
$existing = $db->get('services', $id);
|
|
if (!$existing) {
|
|
jsonResponse(['success' => false, 'message' => 'Service not found'], 404);
|
|
}
|
|
$db->delete('services', $id);
|
|
jsonResponse(['success' => true, 'message' => 'Service deleted']);
|
|
}
|