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.
225 lines
8.5 KiB
PHP
225 lines
8.5 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../helpers.php';
|
|
runAuth();
|
|
|
|
/**
|
|
* Import Business from Scraped Data
|
|
*
|
|
* Creates a complete business with categories, items, modifier templates,
|
|
* and template links via lt_ItemID_TemplateItemID.
|
|
*
|
|
* POST JSON: { business, categories, modifierTemplates, ownerUserID, dryRun }
|
|
*/
|
|
|
|
$response = ['OK' => false, 'steps' => [], 'errors' => [], 'warnings' => []];
|
|
|
|
try {
|
|
$data = readJsonBody();
|
|
if (empty($data)) throw new Exception('No request body provided');
|
|
|
|
$dryRun = !empty($data['dryRun']);
|
|
if ($dryRun) $response['steps'][] = 'DRY RUN MODE - no changes will be made';
|
|
|
|
if (empty($data['business']['name'])) throw new Exception('business.name is required');
|
|
|
|
$biz = $data['business'];
|
|
$ownerUserID = (int)($data['ownerUserID'] ?? 1);
|
|
|
|
// Step 1: Create or find business
|
|
$response['steps'][] = 'Step 1: Creating business record...';
|
|
|
|
$qCheck = queryTimed("SELECT ID FROM Businesses WHERE Name = ? LIMIT 1", [$biz['name']]);
|
|
|
|
if (!empty($qCheck)) {
|
|
$businessID = (int)$qCheck[0]['ID'];
|
|
$response['steps'][] = "Business already exists with ID: $businessID";
|
|
$response['warnings'][] = 'Existing business found - will add to existing menu';
|
|
} elseif (!$dryRun) {
|
|
queryTimed(
|
|
"INSERT INTO Businesses (Name, UserID, AddressID, DeliveryZIPCodes, AddedOn) VALUES (?, ?, 0, '', NOW())",
|
|
[$biz['name'], $ownerUserID]
|
|
);
|
|
$businessID = (int)lastInsertId();
|
|
$response['steps'][] = "Created business with ID: $businessID";
|
|
} else {
|
|
$businessID = 0;
|
|
$response['steps'][] = 'Would create business: ' . $biz['name'];
|
|
}
|
|
|
|
// Step 2: Create modifier templates
|
|
$response['steps'][] = 'Step 2: Creating modifier templates...';
|
|
|
|
$templateMap = []; // Maps template string ID to database ItemID
|
|
$templates = $data['modifierTemplates'] ?? [];
|
|
|
|
foreach ($templates as $tmpl) {
|
|
$templateStringID = $tmpl['id'];
|
|
$templateName = $tmpl['name'];
|
|
$required = !empty($tmpl['required']);
|
|
$maxSelections = (int)($tmpl['maxSelections'] ?? 0);
|
|
|
|
if (!$dryRun) {
|
|
$qTmpl = queryOne(
|
|
"SELECT ID FROM Items WHERE BusinessID = ? AND Name = ? AND ParentItemID = 0 AND ID IN (SELECT TemplateItemID FROM lt_ItemID_TemplateItemID)",
|
|
[$businessID, $templateName]
|
|
);
|
|
|
|
if ($qTmpl) {
|
|
$templateItemID = (int)$qTmpl['ID'];
|
|
$response['steps'][] = "Template exists: $templateName (ID: $templateItemID)";
|
|
} else {
|
|
queryTimed(
|
|
"INSERT INTO Items (BusinessID, Name, ParentItemID, Price, IsActive, RequiresChildSelection, MaxNumSelectionReq, SortOrder, IsCollapsible) VALUES (?, ?, 0, 0, 1, ?, ?, 0, 1)",
|
|
[$businessID, $templateName, $required ? 1 : 0, $maxSelections]
|
|
);
|
|
$templateItemID = (int)lastInsertId();
|
|
$response['steps'][] = "Created template: $templateName (ID: $templateItemID)";
|
|
}
|
|
|
|
$templateMap[$templateStringID] = $templateItemID;
|
|
|
|
// Create template options
|
|
$options = $tmpl['options'] ?? [];
|
|
$optionOrder = 1;
|
|
foreach ($options as $opt) {
|
|
$optName = $opt['name'];
|
|
$optPrice = (float)($opt['price'] ?? 0);
|
|
$optDefault = !empty($opt['isDefault']);
|
|
|
|
$qOpt = queryOne(
|
|
"SELECT ID FROM Items WHERE BusinessID = ? AND Name = ? AND ParentItemID = ?",
|
|
[$businessID, $optName, $templateItemID]
|
|
);
|
|
|
|
if (!$qOpt) {
|
|
queryTimed(
|
|
"INSERT INTO Items (BusinessID, Name, ParentItemID, Price, IsActive, IsCheckedByDefault, SortOrder) VALUES (?, ?, ?, ?, 1, ?, ?)",
|
|
[$businessID, $optName, $templateItemID, $optPrice, $optDefault ? 1 : 0, $optionOrder]
|
|
);
|
|
}
|
|
$optionOrder++;
|
|
}
|
|
} else {
|
|
$response['steps'][] = "Would create template: $templateName with " . count($tmpl['options'] ?? []) . " options";
|
|
$templateMap[$templateStringID] = 0;
|
|
}
|
|
}
|
|
|
|
// Step 3: Create categories
|
|
$response['steps'][] = 'Step 3: Creating categories...';
|
|
|
|
$categoryMap = [];
|
|
$categories = $data['categories'] ?? [];
|
|
$catOrder = 1;
|
|
|
|
foreach ($categories as $cat) {
|
|
$catName = $cat['name'];
|
|
|
|
if (!$dryRun) {
|
|
$qCat = queryOne(
|
|
"SELECT ID FROM Items WHERE BusinessID = ? AND Name = ? AND ParentItemID = 0 AND ID NOT IN (SELECT TemplateItemID FROM lt_ItemID_TemplateItemID)",
|
|
[$businessID, $catName]
|
|
);
|
|
|
|
if ($qCat) {
|
|
$categoryItemID = (int)$qCat['ID'];
|
|
$response['steps'][] = "Category exists: $catName";
|
|
} else {
|
|
queryTimed(
|
|
"INSERT INTO Items (BusinessID, Name, ParentItemID, Price, IsActive, SortOrder) VALUES (?, ?, 0, 0, 1, ?)",
|
|
[$businessID, $catName, $catOrder]
|
|
);
|
|
$categoryItemID = (int)lastInsertId();
|
|
$response['steps'][] = "Created category: $catName (ID: $categoryItemID)";
|
|
}
|
|
|
|
$categoryMap[$catName] = $categoryItemID;
|
|
} else {
|
|
$response['steps'][] = "Would create category: $catName";
|
|
$categoryMap[$catName] = 0;
|
|
}
|
|
$catOrder++;
|
|
}
|
|
|
|
// Step 4: Create menu items
|
|
$response['steps'][] = 'Step 4: Creating menu items...';
|
|
|
|
$totalItems = 0;
|
|
$totalLinks = 0;
|
|
|
|
foreach ($categories as $cat) {
|
|
$catName = $cat['name'];
|
|
$categoryItemID = $categoryMap[$catName];
|
|
$items = $cat['items'] ?? [];
|
|
$itemOrder = 1;
|
|
|
|
foreach ($items as $item) {
|
|
$itemName = $item['name'];
|
|
$itemDesc = $item['description'] ?? '';
|
|
$itemPrice = (float)($item['price'] ?? 0);
|
|
|
|
if (!$dryRun) {
|
|
$qItem = queryOne(
|
|
"SELECT ID FROM Items WHERE BusinessID = ? AND Name = ? AND ParentItemID = ?",
|
|
[$businessID, $itemName, $categoryItemID]
|
|
);
|
|
|
|
if ($qItem) {
|
|
$menuItemID = (int)$qItem['ID'];
|
|
} else {
|
|
queryTimed(
|
|
"INSERT INTO Items (BusinessID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (?, ?, ?, ?, ?, 1, ?)",
|
|
[$businessID, $itemName, $itemDesc, $categoryItemID, $itemPrice, $itemOrder]
|
|
);
|
|
$menuItemID = (int)lastInsertId();
|
|
}
|
|
|
|
// Link modifier templates
|
|
$modifiers = $item['modifiers'] ?? [];
|
|
$modOrder = 1;
|
|
foreach ($modifiers as $modRef) {
|
|
if (isset($templateMap[$modRef])) {
|
|
$templateItemID = $templateMap[$modRef];
|
|
$qLink = queryOne(
|
|
"SELECT 1 FROM lt_ItemID_TemplateItemID WHERE ItemID = ? AND TemplateItemID = ?",
|
|
[$menuItemID, $templateItemID]
|
|
);
|
|
if (!$qLink) {
|
|
queryTimed(
|
|
"INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder) VALUES (?, ?, ?)",
|
|
[$menuItemID, $templateItemID, $modOrder]
|
|
);
|
|
$totalLinks++;
|
|
}
|
|
$modOrder++;
|
|
} else {
|
|
$response['warnings'][] = "Unknown modifier reference: $modRef on item: $itemName";
|
|
}
|
|
}
|
|
}
|
|
|
|
$totalItems++;
|
|
$itemOrder++;
|
|
}
|
|
}
|
|
|
|
$response['steps'][] = "Created $totalItems menu items with $totalLinks template links";
|
|
|
|
$response['OK'] = true;
|
|
$response['summary'] = [
|
|
'businessID' => $businessID,
|
|
'businessName' => $biz['name'],
|
|
'categoriesCreated' => count($categories),
|
|
'templatesCreated' => count($templates),
|
|
'itemsCreated' => $totalItems,
|
|
'templateLinksCreated' => $totalLinks,
|
|
'dryRun' => $dryRun,
|
|
];
|
|
|
|
$response['steps'][] = $dryRun ? 'DRY RUN COMPLETE - no changes were made' : 'IMPORT COMPLETE!';
|
|
|
|
} catch (Exception $e) {
|
|
$response['errors'][] = $e->getMessage();
|
|
}
|
|
|
|
jsonResponse($response);
|