ferrero-naming-tool-nv/public-v2/api-json.php
nickviljoen 58a1a8fdb5 Add project source files and documentation
Includes backend API, public-v2 frontend, database migrations,
Composer config, and deployment/implementation docs.
Config files with credentials are excluded via .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:19:12 +02:00

381 lines
13 KiB
PHP

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE');
header('Access-Control-Allow-Headers: Content-Type');
// Load data from JSON files
$dataFile = __DIR__ . '/../backend/data.json';
$trackingFile = __DIR__ . '/../backend-v2/tracking_data.json';
function loadData() {
global $dataFile;
if (!file_exists($dataFile)) {
return ['error' => 'Data file not found'];
}
$json = file_get_contents($dataFile);
return json_decode($json, true);
}
function saveData($data) {
global $dataFile;
file_put_contents($dataFile, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
function loadTrackingData() {
global $trackingFile;
if (!file_exists($trackingFile)) {
return ['tracking_ids' => [], 'generated_ids' => []];
}
$json = file_get_contents($trackingFile);
return json_decode($json, true);
}
function saveTrackingData($data) {
global $trackingFile;
file_put_contents($trackingFile, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
function generateTrackingId() {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$trackingId = '';
for ($i = 0; $i < 6; $i++) {
$trackingId .= $characters[rand(0, strlen($characters) - 1)];
}
// Check if ID already exists
$trackingData = loadTrackingData();
if (isset($trackingData['tracking_ids'][$trackingId])) {
// If exists, generate a new one
return generateTrackingId();
}
return $trackingId;
}
// Get action from URL
$action = isset($_GET['action']) ? $_GET['action'] : '';
$method = $_SERVER['REQUEST_METHOD'];
switch ($action) {
case 'data':
echo json_encode(loadData());
break;
case 'generate-tracking-id':
if ($method === 'GET') {
$trackingId = generateTrackingId();
echo json_encode(['tracking_id' => $trackingId]);
}
break;
case 'register-tracking-id':
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$trackingId = $input['tracking_id'] ?? '';
$masterFilename = $input['master_filename'] ?? '';
$masterExtension = $input['master_extension'] ?? '';
$opentextId = $input['opentext_id'] ?? '';
$metadata = $input['metadata'] ?? [];
if (empty($trackingId) || empty($masterFilename)) {
echo json_encode(['error' => 'Tracking ID and master filename are required']);
exit;
}
$trackingData = loadTrackingData();
$trackingData['tracking_ids'][$trackingId] = [
'master_filename' => $masterFilename,
'master_extension' => $masterExtension,
'created_date' => date('Y-m-d'),
'opentext_id' => $opentextId,
'metadata' => $metadata
];
if (!in_array($trackingId, $trackingData['generated_ids'])) {
$trackingData['generated_ids'][] = $trackingId;
}
saveTrackingData($trackingData);
echo json_encode(['success' => true, 'message' => 'Tracking ID registered successfully']);
}
break;
case 'lookup-tracking-id':
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$trackingId = $input['tracking_id'] ?? '';
if (empty($trackingId)) {
echo json_encode(['error' => 'Tracking ID is required']);
exit;
}
$trackingData = loadTrackingData();
if (isset($trackingData['tracking_ids'][$trackingId])) {
echo json_encode([
'success' => true,
'tracking_id' => $trackingId,
'data' => $trackingData['tracking_ids'][$trackingId]
]);
} else {
echo json_encode(['error' => 'Tracking ID not found']);
}
}
break;
case 'build':
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$omgJobNumber = $input['omg_job_number'] ?? '';
$brandCode = strtoupper($input['brand_code'] ?? '');
$countryCode = strtoupper($input['country_code'] ?? '');
$languageCode = strtolower($input['language_code'] ?? '');
$subjectTitle = strtoupper($input['subject_title'] ?? '');
$assetType = strtoupper($input['asset_type'] ?? '');
$spotVersion = strtoupper($input['spot_version'] ?? '');
$seconds = $input['seconds'] ?? '';
$aspectRatio = $input['aspect_ratio'] ?? '';
$hasMaster = $input['has_master'] ?? false;
$trackingId = $input['tracking_id'] ?? '';
// Validation
$errors = [];
if (empty($omgJobNumber) || !ctype_digit($omgJobNumber) || strlen($omgJobNumber) > 10) {
$errors[] = 'OMG Job Number is required, must be numbers only, and max 10 digits';
}
if (empty($brandCode) || strlen($brandCode) < 2 || strlen($brandCode) > 5) {
$errors[] = 'Brand code must be 2-5 characters';
}
if (empty($countryCode) || strlen($countryCode) != 2) {
$errors[] = 'Country code must be exactly 2 characters';
}
if (empty($languageCode) || (strlen($languageCode) != 2 && strlen($languageCode) != 3)) {
$errors[] = 'Language code is required and must be 2-3 characters';
}
if (empty($subjectTitle) || strlen($subjectTitle) > 15) {
$errors[] = 'Subject title is required and must be max 15 characters';
}
if (empty($assetType) || strlen($assetType) != 3) {
$errors[] = 'Asset type must be exactly 3 characters';
}
if (empty($seconds)) {
$errors[] = 'Duration in seconds is required';
}
if (empty($aspectRatio)) {
$errors[] = 'Aspect ratio is required';
}
if (!empty($errors)) {
echo json_encode(['error' => implode(', ', $errors)]);
exit;
}
// Build filename - start with OMG Job Number, then brand, country, language
$parts = [$omgJobNumber, $brandCode, $countryCode, $languageCode, $subjectTitle, $assetType];
// Add spot version and MST if applicable
if ($hasMaster && !empty($spotVersion)) {
$parts[] = $spotVersion . '_MST';
} elseif (!empty($spotVersion)) {
$parts[] = $spotVersion;
} elseif ($hasMaster) {
$parts[] = 'MST';
}
// Add duration
$parts[] = $seconds . 'S';
// Add aspect ratio
$parts[] = $aspectRatio;
// Add tracking ID if provided
if (!empty($trackingId)) {
$parts[] = $trackingId;
}
$filename = implode('_', $parts);
// Calculate the final upload filename (without job number and tracking ID)
$uploadParts = [$brandCode, $countryCode, $languageCode, $subjectTitle, $assetType];
if ($hasMaster && !empty($spotVersion)) {
$uploadParts[] = $spotVersion . '_MST';
} elseif (!empty($spotVersion)) {
$uploadParts[] = $spotVersion;
} elseif ($hasMaster) {
$uploadParts[] = 'MST';
}
$uploadParts[] = $seconds . 'S';
$uploadParts[] = $aspectRatio;
$uploadFilename = implode('_', $uploadParts);
echo json_encode([
'filename' => $filename,
'upload_filename' => $uploadFilename,
'has_tracking_id' => !empty($trackingId)
]);
}
break;
case 'decode':
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$filename = $input['filename'] ?? '';
if (empty($filename)) {
echo json_encode(['error' => 'Filename is required']);
exit;
}
// Remove file extension if present
$filename = preg_replace('/\.[^.]+$/', '', $filename);
// Split by underscore
$parts = explode('_', $filename);
if (count($parts) < 8) {
echo json_encode(['error' => 'Invalid filename format. Expected at least 8 parts separated by underscores (including language code)']);
exit;
}
// Parse components (with OMG Job Number at start and language code after country)
$result = [
'omg_job_number' => $parts[0],
'brand_code' => $parts[1],
'country_code' => $parts[2],
'language_code' => $parts[3],
'subject_title' => $parts[4],
'asset_type' => $parts[5],
'spot_version' => '',
'has_master' => false,
'seconds' => '',
'aspect_ratio' => '',
'tracking_id' => ''
];
// Handle optional spot version and MST
$currentIndex = 6;
while ($currentIndex < count($parts)) {
$part = $parts[$currentIndex];
// Check if it's the duration (ends with S and has numbers)
if (preg_match('/^\d+S$/', $part)) {
$result['seconds'] = rtrim($part, 'S');
$currentIndex++;
break;
}
// Check if it's MST
elseif ($part === 'MST') {
$result['has_master'] = true;
$currentIndex++;
}
// Otherwise it's a spot version
else {
$result['spot_version'] = $part;
$currentIndex++;
}
}
// Next part should be aspect ratio
if ($currentIndex < count($parts)) {
$result['aspect_ratio'] = $parts[$currentIndex];
$currentIndex++;
}
// Last part might be tracking ID (6 alphanumeric characters)
if ($currentIndex < count($parts) && preg_match('/^[a-zA-Z0-9]{6}$/', $parts[$currentIndex])) {
$result['tracking_id'] = $parts[$currentIndex];
}
// Load data to get full names
$data = loadData();
$result['brand_name'] = $data['brands'][$result['brand_code']] ?? 'Unknown Brand';
$result['country_name'] = $data['countries'][$result['country_code']] ?? 'Unknown Country';
$result['language_name'] = $data['languages'][$result['language_code']] ?? 'Unknown Language';
$result['asset_type_name'] = $data['asset_types'][$result['asset_type']] ?? 'Unknown Asset Type';
// If tracking ID exists, lookup metadata
if (!empty($result['tracking_id'])) {
$trackingData = loadTrackingData();
if (isset($trackingData['tracking_ids'][$result['tracking_id']])) {
$result['tracking_metadata'] = $trackingData['tracking_ids'][$result['tracking_id']];
}
}
echo json_encode($result);
}
break;
case 'simulate-upload':
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$filename = $input['filename'] ?? '';
if (empty($filename)) {
echo json_encode(['error' => 'Filename is required']);
exit;
}
// Remove file extension if present
$ext = '';
if (preg_match('/(\.[^.]+)$/', $filename, $matches)) {
$ext = $matches[1];
$filename = preg_replace('/\.[^.]+$/', '', $filename);
}
// Split by underscore
$parts = explode('_', $filename);
// Remove job number (first part if it's all digits)
if (ctype_digit($parts[0])) {
array_shift($parts);
}
// Remove tracking ID (last part if it's 6 alphanumeric characters)
$trackingId = '';
if (count($parts) > 0 && preg_match('/^[a-zA-Z0-9]{6}$/', end($parts))) {
$trackingId = array_pop($parts);
}
$uploadFilename = implode('_', $parts) . $ext;
echo json_encode([
'original_filename' => $input['filename'],
'upload_filename' => $uploadFilename,
'stripped_job_number' => true,
'stripped_tracking_id' => !empty($trackingId),
'tracking_id' => $trackingId
]);
}
break;
case 'brands':
case 'countries':
case 'asset-types':
case 'languages':
// These endpoints remain the same as v1
if ($method === 'GET') {
$data = loadData();
$key = str_replace('-', '_', $action);
echo json_encode($data[$key] ?? []);
}
break;
default:
echo json_encode(['error' => 'Invalid action']);
break;
}
?>