payfrit-api/api/menu/saveCategory.php
John Mizerek 1f81d98c52 Initial PHP API migration from CFML
Complete port of all 163 API endpoints from Lucee/CFML to PHP 8.3.
Shared helpers in api/helpers.php (DB, auth, request/response, security).
PDO prepared statements throughout. Same JSON response shapes as CFML.
2026-03-14 14:26:59 -07:00

80 lines
3.1 KiB
PHP

<?php
require_once __DIR__ . '/../helpers.php';
runAuth();
/**
* Save/Update Category
*
* POST body:
* {
* "CategoryID": 123, // Required for update
* "BusinessID": 37, // Required for insert
* "Name": "Breakfast",
* "SortOrder": 1,
* "OrderTypes": "1,2,3",
* "ParentCategoryID": 0,
* "ScheduleStart": "06:00:00",
* "ScheduleEnd": "11:00:00",
* "ScheduleDays": "2,3,4,5,6"
* }
*/
$data = readJsonBody();
$categoryID = (int) ($data['CategoryID'] ?? 0);
$businessID = (int) ($data['BusinessID'] ?? 0);
$name = isset($data['Name']) ? substr(trim($data['Name']), 0, 30) : '';
$sortOrder = (int) ($data['SortOrder'] ?? 0);
$orderTypes = isset($data['OrderTypes']) ? trim($data['OrderTypes']) : '1,2,3';
$scheduleStart = !empty($data['ScheduleStart']) ? trim($data['ScheduleStart']) : null;
$scheduleEnd = !empty($data['ScheduleEnd']) ? trim($data['ScheduleEnd']) : null;
$scheduleDays = !empty($data['ScheduleDays']) ? trim($data['ScheduleDays']) : null;
$parentCategoryID = (int) ($data['ParentCategoryID'] ?? 0);
try {
// Enforce 2-level max: if the proposed parent is itself a subcategory, reject
if ($parentCategoryID > 0) {
$parent = queryOne("SELECT ParentCategoryID FROM Categories WHERE ID = ?", [$parentCategoryID]);
if (!$parent) {
jsonResponse(['OK' => false, 'ERROR' => 'invalid_parent', 'MESSAGE' => 'Parent category not found']);
}
if ((int) $parent['ParentCategoryID'] > 0) {
jsonResponse(['OK' => false, 'ERROR' => 'nesting_too_deep', 'MESSAGE' => 'Subcategories cannot have their own subcategories (max 2 levels)']);
}
}
if ($categoryID > 0) {
// Update existing category
queryTimed("
UPDATE Categories SET
Name = ?,
SortOrder = ?,
OrderTypes = ?,
ParentCategoryID = ?,
ScheduleStart = ?,
ScheduleEnd = ?,
ScheduleDays = ?
WHERE ID = ?
", [$name, $sortOrder, $orderTypes, $parentCategoryID, $scheduleStart, $scheduleEnd, $scheduleDays, $categoryID]);
jsonResponse(['OK' => true, 'CategoryID' => $categoryID, 'MESSAGE' => 'Category updated']);
} elseif ($businessID > 0 && strlen($name) > 0) {
// Insert new category
queryTimed("
INSERT INTO Categories
(BusinessID, Name, SortOrder, OrderTypes, ParentCategoryID,
ScheduleStart, ScheduleEnd, ScheduleDays, AddedOn)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
", [$businessID, $name, $sortOrder, $orderTypes, $parentCategoryID, $scheduleStart, $scheduleEnd, $scheduleDays]);
$newId = lastInsertId();
jsonResponse(['OK' => true, 'CategoryID' => (int) $newId, 'MESSAGE' => 'Category created']);
} else {
jsonResponse(['OK' => false, 'ERROR' => 'invalid_params', 'MESSAGE' => 'CategoryID required for update, or BusinessID and Name for insert']);
}
} catch (Exception $e) {
jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage(), 'DETAIL' => '']);
}