Validation Improvements: - Subject Title: Automatically converts underscores to hyphens - Subject Title: Shows warning when underscores are detected - Spot Version: Always enforces 3-character length - Spot Version: Auto-pads with leading zeros (e.g., 1 → 001) - Both frontend (JavaScript) and backend (PHP) validation Smart Defaults: - Spot Version: Defaults to "001" - Duration: Defaults to "6" seconds - Users can change defaults as needed Applied to Both Versions: - v1 (public/) - Original version updated - v2 (public-v2/) - Tracking ID version updated Technical Implementation: - Real-time underscore detection and conversion - Auto-hide warning after 3 seconds - Input blur event for spot version padding - Form submit validation as final check - Server-side enforcement in API endpoints Testing: - ✅ Underscores converted: "TEST_FILE" → "TEST-FILE" - ✅ Spot version validated: "1" rejected, "001" accepted - ✅ Defaults working: spot=001, duration=6 Improves data consistency and user experience. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
307 lines
11 KiB
PHP
307 lines
11 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 file
|
|
$dataFile = __DIR__ . '/../backend/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));
|
|
}
|
|
|
|
// Get action from URL
|
|
$action = isset($_GET['action']) ? $_GET['action'] : '';
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
switch ($action) {
|
|
case 'data':
|
|
echo json_encode(loadData());
|
|
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'] ?? '');
|
|
// Convert underscores to hyphens in subject title
|
|
$subjectTitle = str_replace('_', '-', $subjectTitle);
|
|
$assetType = strtoupper($input['asset_type'] ?? '');
|
|
$spotVersion = strtoupper($input['spot_version'] ?? '');
|
|
$seconds = $input['seconds'] ?? '';
|
|
$aspectRatio = $input['aspect_ratio'] ?? '';
|
|
$hasMaster = $input['has_master'] ?? false;
|
|
|
|
// 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';
|
|
}
|
|
|
|
// Validate spot version - must be 3 characters if provided
|
|
if (!empty($spotVersion) && strlen($spotVersion) != 3) {
|
|
$errors[] = 'Spot Version must be exactly 3 characters if provided (e.g., 001, 002, V01)';
|
|
}
|
|
|
|
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;
|
|
|
|
$filename = implode('_', $parts);
|
|
|
|
echo json_encode(['filename' => $filename]);
|
|
}
|
|
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' => ''
|
|
];
|
|
|
|
// 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++;
|
|
}
|
|
}
|
|
|
|
// Last part should be aspect ratio
|
|
if ($currentIndex < count($parts)) {
|
|
$result['aspect_ratio'] = $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';
|
|
|
|
echo json_encode($result);
|
|
}
|
|
break;
|
|
|
|
case 'brands':
|
|
if ($method === 'GET') {
|
|
$data = loadData();
|
|
echo json_encode($data['brands']);
|
|
} elseif ($method === 'POST') {
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
$code = strtoupper($input['code'] ?? '');
|
|
$name = $input['name'] ?? '';
|
|
|
|
if (empty($code) || empty($name)) {
|
|
echo json_encode(['error' => 'Code and name are required']);
|
|
exit;
|
|
}
|
|
|
|
if (strlen($code) < 2 || strlen($code) > 5) {
|
|
echo json_encode(['error' => 'Brand code must be 2-5 characters']);
|
|
exit;
|
|
}
|
|
|
|
$data = loadData();
|
|
$data['brands'][$code] = $name;
|
|
saveData($data);
|
|
|
|
echo json_encode(['message' => 'Brand added successfully', 'code' => $code, 'name' => $name]);
|
|
}
|
|
break;
|
|
|
|
case 'countries':
|
|
if ($method === 'GET') {
|
|
$data = loadData();
|
|
echo json_encode($data['countries']);
|
|
} elseif ($method === 'POST') {
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
$code = strtoupper($input['code'] ?? '');
|
|
$name = $input['name'] ?? '';
|
|
|
|
if (empty($code) || empty($name)) {
|
|
echo json_encode(['error' => 'Code and name are required']);
|
|
exit;
|
|
}
|
|
|
|
if (strlen($code) != 2) {
|
|
echo json_encode(['error' => 'Country code must be exactly 2 characters']);
|
|
exit;
|
|
}
|
|
|
|
$data = loadData();
|
|
$data['countries'][$code] = $name;
|
|
saveData($data);
|
|
|
|
echo json_encode(['message' => 'Country added successfully', 'code' => $code, 'name' => $name]);
|
|
}
|
|
break;
|
|
|
|
case 'asset-types':
|
|
if ($method === 'GET') {
|
|
$data = loadData();
|
|
echo json_encode($data['asset_types']);
|
|
} elseif ($method === 'POST') {
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
$code = strtoupper($input['code'] ?? '');
|
|
$name = $input['name'] ?? '';
|
|
|
|
if (empty($code) || empty($name)) {
|
|
echo json_encode(['error' => 'Code and name are required']);
|
|
exit;
|
|
}
|
|
|
|
if (strlen($code) != 3) {
|
|
echo json_encode(['error' => 'Asset type code must be exactly 3 characters']);
|
|
exit;
|
|
}
|
|
|
|
$data = loadData();
|
|
$data['asset_types'][$code] = $name;
|
|
saveData($data);
|
|
|
|
echo json_encode(['message' => 'Asset type added successfully', 'code' => $code, 'name' => $name]);
|
|
}
|
|
break;
|
|
|
|
case 'languages':
|
|
if ($method === 'GET') {
|
|
$data = loadData();
|
|
echo json_encode($data['languages']);
|
|
} elseif ($method === 'POST') {
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
$code = strtolower($input['code'] ?? '');
|
|
$name = $input['name'] ?? '';
|
|
|
|
if (empty($code) || empty($name)) {
|
|
echo json_encode(['error' => 'Code and name are required']);
|
|
exit;
|
|
}
|
|
|
|
if (strlen($code) < 2 || strlen($code) > 3) {
|
|
echo json_encode(['error' => 'Language code must be 2-3 characters']);
|
|
exit;
|
|
}
|
|
|
|
$data = loadData();
|
|
$data['languages'][$code] = $name;
|
|
saveData($data);
|
|
|
|
echo json_encode(['message' => 'Language added successfully', 'code' => $code, 'name' => $name]);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
echo json_encode(['error' => 'Invalid action']);
|
|
break;
|
|
}
|
|
?>
|