Files
MSPE/api/services.php

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']);
}