New test upload panel in Upload workflow: - Upload directly to any folder ID (bypasses campaign selection) - Pre-filled with test folder: e96080ba0cd1427d253a28a87504b6665eaa02cb - Folder ID can be edited for testing different folders - Shows success/failure with full error details - Uses same upload mechanism as regular workflow Use case: - Test if specific folders allow uploads - Bypass campaign workflow for testing - Verify folder permissions - Isolate upload issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2350 lines
122 KiB
PHP
2350 lines
122 KiB
PHP
<?php
|
||
session_start();
|
||
|
||
// Clear session on reset
|
||
if (isset($_GET['reset']) || isset($_POST['reset'])) {
|
||
session_destroy();
|
||
session_start();
|
||
header('Location: workflow_v3.php');
|
||
exit;
|
||
}
|
||
|
||
// Clear specific workflow results
|
||
if (isset($_POST['clear_results'])) {
|
||
unset($_SESSION['workflow_results']);
|
||
$_SESSION['workflow_results'] = [];
|
||
header('Location: workflow_v3.php?tab=' . ($_POST['tab'] ?? 'download'));
|
||
exit;
|
||
}
|
||
|
||
require_once 'config_v3.php';
|
||
require_once 'src/TestRunner.php';
|
||
require_once 'src/CampaignFormatter.php';
|
||
require_once 'src/AssetDownloader.php';
|
||
require_once 'src/MetadataExtractor.php';
|
||
require_once 'src/StatusManager.php';
|
||
require_once 'src/ApiClient.php';
|
||
require_once 'src/AssetUploader.php';
|
||
|
||
$configV3 = new ConfigV3();
|
||
$errors = $configV3->validate();
|
||
|
||
if (!empty($errors)) {
|
||
die("Configuration Error: " . implode(', ', $errors));
|
||
}
|
||
|
||
$config = [
|
||
'baseUrl' => $configV3->getBaseUrl(),
|
||
'timeout' => $configV3->get('api.timeout'),
|
||
'headers' => [
|
||
'Content-Type' => 'application/json',
|
||
'Accept' => 'application/json'
|
||
]
|
||
];
|
||
|
||
$collectionPath = __DIR__ . '/' . $configV3->get('postman_collection');
|
||
|
||
$testRunner = null;
|
||
$error = null;
|
||
$success = null;
|
||
$currentTab = $_GET['tab'] ?? $_POST['tab'] ?? 'download';
|
||
|
||
try {
|
||
if (file_exists($collectionPath)) {
|
||
$testRunner = new TestRunner($collectionPath, $config);
|
||
} else {
|
||
$error = "Postman collection file not found: " . $collectionPath;
|
||
}
|
||
} catch (Exception $e) {
|
||
$error = "Error initializing: " . $e->getMessage();
|
||
}
|
||
|
||
// Initialize results storage
|
||
if (!isset($_SESSION['workflow_results'])) {
|
||
$_SESSION['workflow_results'] = [];
|
||
}
|
||
|
||
$results = &$_SESSION['workflow_results'];
|
||
|
||
// Handle POST actions
|
||
if ($_POST && $testRunner) {
|
||
$action = $_POST['action'] ?? '';
|
||
|
||
try {
|
||
switch ($action) {
|
||
case 'debug_all_campaigns':
|
||
// Check OAuth status first
|
||
$oauth2Status = $testRunner->getOAuth2Status();
|
||
$results['oauth_debug'] = [
|
||
'has_token' => $oauth2Status['has_token'] ?? false,
|
||
'expires_at' => $oauth2Status['expires_at'] ?? 'Unknown'
|
||
];
|
||
|
||
$statusManager = createStatusManager($testRunner);
|
||
$response = $statusManager->searchAllCampaigns($testRunner);
|
||
|
||
if ($response['success']) {
|
||
$data = json_decode($response['body'], true);
|
||
$campaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||
$results['debug_campaigns'] = $campaigns;
|
||
$results['debug_raw'] = $data;
|
||
$results['debug_search_response'] = [
|
||
'http_code' => $response['http_code'],
|
||
'url' => $response['url'] ?? 'N/A',
|
||
'total_results' => $data['search_result_resource']['search_result']['total_hit_count'] ?? 0,
|
||
'response_body_preview' => substr($response['body'] ?? '', 0, 500)
|
||
];
|
||
$success = "Found " . count($campaigns) . " campaigns total (without status filter)";
|
||
} else {
|
||
$error = "Debug search failed: HTTP " . ($response['http_code'] ?? 'N/A') . " - " . ($response['error'] ?? 'Unknown error');
|
||
$results['debug_search_response'] = [
|
||
'http_code' => $response['http_code'],
|
||
'url' => $response['url'] ?? 'N/A',
|
||
'error' => $response['error'] ?? 'Unknown',
|
||
'response_preview' => substr($response['body'] ?? '', 0, 500)
|
||
];
|
||
}
|
||
break;
|
||
|
||
case 'load_campaigns_a1':
|
||
$results['a1_campaigns'] = loadCampaignsByStatus($testRunner, 'A1');
|
||
$success = "Loaded " . count($results['a1_campaigns']) . " campaigns with status A1";
|
||
break;
|
||
|
||
case 'select_campaign_a1':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId && isset($results['a1_campaigns'])) {
|
||
foreach ($results['a1_campaigns'] as $campaign) {
|
||
if ($campaign['asset_id'] === $campaignId) {
|
||
$results['selected_campaign'] = $campaign;
|
||
$success = "Campaign selected: " . $campaign['campaign_name'];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'get_master_assets':
|
||
if (isset($results['selected_campaign'])) {
|
||
$campaignId = $results['selected_campaign']['asset_id'];
|
||
$masterFolderId = findMasterAssetsFolder($testRunner, $campaignId, $configV3);
|
||
|
||
if ($masterFolderId) {
|
||
$results['master_folder_id'] = $masterFolderId;
|
||
$results['master_assets'] = getAssetsFromFolder($testRunner, $masterFolderId);
|
||
$success = "Found Master Assets folder with " . count($results['master_assets']) . " assets";
|
||
} else {
|
||
$error = "Master Assets folder not found in campaign";
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'download_asset':
|
||
$assetId = $_POST['asset_id'] ?? '';
|
||
$filename = $_POST['filename'] ?? '';
|
||
|
||
if ($assetId && isset($results['selected_campaign'])) {
|
||
// Find the asset in our master_assets array to get its full data
|
||
$assetData = null;
|
||
if (isset($results['master_assets'])) {
|
||
foreach ($results['master_assets'] as $asset) {
|
||
if ($asset['asset_id'] === $assetId) {
|
||
$assetData = $asset;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
$result = downloadAsset($testRunner, $assetId, $filename, $results['selected_campaign']['campaign_id'], $assetData);
|
||
$results['last_download'] = $result;
|
||
|
||
if ($result['success']) {
|
||
$success = "Downloaded: " . $result['filename'];
|
||
} else {
|
||
$error = "Download failed: " . $result['error'];
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'download_asset_metadata':
|
||
$assetId = $_POST['asset_id'] ?? '';
|
||
$filename = $_POST['filename'] ?? 'metadata.json';
|
||
|
||
if ($assetId && isset($results['master_assets'])) {
|
||
// Find the asset in master_assets
|
||
foreach ($results['master_assets'] as $asset) {
|
||
if ($asset['asset_id'] === $assetId) {
|
||
// Create JSON file
|
||
$jsonFilename = pathinfo($filename, PATHINFO_FILENAME) . '_metadata.json';
|
||
$jsonContent = json_encode($asset, JSON_PRETTY_PRINT);
|
||
|
||
// Send as download
|
||
header('Content-Type: application/json');
|
||
header('Content-Disposition: attachment; filename="' . $jsonFilename . '"');
|
||
header('Content-Length: ' . strlen($jsonContent));
|
||
echo $jsonContent;
|
||
exit;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'download_all_assets':
|
||
if (isset($results['master_assets']) && isset($results['selected_campaign'])) {
|
||
$downloadResults = downloadAllAssets($testRunner, $results['master_assets'], $results['selected_campaign']['campaign_id']);
|
||
$results['bulk_download'] = $downloadResults;
|
||
// Store master assets metadata for later upload reference
|
||
$results['master_assets_metadata'] = $results['master_assets'];
|
||
$success = "Downloaded {$downloadResults['successful']} of {$downloadResults['total']} assets";
|
||
}
|
||
break;
|
||
|
||
case 'reset_to_a1':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus($campaignId, 'A1');
|
||
|
||
if ($statusResult['success']) {
|
||
$success = "Campaign reset to A1 status for testing";
|
||
// Clear session data so we can start fresh
|
||
unset($results['selected_campaign']);
|
||
unset($results['selected_campaign_a2']);
|
||
unset($results['master_assets_metadata']);
|
||
} else {
|
||
$errorMsg = "Unknown error";
|
||
if (isset($statusResult['response']['body'])) {
|
||
$responseData = json_decode($statusResult['response']['body'], true);
|
||
if ($responseData && isset($responseData['exception_body'])) {
|
||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||
} elseif ($responseData && isset($responseData['error'])) {
|
||
$errorMsg = $responseData['error'];
|
||
}
|
||
}
|
||
$error = "Failed to reset to A1 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||
}
|
||
}
|
||
$currentTab = $_POST['tab'] ?? 'download';
|
||
break;
|
||
|
||
case 'update_status_to_a2':
|
||
if (isset($results['selected_campaign'])) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus(
|
||
$results['selected_campaign']['asset_id'],
|
||
'A2'
|
||
);
|
||
|
||
if ($statusResult['success']) {
|
||
$results['status_update'] = $statusResult;
|
||
$results['selected_campaign']['status'] = 'A2';
|
||
$success = "Campaign status updated to A2: Selected Master Assets sent to Agency";
|
||
} else {
|
||
// Extract error details from API response
|
||
$errorMsg = "Unknown error";
|
||
if (isset($statusResult['response']['body'])) {
|
||
$responseData = json_decode($statusResult['response']['body'], true);
|
||
if ($responseData && isset($responseData['exception_body'])) {
|
||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||
} elseif ($responseData && isset($responseData['error'])) {
|
||
$errorMsg = $responseData['error'];
|
||
}
|
||
}
|
||
$error = "Failed to update status to A2 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||
// Store full result for debugging
|
||
$results['status_update_error'] = $statusResult;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'load_campaigns_a2':
|
||
$results['a2_campaigns'] = loadCampaignsByStatus($testRunner, 'A2');
|
||
$success = "Loaded " . count($results['a2_campaigns']) . " campaigns with status A2";
|
||
$currentTab = 'upload';
|
||
break;
|
||
|
||
case 'select_campaign_a2':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId && isset($results['a2_campaigns'])) {
|
||
foreach ($results['a2_campaigns'] as $campaign) {
|
||
if ($campaign['asset_id'] === $campaignId) {
|
||
$results['selected_campaign_a2'] = $campaign;
|
||
$success = "Campaign selected: " . $campaign['campaign_name'];
|
||
$currentTab = 'upload';
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'get_upload_folder':
|
||
if (isset($results['selected_campaign_a2'])) {
|
||
$campaignId = $results['selected_campaign_a2']['asset_id'];
|
||
|
||
// Find Final Assets or Localized Assets folder for upload
|
||
$uploadFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
|
||
if ($uploadFolderId) {
|
||
$results['upload_folder_id'] = $uploadFolderId;
|
||
|
||
// Get Master Assets to copy their metadata
|
||
try {
|
||
$masterFolderId = findMasterAssetsFolder($testRunner, $campaignId, $configV3);
|
||
if ($masterFolderId) {
|
||
$fullMasterAssets = getAssetsFromFolder($testRunner, $masterFolderId);
|
||
|
||
// Store lightweight version - only IDs and basic info
|
||
$results['master_assets_for_upload'] = [];
|
||
if (!empty($fullMasterAssets)) {
|
||
foreach ($fullMasterAssets as $asset) {
|
||
// Only store minimal fields - no huge metadata structure
|
||
$lightAsset = [
|
||
'asset_id' => $asset['asset_id'] ?? null,
|
||
'name' => $asset['name'] ?? 'Unknown',
|
||
'mime_type' => $asset['mime_type'] ?? null
|
||
];
|
||
|
||
// Safely extract metadata_model_id if it exists
|
||
if (isset($asset['metadata_model_id'])) {
|
||
$lightAsset['metadata_model_id'] = $asset['metadata_model_id'];
|
||
}
|
||
|
||
// Safely extract security policy IDs only
|
||
if (isset($asset['security_policy_list']) && is_array($asset['security_policy_list'])) {
|
||
$policyIds = [];
|
||
foreach ($asset['security_policy_list'] as $policy) {
|
||
if (isset($policy['id'])) {
|
||
$policyIds[] = ['id' => $policy['id']];
|
||
}
|
||
}
|
||
if (!empty($policyIds)) {
|
||
$lightAsset['security_policy_list'] = $policyIds;
|
||
}
|
||
}
|
||
|
||
$results['master_assets_for_upload'][] = $lightAsset;
|
||
}
|
||
}
|
||
|
||
$success = "Found upload folder and " . count($results['master_assets_for_upload']) . " master assets for reference";
|
||
} else {
|
||
$success = "Found upload target folder (no master assets folder found)";
|
||
}
|
||
} catch (Exception $e) {
|
||
$success = "Found upload target folder (master assets error: " . $e->getMessage() . ")";
|
||
}
|
||
} else {
|
||
$error = "Upload folder not found in campaign";
|
||
}
|
||
}
|
||
$currentTab = 'upload';
|
||
break;
|
||
|
||
case 'test_upload_to_folder':
|
||
// Test upload to specific folder provided by Ferrero team
|
||
$testFolderId = $_POST['test_folder_id'] ?? 'e96080ba0cd1427d253a28a87504b6665eaa02cb';
|
||
|
||
if (isset($_FILES['test_upload_file'])) {
|
||
$tmpName = $_FILES['test_upload_file']['tmp_name'];
|
||
$fileName = $_FILES['test_upload_file']['name'];
|
||
$fileError = $_FILES['test_upload_file']['error'];
|
||
|
||
if ($fileError === UPLOAD_ERR_OK) {
|
||
$apiClient = new ApiClient();
|
||
$configV3 = new ConfigV3();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
||
}
|
||
|
||
$uploader = new AssetUploader($apiClient, $testFolderId);
|
||
$result = $uploader->uploadFile($tmpName, $testFolderId, [], null, $testRunner);
|
||
|
||
$results['test_upload_result'] = $result;
|
||
$results['test_folder_id'] = $testFolderId;
|
||
|
||
if ($result['success']) {
|
||
$success = "✅ TEST UPLOAD SUCCESSFUL to folder {$testFolderId}!";
|
||
} else {
|
||
$error = "Test upload failed: " . $result['error'];
|
||
}
|
||
} else {
|
||
$error = "File upload error: " . $fileError;
|
||
}
|
||
}
|
||
$currentTab = 'upload';
|
||
break;
|
||
|
||
case 'upload_files':
|
||
if (isset($_FILES['upload_files']) && isset($results['upload_folder_id'])) {
|
||
// Get selected master asset lightweight data
|
||
$selectedMasterAssetLight = null;
|
||
$masterMetadataIndex = $_POST['master_metadata_index'] ?? '0';
|
||
|
||
// Use master_assets_for_upload (lightweight version)
|
||
if ($masterMetadataIndex !== '' && isset($results['master_assets_for_upload'][$masterMetadataIndex])) {
|
||
$selectedMasterAssetLight = $results['master_assets_for_upload'][$masterMetadataIndex];
|
||
} elseif (isset($results['master_assets_for_upload']) && !empty($results['master_assets_for_upload'])) {
|
||
// If no selection, use first master asset as default
|
||
$selectedMasterAssetLight = $results['master_assets_for_upload'][0];
|
||
}
|
||
|
||
// Use the lightweight master asset data directly
|
||
// Full metadata fetch causes crashes - we only need model ID and security policies
|
||
$selectedMasterAsset = $selectedMasterAssetLight;
|
||
|
||
// Store debug info about selected master asset and uploaded file
|
||
$uploadFileName = is_array($_FILES['upload_files']['name']) ? $_FILES['upload_files']['name'][0] : $_FILES['upload_files']['name'];
|
||
$uploadTmpName = is_array($_FILES['upload_files']['tmp_name']) ? $_FILES['upload_files']['tmp_name'][0] : $_FILES['upload_files']['tmp_name'];
|
||
$uploadMimeType = file_exists($uploadTmpName) ? mime_content_type($uploadTmpName) : 'Unknown';
|
||
|
||
$results['upload_debug'] = [
|
||
'selected_master_asset_id' => $selectedMasterAsset['asset_id'] ?? 'N/A',
|
||
'selected_master_name' => $selectedMasterAsset['name'] ?? 'N/A',
|
||
'metadata_model_id' => $selectedMasterAsset['metadata_model_id'] ?? 'NOT FOUND',
|
||
'has_security_policies' => isset($selectedMasterAsset['security_policy_list']) ? 'YES' : 'NO',
|
||
'security_policy_count' => isset($selectedMasterAsset['security_policy_list']) ? count($selectedMasterAsset['security_policy_list']) : 0,
|
||
'master_mime_type' => $selectedMasterAsset['mime_type'] ?? 'Unknown',
|
||
'upload_filename' => $uploadFileName,
|
||
'upload_detected_mime' => $uploadMimeType,
|
||
'upload_folder_id' => $results['upload_folder_id']
|
||
];
|
||
|
||
$uploadResults = uploadFiles($testRunner, $_FILES['upload_files'], $results['upload_folder_id'], $selectedMasterAsset);
|
||
$results['upload_results'] = $uploadResults;
|
||
|
||
if ($uploadResults['successful'] > 0) {
|
||
$success = "Uploaded {$uploadResults['successful']} of {$uploadResults['total']} files";
|
||
} else {
|
||
$error = "All uploads failed";
|
||
}
|
||
}
|
||
$currentTab = 'upload';
|
||
break;
|
||
|
||
case 'update_status_to_a3':
|
||
if (isset($results['selected_campaign_a2'])) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus(
|
||
$results['selected_campaign_a2']['asset_id'],
|
||
'A3'
|
||
);
|
||
|
||
if ($statusResult['success']) {
|
||
$results['status_update_a3'] = $statusResult;
|
||
$success = "Campaign status updated to A3: Localized Asset received from Agency";
|
||
} else {
|
||
// Extract error details from API response
|
||
$errorMsg = "Unknown error";
|
||
if (isset($statusResult['response']['body'])) {
|
||
$responseData = json_decode($statusResult['response']['body'], true);
|
||
if ($responseData && isset($responseData['exception_body'])) {
|
||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||
} elseif ($responseData && isset($responseData['error'])) {
|
||
$errorMsg = $responseData['error'];
|
||
}
|
||
}
|
||
$error = "Failed to update status to A3 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||
$results['status_update_a3_error'] = $statusResult;
|
||
}
|
||
}
|
||
$currentTab = 'upload';
|
||
break;
|
||
|
||
case 'debug_all_campaigns_rework':
|
||
// Check OAuth status first
|
||
$oauth2Status = $testRunner->getOAuth2Status();
|
||
$results['oauth_debug_rework'] = [
|
||
'has_token' => $oauth2Status['has_token'] ?? false,
|
||
'expires_at' => $oauth2Status['expires_at'] ?? 'Unknown'
|
||
];
|
||
|
||
$statusManager = createStatusManager($testRunner);
|
||
$response = $statusManager->searchAllCampaigns($testRunner);
|
||
|
||
if ($response['success']) {
|
||
$data = json_decode($response['body'], true);
|
||
$campaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||
$results['debug_campaigns_rework'] = $campaigns;
|
||
$results['debug_raw_rework'] = $data;
|
||
$results['debug_search_response_rework'] = [
|
||
'http_code' => $response['http_code'],
|
||
'url' => $response['url'] ?? 'N/A',
|
||
'total_results' => $data['search_result_resource']['search_result']['total_hit_count'] ?? 0,
|
||
'response_body_preview' => substr($response['body'] ?? '', 0, 500)
|
||
];
|
||
$success = "Found " . count($campaigns) . " campaigns total (without status filter)";
|
||
} else {
|
||
$error = "Debug search failed: HTTP " . ($response['http_code'] ?? 'N/A') . " - " . ($response['error'] ?? 'Unknown error');
|
||
$results['debug_search_response_rework'] = [
|
||
'http_code' => $response['http_code'],
|
||
'url' => $response['url'] ?? 'N/A',
|
||
'error' => $response['error'] ?? 'Unknown',
|
||
'response_preview' => substr($response['body'] ?? '', 0, 500)
|
||
];
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'reset_to_a5':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus($campaignId, 'A5');
|
||
|
||
if ($statusResult['success']) {
|
||
$success = "Campaign reset to A5 status for testing";
|
||
// Clear session data
|
||
unset($results['selected_campaign_a5']);
|
||
unset($results['rework_assets']);
|
||
} else {
|
||
$errorMsg = "Unknown error";
|
||
if (isset($statusResult['response']['body'])) {
|
||
$responseData = json_decode($statusResult['response']['body'], true);
|
||
if ($responseData && isset($responseData['exception_body'])) {
|
||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||
} elseif ($responseData && isset($responseData['error'])) {
|
||
$errorMsg = $responseData['error'];
|
||
}
|
||
}
|
||
$error = "Failed to reset to A5 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||
}
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'load_campaigns_a5':
|
||
$results['a5_campaigns'] = loadCampaignsByStatus($testRunner, 'A5');
|
||
$success = "Loaded " . count($results['a5_campaigns']) . " campaigns with status A5";
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'select_campaign_a5':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId && isset($results['a5_campaigns'])) {
|
||
foreach ($results['a5_campaigns'] as $campaign) {
|
||
if ($campaign['asset_id'] === $campaignId) {
|
||
$results['selected_campaign_a5'] = $campaign;
|
||
$success = "Campaign selected: " . $campaign['campaign_name'];
|
||
$currentTab = 'rework';
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'get_rework_assets':
|
||
if (isset($results['selected_campaign_a5'])) {
|
||
$campaignId = $results['selected_campaign_a5']['asset_id'];
|
||
// Find folder with rework assets (could be Final Assets or Rework folder)
|
||
$reworkFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
|
||
if ($reworkFolderId) {
|
||
$results['rework_folder_id'] = $reworkFolderId;
|
||
$results['rework_assets'] = getAssetsFromFolder($testRunner, $reworkFolderId);
|
||
$success = "Found " . count($results['rework_assets']) . " assets needing rework";
|
||
} else {
|
||
$error = "Rework assets folder not found";
|
||
}
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'download_rework_asset':
|
||
$assetId = $_POST['asset_id'] ?? '';
|
||
$filename = $_POST['filename'] ?? '';
|
||
|
||
if ($assetId && isset($results['selected_campaign_a5'])) {
|
||
$assetData = null;
|
||
if (isset($results['rework_assets'])) {
|
||
foreach ($results['rework_assets'] as $asset) {
|
||
if ($asset['asset_id'] === $assetId) {
|
||
$assetData = $asset;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
$result = downloadAsset($testRunner, $assetId, $filename, $results['selected_campaign_a5']['campaign_id'], $assetData);
|
||
$results['last_rework_download'] = $result;
|
||
|
||
if ($result['success']) {
|
||
$success = "Downloaded rework asset: " . $result['filename'];
|
||
} else {
|
||
$error = "Download failed: " . $result['error'];
|
||
}
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'download_all_rework':
|
||
if (isset($results['rework_assets']) && isset($results['selected_campaign_a5'])) {
|
||
$downloadResults = downloadAllAssets($testRunner, $results['rework_assets'], $results['selected_campaign_a5']['campaign_id']);
|
||
$results['rework_bulk_download'] = $downloadResults;
|
||
$success = "Downloaded {$downloadResults['successful']} of {$downloadResults['total']} rework assets";
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
|
||
case 'update_status_to_a6':
|
||
if (isset($results['selected_campaign_a5'])) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus(
|
||
$results['selected_campaign_a5']['asset_id'],
|
||
'A6'
|
||
);
|
||
|
||
if ($statusResult['success']) {
|
||
$results['status_update_a6'] = $statusResult;
|
||
$success = "Campaign status updated to A6: Assets to be reworked received by the Agency";
|
||
} else {
|
||
// Extract error details from API response
|
||
$errorMsg = "Unknown error";
|
||
if (isset($statusResult['response']['body'])) {
|
||
$responseData = json_decode($statusResult['response']['body'], true);
|
||
if ($responseData && isset($responseData['exception_body'])) {
|
||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||
} elseif ($responseData && isset($responseData['error'])) {
|
||
$errorMsg = $responseData['error'];
|
||
}
|
||
}
|
||
$error = "Failed to update status to A6 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||
$results['status_update_a6_error'] = $statusResult;
|
||
}
|
||
}
|
||
$currentTab = 'rework';
|
||
break;
|
||
}
|
||
} catch (Exception $e) {
|
||
$error = "Action failed: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
// Helper Functions
|
||
|
||
function loadCampaignsByStatus($testRunner, $status)
|
||
{
|
||
// Search for ALL Local Adaptation campaigns (without status filter in API)
|
||
// Then let CampaignFormatter filter by status in PHP
|
||
$statusManager = createStatusManager($testRunner);
|
||
$response = $statusManager->searchAllCampaigns($testRunner);
|
||
|
||
if ($response['success']) {
|
||
// Get ALL campaigns first
|
||
$allCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||
|
||
// Debug: Store all campaigns to see their statuses
|
||
global $results;
|
||
$results['debug_all_campaigns_count'] = count($allCampaigns);
|
||
$results['debug_status_filter'] = $status;
|
||
|
||
// Now filter by status
|
||
$filteredCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], ['status' => $status]);
|
||
$results['debug_filtered_count'] = count($filteredCampaigns);
|
||
|
||
return $filteredCampaigns;
|
||
}
|
||
|
||
return [];
|
||
}
|
||
|
||
function findMasterAssetsFolder($testRunner, $campaignId, $configV3)
|
||
{
|
||
$masterFolderName = $configV3->getFolderName('master_assets');
|
||
|
||
$requests = $testRunner->getAvailableRequests();
|
||
|
||
foreach ($requests as $index => $request) {
|
||
$name = strtolower($request['name']);
|
||
if (strpos($name, 'retrieve master asset folder') !== false ||
|
||
strpos($name, 'master asset folder and final') !== false) {
|
||
|
||
$modifiedRequest = $request;
|
||
$url = is_array($request['request']['url']) ? $request['request']['url']['raw'] : $request['request']['url'];
|
||
$url = preg_replace('/folders\/[a-f0-9]+\//', "folders/{$campaignId}/", $url);
|
||
$url = str_replace('{{baseUrl}}', $configV3->getBaseUrl(), $url);
|
||
|
||
if (is_array($modifiedRequest['request']['url'])) {
|
||
$modifiedRequest['request']['url']['raw'] = $url;
|
||
} else {
|
||
$modifiedRequest['request']['url'] = $url;
|
||
}
|
||
|
||
$result = $testRunner->runSingleTest($modifiedRequest, $index);
|
||
|
||
if ($result['status'] === 'PASS') {
|
||
$data = json_decode($result['response']['body'], true);
|
||
$folders = $data['folder_children']['asset_list'] ?? [];
|
||
|
||
foreach ($folders as $folder) {
|
||
$folderName = extractFolderName($folder);
|
||
if (strpos($folderName, 'Master') !== false || $folderName === $masterFolderName) {
|
||
return $folder['asset_id'];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
function extractFolderName($folder)
|
||
{
|
||
$nameFields = [
|
||
'INER_NAME_GENERIC',
|
||
'ARTESIA.FIELD.NAME',
|
||
'FERRERO.FIELD.CAMPAIGN_NAME',
|
||
'ARTESIA.FIELD.TITLE'
|
||
];
|
||
|
||
if (isset($folder['metadata']['metadata_element_list'])) {
|
||
foreach ($folder['metadata']['metadata_element_list'] as $category) {
|
||
if (isset($category['metadata_element_list'])) {
|
||
foreach ($category['metadata_element_list'] as $field) {
|
||
if (in_array($field['id'], $nameFields) && isset($field['value']['value']['value'])) {
|
||
return $field['value']['value']['value'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $folder['name'] ?? $folder['title'] ?? 'Unnamed';
|
||
}
|
||
|
||
function getAssetsFromFolder($testRunner, $folderId)
|
||
{
|
||
$requests = $testRunner->getAvailableRequests();
|
||
|
||
foreach ($requests as $index => $request) {
|
||
$name = strtolower($request['name']);
|
||
if (strpos($name, 'retrieve all assets from') !== false) {
|
||
$modifiedRequest = $request;
|
||
$url = is_array($request['request']['url']) ? $request['request']['url']['raw'] : $request['request']['url'];
|
||
$url = preg_replace('/folders\/[a-f0-9]+\//', "folders/{$folderId}/", $url);
|
||
|
||
if (is_array($modifiedRequest['request']['url'])) {
|
||
$modifiedRequest['request']['url']['raw'] = $url;
|
||
} else {
|
||
$modifiedRequest['request']['url'] = $url;
|
||
}
|
||
|
||
$result = $testRunner->runSingleTest($modifiedRequest, $index);
|
||
|
||
if ($result['status'] === 'PASS') {
|
||
$data = json_decode($result['response']['body'], true);
|
||
$assets = $data['folder_children']['asset_list'] ?? [];
|
||
|
||
// Filter out folders, only return files
|
||
return array_filter($assets, function($asset) {
|
||
return ($asset['data_type'] ?? '') !== 'CONTAINER';
|
||
});
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
return [];
|
||
}
|
||
|
||
function downloadAsset($testRunner, $assetId, $filename, $campaignId, $assetData = null)
|
||
{
|
||
$apiClient = new ApiClient();
|
||
$configV3 = new ConfigV3();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
// Get OAuth2 token
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
||
}
|
||
|
||
$renditionUrl = null;
|
||
$debugInfo = [];
|
||
|
||
// If we have asset data from folder listing, use it directly
|
||
if ($assetData) {
|
||
$debugInfo['using_cached_asset_data'] = true;
|
||
|
||
// Look for rendition URL in asset_content_info from folder listing
|
||
if (isset($assetData['asset_content_info']['master_content']['url'])) {
|
||
$renditionUrl = $assetData['asset_content_info']['master_content']['url'];
|
||
$debugInfo['found_master_content_url'] = true;
|
||
}
|
||
elseif (isset($assetData['asset_content_info'][0]['url'])) {
|
||
$renditionUrl = $assetData['asset_content_info'][0]['url'];
|
||
$debugInfo['found_array_url'] = true;
|
||
}
|
||
elseif (isset($assetData['asset_content_info']['url'])) {
|
||
$renditionUrl = $assetData['asset_content_info']['url'];
|
||
$debugInfo['found_direct_url'] = true;
|
||
}
|
||
|
||
$debugInfo['has_asset_content_info'] = isset($assetData['asset_content_info']);
|
||
$debugInfo['asset_content_info_type'] = isset($assetData['asset_content_info']) ? gettype($assetData['asset_content_info']) : 'not set';
|
||
}
|
||
|
||
// Fallback: Fetch asset metadata if not provided or rendition not found
|
||
if (!$renditionUrl) {
|
||
$debugInfo['fetching_from_api'] = true;
|
||
|
||
$metadataRequest = [
|
||
'method' => 'GET',
|
||
'url' => "/v6/assets/{$assetId}?load_type=full"
|
||
];
|
||
|
||
$metadataResponse = $apiClient->executeRequest($metadataRequest);
|
||
|
||
if ($metadataResponse['success']) {
|
||
$fetchedData = json_decode($metadataResponse['body'], true);
|
||
$asset = $fetchedData['asset'] ?? $fetchedData;
|
||
|
||
if (isset($asset['asset_content_info']['master_content']['url'])) {
|
||
$renditionUrl = $asset['asset_content_info']['master_content']['url'];
|
||
}
|
||
elseif (isset($asset['asset_content_info'][0]['url'])) {
|
||
$renditionUrl = $asset['asset_content_info'][0]['url'];
|
||
}
|
||
elseif (isset($asset['asset_content_info']['url'])) {
|
||
$renditionUrl = $asset['asset_content_info']['url'];
|
||
}
|
||
|
||
$debugInfo['api_has_asset_content_info'] = isset($asset['asset_content_info']);
|
||
}
|
||
}
|
||
|
||
// Try direct download if no rendition URL found
|
||
if (!$renditionUrl) {
|
||
$renditionUrl = "/v6/assets/{$assetId}/contents";
|
||
}
|
||
|
||
// Clean up the URL - remove /otmmapi prefix if present (base URL already has it)
|
||
$renditionUrl = str_replace('/otmmapi/', '/', $renditionUrl);
|
||
|
||
$debugInfo['final_url'] = $renditionUrl;
|
||
|
||
// Try to download - first attempt with original/master rendition
|
||
$request = [
|
||
'method' => 'GET',
|
||
'url' => $renditionUrl
|
||
];
|
||
|
||
$response = $apiClient->executeRequest($request);
|
||
$attempts = [['url' => $renditionUrl, 'type' => 'original', 'http_code' => $response['http_code']]];
|
||
|
||
// If original fails and we have asset data, try preview/thumbnail renditions
|
||
if ($response['success'] && !empty($response['body'])) {
|
||
$jsonCheck = json_decode($response['body'], true);
|
||
|
||
if ($jsonCheck && isset($jsonCheck['exception_body'])) {
|
||
// Original failed, try alternative renditions from asset data
|
||
$alternativeRenditions = [];
|
||
|
||
if ($assetData && isset($assetData['asset_content_info'])) {
|
||
$debugInfo['asset_content_info_count'] = count($assetData['asset_content_info']);
|
||
|
||
foreach ($assetData['asset_content_info'] as $key => $contentInfo) {
|
||
if (is_array($contentInfo)) {
|
||
$rendType = $contentInfo['rendition_type'] ?? $key;
|
||
$debugInfo['content_info_keys'][] = $key;
|
||
|
||
if (isset($contentInfo['url'])) {
|
||
// Add ALL renditions, not just preview/thumbnail
|
||
$alternativeRenditions[] = [
|
||
'url' => str_replace('/otmmapi/', '/', $contentInfo['url']),
|
||
'type' => $rendType
|
||
];
|
||
}
|
||
}
|
||
}
|
||
|
||
$debugInfo['alternative_renditions_found'] = count($alternativeRenditions);
|
||
}
|
||
|
||
// Try alternative renditions
|
||
foreach ($alternativeRenditions as $altRendition) {
|
||
$altRequest = ['method' => 'GET', 'url' => $altRendition['url']];
|
||
$altResponse = $apiClient->executeRequest($altRequest);
|
||
$attempts[] = ['url' => $altRendition['url'], 'type' => $altRendition['type'], 'http_code' => $altResponse['http_code']];
|
||
|
||
if ($altResponse['success'] && !empty($altResponse['body'])) {
|
||
$altCheck = json_decode($altResponse['body'], true);
|
||
if (!$altCheck || !isset($altCheck['exception_body'])) {
|
||
// Success with alternative rendition!
|
||
$response = $altResponse;
|
||
$renditionUrl = $altRendition['url'];
|
||
$debugInfo['used_rendition'] = $altRendition['type'];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Still failed after all attempts
|
||
$finalCheck = json_decode($response['body'], true);
|
||
if ($finalCheck && isset($finalCheck['exception_body'])) {
|
||
return [
|
||
'success' => false,
|
||
'error' => $finalCheck['exception_body']['message'] ?? 'File not found in storage',
|
||
'http_code' => $finalCheck['exception_body']['http_response_code'] ?? 500,
|
||
'debug_message' => $finalCheck['exception_body']['debug_message'] ?? '',
|
||
'tried_url' => $renditionUrl,
|
||
'debug_info' => $debugInfo,
|
||
'all_attempts' => $attempts
|
||
];
|
||
}
|
||
}
|
||
|
||
$downloadPath = $configV3->getDownloadPath($campaignId);
|
||
|
||
if (!is_dir($downloadPath)) {
|
||
mkdir($downloadPath, 0755, true);
|
||
}
|
||
|
||
$safeFilename = preg_replace('/[^a-zA-Z0-9._-]/', '_', $filename ?: "asset_{$assetId}");
|
||
$fullPath = $downloadPath . '/' . $safeFilename;
|
||
$bytesWritten = file_put_contents($fullPath, $response['body']);
|
||
|
||
return [
|
||
'success' => $bytesWritten !== false,
|
||
'filename' => $safeFilename,
|
||
'filepath' => $fullPath,
|
||
'size' => $bytesWritten,
|
||
'asset_id' => $assetId,
|
||
'download_method' => 'rendition',
|
||
'rendition_url' => $renditionUrl
|
||
];
|
||
}
|
||
|
||
return [
|
||
'success' => false,
|
||
'error' => $response['error'] ?? 'Download failed',
|
||
'http_code' => $response['http_code'],
|
||
'tried_url' => $renditionUrl
|
||
];
|
||
}
|
||
|
||
function downloadAllAssets($testRunner, $assets, $campaignId)
|
||
{
|
||
$results = [
|
||
'total' => count($assets),
|
||
'successful' => 0,
|
||
'failed' => 0,
|
||
'details' => []
|
||
];
|
||
|
||
foreach ($assets as $asset) {
|
||
$filename = extractFolderName($asset);
|
||
$result = downloadAsset($testRunner, $asset['asset_id'], $filename, $campaignId);
|
||
|
||
if ($result['success']) {
|
||
$results['successful']++;
|
||
} else {
|
||
$results['failed']++;
|
||
}
|
||
|
||
$results['details'][] = $result;
|
||
}
|
||
|
||
return $results;
|
||
}
|
||
|
||
function createStatusManager($testRunner)
|
||
{
|
||
$apiClient = new ApiClient();
|
||
$configV3 = new ConfigV3();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
||
}
|
||
|
||
return new StatusManager($apiClient);
|
||
}
|
||
|
||
function findUploadFolder($testRunner, $campaignId, $configV3)
|
||
{
|
||
$finalFolderName = $configV3->getFolderName('final_assets');
|
||
|
||
$requests = $testRunner->getAvailableRequests();
|
||
|
||
foreach ($requests as $index => $request) {
|
||
$name = strtolower($request['name']);
|
||
if (strpos($name, 'retrieve master asset folder') !== false ||
|
||
strpos($name, 'master asset folder and final') !== false) {
|
||
|
||
$modifiedRequest = $request;
|
||
$url = is_array($request['request']['url']) ? $request['request']['url']['raw'] : $request['request']['url'];
|
||
$url = preg_replace('/folders\/[a-f0-9]+\//', "folders/{$campaignId}/", $url);
|
||
$url = str_replace('{{baseUrl}}', $configV3->getBaseUrl(), $url);
|
||
|
||
if (is_array($modifiedRequest['request']['url'])) {
|
||
$modifiedRequest['request']['url']['raw'] = $url;
|
||
} else {
|
||
$modifiedRequest['request']['url'] = $url;
|
||
}
|
||
|
||
$result = $testRunner->runSingleTest($modifiedRequest, $index);
|
||
|
||
if ($result['status'] === 'PASS') {
|
||
$data = json_decode($result['response']['body'], true);
|
||
$folders = $data['folder_children']['asset_list'] ?? [];
|
||
|
||
foreach ($folders as $folder) {
|
||
$folderName = extractFolderName($folder);
|
||
// Look for Final Assets or Localized folder
|
||
if (strpos($folderName, 'Final') !== false ||
|
||
strpos($folderName, 'Localized') !== false ||
|
||
$folderName === $finalFolderName) {
|
||
return $folder['asset_id'];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
function fetchFullAssetMetadata($testRunner, $assetId)
|
||
{
|
||
$apiClient = new ApiClient();
|
||
$configV3 = new ConfigV3();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
// Get OAuth2 token
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
||
}
|
||
|
||
// Fetch full asset with metadata
|
||
$request = [
|
||
'method' => 'GET',
|
||
'url' => "/v6/assets/{$assetId}?load_type=full"
|
||
];
|
||
|
||
$response = $apiClient->executeRequest($request);
|
||
|
||
if ($response['success']) {
|
||
$data = json_decode($response['body'], true);
|
||
return $data['asset'] ?? null;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
function uploadFiles($testRunner, $uploadedFiles, $folderId, $selectedMasterAsset = null)
|
||
{
|
||
$apiClient = new ApiClient();
|
||
$configV3 = new ConfigV3();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
||
}
|
||
|
||
$uploader = new AssetUploader($apiClient, $folderId);
|
||
|
||
$results = [
|
||
'total' => 0,
|
||
'successful' => 0,
|
||
'failed' => 0,
|
||
'details' => []
|
||
];
|
||
|
||
// Handle multiple file upload
|
||
if (isset($uploadedFiles['tmp_name'])) {
|
||
$fileCount = is_array($uploadedFiles['tmp_name']) ? count($uploadedFiles['tmp_name']) : 1;
|
||
$results['total'] = $fileCount;
|
||
|
||
for ($i = 0; $i < $fileCount; $i++) {
|
||
$tmpName = is_array($uploadedFiles['tmp_name']) ? $uploadedFiles['tmp_name'][$i] : $uploadedFiles['tmp_name'];
|
||
$fileName = is_array($uploadedFiles['name']) ? $uploadedFiles['name'][$i] : $uploadedFiles['name'];
|
||
$fileError = is_array($uploadedFiles['error']) ? $uploadedFiles['error'][$i] : $uploadedFiles['error'];
|
||
|
||
if ($fileError !== UPLOAD_ERR_OK) {
|
||
$results['details'][] = [
|
||
'success' => false,
|
||
'filename' => $fileName,
|
||
'error' => 'Upload error code: ' . $fileError
|
||
];
|
||
$results['failed']++;
|
||
continue;
|
||
}
|
||
|
||
// Pass the entire selected master asset (not just metadata) and TestRunner
|
||
$result = $uploader->uploadFile($tmpName, $folderId, [], $selectedMasterAsset, $testRunner);
|
||
|
||
if ($result['success']) {
|
||
$results['successful']++;
|
||
} else {
|
||
$results['failed']++;
|
||
}
|
||
|
||
$results['details'][] = $result;
|
||
}
|
||
}
|
||
|
||
return $results;
|
||
}
|
||
|
||
$oauth2Status = $testRunner ? $testRunner->getOAuth2Status() : null;
|
||
$envInfo = $configV3->getEnvironmentInfo();
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Content Scaling Workflow V3</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
background-color: #f5f5f5;
|
||
padding: 20px;
|
||
}
|
||
|
||
.container {
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
background: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.header {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
padding: 30px;
|
||
text-align: center;
|
||
}
|
||
|
||
.header h1 { margin-bottom: 10px; }
|
||
.header p { opacity: 0.9; }
|
||
|
||
.env-info {
|
||
background: rgba(255,255,255,0.2);
|
||
padding: 10px;
|
||
border-radius: 4px;
|
||
margin-top: 15px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
background: #f8f9fa;
|
||
border-bottom: 2px solid #dee2e6;
|
||
}
|
||
|
||
.tab {
|
||
flex: 1;
|
||
padding: 15px 20px;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
border: none;
|
||
background: transparent;
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
color: #6c757d;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.tab:hover { background: #e9ecef; }
|
||
|
||
.tab.active {
|
||
background: white;
|
||
color: #667eea;
|
||
border-bottom: 3px solid #667eea;
|
||
}
|
||
|
||
.tab-content {
|
||
padding: 30px;
|
||
display: none;
|
||
}
|
||
|
||
.tab-content.active { display: block; }
|
||
|
||
.alert {
|
||
padding: 12px 20px;
|
||
border-radius: 6px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.alert-error {
|
||
background: #f8d7da;
|
||
color: #721c24;
|
||
border: 1px solid #f5c6cb;
|
||
}
|
||
|
||
.alert-success {
|
||
background: #d4edda;
|
||
color: #155724;
|
||
border: 1px solid #c3e6cb;
|
||
}
|
||
|
||
.alert-info {
|
||
background: #d1ecf1;
|
||
color: #0c5460;
|
||
border: 1px solid #bee5eb;
|
||
}
|
||
|
||
.btn {
|
||
padding: 12px 24px;
|
||
border: none;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
margin-right: 10px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: #667eea;
|
||
color: white;
|
||
}
|
||
|
||
.btn-primary:hover { background: #5568d3; }
|
||
|
||
.btn-success {
|
||
background: #28a745;
|
||
color: white;
|
||
}
|
||
|
||
.btn-success:hover { background: #218838; }
|
||
|
||
.btn-danger {
|
||
background: #dc3545;
|
||
color: white;
|
||
}
|
||
|
||
.btn-secondary {
|
||
background: #6c757d;
|
||
color: white;
|
||
}
|
||
|
||
.campaign-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||
gap: 20px;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.campaign-card {
|
||
background: #f8f9fa;
|
||
border: 2px solid #dee2e6;
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.campaign-card:hover {
|
||
border-color: #667eea;
|
||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
|
||
}
|
||
|
||
.campaign-card.selected {
|
||
border-color: #28a745;
|
||
background: #f8fff9;
|
||
}
|
||
|
||
.campaign-card h3 {
|
||
color: #333;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.campaign-card p {
|
||
margin: 5px 0;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.asset-list {
|
||
background: #f8f9fa;
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
.asset-item {
|
||
background: white;
|
||
border: 1px solid #dee2e6;
|
||
border-radius: 6px;
|
||
padding: 15px;
|
||
margin: 10px 0;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.asset-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.asset-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
.metadata-display {
|
||
background: #e9ecef;
|
||
padding: 15px;
|
||
border-radius: 6px;
|
||
margin-top: 10px;
|
||
font-size: 12px;
|
||
font-family: monospace;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
display: none;
|
||
}
|
||
|
||
.status-badge {
|
||
display: inline-block;
|
||
padding: 4px 12px;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.status-a1 { background: #fff3cd; color: #856404; }
|
||
.status-a2 { background: #cfe2ff; color: #084298; }
|
||
.status-a3 { background: #d1e7dd; color: #0f5132; }
|
||
.status-a5 { background: #f8d7da; color: #842029; }
|
||
.status-a6 { background: #e2d9f3; color: #432874; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="header">
|
||
<h1>🎯 Content Scaling Workflow V3</h1>
|
||
<p>Status-based workflow management for Ferrero DAM</p>
|
||
<div class="env-info">
|
||
<strong>Environment:</strong> <?= htmlspecialchars($envInfo['description']) ?>
|
||
(<?= htmlspecialchars($envInfo['name']) ?>)
|
||
<br>
|
||
<strong>Base URL:</strong> <?= htmlspecialchars($envInfo['baseUrl']) ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if ($error): ?>
|
||
<div style="padding: 20px;">
|
||
<div class="alert alert-error">
|
||
<strong>❌ Error:</strong> <?= htmlspecialchars($error) ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($success): ?>
|
||
<div style="padding: 20px;">
|
||
<div class="alert alert-success">
|
||
<strong>✅ Success:</strong> <?= htmlspecialchars($success) ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($oauth2Status && $oauth2Status['enabled']): ?>
|
||
<div style="padding: 20px; padding-bottom: 0;">
|
||
<div class="alert alert-<?= ($oauth2Status['has_token'] ?? false) ? 'success' : 'error' ?>">
|
||
<?= ($oauth2Status['has_token'] ?? false) ? '✅ OAuth2 Token Active' : '❌ OAuth2 Token Issue' ?>
|
||
<?php if (($oauth2Status['has_token'] ?? false) && isset($oauth2Status['expires_at'])): ?>
|
||
- Expires: <?= htmlspecialchars($oauth2Status['expires_at']) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="tabs">
|
||
<button class="tab <?= $currentTab === 'download' ? 'active' : '' ?>"
|
||
onclick="switchTab('download')">
|
||
📥 Download Workflow (A1→A2)
|
||
</button>
|
||
<button class="tab <?= $currentTab === 'upload' ? 'active' : '' ?>"
|
||
onclick="switchTab('upload')">
|
||
📤 Upload Workflow (A2→A3)
|
||
</button>
|
||
<button class="tab <?= $currentTab === 'rework' ? 'active' : '' ?>"
|
||
onclick="switchTab('rework')">
|
||
🔄 Rework Workflow (A5→A6)
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Download Workflow Tab -->
|
||
<div id="tab-download" class="tab-content <?= $currentTab === 'download' ? 'active' : '' ?>">
|
||
<h2>📥 Download Workflow: A1 → A2</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0;">
|
||
Load campaigns with status A1, download master assets, and update status to A2
|
||
</p>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="load_campaigns_a1">
|
||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A1)</button>
|
||
</form>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="debug_all_campaigns">
|
||
<button type="submit" class="btn btn-secondary">🔍 Debug: Load ALL Campaigns (no filter)</button>
|
||
</form>
|
||
|
||
<?php if (!empty($results)): ?>
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="clear_results" value="1">
|
||
<button type="submit" class="btn btn-secondary">🗑️ Clear Workflow Data</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_campaigns']) || isset($results['debug_search_response'])): ?>
|
||
<div class="alert alert-<?= ($results['debug_search_response']['http_code'] ?? 0) == 503 ? 'error' : 'info' ?>" style="margin-top: 30px;">
|
||
<h3>🔍 Debug Results: Found <?= count($results['debug_campaigns'] ?? []) ?> Campaigns</h3>
|
||
|
||
<?php if (isset($results['oauth_debug'])): ?>
|
||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||
<strong>OAuth Status:</strong>
|
||
<?= $results['oauth_debug']['has_token'] ? '✅ Token Active' : '❌ No Token' ?> |
|
||
Expires: <?= htmlspecialchars($results['oauth_debug']['expires_at']) ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_search_response'])): ?>
|
||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||
<strong>API Response:</strong> HTTP <?= $results['debug_search_response']['http_code'] ?>
|
||
<?php if ($results['debug_search_response']['http_code'] == 503): ?>
|
||
<span style="color: #dc3545; font-weight: bold;">- Service Unavailable (Server may be down or OAuth token expired)</span>
|
||
<?php endif; ?>
|
||
<br>
|
||
<strong>Total results from API:</strong> <?= $results['debug_search_response']['total_results'] ?? 0 ?><br>
|
||
<strong>URL:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($results['debug_search_response']['url']) ?></code>
|
||
<?php if (isset($results['debug_search_response']['response_body_preview'])): ?>
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer;">View Response Body</summary>
|
||
<pre style="font-size: 11px; background: #f8f9fa; padding: 10px; margin-top: 5px;"><?= htmlspecialchars($results['debug_search_response']['response_body_preview']) ?></pre>
|
||
</details>
|
||
<?php endif; ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($results['debug_campaigns'])): ?>
|
||
<p>Showing ALL campaigns without status filter to see their metadata fields:</p>
|
||
|
||
<?php foreach ($results['debug_campaigns'] as $idx => $campaign): ?>
|
||
<details style="margin: 15px 0; background: white; padding: 15px; border-radius: 6px;">
|
||
<summary style="cursor: pointer; font-weight: 600;">
|
||
Campaign <?= $idx + 1 ?>: <?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed') ?>
|
||
(<?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?>)
|
||
- Content Scaling Status: <span class="status-badge status-<?= strtolower($campaign['status'] ?? 'unknown') ?>"><?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></span>
|
||
</summary>
|
||
<div style="margin-top: 15px;">
|
||
<p><strong>Asset ID:</strong> <?= htmlspecialchars($campaign['asset_id']) ?></p>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Content Scaling Status:</strong> <?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></p>
|
||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||
|
||
<form method="POST" style="margin-top: 15px; display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="reset_to_a1">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-danger" onclick="return confirm('Reset campaign <?= htmlspecialchars($campaign['campaign_name']) ?> to A1 status?')">
|
||
🔄 Reset to A1 (for testing)
|
||
</button>
|
||
</form>
|
||
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer; font-size: 13px;">View Full Raw Metadata</summary>
|
||
<pre style="background: #f0f0f0; padding: 10px; border-radius: 4px; overflow: auto; max-height: 400px; font-size: 11px; margin-top: 10px;"><?= htmlspecialchars(json_encode($campaign, JSON_PRETTY_PRINT)) ?></pre>
|
||
</details>
|
||
</div>
|
||
</details>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<p style="margin-top: 15px;">No campaigns returned from API (check OAuth status and response body above)</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_all_campaigns_count'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 20px;">
|
||
<strong>🔍 Debug Info:</strong><br>
|
||
Found <?= $results['debug_all_campaigns_count'] ?> total campaigns before filtering<br>
|
||
Filtering for Content Scaling Status: "<?= htmlspecialchars($results['debug_status_filter']) ?>"<br>
|
||
Campaigns after filtering: <?= $results['debug_filtered_count'] ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['a1_campaigns']) && !empty($results['a1_campaigns'])): ?>
|
||
<h3 style="margin-top: 30px;">Found <?= count($results['a1_campaigns']) ?> Campaigns</h3>
|
||
<div class="campaign-grid">
|
||
<?php foreach ($results['a1_campaigns'] as $campaign): ?>
|
||
<div class="campaign-card <?= (isset($results['selected_campaign']) && $results['selected_campaign']['asset_id'] === $campaign['asset_id']) ? 'selected' : '' ?>"
|
||
onclick="selectCampaign('<?= htmlspecialchars($campaign['asset_id']) ?>')">
|
||
<h3><?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed Campaign') ?></h3>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Asset ID:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($campaign['asset_id']) ?></code></p>
|
||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a1"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Ready for Localization</span></p>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<form method="POST" id="select-campaign-form">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="select_campaign_a1">
|
||
<input type="hidden" name="campaign_id" id="selected-campaign-id">
|
||
<button type="submit" class="btn btn-success" id="select-campaign-btn" disabled>
|
||
Select Campaign & Continue
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['selected_campaign'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 30px;">
|
||
<strong>Selected Campaign:</strong>
|
||
<?= htmlspecialchars($results['selected_campaign']['campaign_name']) ?>
|
||
(<?= htmlspecialchars($results['selected_campaign']['campaign_id']) ?>)
|
||
<br>
|
||
<small><strong>Asset ID:</strong> <code><?= htmlspecialchars($results['selected_campaign']['asset_id']) ?></code></small>
|
||
<br>
|
||
<a href="debug_assets.php?action=get_folders&campaign_id=<?= urlencode($results['selected_campaign']['asset_id']) ?>"
|
||
target="_blank" style="color: #667eea; font-size: 12px;">
|
||
🔍 Debug folder structure for this campaign
|
||
</a>
|
||
</div>
|
||
|
||
<form method="POST" style="margin-top: 20px;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="get_master_assets">
|
||
<button type="submit" class="btn btn-primary">Get Master Assets</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['master_assets']) && !empty($results['master_assets'])): ?>
|
||
<h3 style="margin-top: 30px;">Master Assets (<?= count($results['master_assets']) ?> files)</h3>
|
||
|
||
<form method="POST" style="margin: 20px 0;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="download_all_assets">
|
||
<button type="submit" class="btn btn-success">📥 Download All Assets</button>
|
||
</form>
|
||
|
||
<div class="asset-list">
|
||
<?php foreach ($results['master_assets'] as $index => $asset): ?>
|
||
<?php
|
||
$assetName = extractFolderName($asset);
|
||
$assetId = $asset['asset_id'];
|
||
$metadataId = 'metadata-' . $index; // Use index instead of asset_id for simpler ID
|
||
?>
|
||
<div class="asset-item">
|
||
<div class="asset-info">
|
||
<strong><?= htmlspecialchars($assetName) ?></strong><br>
|
||
<small>ID: <?= htmlspecialchars($assetId) ?></small><br>
|
||
<small>Type: <?= htmlspecialchars($asset['mime_type'] ?? 'Unknown') ?></small>
|
||
<?php if (isset($asset['file_size'])): ?>
|
||
<small> | Size: <?= number_format($asset['file_size']) ?> bytes</small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="asset-actions">
|
||
<form method="POST" style="display: inline;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="download_asset">
|
||
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($assetId) ?>">
|
||
<input type="hidden" name="filename" value="<?= htmlspecialchars($assetName) ?>">
|
||
<button type="submit" class="btn btn-success">📥 Download</button>
|
||
</form>
|
||
<form method="POST" style="display: inline;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="download_asset_metadata">
|
||
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($assetId) ?>">
|
||
<input type="hidden" name="filename" value="<?= htmlspecialchars($assetName) ?>">
|
||
<button type="submit" class="btn btn-secondary">💾 JSON</button>
|
||
</form>
|
||
<button class="btn btn-secondary"
|
||
onclick="toggleMetadata('<?= $metadataId ?>')">
|
||
📋 View
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div id="<?= $metadataId ?>" class="metadata-display" style="display: none;">
|
||
<?php
|
||
$metadata = MetadataExtractor::extractAllMetadata($asset);
|
||
if (!empty($metadata)):
|
||
?>
|
||
<div style="font-size: 13px;">
|
||
<!-- Basic Info -->
|
||
<?php if (isset($metadata['basic'])): ?>
|
||
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #667eea;">
|
||
<strong>📋 Basic Info:</strong><br>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
|
||
<?php foreach ($metadata['basic'] as $key => $value): ?>
|
||
<?php if ($value !== null): ?>
|
||
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
|
||
<div><strong><?= htmlspecialchars($value) ?></strong></div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Content Info -->
|
||
<?php if (isset($metadata['content'])): ?>
|
||
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #28a745;">
|
||
<strong>🖼️ Content Info:</strong><br>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
|
||
<?php foreach ($metadata['content'] as $key => $value): ?>
|
||
<?php if ($value !== null && $value !== -1): ?>
|
||
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
|
||
<div><strong><?= is_string($value) ? htmlspecialchars($value) : $value ?></strong></div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Custom Fields by Category -->
|
||
<?php if (isset($metadata['custom_fields'])): ?>
|
||
<?php foreach ($metadata['custom_fields'] as $category => $fields): ?>
|
||
<?php if (!empty($fields)): ?>
|
||
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #ffc107;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #333;">
|
||
📁 <?= htmlspecialchars($category) ?> (<?= count($fields) ?> fields)
|
||
</summary>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 200px 1fr; gap: 5px;">
|
||
<?php foreach ($fields as $fieldName => $fieldData): ?>
|
||
<div style="color: #666; padding-top: 4px;"><?= htmlspecialchars($fieldName) ?>:</div>
|
||
<div style="padding-top: 4px;">
|
||
<strong>
|
||
<?php
|
||
if (is_array($fieldData['value'])) {
|
||
echo htmlspecialchars(implode(', ', $fieldData['value']));
|
||
} else {
|
||
echo htmlspecialchars($fieldData['value']);
|
||
}
|
||
?>
|
||
</strong>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
|
||
<!-- Permissions -->
|
||
<?php if (isset($metadata['permissions'])): ?>
|
||
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #dc3545;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #333;">🔐 Permissions</summary>
|
||
<div style="margin-top: 8px; columns: 2;">
|
||
<?php foreach ($metadata['permissions'] as $perm => $value): ?>
|
||
<div style="padding: 2px 0;">
|
||
<?= $value ? '✅' : '❌' ?> <?= htmlspecialchars(preg_replace('/Permission$/', '', $perm)) ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
|
||
<!-- Renditions -->
|
||
<?php if (isset($metadata['renditions'])): ?>
|
||
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #17a2b8;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #333;">🎨 Renditions (<?= count($metadata['renditions']) ?>)</summary>
|
||
<div style="margin-top: 8px;">
|
||
<?php foreach ($metadata['renditions'] as $rendName => $rendData): ?>
|
||
<div style="background: #f8f9fa; padding: 8px; margin: 4px 0; border-radius: 3px;">
|
||
<strong><?= htmlspecialchars($rendName) ?></strong><br>
|
||
<small>Size: <?= number_format($rendData['content_size'] ?? 0) ?> bytes |
|
||
<?= $rendData['width'] ?? 0 ?>x<?= $rendData['height'] ?? 0 ?>px |
|
||
<?= htmlspecialchars($rendData['mime_type'] ?? 'N/A') ?></small>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php else: ?>
|
||
<p>No metadata available for this asset</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div style="margin-top: 30px; padding: 20px; background: #fff3cd; border-radius: 8px;">
|
||
<h4>⚠️ Update Status to A2</h4>
|
||
<p style="margin: 10px 0;">
|
||
Once all assets are downloaded (or attempted), update the campaign status to A2
|
||
(Selected Master Assets sent to Agency)
|
||
</p>
|
||
<p style="margin: 10px 0; font-size: 13px; color: #856404;">
|
||
<strong>Note:</strong> If files don't exist in storage (test environment), you can still
|
||
update the status to test the workflow progression.
|
||
</p>
|
||
<form method="POST">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="update_status_to_a2">
|
||
<button type="submit" class="btn btn-success">Update Status: A1 → A2</button>
|
||
</form>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['status_update_error'])): ?>
|
||
<div class="alert alert-error" style="margin-top: 20px;">
|
||
<strong>⚠️ Status Update Debug Information:</strong>
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer; font-weight: 600;">View detailed error information</summary>
|
||
<div style="margin-top: 10px; font-size: 12px; font-family: monospace;">
|
||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||
<strong>HTTP Status Code:</strong> <?= htmlspecialchars($results['status_update_error']['http_code']) ?>
|
||
</div>
|
||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||
<strong>Folder ID:</strong> <?= htmlspecialchars($results['status_update_error']['folder_id']) ?>
|
||
</div>
|
||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||
<strong>Target Status:</strong> <?= htmlspecialchars($results['status_update_error']['new_status']) ?>
|
||
</div>
|
||
<?php if (isset($results['status_update_error']['response']['body'])): ?>
|
||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||
<strong>API Response Body:</strong>
|
||
<pre style="margin-top: 5px; white-space: pre-wrap; word-wrap: break-word;"><?= htmlspecialchars($results['status_update_error']['response']['body']) ?></pre>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php if (isset($results['status_update_error']['response']['url'])): ?>
|
||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||
<strong>Request URL:</strong> <?= htmlspecialchars($results['status_update_error']['response']['url']) ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['last_download'])): ?>
|
||
<?php $dl = $results['last_download']; ?>
|
||
<div class="alert alert-<?= $dl['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<?php if ($dl['success']): ?>
|
||
<strong>✅ Download Successful:</strong> <?= htmlspecialchars($dl['filename']) ?>
|
||
<br><small>Size: <?= number_format($dl['size']) ?> bytes | Path: <?= htmlspecialchars($dl['filepath']) ?></small>
|
||
<?php if (isset($dl['download_method'])): ?>
|
||
<br><small>Method: <?= htmlspecialchars($dl['download_method']) ?> | URL: <?= htmlspecialchars($dl['rendition_url'] ?? 'N/A') ?></small>
|
||
<?php endif; ?>
|
||
<?php else: ?>
|
||
<strong>❌ Download Failed:</strong> <?= htmlspecialchars($dl['error']) ?>
|
||
<br><small>HTTP Code: <?= $dl['http_code'] ?></small>
|
||
<?php if (isset($dl['tried_url'])): ?>
|
||
<br><small>Tried URL: <?= htmlspecialchars($dl['tried_url']) ?></small>
|
||
<?php endif; ?>
|
||
<?php if (isset($dl['debug_message'])): ?>
|
||
<br><small>Details: <?= htmlspecialchars($dl['debug_message']) ?></small>
|
||
<?php endif; ?>
|
||
<?php if (isset($dl['debug_info']) && !empty($dl['debug_info'])): ?>
|
||
<br><small>Debug: <?= htmlspecialchars(json_encode($dl['debug_info'])) ?></small>
|
||
<?php endif; ?>
|
||
<?php if (isset($dl['all_attempts']) && !empty($dl['all_attempts'])): ?>
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer; font-size: 12px;">View all download attempts (<?= count($dl['all_attempts']) ?>)</summary>
|
||
<div style="margin-top: 8px; font-size: 11px;">
|
||
<?php foreach ($dl['all_attempts'] as $idx => $att): ?>
|
||
<div style="padding: 4px; background: #f8f9fa; margin: 2px 0; border-radius: 3px;">
|
||
<?= $idx + 1 ?>. [<?= htmlspecialchars($att['type']) ?>] <?= htmlspecialchars($att['url']) ?>
|
||
- HTTP <?= $att['http_code'] ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['bulk_download'])): ?>
|
||
<div class="alert alert-<?= $results['bulk_download']['successful'] === $results['bulk_download']['total'] ? 'success' : 'error' ?>"
|
||
style="margin-top: 20px;">
|
||
<strong>Bulk Download Results:</strong>
|
||
<?= $results['bulk_download']['successful'] ?> of <?= $results['bulk_download']['total'] ?> assets downloaded successfully
|
||
<?php if ($results['bulk_download']['failed'] > 0): ?>
|
||
<br><small><?= $results['bulk_download']['failed'] ?> files failed (may not exist in storage)</small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Upload Workflow Tab -->
|
||
<div id="tab-upload" class="tab-content <?= $currentTab === 'upload' ? 'active' : '' ?>">
|
||
<h2>📤 Upload Workflow: A2 → A3</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0;">
|
||
Load campaigns with status A2 (assets sent to agency), upload processed files, and update status to A3
|
||
</p>
|
||
|
||
<!-- Test Upload Section -->
|
||
<div style="background: #fff3cd; border: 2px solid #ffc107; border-radius: 8px; padding: 20px; margin-bottom: 30px;">
|
||
<h3 style="color: #856404;">🧪 Test Upload to Specific Folder</h3>
|
||
<p style="color: #856404; margin: 10px 0;">
|
||
Upload directly to a folder ID for testing (bypasses campaign workflow)
|
||
</p>
|
||
|
||
<form method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="test_upload_to_folder">
|
||
|
||
<div style="margin: 15px 0;">
|
||
<label style="display: block; margin-bottom: 5px; font-weight: 600;">Target Folder ID:</label>
|
||
<input type="text" name="test_folder_id"
|
||
value="e96080ba0cd1427d253a28a87504b6665eaa02cb"
|
||
style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-family: monospace;">
|
||
</div>
|
||
|
||
<div style="margin: 15px 0;">
|
||
<label style="display: block; margin-bottom: 5px; font-weight: 600;">Select file to upload:</label>
|
||
<input type="file" name="test_upload_file" required
|
||
style="padding: 10px; border: 2px solid #ffc107; border-radius: 6px; width: 100%; background: white;">
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn-primary">🧪 Test Upload to This Folder</button>
|
||
</form>
|
||
|
||
<?php if (isset($results['test_upload_result'])): ?>
|
||
<?php $tr = $results['test_upload_result']; ?>
|
||
<div class="alert alert-<?= $tr['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<?php if ($tr['success']): ?>
|
||
<strong>✅ TEST UPLOAD SUCCESSFUL!</strong><br>
|
||
Filename: <?= htmlspecialchars($tr['filename']) ?><br>
|
||
Asset ID: <?= htmlspecialchars($tr['asset_id'] ?? 'N/A') ?><br>
|
||
Folder: <?= htmlspecialchars($results['test_folder_id']) ?>
|
||
<?php else: ?>
|
||
<strong>❌ Test Upload Failed:</strong> <?= htmlspecialchars($tr['error']) ?><br>
|
||
HTTP Code: <?= $tr['http_code'] ?><br>
|
||
Folder: <?= htmlspecialchars($results['test_folder_id']) ?>
|
||
<?php if (isset($tr['response_body'])): ?>
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer;">View API Response</summary>
|
||
<pre style="font-size: 11px; background: white; padding: 10px; margin-top: 5px;"><?= htmlspecialchars($tr['response_body']) ?></pre>
|
||
</details>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<hr style="margin: 30px 0;">
|
||
<!-- End Test Upload Section -->
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="load_campaigns_a2">
|
||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A2)</button>
|
||
</form>
|
||
|
||
<?php if (!empty($results) && $currentTab === 'upload'): ?>
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="clear_results" value="1">
|
||
<button type="submit" class="btn btn-secondary">🗑️ Clear Workflow Data</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['a2_campaigns']) && !empty($results['a2_campaigns'])): ?>
|
||
<h3 style="margin-top: 30px;">Found <?= count($results['a2_campaigns']) ?> Campaigns</h3>
|
||
<div class="campaign-grid">
|
||
<?php foreach ($results['a2_campaigns'] as $campaign): ?>
|
||
<div class="campaign-card <?= (isset($results['selected_campaign_a2']) && $results['selected_campaign_a2']['asset_id'] === $campaign['asset_id']) ? 'selected' : '' ?>"
|
||
onclick="selectCampaignA2('<?= htmlspecialchars($campaign['asset_id']) ?>')">
|
||
<h3><?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed Campaign') ?></h3>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Asset ID:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($campaign['asset_id']) ?></code></p>
|
||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a2"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Assets Sent to Agency</span></p>
|
||
|
||
<form method="POST" style="margin-top: 10px;" onclick="event.stopPropagation();">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="reset_to_a1">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-danger" style="font-size: 12px; padding: 8px 12px;" onclick="return confirm('Reset <?= htmlspecialchars($campaign['campaign_name']) ?> to A1 for testing?')">
|
||
🔄 Reset to A1
|
||
</button>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<form method="POST" id="select-campaign-a2-form">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="select_campaign_a2">
|
||
<input type="hidden" name="campaign_id" id="selected-campaign-a2-id">
|
||
<button type="submit" class="btn btn-success" id="select-campaign-a2-btn" disabled>
|
||
Select Campaign & Continue
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['selected_campaign_a2'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 30px;">
|
||
<strong>Selected Campaign:</strong>
|
||
<?= htmlspecialchars($results['selected_campaign_a2']['campaign_name']) ?>
|
||
(<?= htmlspecialchars($results['selected_campaign_a2']['campaign_id']) ?>)
|
||
</div>
|
||
|
||
<?php if (!isset($results['upload_folder_id'])): ?>
|
||
<form method="POST" style="margin-top: 20px;">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="get_upload_folder">
|
||
<button type="submit" class="btn btn-primary">Find Upload Folder & Get Master Assets Metadata</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['upload_folder_id'])): ?>
|
||
<div class="alert alert-success" style="margin-top: 20px;">
|
||
✅ Upload target folder found
|
||
</div>
|
||
|
||
<h3 style="margin-top: 30px;">Upload Processed Files</h3>
|
||
|
||
<?php if (isset($results['master_assets_for_upload']) && !empty($results['master_assets_for_upload'])): ?>
|
||
<div class="alert alert-success" style="margin-bottom: 20px;">
|
||
✅ Found <?= count($results['master_assets_for_upload']) ?> master assets from this campaign
|
||
</div>
|
||
|
||
<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
|
||
<h4>📋 Select Master Asset Metadata to Use:</h4>
|
||
<p style="color: #666; margin: 10px 0;">
|
||
Choose which master asset's metadata structure to use for your upload.
|
||
Your uploaded file will inherit all metadata (model, security, fields) from the selected master asset.
|
||
Only the filename will be updated to match your new file.
|
||
</p>
|
||
|
||
<?php foreach ($results['master_assets_for_upload'] as $idx => $masterAsset): ?>
|
||
<div style="background: white; border: 2px solid #dee2e6; border-radius: 6px; padding: 15px; margin: 10px 0;">
|
||
<label style="display: flex; align-items: center; cursor: pointer;">
|
||
<input type="radio" name="selected_master_metadata" value="<?= $idx ?>"
|
||
onchange="selectMasterMetadata(<?= $idx ?>)"
|
||
<?= $idx === 0 ? 'checked' : '' ?>
|
||
style="margin-right: 10px; transform: scale(1.3);">
|
||
<div>
|
||
<strong><?= htmlspecialchars($masterAsset['name'] ?? 'Unknown') ?></strong><br>
|
||
<small>Asset ID: <?= htmlspecialchars($masterAsset['asset_id']) ?></small><br>
|
||
<small>Type: <?= htmlspecialchars($masterAsset['mime_type'] ?? 'Unknown') ?></small>
|
||
<?php if (isset($masterAsset['metadata_model_id'])): ?>
|
||
<br><small style="color: #28a745;">✅ Model: <?= htmlspecialchars($masterAsset['metadata_model_id']) ?></small>
|
||
<?php else: ?>
|
||
<br><small style="color: #dc3545;">⚠️ No Metadata Model ID</small>
|
||
<?php endif; ?>
|
||
<?php if (isset($masterAsset['security_policy_list'])): ?>
|
||
<br><small style="color: #28a745;">✅ <?= count($masterAsset['security_policy_list']) ?> Security Policies</small>
|
||
<?php else: ?>
|
||
<br><small style="color: #dc3545;">⚠️ No Security Policies</small>
|
||
<?php endif; ?>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="alert alert-info" style="margin-bottom: 20px;">
|
||
ℹ️ <strong>Note:</strong> No master assets found.
|
||
<br>Click "Find Upload Folder" above to fetch master assets from this campaign.
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<form method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="upload_files">
|
||
<input type="hidden" name="master_metadata_index" id="master-metadata-index" value="0">
|
||
|
||
<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0;">
|
||
<label style="display: block; margin-bottom: 10px; font-weight: 600;">
|
||
Select files to upload:
|
||
</label>
|
||
<input type="file" name="upload_files[]" multiple
|
||
accept=".jpg,.jpeg,.png,.gif,.pdf,.ai,.psd,.eps,.tif,.tiff,.mov,.mp4,.avi,.zip,.txt,.doc,.docx,.xls,.xlsx"
|
||
style="padding: 10px; border: 2px dashed #667eea; border-radius: 6px; width: 100%; background: white;">
|
||
<p style="font-size: 13px; color: #666; margin-top: 10px;">
|
||
Accepted formats: Images (JPG, PNG, GIF, TIFF), Documents (PDF, AI, PSD, EPS), Video (MOV, MP4, AVI), Archives (ZIP), Office (DOC, XLS, TXT)
|
||
</p>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn-success">📤 Upload Files to DAM</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['upload_debug'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 20px;">
|
||
<strong>🔍 Upload Debug Info:</strong><br>
|
||
<strong>Your File:</strong> <?= htmlspecialchars($results['upload_debug']['upload_filename']) ?>
|
||
(<?= htmlspecialchars($results['upload_debug']['upload_detected_mime']) ?>)<br>
|
||
<strong>Target Folder ID:</strong> <?= htmlspecialchars($results['upload_debug']['upload_folder_id']) ?><br>
|
||
<hr style="margin: 10px 0;">
|
||
<strong>Using Metadata From:</strong> <?= htmlspecialchars($results['upload_debug']['selected_master_name']) ?><br>
|
||
Master Asset ID: <?= htmlspecialchars($results['upload_debug']['selected_master_asset_id']) ?><br>
|
||
Metadata Model ID: <strong><?= htmlspecialchars($results['upload_debug']['metadata_model_id']) ?></strong><br>
|
||
Has Security Policies: <?= $results['upload_debug']['has_security_policies'] ?> (<?= $results['upload_debug']['security_policy_count'] ?> policies)<br>
|
||
Master MIME Type: <?= htmlspecialchars($results['upload_debug']['master_mime_type']) ?><br>
|
||
<hr style="margin: 10px 0;">
|
||
<strong>Sending:</strong> asset_representation (model ID + security policies only) + manifest + parent_folder_id + files<br>
|
||
<small>Note: Full metadata too large to send - using model ID inheritance instead</small>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['upload_results'])): ?>
|
||
<?php $ur = $results['upload_results']; ?>
|
||
<div class="alert alert-<?= $ur['successful'] > 0 ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<strong>Upload Results:</strong>
|
||
<?= $ur['successful'] ?> of <?= $ur['total'] ?> files uploaded successfully
|
||
|
||
<?php if (!empty($ur['details'])): ?>
|
||
<details style="margin-top: 15px;">
|
||
<summary style="cursor: pointer;">View upload details</summary>
|
||
<div style="margin-top: 10px;">
|
||
<?php foreach ($ur['details'] as $idx => $detail): ?>
|
||
<div style="padding: 8px; margin: 5px 0; background: white; border-radius: 4px;">
|
||
<?php if ($detail['success']): ?>
|
||
✅ <?= htmlspecialchars($detail['filename']) ?>
|
||
<br><small>Asset ID: <?= htmlspecialchars($detail['asset_id'] ?? 'N/A') ?></small>
|
||
<?php else: ?>
|
||
❌ <?= htmlspecialchars($detail['filename'] ?? 'Unknown') ?>
|
||
<br><small style="color: #dc3545;"><strong>Error:</strong> <?= htmlspecialchars($detail['error']) ?></small>
|
||
<?php if (isset($detail['http_code'])): ?>
|
||
<br><small>HTTP Code: <?= $detail['http_code'] ?></small>
|
||
<?php endif; ?>
|
||
<?php if (isset($detail['response_body']) && !empty($detail['response_body'])): ?>
|
||
<details style="margin-top: 5px;">
|
||
<summary style="cursor: pointer; font-size: 11px;">View API Response</summary>
|
||
<pre style="font-size: 10px; background: #f8f9fa; padding: 5px; margin-top: 5px; max-height: 200px; overflow: auto;"><?= htmlspecialchars($detail['response_body']) ?></pre>
|
||
</details>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if ($ur['successful'] > 0): ?>
|
||
<div style="margin-top: 30px; padding: 20px; background: #d4edda; border-radius: 8px;">
|
||
<h4>✅ Update Status to A3</h4>
|
||
<p style="margin: 10px 0;">
|
||
Files have been uploaded. Update the campaign status to A3
|
||
(Localized Asset received from Agency)
|
||
</p>
|
||
<form method="POST">
|
||
<input type="hidden" name="tab" value="upload">
|
||
<input type="hidden" name="action" value="update_status_to_a3">
|
||
<button type="submit" class="btn btn-success">Update Status: A2 → A3</button>
|
||
</form>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Rework Workflow Tab -->
|
||
<div id="tab-rework" class="tab-content <?= $currentTab === 'rework' ? 'active' : '' ?>">
|
||
<h2>🔄 Rework Workflow: A5 → A6</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0;">
|
||
Load campaigns with status A5 (rework needed), download assets for rework, and update status to A6
|
||
</p>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="load_campaigns_a5">
|
||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A5)</button>
|
||
</form>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="debug_all_campaigns_rework">
|
||
<button type="submit" class="btn btn-secondary">🔍 Debug: Load ALL Campaigns (no filter)</button>
|
||
</form>
|
||
|
||
<?php if (!empty($results) && $currentTab === 'rework'): ?>
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="clear_results" value="1">
|
||
<button type="submit" class="btn btn-secondary">🗑️ Clear Workflow Data</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_campaigns_rework']) || isset($results['debug_search_response_rework'])): ?>
|
||
<div class="alert alert-<?= ($results['debug_search_response_rework']['http_code'] ?? 0) == 503 ? 'error' : 'info' ?>" style="margin-top: 30px;">
|
||
<h3>🔍 Debug Results: Found <?= count($results['debug_campaigns_rework'] ?? []) ?> Campaigns</h3>
|
||
|
||
<?php if (isset($results['oauth_debug_rework'])): ?>
|
||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||
<strong>OAuth Status:</strong>
|
||
<?= $results['oauth_debug_rework']['has_token'] ? '✅ Token Active' : '❌ No Token' ?> |
|
||
Expires: <?= htmlspecialchars($results['oauth_debug_rework']['expires_at']) ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_search_response_rework'])): ?>
|
||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||
<strong>API Response:</strong> HTTP <?= $results['debug_search_response_rework']['http_code'] ?>
|
||
<?php if ($results['debug_search_response_rework']['http_code'] == 503): ?>
|
||
<span style="color: #dc3545; font-weight: bold;">- Service Unavailable</span>
|
||
<?php endif; ?>
|
||
<br>
|
||
<strong>Total results from API:</strong> <?= $results['debug_search_response_rework']['total_results'] ?? 0 ?><br>
|
||
<strong>URL:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($results['debug_search_response_rework']['url']) ?></code>
|
||
</p>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($results['debug_campaigns_rework'])): ?>
|
||
<p>Showing ALL campaigns - use reset button to change any to A5 for testing:</p>
|
||
|
||
<?php foreach ($results['debug_campaigns_rework'] as $idx => $campaign): ?>
|
||
<details style="margin: 15px 0; background: white; padding: 15px; border-radius: 6px;">
|
||
<summary style="cursor: pointer; font-weight: 600;">
|
||
Campaign <?= $idx + 1 ?>: <?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed') ?>
|
||
(<?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?>)
|
||
- Content Scaling Status: <span class="status-badge status-<?= strtolower($campaign['status'] ?? 'unknown') ?>"><?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></span>
|
||
</summary>
|
||
<div style="margin-top: 15px;">
|
||
<p><strong>Asset ID:</strong> <?= htmlspecialchars($campaign['asset_id']) ?></p>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Content Scaling Status:</strong> <?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></p>
|
||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||
|
||
<form method="POST" style="margin-top: 15px; display: inline-block;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="reset_to_a5">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-danger" onclick="return confirm('Reset campaign <?= htmlspecialchars($campaign['campaign_name']) ?> to A5 status?')">
|
||
🔄 Reset to A5 (for testing)
|
||
</button>
|
||
</form>
|
||
|
||
<details style="margin-top: 10px;">
|
||
<summary style="cursor: pointer; font-size: 13px;">View Full Raw Metadata</summary>
|
||
<pre style="background: #f0f0f0; padding: 10px; border-radius: 4px; overflow: auto; max-height: 400px; font-size: 11px; margin-top: 10px;"><?= htmlspecialchars(json_encode($campaign, JSON_PRETTY_PRINT)) ?></pre>
|
||
</details>
|
||
</div>
|
||
</details>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<p style="margin-top: 15px;">No campaigns returned from API (check OAuth status and response above)</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['a5_campaigns']) && !empty($results['a5_campaigns'])): ?>
|
||
<h3 style="margin-top: 30px;">Found <?= count($results['a5_campaigns']) ?> Campaigns Needing Rework</h3>
|
||
<div class="campaign-grid">
|
||
<?php foreach ($results['a5_campaigns'] as $campaign): ?>
|
||
<div class="campaign-card <?= (isset($results['selected_campaign_a5']) && $results['selected_campaign_a5']['asset_id'] === $campaign['asset_id']) ? 'selected' : '' ?>"
|
||
onclick="selectCampaignA5('<?= htmlspecialchars($campaign['asset_id']) ?>')">
|
||
<h3><?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed Campaign') ?></h3>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Asset ID:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($campaign['asset_id']) ?></code></p>
|
||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a5"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Rework Needed</span></p>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<form method="POST" id="select-campaign-a5-form">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="select_campaign_a5">
|
||
<input type="hidden" name="campaign_id" id="selected-campaign-a5-id">
|
||
<button type="submit" class="btn btn-success" id="select-campaign-a5-btn" disabled>
|
||
Select Campaign & Continue
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['selected_campaign_a5'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 30px;">
|
||
<strong>Selected Campaign:</strong>
|
||
<?= htmlspecialchars($results['selected_campaign_a5']['campaign_name']) ?>
|
||
(<?= htmlspecialchars($results['selected_campaign_a5']['campaign_id']) ?>)
|
||
</div>
|
||
|
||
<form method="POST" style="margin-top: 20px;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="get_rework_assets">
|
||
<button type="submit" class="btn btn-primary">Get Rework Assets</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['rework_assets']) && !empty($results['rework_assets'])): ?>
|
||
<h3 style="margin-top: 30px;">Rework Assets (<?= count($results['rework_assets']) ?> files)</h3>
|
||
|
||
<form method="POST" style="margin: 20px 0;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="download_all_rework">
|
||
<button type="submit" class="btn btn-success">📥 Download All Rework Assets</button>
|
||
</form>
|
||
|
||
<div class="asset-list">
|
||
<?php foreach ($results['rework_assets'] as $index => $asset): ?>
|
||
<?php
|
||
$assetName = extractFolderName($asset);
|
||
$assetId = $asset['asset_id'];
|
||
$metadataId = 'rework-metadata-' . $index;
|
||
?>
|
||
<div class="asset-item">
|
||
<div class="asset-info">
|
||
<strong><?= htmlspecialchars($assetName) ?></strong><br>
|
||
<small>ID: <?= htmlspecialchars($assetId) ?></small><br>
|
||
<small>Type: <?= htmlspecialchars($asset['mime_type'] ?? 'Unknown') ?></small>
|
||
<?php if (isset($asset['file_size'])): ?>
|
||
<small> | Size: <?= number_format($asset['file_size']) ?> bytes</small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="asset-actions">
|
||
<form method="POST" style="display: inline;">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="download_rework_asset">
|
||
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($assetId) ?>">
|
||
<input type="hidden" name="filename" value="<?= htmlspecialchars($assetName) ?>">
|
||
<button type="submit" class="btn btn-success">📥 Download</button>
|
||
</form>
|
||
<button class="btn btn-secondary"
|
||
onclick="toggleMetadata('<?= $metadataId ?>')">
|
||
📋 Metadata
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div id="<?= $metadataId ?>" class="metadata-display" style="display: none;">
|
||
<?php
|
||
$metadata = MetadataExtractor::extractAllMetadata($asset);
|
||
if (!empty($metadata)):
|
||
?>
|
||
<div style="font-size: 13px;">
|
||
<!-- Same metadata display as download tab -->
|
||
<?php if (isset($metadata['basic'])): ?>
|
||
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #667eea;">
|
||
<strong>📋 Basic Info:</strong><br>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
|
||
<?php foreach ($metadata['basic'] as $key => $value): ?>
|
||
<?php if ($value !== null): ?>
|
||
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
|
||
<div><strong><?= htmlspecialchars($value) ?></strong></div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php else: ?>
|
||
<p>No metadata available for this asset</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div style="margin-top: 30px; padding: 20px; background: #fff3cd; border-radius: 8px;">
|
||
<h4>⚠️ Update Status to A6</h4>
|
||
<p style="margin: 10px 0;">
|
||
Once rework assets are downloaded, update the campaign status to A6
|
||
(Assets to be reworked received by the Agency)
|
||
</p>
|
||
<form method="POST">
|
||
<input type="hidden" name="tab" value="rework">
|
||
<input type="hidden" name="action" value="update_status_to_a6">
|
||
<button type="submit" class="btn btn-success">Update Status: A5 → A6</button>
|
||
</form>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['last_rework_download'])): ?>
|
||
<?php $dl = $results['last_rework_download']; ?>
|
||
<div class="alert alert-<?= $dl['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<?php if ($dl['success']): ?>
|
||
<strong>✅ Download Successful:</strong> <?= htmlspecialchars($dl['filename']) ?>
|
||
<br><small>Size: <?= number_format($dl['size']) ?> bytes</small>
|
||
<?php else: ?>
|
||
<strong>❌ Download Failed:</strong> <?= htmlspecialchars($dl['error']) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['rework_bulk_download'])): ?>
|
||
<div class="alert alert-success" style="margin-top: 20px;">
|
||
<strong>Bulk Download Results:</strong>
|
||
<?= $results['rework_bulk_download']['successful'] ?> of <?= $results['rework_bulk_download']['total'] ?> rework assets downloaded
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function switchTab(tabName) {
|
||
// Update tabs
|
||
document.querySelectorAll('.tab').forEach(tab => tab.classList.remove('active'));
|
||
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
|
||
|
||
event.target.classList.add('active');
|
||
document.getElementById('tab-' + tabName).classList.add('active');
|
||
|
||
// Update URL without reload
|
||
const url = new URL(window.location);
|
||
url.searchParams.set('tab', tabName);
|
||
window.history.pushState({}, '', url);
|
||
}
|
||
|
||
function selectCampaign(campaignId) {
|
||
document.querySelectorAll('.campaign-card').forEach(card => {
|
||
card.classList.remove('selected');
|
||
});
|
||
|
||
event.currentTarget.classList.add('selected');
|
||
document.getElementById('selected-campaign-id').value = campaignId;
|
||
document.getElementById('select-campaign-btn').disabled = false;
|
||
}
|
||
|
||
function toggleMetadata(metadataId) {
|
||
const metadataDiv = document.getElementById(metadataId);
|
||
if (metadataDiv) {
|
||
metadataDiv.style.display = metadataDiv.style.display === 'none' ? 'block' : 'none';
|
||
}
|
||
}
|
||
|
||
function selectCampaignA2(campaignId) {
|
||
document.querySelectorAll('.campaign-card').forEach(card => {
|
||
card.classList.remove('selected');
|
||
});
|
||
|
||
event.currentTarget.classList.add('selected');
|
||
document.getElementById('selected-campaign-a2-id').value = campaignId;
|
||
document.getElementById('select-campaign-a2-btn').disabled = false;
|
||
}
|
||
|
||
function selectCampaignA5(campaignId) {
|
||
document.querySelectorAll('.campaign-card').forEach(card => {
|
||
card.classList.remove('selected');
|
||
});
|
||
|
||
event.currentTarget.classList.add('selected');
|
||
document.getElementById('selected-campaign-a5-id').value = campaignId;
|
||
document.getElementById('select-campaign-a5-btn').disabled = false;
|
||
}
|
||
|
||
function selectMasterMetadata(index) {
|
||
document.getElementById('master-metadata-index').value = index;
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|