Fixed: - Replaced non-existent createAssetManager() with existing helper functions - Added findMasterAssetsFolder() helper function (mirrors findUploadFolder logic) - Added extractStatusFromAsset() helper to extract status from asset metadata - Uses existing getAssetsFromFolder() function to retrieve assets Now properly: - Finds Master Assets folder using findMasterAssetsFolder() - Finds Final Assets folder using findUploadFolder() - Gets assets using getAssetsFromFolder() - Extracts status from asset metadata structure No more 500 errors - folder viewing should work now! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
4367 lines
228 KiB
PHP
4367 lines
228 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';
|
||
require_once 'src/AssetUploaderSimple.php';
|
||
require_once 'src/BoxClient.php';
|
||
require_once 'src/IDGenerator.php';
|
||
require_once 'src/DatabaseClient.php';
|
||
require_once 'src/FilenameParser.php';
|
||
require_once 'src/MetadataMerger.php';
|
||
require_once 'src/BoxFileRetriever.php';
|
||
require_once 'src/MetadataExtractorMVP.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 AJAX requests (return JSON)
|
||
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
|
||
header('Content-Type: application/json');
|
||
|
||
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
||
$response = ['success' => false, 'error' => 'Unknown action'];
|
||
|
||
try {
|
||
switch ($action) {
|
||
case 'box_list_files':
|
||
$folderId = $_POST['folder_id'] ?? '';
|
||
if (empty($folderId)) {
|
||
$response = ['success' => false, 'error' => 'Folder ID is required'];
|
||
break;
|
||
}
|
||
|
||
$retriever = new BoxFileRetriever();
|
||
$result = $retriever->listFilesWithTrackingIDs($folderId);
|
||
|
||
if ($result['success']) {
|
||
// Parse each filename
|
||
$parser = new FilenameParser();
|
||
foreach ($result['files'] as &$file) {
|
||
$parsed = $parser->parseFilename($file['name']);
|
||
$file['parsed'] = $parsed;
|
||
$file['is_valid'] = $parsed ? $parsed['is_valid'] : false;
|
||
$file['clean_filename'] = $parsed ? $parser->stripUploadComponents($file['name']) : $file['name'];
|
||
}
|
||
}
|
||
|
||
$response = $result;
|
||
break;
|
||
|
||
case 'parse_filename':
|
||
$filename = $_POST['filename'] ?? '';
|
||
if (empty($filename)) {
|
||
$response = ['success' => false, 'error' => 'Filename is required'];
|
||
break;
|
||
}
|
||
|
||
$parser = new FilenameParser();
|
||
$parsed = $parser->parseFilename($filename);
|
||
|
||
$response = [
|
||
'success' => true,
|
||
'parsed' => $parsed,
|
||
'clean_filename' => $parser->stripUploadComponents($filename)
|
||
];
|
||
break;
|
||
|
||
case 'load_master_metadata':
|
||
$trackingId = $_POST['tracking_id'] ?? '';
|
||
if (empty($trackingId)) {
|
||
$response = ['success' => false, 'error' => 'Tracking ID is required'];
|
||
break;
|
||
}
|
||
|
||
$db = new DatabaseClient();
|
||
$stmt = $db->getConnection()->prepare("
|
||
SELECT tracking_id, opentext_id, upload_directory, description,
|
||
brand_code, country_code, language_code, asset_type, full_metadata
|
||
FROM master_assets
|
||
WHERE tracking_id = :tracking_id AND status = 'active'
|
||
");
|
||
$stmt->execute(['tracking_id' => $trackingId]);
|
||
$masterAsset = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if ($masterAsset) {
|
||
// Decode full_metadata JSONB column (contains COMPLETE DAM metadata)
|
||
if (isset($masterAsset['full_metadata'])) {
|
||
$masterAsset['metadata'] = json_decode($masterAsset['full_metadata'], true);
|
||
} else {
|
||
$masterAsset['metadata'] = [];
|
||
}
|
||
|
||
$response = [
|
||
'success' => true,
|
||
'master_asset' => $masterAsset
|
||
];
|
||
} else {
|
||
$response = [
|
||
'success' => false,
|
||
'error' => "No master asset found for tracking ID: $trackingId"
|
||
];
|
||
}
|
||
break;
|
||
|
||
case 'merge_metadata':
|
||
$masterMetadata = json_decode($_POST['master_metadata'] ?? '{}', true);
|
||
$parsedFilename = json_decode($_POST['parsed_filename'] ?? '{}', true);
|
||
|
||
if (empty($masterMetadata) || empty($parsedFilename)) {
|
||
$response = ['success' => false, 'error' => 'Master metadata and parsed filename are required'];
|
||
break;
|
||
}
|
||
|
||
$merger = new MetadataMerger();
|
||
$merged = $merger->mergeMetadata($masterMetadata, $parsedFilename);
|
||
$editableFields = $merger->identifyEditableFields($merged);
|
||
|
||
$response = [
|
||
'success' => true,
|
||
'merged' => $merged,
|
||
'editable_fields' => $editableFields
|
||
];
|
||
break;
|
||
|
||
case 'upload_from_box':
|
||
// Main upload handler for Box files
|
||
$fileId = $_POST['file_id'] ?? '';
|
||
$filename = $_POST['filename'] ?? '';
|
||
$trackingId = $_POST['tracking_id'] ?? '';
|
||
|
||
if (empty($fileId) || empty($filename) || empty($trackingId)) {
|
||
$response = ['success' => false, 'error' => 'Missing required parameters'];
|
||
break;
|
||
}
|
||
|
||
try {
|
||
// 1. Parse filename first (validate V2 convention)
|
||
$parser = new FilenameParser();
|
||
$parsed = $parser->parseFilename($filename);
|
||
|
||
if (!$parsed || !$parsed['is_valid']) {
|
||
$errors = $parsed ? implode(', ', $parsed['validation_errors']) : 'Invalid filename';
|
||
$response = ['success' => false, 'error' => 'Invalid filename: ' . $errors];
|
||
break;
|
||
}
|
||
|
||
// 2. Load master metadata from database (FULL metadata from JSONB column)
|
||
$db = new DatabaseClient();
|
||
$stmt = $db->getConnection()->prepare("
|
||
SELECT tracking_id, opentext_id, upload_directory, description,
|
||
brand_code, country_code, language_code, asset_type, full_metadata
|
||
FROM master_assets
|
||
WHERE tracking_id = :tracking_id AND status = 'active'
|
||
");
|
||
$stmt->execute(['tracking_id' => $trackingId]);
|
||
$masterAsset = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if (!$masterAsset) {
|
||
$response = ['success' => false, 'error' => "Master asset not found for tracking ID: $trackingId"];
|
||
break;
|
||
}
|
||
|
||
// Decode full_metadata JSONB column (contains COMPLETE DAM metadata - no truncation)
|
||
if (isset($masterAsset['full_metadata'])) {
|
||
$masterAsset['metadata'] = json_decode($masterAsset['full_metadata'], true);
|
||
error_log("Upload from Box: Loaded full metadata - size: " . strlen($masterAsset['full_metadata']) . " bytes");
|
||
} else {
|
||
$masterAsset['metadata'] = [];
|
||
error_log("Upload from Box: WARNING - No full_metadata found for tracking ID: $trackingId");
|
||
}
|
||
|
||
// Check if upload directory exists
|
||
if (empty($masterAsset['upload_directory'])) {
|
||
$response = ['success' => false, 'error' => 'Upload directory not found in master asset'];
|
||
break;
|
||
}
|
||
|
||
// 3. Download file from Box
|
||
$retriever = new BoxFileRetriever();
|
||
$downloadResult = $retriever->downloadFile($fileId, $filename);
|
||
|
||
if (!$downloadResult['success']) {
|
||
$response = ['success' => false, 'error' => 'Box download failed: ' . $downloadResult['error']];
|
||
break;
|
||
}
|
||
|
||
$localPath = $downloadResult['local_path'];
|
||
|
||
// 4. Extract video metadata from downloaded file (for width/height)
|
||
require_once 'src/VideoMetadataExtractor.php';
|
||
$videoExtractor = new VideoMetadataExtractor();
|
||
$videoMetadata = $videoExtractor->extractVideoMetadata($localPath);
|
||
|
||
// 5. Get clean filename (strip OMG Job Number & Tracking ID)
|
||
$cleanFilename = $parser->stripUploadComponents($filename);
|
||
|
||
if (!$cleanFilename) {
|
||
unlink($localPath);
|
||
$response = ['success' => false, 'error' => 'Failed to generate clean filename'];
|
||
break;
|
||
}
|
||
|
||
// 6. Extract ONLY MVP fields from master metadata + update from filename
|
||
$mvpExtractor = new MetadataExtractorMVP();
|
||
$assetRepresentation = $mvpExtractor->buildMVPAssetRepresentation(
|
||
$masterAsset,
|
||
$cleanFilename,
|
||
$parsed, // Parsed V2 filename for field extraction
|
||
$localPath // Local file for video metadata extraction
|
||
);
|
||
|
||
error_log("Upload from Box: Built MVP asset representation with clean filename: $cleanFilename");
|
||
|
||
// 7. Upload to DAM
|
||
$apiClient = new ApiClient();
|
||
$apiClient->setBaseUrl($configV3->getBaseUrl());
|
||
|
||
// Get OAuth token from TestRunner
|
||
if ($testRunner) {
|
||
$reflection = new ReflectionClass($testRunner);
|
||
$property = $reflection->getProperty('oauth2Handler');
|
||
$property->setAccessible(true);
|
||
$oauth2Handler = $property->getValue($testRunner);
|
||
|
||
if ($oauth2Handler) {
|
||
$accessToken = $oauth2Handler->getAccessToken();
|
||
$apiClient->setHeaders(['Authorization' => 'Bearer ' . $accessToken]);
|
||
}
|
||
}
|
||
|
||
// Rename temp file to clean filename before upload
|
||
$tempDir = dirname($localPath);
|
||
$cleanLocalPath = $tempDir . '/' . $cleanFilename;
|
||
|
||
if ($localPath !== $cleanLocalPath) {
|
||
rename($localPath, $cleanLocalPath);
|
||
$localPath = $cleanLocalPath;
|
||
}
|
||
|
||
$uploader = new AssetUploaderSimple($apiClient);
|
||
$uploadResult = $uploader->uploadWithMetadata(
|
||
$localPath,
|
||
$masterAsset['upload_directory'],
|
||
$assetRepresentation,
|
||
$videoMetadata // Pass video dimensions to upload manifest
|
||
);
|
||
|
||
// 8. Clean up temp file
|
||
if (file_exists($localPath)) {
|
||
unlink($localPath);
|
||
}
|
||
|
||
// 9. Return result
|
||
if ($uploadResult['success']) {
|
||
$response = [
|
||
'success' => true,
|
||
'filename' => $filename,
|
||
'clean_filename' => $cleanFilename,
|
||
'asset_id' => $uploadResult['asset_id'] ?? 'Unknown',
|
||
'tracking_id' => $trackingId,
|
||
'upload_folder' => $masterAsset['upload_directory'],
|
||
'master_asset_id' => $masterAsset['opentext_id'],
|
||
'http_code' => $uploadResult['http_code'] ?? 202,
|
||
'asset_representation' => $assetRepresentation // Include for download/view
|
||
];
|
||
} else {
|
||
$response = [
|
||
'success' => false,
|
||
'error' => 'Upload failed: ' . ($uploadResult['error'] ?? 'Unknown error'),
|
||
'filename' => $filename,
|
||
'http_code' => $uploadResult['http_code'] ?? 0
|
||
];
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
// Clean up on error
|
||
if (isset($localPath) && file_exists($localPath)) {
|
||
unlink($localPath);
|
||
}
|
||
$response = ['success' => false, 'error' => 'Upload exception: ' . $e->getMessage()];
|
||
}
|
||
break;
|
||
|
||
default:
|
||
$response = ['success' => false, 'error' => 'Unknown action: ' . $action];
|
||
}
|
||
} catch (Exception $e) {
|
||
$response = ['success' => false, 'error' => $e->getMessage()];
|
||
}
|
||
|
||
echo json_encode($response);
|
||
exit;
|
||
}
|
||
|
||
// 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->searchAllCampaignTypes($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 (Local Adaptation + Global comm)";
|
||
} 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);
|
||
|
||
// ALSO find Final Assets folder ID for uploads (stored in DB)
|
||
$finalFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
if ($finalFolderId) {
|
||
$results['final_assets_folder_id'] = $finalFolderId;
|
||
$success = "Found Master Assets (" . count($results['master_assets']) . " files) and Final Assets folder";
|
||
} else {
|
||
$success = "Found Master Assets folder with " . count($results['master_assets']) . " assets";
|
||
}
|
||
} else {
|
||
$error = "Master Assets folder not found in campaign";
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'get_final_assets':
|
||
if (isset($results['selected_campaign'])) {
|
||
$campaignId = $results['selected_campaign']['asset_id'];
|
||
$finalFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
|
||
if ($finalFolderId) {
|
||
$results['final_assets_folder_id'] = $finalFolderId;
|
||
$results['final_assets'] = getAssetsFromFolder($testRunner, $finalFolderId);
|
||
$success = "Found Final Assets folder with " . count($results['final_assets']) . " assets";
|
||
} else {
|
||
$error = "Final 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 'download_and_upload_to_box':
|
||
if (isset($results['master_assets']) && isset($results['selected_campaign'])) {
|
||
$campaign = $results['selected_campaign'];
|
||
|
||
// Download from DAM
|
||
$downloadResults = downloadAllAssets($testRunner, $results['master_assets'], $campaign['campaign_id']);
|
||
|
||
// Upload to Box with upload folder ID
|
||
$boxResults = uploadAssetsToBox(
|
||
$downloadResults,
|
||
$campaign['campaign_id'],
|
||
$campaign['campaign_name'],
|
||
$results['master_assets'],
|
||
$results['final_assets_folder_id'] ?? null
|
||
);
|
||
|
||
$results['bulk_download'] = $downloadResults;
|
||
$results['box_upload'] = $boxResults;
|
||
|
||
$success = "Downloaded {$downloadResults['successful']} assets and uploaded {$boxResults['successful']} to Box";
|
||
}
|
||
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());
|
||
}
|
||
|
||
// Use SIMPLE uploader that exactly matches standalone script
|
||
$uploader = new AssetUploaderSimple($apiClient);
|
||
|
||
// Create a copy with the actual filename
|
||
$actualFilePath = sys_get_temp_dir() . '/' . $fileName;
|
||
copy($tmpName, $actualFilePath);
|
||
|
||
$result = $uploader->uploadFile($actualFilePath, $testFolderId);
|
||
|
||
// Clean up
|
||
@unlink($actualFilePath);
|
||
|
||
$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;
|
||
|
||
case 'load_campaigns_b1':
|
||
$results['b1_campaigns'] = loadCampaignsGlobal($testRunner, 'B1');
|
||
$success = "Loaded " . count($results['b1_campaigns']) . " Global campaigns with status B1";
|
||
break;
|
||
|
||
case 'select_campaign_b1':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId && isset($results['b1_campaigns'])) {
|
||
foreach ($results['b1_campaigns'] as $campaign) {
|
||
if ($campaign['asset_id'] === $campaignId) {
|
||
$results['selected_campaign_b1'] = $campaign;
|
||
$success = "Campaign selected: " . $campaign['campaign_name'];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
$currentTab = 'global-masters';
|
||
break;
|
||
|
||
case 'get_global_master_assets':
|
||
if (isset($results['selected_campaign_b1'])) {
|
||
$campaignId = $results['selected_campaign_b1']['asset_id'];
|
||
|
||
// B1 campaigns use "05. Final Assets" folder (not "01. Master Assets")
|
||
$finalAssetsFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
|
||
if ($finalAssetsFolderId) {
|
||
$results['global_master_folder_id'] = $finalAssetsFolderId;
|
||
$results['global_master_assets'] = getAssetsFromFolder($testRunner, $finalAssetsFolderId);
|
||
$success = "Found " . count($results['global_master_assets']) . " Global Master assets in Final Assets folder";
|
||
} else {
|
||
$error = "Final Assets folder not found in campaign (B1 campaigns use '05. Final Assets')";
|
||
}
|
||
}
|
||
$currentTab = 'global-masters';
|
||
break;
|
||
|
||
case 'update_status_to_b2':
|
||
$campaignId = $_POST['campaign_id'] ?? null;
|
||
if (!$campaignId && isset($results['selected_campaign_b1'])) {
|
||
$campaignId = $results['selected_campaign_b1']['asset_id'];
|
||
}
|
||
|
||
if ($campaignId) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus($campaignId, 'B2');
|
||
|
||
if ($statusResult['success']) {
|
||
$results['status_update_b2'] = $statusResult;
|
||
$success = "Campaign status updated to B2: Master campaign received from Agency";
|
||
} else {
|
||
$error = "Failed to update status to B2";
|
||
$results['status_update_b2_error'] = $statusResult;
|
||
}
|
||
}
|
||
$currentTab = 'global-masters';
|
||
break;
|
||
|
||
case 'reset_to_b1':
|
||
$campaignId = $_POST['campaign_id'] ?? '';
|
||
if ($campaignId) {
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus($campaignId, 'B1');
|
||
|
||
if ($statusResult['success']) {
|
||
$success = "Campaign status reset to B1";
|
||
unset($results['b1_campaigns']);
|
||
} else {
|
||
$error = "Failed to reset status to B1";
|
||
}
|
||
}
|
||
break;
|
||
|
||
case 'debug_all_global_campaigns':
|
||
$statusManager = createStatusManager($testRunner);
|
||
$response = $statusManager->searchGlobalCampaigns($testRunner);
|
||
|
||
if ($response['success']) {
|
||
$data = json_decode($response['body'], true);
|
||
$campaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||
$results['debug_global_campaigns'] = $campaigns;
|
||
$success = "Found " . count($campaigns) . " Global campaigns total";
|
||
} else {
|
||
$error = "Debug search failed for Global campaigns";
|
||
}
|
||
break;
|
||
|
||
// Debug View Actions
|
||
case 'load_all_campaigns_debug':
|
||
$statusManager = createStatusManager($testRunner);
|
||
$allStatuses = ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'B1', 'B2'];
|
||
$allCampaigns = [];
|
||
|
||
foreach ($allStatuses as $status) {
|
||
$campaigns = loadCampaignsByStatus($testRunner, $status);
|
||
foreach ($campaigns as $campaign) {
|
||
$campaign['current_status'] = $status;
|
||
$allCampaigns[] = $campaign;
|
||
}
|
||
}
|
||
|
||
$results['debug_all_campaigns'] = $allCampaigns;
|
||
$success = "Loaded " . count($allCampaigns) . " campaigns across all statuses";
|
||
$currentTab = 'debug-view';
|
||
break;
|
||
|
||
case 'update_campaign_status_debug':
|
||
$selectedIndex = $_POST['selected_campaign'] ?? null;
|
||
$targetStatus = $_POST['target_status'] ?? null;
|
||
|
||
if ($selectedIndex !== null && $targetStatus && isset($results['debug_all_campaigns'][$selectedIndex])) {
|
||
$campaign = $results['debug_all_campaigns'][$selectedIndex];
|
||
$campaignId = $campaign['asset_id'];
|
||
$campaignName = $campaign['campaign_name'];
|
||
$campaignNumber = $campaign['campaign_id'] ?? 'N/A';
|
||
$oldStatus = $campaign['current_status'];
|
||
|
||
$statusManager = createStatusManager($testRunner);
|
||
$statusResult = $statusManager->updateCampaignStatus($campaignId, $targetStatus);
|
||
|
||
if ($statusResult['success']) {
|
||
$results['status_update_result'] = [
|
||
'success' => true,
|
||
'campaign_name' => $campaignName,
|
||
'campaign_number' => $campaignNumber,
|
||
'old_status' => $oldStatus,
|
||
'new_status' => $targetStatus
|
||
];
|
||
$success = "Campaign status updated: {$oldStatus} → {$targetStatus}";
|
||
unset($results['debug_all_campaigns']);
|
||
} else {
|
||
$results['status_update_result'] = [
|
||
'success' => false,
|
||
'error' => $statusResult['error'] ?? 'Unknown error',
|
||
'campaign_name' => $campaignName
|
||
];
|
||
$error = "Failed to update campaign status";
|
||
}
|
||
} else {
|
||
$error = "Please select a campaign and target status";
|
||
}
|
||
$currentTab = 'debug-view';
|
||
break;
|
||
|
||
case 'view_master_assets_folder':
|
||
case 'view_final_assets_folder':
|
||
$folderType = ($action === 'view_master_assets_folder') ? 'Master Assets' : 'Final Assets';
|
||
$folderName = ($action === 'view_master_assets_folder') ? '01. Master Assets' : '01. Final Assets';
|
||
|
||
$assetManager = createAssetManager($testRunner);
|
||
$searchResult = $assetManager->searchForFolder($folderName);
|
||
|
||
if ($searchResult['success'] && count($searchResult['folders']) > 0) {
|
||
$folderId = $searchResult['folders'][0]['id'];
|
||
$contentsResult = $assetManager->getFolderContents($folderId);
|
||
|
||
if ($contentsResult['success']) {
|
||
$items = $contentsResult['items'];
|
||
|
||
foreach ($items as &$item) {
|
||
if ($item['type'] === 'folder') {
|
||
$item['campaign_id'] = extractCampaignId($item);
|
||
$item['status'] = extractStatus($item);
|
||
}
|
||
}
|
||
|
||
$results['debug_folder_contents'] = [
|
||
'folder_name' => $folderName,
|
||
'folder_type' => $folderType,
|
||
'folder_id' => $folderId,
|
||
'items' => $items
|
||
];
|
||
$success = "Found " . count($items) . " items in {$folderName}";
|
||
} else {
|
||
$results['debug_folder_error'] = "Failed to load folder contents";
|
||
$error = $results['debug_folder_error'];
|
||
}
|
||
} else {
|
||
$results['debug_folder_error'] = "Folder '{$folderName}' not found";
|
||
$error = $results['debug_folder_error'];
|
||
}
|
||
$currentTab = 'debug-view';
|
||
break;
|
||
|
||
case 'select_campaign_and_view_folders':
|
||
$campaignIndex = $_POST['campaign_index'] ?? null;
|
||
$folderType = $_POST['folder_type'] ?? 'master';
|
||
|
||
if ($campaignIndex !== null && isset($results['debug_all_campaigns'][$campaignIndex])) {
|
||
$campaign = $results['debug_all_campaigns'][$campaignIndex];
|
||
$results['selected_campaign_debug'] = $campaign;
|
||
|
||
// Find the campaign's folder
|
||
$campaignId = $campaign['asset_id'];
|
||
$folderName = ($folderType === 'master') ? '01. Master Assets' : '01. Final Assets';
|
||
$results['debug_folder_view_type'] = $folderName;
|
||
|
||
// Use existing helper function to find folder
|
||
if ($folderType === 'master') {
|
||
$folderId = findMasterAssetsFolder($testRunner, $campaignId);
|
||
} else {
|
||
$folderId = findUploadFolder($testRunner, $campaignId, $configV3);
|
||
}
|
||
|
||
if ($folderId) {
|
||
// Get assets from folder using existing helper
|
||
$assets = getAssetsFromFolder($testRunner, $folderId);
|
||
|
||
$results['debug_folder_contents'] = [
|
||
'folder_name' => $folderName,
|
||
'folder_type' => ucfirst($folderType) . ' Assets',
|
||
'folder_id' => $folderId,
|
||
'items' => array_map(function($asset) {
|
||
return [
|
||
'type' => 'asset',
|
||
'name' => $asset['name'] ?? 'Unknown',
|
||
'id' => $asset['asset_id'] ?? '',
|
||
'size' => $asset['file_size'] ?? 0,
|
||
'status' => extractStatusFromAsset($asset)
|
||
];
|
||
}, $assets)
|
||
];
|
||
$success = "Found " . count($assets) . " assets in {$folderName} for campaign";
|
||
} else {
|
||
$results['debug_folder_error'] = "Folder '{$folderName}' not found in campaign";
|
||
$error = $results['debug_folder_error'];
|
||
}
|
||
} else {
|
||
$error = "Campaign not found";
|
||
}
|
||
$currentTab = 'debug-view';
|
||
break;
|
||
|
||
case 'view_folder_contents':
|
||
$folderId = $_POST['folder_id'] ?? '';
|
||
$folderName = $_POST['folder_name'] ?? 'Unknown Folder';
|
||
|
||
if ($folderId) {
|
||
$assetManager = createAssetManager($testRunner);
|
||
$contentsResult = $assetManager->getFolderContents($folderId);
|
||
|
||
if ($contentsResult['success']) {
|
||
$items = $contentsResult['items'];
|
||
|
||
foreach ($items as &$item) {
|
||
if ($item['type'] === 'folder') {
|
||
$item['campaign_id'] = extractCampaignId($item);
|
||
$item['status'] = extractStatus($item);
|
||
}
|
||
}
|
||
|
||
$results['debug_folder_contents'] = [
|
||
'folder_name' => $folderName,
|
||
'folder_type' => 'Subfolder',
|
||
'folder_id' => $folderId,
|
||
'items' => $items
|
||
];
|
||
$success = "Found " . count($items) . " items in {$folderName}";
|
||
} else {
|
||
$results['debug_folder_error'] = "Failed to load folder";
|
||
$error = $results['debug_folder_error'];
|
||
}
|
||
} else {
|
||
$error = "Folder ID is required";
|
||
}
|
||
$currentTab = 'debug-view';
|
||
break;
|
||
}
|
||
} catch (Exception $e) {
|
||
$error = "Action failed: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
// Helper Functions
|
||
|
||
function extractCampaignId($folder)
|
||
{
|
||
if (isset($folder['metadata'])) {
|
||
foreach ($folder['metadata'] as $field) {
|
||
if (isset($field['id']) && $field['id'] === 'FERRERO.FIELD.CAMPAIGN ID') {
|
||
return $field['value']['value']['value'] ?? null;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function extractStatus($folder)
|
||
{
|
||
if (isset($folder['metadata'])) {
|
||
foreach ($folder['metadata'] as $field) {
|
||
if (isset($field['id']) && $field['id'] === 'CONTENT.SCALING.STATUS') {
|
||
return $field['value']['value']['value'] ?? null;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function extractStatusFromAsset($asset)
|
||
{
|
||
if (isset($asset['metadata']) && isset($asset['metadata']['metadata_element_list'])) {
|
||
foreach ($asset['metadata']['metadata_element_list'] as $category) {
|
||
if (isset($category['metadata_element_list'])) {
|
||
foreach ($category['metadata_element_list'] as $field) {
|
||
if ($field['id'] === 'CONTENT.SCALING.STATUS') {
|
||
return $field['value']['value']['value'] ?? null;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function findMasterAssetsFolder($testRunner, $campaignId)
|
||
{
|
||
// Similar to findUploadFolder but looks for Master Assets instead
|
||
$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);
|
||
|
||
$configV3 = new ConfigV3();
|
||
$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 Master Assets folder
|
||
if (strpos($folderName, 'Master') !== false) {
|
||
return $folder['asset_id'];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
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 loadCampaignsGlobal($testRunner, $status)
|
||
{
|
||
// Search for ALL Global comm campaigns
|
||
// Then filter by status in PHP
|
||
$statusManager = createStatusManager($testRunner);
|
||
$response = $statusManager->searchGlobalCampaigns($testRunner);
|
||
|
||
if ($response['success']) {
|
||
$allCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||
|
||
global $results;
|
||
$results['debug_all_global_count'] = count($allCampaigns);
|
||
$results['debug_status_filter_global'] = $status;
|
||
|
||
// Filter by status
|
||
$filteredCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], ['status' => $status]);
|
||
$results['debug_filtered_global_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 uploadAssetsToBox($downloadResults, $campaignId, $campaignName, $masterAssets, $uploadFolderId = null)
|
||
{
|
||
// Debug
|
||
error_log("Box Upload: Starting with " . count($downloadResults['details'] ?? []) . " downloads");
|
||
|
||
// Load Box credentials and use JWT authentication
|
||
$boxConfig = json_decode(file_get_contents(__DIR__ . '/Box-config.json'), true);
|
||
$clientId = $boxConfig['boxAppSettings']['clientID'];
|
||
$clientSecret = $boxConfig['boxAppSettings']['clientSecret'];
|
||
|
||
$boxClient = new BoxClient($clientId, $clientSecret);
|
||
$idGenerator = new IDGenerator(true); // Use database for ID generation
|
||
$dbClient = new DatabaseClient();
|
||
|
||
// Test Box connection first
|
||
$connectionTest = $boxClient->testConnection();
|
||
error_log("Box Connection Test: " . ($connectionTest['success'] ? 'SUCCESS' : 'FAILED'));
|
||
|
||
if (!$connectionTest['success']) {
|
||
return [
|
||
'success' => false,
|
||
'error' => 'Box connection failed. Check developer token.',
|
||
'total' => 0,
|
||
'successful' => 0,
|
||
'failed' => 0
|
||
];
|
||
}
|
||
|
||
// Create campaign folder in Box
|
||
$folderResult = $boxClient->createCampaignFolder($campaignId, $campaignName);
|
||
error_log("Box Folder Creation: " . ($folderResult['success'] ? 'SUCCESS' : 'FAILED'));
|
||
|
||
if (!$folderResult['success']) {
|
||
return [
|
||
'success' => false,
|
||
'error' => 'Failed to create Box folder: ' . ($folderResult['error'] ?? 'Unknown'),
|
||
'total' => 0,
|
||
'successful' => 0,
|
||
'failed' => 0
|
||
];
|
||
}
|
||
|
||
$boxFolderId = $folderResult['folder_id'];
|
||
|
||
$downloadDetails = $downloadResults['details'] ?? [];
|
||
error_log("Box Upload: Processing " . count($downloadDetails) . " files");
|
||
error_log("Box Upload: Upload folder ID passed: " . ($uploadFolderId ?? 'NULL'));
|
||
error_log("Box Upload: Master assets count: " . count($masterAssets));
|
||
|
||
$results = [
|
||
'total' => count($downloadDetails),
|
||
'successful' => 0,
|
||
'failed' => 0,
|
||
'details' => [],
|
||
'box_folder_id' => $boxFolderId,
|
||
'box_folder_name' => $folderResult['folder_name']
|
||
];
|
||
|
||
// Upload each successfully downloaded file to Box
|
||
foreach ($downloadDetails as $index => $download) {
|
||
if (!$download['success']) {
|
||
$results['details'][] = [
|
||
'success' => false,
|
||
'filename' => $download['filename'] ?? 'Unknown',
|
||
'error' => 'Download failed'
|
||
];
|
||
$results['failed']++;
|
||
continue;
|
||
}
|
||
|
||
// Generate unique ID
|
||
$idResult = $idGenerator->generateId();
|
||
$uniqueId = $idResult['id'];
|
||
|
||
// Get asset metadata - use numeric index to match download order
|
||
$assetMetadata = $masterAssets[$index] ?? [];
|
||
error_log("Box Upload: Asset index " . $index . " has " . count(array_keys($assetMetadata)) . " keys");
|
||
|
||
// Upload to Box
|
||
$boxUploadResult = $boxClient->uploadFile(
|
||
$download['filepath'],
|
||
$download['filename'],
|
||
$uniqueId,
|
||
$boxFolderId,
|
||
$assetMetadata
|
||
);
|
||
|
||
if ($boxUploadResult['success']) {
|
||
$results['successful']++;
|
||
|
||
// Store in database with upload folder ID
|
||
error_log("Box Upload: Storing in DB with upload folder: " . ($uploadFolderId ?? 'NULL'));
|
||
|
||
$dbResult = $dbClient->storeMasterAsset(
|
||
$uniqueId,
|
||
$assetMetadata,
|
||
$boxUploadResult['file_id'],
|
||
$boxUploadResult['box_url'],
|
||
$uploadFolderId // MISSING PARAMETER - was causing NULL!
|
||
);
|
||
|
||
$results['details'][] = [
|
||
'success' => true,
|
||
'original_filename' => $download['filename'],
|
||
'box_filename' => $boxUploadResult['filename'],
|
||
'unique_id' => $uniqueId,
|
||
'box_file_id' => $boxUploadResult['file_id'],
|
||
'box_url' => $boxUploadResult['box_url'],
|
||
'db_stored' => $dbResult['success'] ?? false,
|
||
'id_source' => $idResult['source'] ?? 'unknown'
|
||
];
|
||
} else {
|
||
$results['failed']++;
|
||
$results['details'][] = [
|
||
'success' => false,
|
||
'filename' => $download['filename'],
|
||
'error' => $boxUploadResult['error'] ?? 'Unknown error'
|
||
];
|
||
}
|
||
}
|
||
|
||
return $results;
|
||
}
|
||
|
||
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());
|
||
}
|
||
|
||
// Use SIMPLE uploader that works!
|
||
$uploader = new AssetUploaderSimple($apiClient);
|
||
|
||
$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;
|
||
}
|
||
|
||
// Create temp file with actual filename (not phpXXXXX)
|
||
$actualFilePath = sys_get_temp_dir() . '/' . $fileName;
|
||
copy($tmpName, $actualFilePath);
|
||
|
||
$result = $uploader->uploadFile($actualFilePath, $folderId);
|
||
|
||
// Clean up
|
||
@unlink($actualFilePath);
|
||
|
||
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>Ferrero Content Scaling Workflow</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: 'Montserrat', -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, #431b06 0%, #6b2d10 100%);
|
||
color: white;
|
||
padding: 30px;
|
||
text-align: center;
|
||
}
|
||
|
||
.header h1 {
|
||
margin-bottom: 10px;
|
||
font-weight: 600;
|
||
letter-spacing: -0.5px;
|
||
}
|
||
.header p {
|
||
opacity: 0.9;
|
||
font-weight: 300;
|
||
}
|
||
|
||
.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: #431b06;
|
||
border-bottom: 3px solid #431b06;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.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: #431b06;
|
||
color: white;
|
||
font-family: 'Montserrat', sans-serif;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.btn-primary:hover { background: #6b2d10; }
|
||
|
||
.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: #431b06;
|
||
box-shadow: 0 4px 12px rgba(67, 27, 6, 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>
|
||
<button class="tab <?= $currentTab === 'box-upload' ? 'active' : '' ?>"
|
||
onclick="switchTab('box-upload')">
|
||
📦 Upload from Box (A2→A3)
|
||
</button>
|
||
<button class="tab <?= $currentTab === 'global-masters' ? 'active' : '' ?>"
|
||
onclick="switchTab('global-masters')">
|
||
🌍 Global Masters (B1→B2)
|
||
</button>
|
||
<button class="tab <?= $currentTab === 'debug-view' ? 'active' : '' ?>"
|
||
onclick="switchTab('debug-view')">
|
||
🔧 Debug View
|
||
</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>
|
||
|
||
<?php if ($campaign['status'] === 'B1'): ?>
|
||
<form method="POST" style="margin-top: 15px; display: inline-block; margin-left: 10px;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="update_status_to_b2">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-success" onclick="return confirm('Update campaign <?= htmlspecialchars($campaign['campaign_name']) ?> to B2 status?')">
|
||
✅ Update B1 → B2
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($campaign['status'] === 'B2'): ?>
|
||
<form method="POST" style="margin-top: 15px; display: inline-block; margin-left: 10px;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="reset_to_b1">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-warning" onclick="return confirm('Reset campaign <?= htmlspecialchars($campaign['campaign_name']) ?> to B1 status?')">
|
||
🔄 Reset B2 → B1 (for testing)
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<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: #431b06; font-size: 12px;">
|
||
🔍 Debug folder structure for this campaign
|
||
</a>
|
||
</div>
|
||
|
||
<form method="POST" style="margin-top: 20px; display: inline-block; margin-right: 10px;">
|
||
<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>
|
||
|
||
<form method="POST" style="margin-top: 20px; display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="get_final_assets">
|
||
<button type="submit" class="btn btn-success">Get Final Assets (Uploaded)</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; display: inline-block; margin-right: 10px;">
|
||
<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>
|
||
|
||
<form method="POST" style="margin: 20px 0; display: inline-block;">
|
||
<input type="hidden" name="tab" value="download">
|
||
<input type="hidden" name="action" value="download_and_upload_to_box">
|
||
<button type="submit" class="btn btn-primary">📥📦 Download & Upload to Box</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 #431b06;">
|
||
<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; ?>
|
||
|
||
<!-- CREATIVEX Fields -->
|
||
<?php if (isset($metadata['creativex_fields']) && !empty($metadata['creativex_fields'])): ?>
|
||
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #9b59b6;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #333;">🎯 CREATIVEX Fields (<?= count($metadata['creativex_fields']) ?>)</summary>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 250px 1fr; gap: 5px;">
|
||
<?php foreach ($metadata['creativex_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>
|
||
<br><small style="color: #999;"><?= htmlspecialchars($fieldData['id']) ?></small>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?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['final_assets']) && !empty($results['final_assets'])): ?>
|
||
<h3 style="margin-top: 30px;">Final Assets / Uploaded Assets (<?= count($results['final_assets']) ?> files)</h3>
|
||
<p style="color: #666; font-size: 14px; margin: 10px 0;">
|
||
These are the localized/processed assets that have been uploaded back to the DAM.
|
||
</p>
|
||
|
||
<div class="asset-list">
|
||
<?php foreach ($results['final_assets'] as $index => $asset): ?>
|
||
<?php
|
||
$assetName = extractFolderName($asset);
|
||
$assetId = $asset['asset_id'];
|
||
$metadataId = 'final-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; ?>
|
||
<?php if (isset($asset['metadata_model_id'])): ?>
|
||
<br><small style="color: #28a745;">✅ Model: <?= htmlspecialchars($asset['metadata_model_id']) ?></small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="asset-actions">
|
||
<button class="btn btn-secondary"
|
||
onclick="toggleMetadata('<?= $metadataId ?>')">
|
||
📋 View 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;">
|
||
<!-- Basic Info -->
|
||
<?php if (isset($metadata['basic'])): ?>
|
||
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #28a745;">
|
||
<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): ?>
|
||
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
|
||
<div><strong><?= htmlspecialchars($value) ?></strong></div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Custom Metadata Fields (by Category) - SAME FORMAT AS MASTER -->
|
||
<?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; ?>
|
||
|
||
<!-- CREATIVEX Fields (Final Assets) -->
|
||
<?php if (isset($metadata['creativex_fields']) && !empty($metadata['creativex_fields'])): ?>
|
||
<details open style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #9b59b6;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #333;">🎯 CREATIVEX Fields (<?= count($metadata['creativex_fields']) ?>)</summary>
|
||
<div style="margin-top: 8px; display: grid; grid-template-columns: 250px 1fr; gap: 5px;">
|
||
<?php foreach ($metadata['creativex_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>
|
||
<br><small style="color: #999;"><?= htmlspecialchars($fieldData['id']) ?></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>
|
||
<?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; ?>
|
||
|
||
<?php if (isset($results['box_upload'])): ?>
|
||
<div class="alert alert-<?= $results['box_upload']['successful'] > 0 ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<strong>📦 Box Upload Results:</strong>
|
||
<?= $results['box_upload']['successful'] ?> of <?= $results['box_upload']['total'] ?> files uploaded to Box
|
||
<br><strong>Box Folder:</strong> <?= htmlspecialchars($results['box_upload']['box_folder_name'] ?? 'N/A') ?>
|
||
<br><strong>Folder ID:</strong> <code><?= htmlspecialchars($results['box_upload']['box_folder_id'] ?? 'N/A') ?></code>
|
||
|
||
<?php if (!empty($results['box_upload']['details'])): ?>
|
||
<details style="margin-top: 15px;">
|
||
<summary style="cursor: pointer;">View Box upload details</summary>
|
||
<div style="margin-top: 10px;">
|
||
<?php foreach ($results['box_upload']['details'] as $detail): ?>
|
||
<div style="padding: 8px; margin: 5px 0; background: white; border-radius: 4px;">
|
||
<?php if ($detail['success']): ?>
|
||
✅ <strong><?= htmlspecialchars($detail['original_filename']) ?></strong>
|
||
→ <?= htmlspecialchars($detail['box_filename']) ?>
|
||
<br><small>
|
||
Tracking ID: <code style="background: #d4edda; padding: 2px 6px; border-radius: 3px; font-weight: bold;"><?= htmlspecialchars($detail['unique_id']) ?></code> |
|
||
<a href="<?= htmlspecialchars($detail['box_url']) ?>" target="_blank" style="color: #007bff;">📦 View in Box</a>
|
||
<?php if (isset($detail['db_stored'])): ?>
|
||
| DB: <?= $detail['db_stored'] ? '✅ Stored' : '❌ Failed' ?>
|
||
<?php endif; ?>
|
||
<?php if (isset($detail['id_source'])): ?>
|
||
| ID Source: <?= htmlspecialchars($detail['id_source']) ?>
|
||
<?php endif; ?>
|
||
</small>
|
||
<?php else: ?>
|
||
❌ <?= htmlspecialchars($detail['filename']) ?>
|
||
<br><small>Error: <?= htmlspecialchars($detail['error']) ?></small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</details>
|
||
<?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>
|
||
|
||
<?php if ($oauth2Status && ($oauth2Status['has_token'] ?? false)): ?>
|
||
<details style="background: white; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
|
||
<summary style="cursor: pointer; font-weight: 600; color: #856404;">
|
||
📋 Copy OAuth Token for Standalone Test
|
||
</summary>
|
||
<div style="margin-top: 10px;">
|
||
<p style="font-size: 12px; color: #666;">
|
||
Use this token with: <code>php test_upload_standalone.php "token"</code>
|
||
</p>
|
||
<textarea readonly onclick="this.select()"
|
||
style="width: 100%; height: 80px; font-family: monospace; font-size: 11px; padding: 5px; margin-top: 5px;"><?php
|
||
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
||
$oauth2Handler->setAccessible(true);
|
||
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
||
if ($oauth2HandlerInstance) {
|
||
$authHeader = $oauth2HandlerInstance->getAuthHeader();
|
||
echo str_replace('Bearer ', '', $authHeader);
|
||
}
|
||
?></textarea>
|
||
</div>
|
||
</details>
|
||
<?php endif; ?>
|
||
|
||
<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 #431b06; 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 #431b06;">
|
||
<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>
|
||
|
||
<!-- Upload from Box Workflow Tab -->
|
||
<div id="tab-box-upload" class="tab-content <?= $currentTab === 'box-upload' ? 'active' : '' ?>">
|
||
<h2>📦 Upload from Box: A2 → A3</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0;">
|
||
Load files from a Box folder, parse V2 filenames, merge metadata, and upload to DAM
|
||
</p>
|
||
|
||
<!-- Box Folder Input -->
|
||
<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
|
||
<h3>Step 1: Load Files from Box Folder</h3>
|
||
<div style="margin-top: 15px;">
|
||
<label for="box-folder-id" style="display: block; margin-bottom: 5px; font-weight: 600;">
|
||
Box Folder ID:
|
||
</label>
|
||
<div style="display: flex; gap: 10px;">
|
||
<input type="text"
|
||
id="box-folder-id"
|
||
placeholder="e.g., 348304357505"
|
||
value="348526703108"
|
||
style="flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
|
||
<button type="button"
|
||
class="btn btn-primary"
|
||
onclick="loadBoxFiles()">
|
||
Load Files
|
||
</button>
|
||
</div>
|
||
<p style="margin-top: 8px; font-size: 13px; color: #666;">
|
||
Enter the Box Folder ID containing files ready for upload. Files must follow the V2 naming convention.
|
||
</p>
|
||
</div>
|
||
<div id="box-loading" style="display: none; margin-top: 15px; padding: 15px; background: #fff3cd; border-radius: 4px;">
|
||
<strong>⏳ Loading files from Box...</strong>
|
||
</div>
|
||
<div id="box-error" style="display: none; margin-top: 15px;" class="alert alert-error"></div>
|
||
</div>
|
||
|
||
<!-- File List Table -->
|
||
<div id="box-files-container" style="display: none;">
|
||
<h3>Step 2: Select Files to Upload</h3>
|
||
<p style="color: #666; margin-bottom: 15px;">
|
||
Review parsed filenames and select files to upload. ✅ Valid | ❌ Invalid
|
||
</p>
|
||
|
||
<div style="overflow-x: auto; background: white; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
||
<table style="width: 100%; border-collapse: collapse;">
|
||
<thead style="background: #f8f9fa;">
|
||
<tr>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">
|
||
<input type="checkbox" id="select-all-files" onclick="toggleAllFiles(this)">
|
||
</th>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">Filename</th>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">Tracking ID</th>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">Valid</th>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">Size</th>
|
||
<th style="padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;">Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="box-files-list">
|
||
<!-- Populated by JavaScript -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; display: flex; gap: 10px;">
|
||
<button type="button"
|
||
class="btn btn-success"
|
||
onclick="uploadSelectedFiles()"
|
||
id="upload-selected-btn">
|
||
Upload Selected Files
|
||
</button>
|
||
<button type="button"
|
||
class="btn btn-secondary"
|
||
onclick="clearBoxFiles()">
|
||
Clear
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Upload Progress -->
|
||
<div id="upload-progress-container" style="display: none; margin-top: 20px;">
|
||
<h3>Upload Progress</h3>
|
||
<div id="upload-progress-list"></div>
|
||
</div>
|
||
|
||
<!-- Upload Results -->
|
||
<div id="upload-results-container" style="display: none; margin-top: 20px;">
|
||
<h3>Upload Results</h3>
|
||
<div id="upload-results-summary" class="alert alert-info"></div>
|
||
<div id="upload-results-details"></div>
|
||
</div>
|
||
</div>
|
||
<!-- Global Masters B1→B2 Workflow Tab -->
|
||
<div id="tab-global-masters" class="tab-content <?= $currentTab === 'global-masters' ? 'active' : '' ?>">
|
||
<h2>🌍 Global Masters Workflow: B1 → B2</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0;">
|
||
Download Global Master assets for re-mastering workflow
|
||
</p>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="load_campaigns_b1">
|
||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = B1)</button>
|
||
</form>
|
||
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="debug_all_global_campaigns">
|
||
<button type="submit" class="btn btn-secondary">🔍 Debug: Load ALL Global Campaigns</button>
|
||
</form>
|
||
|
||
<?php if (!empty($results) && $currentTab === 'global-masters'): ?>
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<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['selected_campaign_b1'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 30px;">
|
||
<strong>Selected Campaign:</strong>
|
||
<?= htmlspecialchars($results['selected_campaign_b1']['campaign_name']) ?>
|
||
(<?= htmlspecialchars($results['selected_campaign_b1']['campaign_id'] ?? 'N/A') ?>)
|
||
<br>
|
||
<small><strong>Asset ID:</strong> <code><?= htmlspecialchars($results['selected_campaign_b1']['asset_id']) ?></code></small>
|
||
<br>
|
||
<small><strong>Type:</strong> Global Masters</small>
|
||
<br>
|
||
<a href="debug_assets.php?action=get_folders&campaign_id=<?= urlencode($results['selected_campaign_b1']['asset_id']) ?>"
|
||
target="_blank" style="color: #431b06; font-size: 12px;">
|
||
🔍 Debug folder structure for this campaign
|
||
</a>
|
||
</div>
|
||
|
||
<form method="POST" style="margin-top: 20px;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="get_global_master_assets">
|
||
<button type="submit" class="btn btn-primary">Get Global Master Assets</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['global_master_assets']) && !empty($results['global_master_assets'])): ?>
|
||
<h3 style="margin-top: 30px;">Global Master Assets (<?= count($results['global_master_assets']) ?> files)</h3>
|
||
<div class="asset-list">
|
||
<?php foreach ($results['global_master_assets'] as $index => $asset): ?>
|
||
<?php
|
||
$assetName = extractFolderName($asset);
|
||
$assetId = $asset['asset_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>
|
||
</div>
|
||
<div class="asset-actions">
|
||
<button class="btn btn-secondary">📋 View Metadata</button>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_global_campaigns']) && !empty($results['debug_global_campaigns'])): ?>
|
||
<div class="alert alert-info" style="margin-top: 30px;">
|
||
<h3>🔍 Debug Results: Found <?= count($results['debug_global_campaigns']) ?> Global Campaigns</h3>
|
||
<?php foreach ($results['debug_global_campaigns'] as $campaign): ?>
|
||
<details style="margin: 15px 0; background: white; padding: 15px; border-radius: 6px;">
|
||
<summary style="cursor: pointer; font-weight: 600;">
|
||
<?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed') ?>
|
||
- Status: <span class="status-badge"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?></span>
|
||
</summary>
|
||
<div style="margin-top: 15px;">
|
||
<p><strong>Campaign Type:</strong> <?= htmlspecialchars($campaign['campaign_type'] ?? 'N/A') ?></p>
|
||
<p><strong>Status:</strong> <?= htmlspecialchars($campaign['status'] ?? 'N/A') ?></p>
|
||
<p><strong>Asset ID:</strong> <?= htmlspecialchars($campaign['asset_id']) ?></p>
|
||
|
||
<?php if ($campaign['status'] === 'B1'): ?>
|
||
<form method="POST" style="margin-top: 15px; display: inline-block;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="update_status_to_b2">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-success" onclick="return confirm('Update <?= htmlspecialchars($campaign['campaign_name']) ?> to B2?')">
|
||
✅ Update B1 → B2
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($campaign['status'] === 'B2'): ?>
|
||
<form method="POST" style="margin-top: 15px; display: inline-block;">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="reset_to_b1">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-warning" onclick="return confirm('Reset <?= htmlspecialchars($campaign['campaign_name']) ?> to B1?')">
|
||
🔄 Reset B2 → B1
|
||
</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
</div>
|
||
</details>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['selected_campaign_b1'])): ?>
|
||
|
||
<div style="margin-top: 30px; padding: 20px; background: #fff3cd; border-radius: 8px;">
|
||
<h4>⚠️ Update Status to B2</h4>
|
||
<p style="margin: 10px 0;">
|
||
Once all Global Master assets are downloaded and sent to Agency, update the campaign status to B2
|
||
</p>
|
||
<form method="POST">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="update_status_to_b2">
|
||
<button type="submit" class="btn btn-success">Update Status: B1 → B2</button>
|
||
</form>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['b1_campaigns']) && !empty($results['b1_campaigns'])): ?>
|
||
<h3 style="margin-top: 30px;">Found <?= count($results['b1_campaigns']) ?> Global Campaigns (B1)</h3>
|
||
<div class="campaign-grid">
|
||
<?php foreach ($results['b1_campaigns'] as $campaign): ?>
|
||
<div class="campaign-card">
|
||
<h3><?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed Campaign') ?></h3>
|
||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||
<p><strong>Status:</strong> <span class="status-badge status-b1">B1</span></p>
|
||
<p><strong>Type:</strong> <?= htmlspecialchars($campaign['campaign_type'] ?? 'Global comm') ?></p>
|
||
<form method="POST">
|
||
<input type="hidden" name="tab" value="global-masters">
|
||
<input type="hidden" name="action" value="select_campaign_b1">
|
||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||
<button type="submit" class="btn btn-success">Select Campaign</button>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Debug View Tab -->
|
||
<div id="tab-debug-view" class="tab-content <?= $currentTab === 'debug-view' ? 'active' : '' ?>">
|
||
<h2>🔧 Debug View</h2>
|
||
<p style="color: #666; margin: 10px 0 20px 0; font-weight: 300;">
|
||
Campaign status management and folder inspection tools for testing workflows
|
||
</p>
|
||
|
||
<!-- Section 1: Campaign Status Management -->
|
||
<div style="background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||
<h3 style="margin-top: 0; color: #431b06; font-weight: 600;">📋 Campaign Status Management</h3>
|
||
|
||
<div style="margin-bottom: 20px;">
|
||
<form method="POST" style="display: inline-block; margin-right: 10px;">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="action" value="load_all_campaigns_debug">
|
||
<button type="submit" class="btn btn-primary">Load All Campaigns (All Statuses)</button>
|
||
</form>
|
||
|
||
<?php if (isset($results['debug_all_campaigns']) || isset($results['debug_folder_contents'])): ?>
|
||
<form method="POST" style="display: inline-block;">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="clear_results" value="1">
|
||
<button type="submit" class="btn btn-secondary">🗑️ Reset / Clear Results</button>
|
||
</form>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if (isset($results['debug_all_campaigns'])): ?>
|
||
<div class="alert alert-info">
|
||
<strong>Found <?= count($results['debug_all_campaigns']) ?> campaigns</strong>
|
||
</div>
|
||
|
||
<?php if (count($results['debug_all_campaigns']) > 0): ?>
|
||
<!-- Two separate forms: one for status update, one for folder viewing -->
|
||
|
||
<!-- Status Update Form -->
|
||
<form method="POST" id="status-update-form">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="action" value="update_campaign_status_debug">
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="results-table" style="width: 100%; margin-top: 20px; table-layout: fixed;">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 60px; text-align: center;">Select</th>
|
||
<th style="width: 40%;">Campaign Name</th>
|
||
<th style="width: 150px;">Campaign Number</th>
|
||
<th style="width: 120px; text-align: center;">Current Status</th>
|
||
<th style="width: 150px;">Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($results['debug_all_campaigns'] as $index => $campaign): ?>
|
||
<tr>
|
||
<td style="text-align: center; vertical-align: middle;">
|
||
<input type="radio"
|
||
name="selected_campaign"
|
||
value="<?= $index ?>"
|
||
id="campaign_<?= $index ?>"
|
||
onchange="handleCampaignSelection(<?= $index ?>)">
|
||
</td>
|
||
<td style="vertical-align: middle;">
|
||
<label for="campaign_<?= $index ?>" style="cursor: pointer; display: block; padding: 5px 0; font-weight: 400;">
|
||
<?= htmlspecialchars($campaign['campaign_name']) ?>
|
||
</label>
|
||
</td>
|
||
<td style="vertical-align: middle;">
|
||
<label for="campaign_<?= $index ?>" style="cursor: pointer; display: block; padding: 5px 0;">
|
||
<?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?>
|
||
</label>
|
||
</td>
|
||
<td style="text-align: center; vertical-align: middle;">
|
||
<label for="campaign_<?= $index ?>" style="cursor: pointer; display: block; padding: 5px 0;">
|
||
<span class="badge badge-info"><?= htmlspecialchars($campaign['current_status']) ?></span>
|
||
</label>
|
||
</td>
|
||
<td style="vertical-align: middle;">
|
||
<div id="actions_<?= $index ?>" style="display: none;">
|
||
<button type="button" onclick="viewCampaignFolder(<?= $index ?>, 'master')" class="btn btn-secondary" style="font-size: 13px; padding: 8px 12px; margin-right: 6px; font-weight: 500;">
|
||
📂 Master
|
||
</button>
|
||
<button type="button" onclick="viewCampaignFolder(<?= $index ?>, 'final')" class="btn btn-secondary" style="font-size: 13px; padding: 8px 12px; font-weight: 500;">
|
||
📂 Final
|
||
</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 4px;">
|
||
<label for="target_status" style="font-weight: 600; margin-right: 10px;">
|
||
Update selected campaign to:
|
||
</label>
|
||
<select name="target_status" id="target_status" required style="padding: 8px; font-size: 14px; border-radius: 4px; border: 1px solid #ddd; font-family: 'Montserrat', sans-serif;">
|
||
<option value="">-- Select Status --</option>
|
||
<option value="A1">A1</option>
|
||
<option value="A2">A2</option>
|
||
<option value="A3">A3</option>
|
||
<option value="A4">A4</option>
|
||
<option value="A5">A5</option>
|
||
<option value="A6">A6</option>
|
||
<option value="B1">B1</option>
|
||
<option value="B2">B2</option>
|
||
</select>
|
||
|
||
<button type="submit" class="btn btn-warning" style="margin-left: 20px;">
|
||
Update Campaign Status
|
||
</button>
|
||
</div>
|
||
</form>
|
||
|
||
<!-- Hidden forms for folder viewing -->
|
||
<?php foreach ($results['debug_all_campaigns'] as $index => $campaign): ?>
|
||
<form method="POST" id="view-master-<?= $index ?>" style="display: none;">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="action" value="select_campaign_and_view_folders">
|
||
<input type="hidden" name="campaign_index" value="<?= $index ?>">
|
||
<input type="hidden" name="folder_type" value="master">
|
||
</form>
|
||
<form method="POST" id="view-final-<?= $index ?>" style="display: none;">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="action" value="select_campaign_and_view_folders">
|
||
<input type="hidden" name="campaign_index" value="<?= $index ?>">
|
||
<input type="hidden" name="folder_type" value="final">
|
||
</form>
|
||
<?php endforeach; ?>
|
||
|
||
<script>
|
||
function handleCampaignSelection(index) {
|
||
console.log('Selected campaign index:', index);
|
||
// Hide all action buttons
|
||
document.querySelectorAll('[id^="actions_"]').forEach(el => el.style.display = 'none');
|
||
// Show actions for selected campaign
|
||
const actionsDiv = document.getElementById('actions_' + index);
|
||
if (actionsDiv) {
|
||
actionsDiv.style.display = 'block';
|
||
console.log('Showing actions for campaign', index);
|
||
} else {
|
||
console.error('Actions div not found for index', index);
|
||
}
|
||
}
|
||
|
||
function viewCampaignFolder(index, folderType) {
|
||
console.log('Viewing folder:', folderType, 'for campaign', index);
|
||
const formId = 'view-' + folderType + '-' + index;
|
||
const form = document.getElementById(formId);
|
||
if (form) {
|
||
console.log('Submitting form:', formId);
|
||
form.submit();
|
||
} else {
|
||
console.error('Form not found:', formId);
|
||
alert('Error: Form not found. Please try reloading the page.');
|
||
}
|
||
}
|
||
</script>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['status_update_result'])): ?>
|
||
<div class="alert alert-<?= $results['status_update_result']['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||
<?php if ($results['status_update_result']['success']): ?>
|
||
<h4>✓ Campaign Status Updated Successfully</h4>
|
||
<p><strong>Campaign:</strong> <?= htmlspecialchars($results['status_update_result']['campaign_name']) ?></p>
|
||
<p><strong>Number:</strong> <?= htmlspecialchars($results['status_update_result']['campaign_number']) ?></p>
|
||
<p><strong>Previous Status:</strong> <?= htmlspecialchars($results['status_update_result']['old_status']) ?></p>
|
||
<p><strong>New Status:</strong> <?= htmlspecialchars($results['status_update_result']['new_status']) ?></p>
|
||
<?php else: ?>
|
||
<h4>✗ Status Update Failed</h4>
|
||
<p><strong>Error:</strong> htmlspecialchars($results['status_update_result']['error']) ?></p>
|
||
<p><strong>Campaign:</strong> <?= htmlspecialchars($results['status_update_result']['campaign_name'] ?? 'N/A') ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Section 2: Campaign Folder Contents -->
|
||
<?php if (isset($results['selected_campaign_debug'])): ?>
|
||
<div style="background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||
<h3 style="margin-top: 0; color: #431b06; font-weight: 600;">
|
||
📁 <?= htmlspecialchars($results['selected_campaign_debug']['campaign_name']) ?>
|
||
</h3>
|
||
<p style="color: #666; font-size: 14px; font-weight: 300;">
|
||
Campaign: <?= htmlspecialchars($results['selected_campaign_debug']['campaign_id'] ?? 'N/A') ?> |
|
||
Status: <span class="badge badge-info"><?= htmlspecialchars($results['selected_campaign_debug']['current_status']) ?></span>
|
||
</p>
|
||
<p style="color: #666; font-size: 13px; font-weight: 300; margin-top: 5px;">
|
||
Viewing: <?= htmlspecialchars($results['debug_folder_view_type'] ?? 'Folder Contents') ?>
|
||
</p>
|
||
|
||
<?php if (isset($results['debug_folder_contents'])): ?>
|
||
<div class="alert alert-info" style="margin-bottom: 20px;">
|
||
<h4><?= htmlspecialchars($results['debug_folder_contents']['folder_name']) ?></h4>
|
||
<p><strong>Folder Type:</strong> <?= htmlspecialchars($results['debug_folder_contents']['folder_type']) ?></p>
|
||
<p><strong>Total Items:</strong> <?= count($results['debug_folder_contents']['items']) ?></p>
|
||
</div>
|
||
|
||
<?php if (count($results['debug_folder_contents']['items']) > 0): ?>
|
||
<table class="results-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Name</th>
|
||
<th>Campaign/Folder</th>
|
||
<th>Status</th>
|
||
<th>Details</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($results['debug_folder_contents']['items'] as $item): ?>
|
||
<tr>
|
||
<td>
|
||
<?php if ($item['type'] === 'folder'): ?>
|
||
📁 Folder
|
||
<?php else: ?>
|
||
📄 Asset
|
||
<?php endif; ?>
|
||
</td>
|
||
<td><?= htmlspecialchars($item['name']) ?></td>
|
||
<td>
|
||
<?php if ($item['type'] === 'folder'): ?>
|
||
<?= htmlspecialchars($item['campaign_id'] ?? 'N/A') ?>
|
||
<?php else: ?>
|
||
-
|
||
<?php endif; ?>
|
||
</td>
|
||
<td>
|
||
<?php if (isset($item['status'])): ?>
|
||
<span class="badge badge-info"><?= htmlspecialchars($item['status']) ?></span>
|
||
<?php else: ?>
|
||
-
|
||
<?php endif; ?>
|
||
</td>
|
||
<td>
|
||
<?php if ($item['type'] === 'folder'): ?>
|
||
<form method="POST" style="display: inline;">
|
||
<input type="hidden" name="tab" value="debug-view">
|
||
<input type="hidden" name="action" value="view_folder_contents">
|
||
<input type="hidden" name="folder_id" value="<?= htmlspecialchars($item['id']) ?>">
|
||
<input type="hidden" name="folder_name" value="<?= htmlspecialchars($item['name']) ?>">
|
||
<button type="submit" class="btn btn-sm">View Contents</button>
|
||
</form>
|
||
<?php else: ?>
|
||
Size: <?= number_format($item['size'] ?? 0) ?> bytes
|
||
<?php endif; ?>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php else: ?>
|
||
<p style="color: #999; font-style: italic;">No items found in this folder</p>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($results['debug_folder_error'])): ?>
|
||
<div class="alert alert-error">
|
||
<h4>Error Loading Folder</h4>
|
||
<p><?= htmlspecialchars($results['debug_folder_error']) ?></p>
|
||
</div>
|
||
<?php endif; ?>
|
||
</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;
|
||
}
|
||
|
||
// Upload from Box functions
|
||
let boxFilesData = [];
|
||
let uploadResults = [];
|
||
|
||
function loadBoxFiles() {
|
||
const folderId = document.getElementById('box-folder-id').value.trim();
|
||
|
||
if (!folderId) {
|
||
showBoxError('Please enter a Box Folder ID');
|
||
return;
|
||
}
|
||
|
||
// Show loading
|
||
document.getElementById('box-loading').style.display = 'block';
|
||
document.getElementById('box-error').style.display = 'none';
|
||
document.getElementById('box-files-container').style.display = 'none';
|
||
|
||
// Make AJAX request
|
||
fetch('workflow_v3.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded',
|
||
'X-Requested-With': 'XMLHttpRequest'
|
||
},
|
||
body: 'action=box_list_files&folder_id=' + encodeURIComponent(folderId)
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
document.getElementById('box-loading').style.display = 'none';
|
||
|
||
if (data.success) {
|
||
boxFilesData = data.files;
|
||
displayBoxFiles(data.files);
|
||
} else {
|
||
showBoxError(data.error || 'Failed to load files from Box');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
document.getElementById('box-loading').style.display = 'none';
|
||
showBoxError('Error: ' + error.message);
|
||
});
|
||
}
|
||
|
||
function displayBoxFiles(files) {
|
||
if (!files || files.length === 0) {
|
||
showBoxError('No files found in Box folder');
|
||
return;
|
||
}
|
||
|
||
const tbody = document.getElementById('box-files-list');
|
||
tbody.innerHTML = '';
|
||
|
||
files.forEach((file, index) => {
|
||
const row = document.createElement('tr');
|
||
row.style.borderBottom = '1px solid #dee2e6';
|
||
|
||
const isValid = file.is_valid && file.has_tracking_id;
|
||
const validIcon = isValid ? '✅' : '❌';
|
||
const validColor = isValid ? '#28a745' : '#dc3545';
|
||
|
||
row.innerHTML = `
|
||
<td style="padding: 12px;">
|
||
<input type="checkbox"
|
||
class="file-checkbox"
|
||
data-index="${index}"
|
||
${isValid ? '' : 'disabled'}
|
||
onclick="updateUploadButton()">
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
<div style="font-weight: 600;">${escapeHtml(file.name)}</div>
|
||
${file.clean_filename && file.clean_filename !== file.name ?
|
||
`<div style="font-size: 12px; color: #666; margin-top: 4px;">
|
||
Upload as: ${escapeHtml(file.clean_filename)}
|
||
</div>` : ''}
|
||
${!isValid && file.parsed && file.parsed.validation_errors ?
|
||
`<div style="font-size: 11px; color: #dc3545; margin-top: 4px;">
|
||
${file.parsed.validation_errors.join(', ')}
|
||
</div>` : ''}
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
${file.tracking_id ?
|
||
`<span style="font-family: monospace; background: #e9ecef; padding: 2px 6px; border-radius: 3px;">${escapeHtml(file.tracking_id)}</span>` :
|
||
'<span style="color: #999;">None</span>'}
|
||
</td>
|
||
<td style="padding: 12px; color: ${validColor}; font-weight: 600;">
|
||
${validIcon} ${isValid ? 'Valid' : 'Invalid'}
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
${formatFileSize(file.size)}
|
||
</td>
|
||
<td style="padding: 12px;">
|
||
<a href="${file.box_url}" target="_blank" style="color: #007bff; text-decoration: none;">
|
||
View in Box
|
||
</a>
|
||
</td>
|
||
`;
|
||
|
||
tbody.appendChild(row);
|
||
});
|
||
|
||
document.getElementById('box-files-container').style.display = 'block';
|
||
updateUploadButton();
|
||
}
|
||
|
||
function toggleAllFiles(checkbox) {
|
||
document.querySelectorAll('.file-checkbox:not(:disabled)').forEach(cb => {
|
||
cb.checked = checkbox.checked;
|
||
});
|
||
updateUploadButton();
|
||
}
|
||
|
||
function updateUploadButton() {
|
||
const checkedCount = document.querySelectorAll('.file-checkbox:checked').length;
|
||
const btn = document.getElementById('upload-selected-btn');
|
||
btn.disabled = checkedCount === 0;
|
||
btn.textContent = `Upload Selected Files (${checkedCount})`;
|
||
}
|
||
|
||
function uploadSelectedFiles() {
|
||
const checkboxes = document.querySelectorAll('.file-checkbox:checked');
|
||
if (checkboxes.length === 0) {
|
||
alert('Please select at least one file to upload');
|
||
return;
|
||
}
|
||
|
||
// Get selected files
|
||
const selectedFiles = [];
|
||
checkboxes.forEach(cb => {
|
||
const index = parseInt(cb.dataset.index);
|
||
selectedFiles.push(boxFilesData[index]);
|
||
});
|
||
|
||
// Show progress container
|
||
document.getElementById('upload-progress-container').style.display = 'block';
|
||
document.getElementById('upload-results-container').style.display = 'none';
|
||
document.getElementById('upload-progress-list').innerHTML = '';
|
||
|
||
// Disable upload button
|
||
document.getElementById('upload-selected-btn').disabled = true;
|
||
|
||
// Upload files sequentially
|
||
uploadFilesSequentially(selectedFiles, 0, []);
|
||
}
|
||
|
||
function uploadFilesSequentially(files, index, results) {
|
||
if (index >= files.length) {
|
||
// All files processed - show results
|
||
showUploadResults(results);
|
||
return;
|
||
}
|
||
|
||
const file = files[index];
|
||
const progressList = document.getElementById('upload-progress-list');
|
||
|
||
// Add progress item
|
||
const progressItem = document.createElement('div');
|
||
progressItem.id = `progress-${index}`;
|
||
progressItem.style.padding = '10px';
|
||
progressItem.style.marginBottom = '5px';
|
||
progressItem.style.background = '#fff3cd';
|
||
progressItem.style.borderRadius = '4px';
|
||
progressItem.style.border = '1px solid #ffc107';
|
||
progressItem.innerHTML = `
|
||
<strong>${index + 1}/${files.length}:</strong> ${escapeHtml(file.name)}<br>
|
||
<small>⏳ Uploading to DAM...</small>
|
||
`;
|
||
progressList.appendChild(progressItem);
|
||
|
||
// Upload this file
|
||
fetch('workflow_v3.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded',
|
||
'X-Requested-With': 'XMLHttpRequest'
|
||
},
|
||
body: `action=upload_from_box&file_id=${encodeURIComponent(file.id)}&filename=${encodeURIComponent(file.name)}&tracking_id=${encodeURIComponent(file.tracking_id)}`
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
progressItem.style.background = '#d4edda';
|
||
progressItem.style.border = '1px solid #28a745';
|
||
progressItem.innerHTML = `
|
||
<strong>${index + 1}/${files.length}:</strong> ${escapeHtml(file.name)}<br>
|
||
<small style="color: #28a745;">✅ Uploaded as: ${escapeHtml(data.clean_filename)}</small><br>
|
||
<small style="color: #666;">Asset ID: ${data.asset_id} | Folder: ${data.upload_folder}</small><br>
|
||
<small><a href="debug_assets.php?action=get_assets&folder_id=${data.upload_folder}" target="_blank" style="color: #007bff;">
|
||
🔍 View in Final Assets Folder
|
||
</a></small>
|
||
`;
|
||
|
||
results.push({
|
||
filename: file.name,
|
||
success: true,
|
||
asset_id: data.asset_id,
|
||
clean_filename: data.clean_filename,
|
||
upload_folder: data.upload_folder,
|
||
master_asset_id: data.master_asset_id,
|
||
asset_representation: data.asset_representation
|
||
});
|
||
} else {
|
||
progressItem.style.background = '#f8d7da';
|
||
progressItem.style.border = '1px solid #dc3545';
|
||
progressItem.innerHTML = `
|
||
<strong>${index + 1}/${files.length}:</strong> ${escapeHtml(file.name)}<br>
|
||
<small style="color: #dc3545;">❌ Error: ${escapeHtml(data.error)}</small>
|
||
`;
|
||
|
||
results.push({
|
||
filename: file.name,
|
||
success: false,
|
||
error: data.error
|
||
});
|
||
}
|
||
|
||
// Upload next file
|
||
setTimeout(() => uploadFilesSequentially(files, index + 1, results), 500);
|
||
})
|
||
.catch(error => {
|
||
progressItem.style.background = '#f8d7da';
|
||
progressItem.style.border = '1px solid #dc3545';
|
||
progressItem.innerHTML = `
|
||
<strong>${index + 1}/${files.length}:</strong> ${escapeHtml(file.name)}<br>
|
||
<small style="color: #dc3545;">❌ Error: ${escapeHtml(error.message)}</small>
|
||
`;
|
||
|
||
results.push({
|
||
filename: file.name,
|
||
success: false,
|
||
error: error.message
|
||
});
|
||
|
||
// Continue with next file
|
||
setTimeout(() => uploadFilesSequentially(files, index + 1, results), 500);
|
||
});
|
||
}
|
||
|
||
function showUploadResults(results) {
|
||
// Store results globally for download/view functions
|
||
uploadResults = results;
|
||
|
||
const successCount = results.filter(r => r.success).length;
|
||
const failCount = results.length - successCount;
|
||
|
||
// Show results container
|
||
document.getElementById('upload-results-container').style.display = 'block';
|
||
|
||
const summaryDiv = document.getElementById('upload-results-summary');
|
||
summaryDiv.className = successCount === results.length ? 'alert alert-success' : 'alert alert-warning';
|
||
summaryDiv.innerHTML = `
|
||
<strong>Upload Complete!</strong><br>
|
||
✅ ${successCount} succeeded | ❌ ${failCount} failed | Total: ${results.length}
|
||
`;
|
||
|
||
// Show details
|
||
const detailsDiv = document.getElementById('upload-results-details');
|
||
detailsDiv.innerHTML = '';
|
||
|
||
if (successCount > 0) {
|
||
const successDiv = document.createElement('div');
|
||
successDiv.style.marginTop = '15px';
|
||
successDiv.innerHTML = '<h4 style="color: #28a745;">✅ Successful Uploads:</h4>';
|
||
|
||
results.filter(r => r.success).forEach((result, idx) => {
|
||
const item = document.createElement('div');
|
||
item.style.padding = '10px';
|
||
item.style.marginTop = '5px';
|
||
item.style.background = '#d4edda';
|
||
item.style.borderRadius = '4px';
|
||
item.style.border = '1px solid #28a745';
|
||
item.innerHTML = `
|
||
<strong>${escapeHtml(result.filename)}</strong><br>
|
||
<small>Clean filename: ${escapeHtml(result.clean_filename)}</small><br>
|
||
<small>Asset ID: ${result.asset_id}</small><br>
|
||
<button onclick="downloadAssetRepresentation(${idx})" class="btn btn-secondary" style="font-size: 11px; padding: 4px 8px; margin-top: 8px;">
|
||
💾 Download Asset Representation JSON
|
||
</button>
|
||
<button onclick="viewAssetRepresentation(${idx})" class="btn btn-secondary" style="font-size: 11px; padding: 4px 8px; margin-top: 8px; margin-left: 5px;">
|
||
👁️ View JSON
|
||
</button>
|
||
`;
|
||
successDiv.appendChild(item);
|
||
});
|
||
|
||
detailsDiv.appendChild(successDiv);
|
||
}
|
||
|
||
if (failCount > 0) {
|
||
const failDiv = document.createElement('div');
|
||
failDiv.style.marginTop = '15px';
|
||
failDiv.innerHTML = '<h4 style="color: #dc3545;">❌ Failed Uploads:</h4>';
|
||
|
||
results.filter(r => !r.success).forEach(result => {
|
||
const item = document.createElement('div');
|
||
item.style.padding = '10px';
|
||
item.style.marginTop = '5px';
|
||
item.style.background = '#f8d7da';
|
||
item.style.borderRadius = '4px';
|
||
item.style.border = '1px solid #dc3545';
|
||
item.innerHTML = `
|
||
<strong>${escapeHtml(result.filename)}</strong><br>
|
||
<small style="color: #dc3545;">Error: ${escapeHtml(result.error)}</small>
|
||
`;
|
||
failDiv.appendChild(item);
|
||
});
|
||
|
||
detailsDiv.appendChild(failDiv);
|
||
}
|
||
|
||
// Re-enable upload button
|
||
document.getElementById('upload-selected-btn').disabled = false;
|
||
}
|
||
|
||
function clearBoxFiles() {
|
||
boxFilesData = [];
|
||
document.getElementById('box-files-list').innerHTML = '';
|
||
document.getElementById('box-files-container').style.display = 'none';
|
||
document.getElementById('upload-progress-container').style.display = 'none';
|
||
document.getElementById('upload-results-container').style.display = 'none';
|
||
document.getElementById('box-folder-id').value = '';
|
||
}
|
||
|
||
function showBoxError(message) {
|
||
const errorDiv = document.getElementById('box-error');
|
||
errorDiv.textContent = message;
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
|
||
function escapeHtml(text) {
|
||
const div = document.createElement('div');
|
||
div.textContent = text;
|
||
return div.innerHTML;
|
||
}
|
||
|
||
function formatFileSize(bytes) {
|
||
if (bytes < 1024) return bytes + ' B';
|
||
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
||
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
||
}
|
||
|
||
function downloadAssetRepresentation(index) {
|
||
const successResults = uploadResults.filter(r => r.success);
|
||
if (!successResults[index] || !successResults[index].asset_representation) {
|
||
alert('Asset representation not available');
|
||
return;
|
||
}
|
||
|
||
const result = successResults[index];
|
||
const json = JSON.stringify(result.asset_representation, null, 2);
|
||
const blob = new Blob([json], { type: 'application/json' });
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `asset_representation_${result.asset_id}.json`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a);
|
||
URL.revokeObjectURL(url);
|
||
}
|
||
|
||
function viewAssetRepresentation(index) {
|
||
const successResults = uploadResults.filter(r => r.success);
|
||
if (!successResults[index] || !successResults[index].asset_representation) {
|
||
alert('Asset representation not available');
|
||
return;
|
||
}
|
||
|
||
const result = successResults[index];
|
||
const json = JSON.stringify(result.asset_representation, null, 2);
|
||
|
||
// Create modal to show JSON
|
||
const modal = document.createElement('div');
|
||
modal.style.cssText = 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.8); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 20px;';
|
||
modal.innerHTML = `
|
||
<div style="background: white; border-radius: 8px; max-width: 900px; max-height: 90vh; overflow: hidden; display: flex; flex-direction: column;">
|
||
<div style="padding: 20px; border-bottom: 1px solid #ddd; display: flex; justify-content: space-between; align-items: center;">
|
||
<h3 style="margin: 0;">Asset Representation JSON - Asset ${result.asset_id}</h3>
|
||
<button onclick="this.closest('div').parentElement.parentElement.remove()" class="btn btn-secondary">Close</button>
|
||
</div>
|
||
<div style="padding: 20px; overflow: auto;">
|
||
<pre style="background: #f8f9fa; padding: 15px; border-radius: 6px; font-size: 12px; margin: 0;">${escapeHtml(json)}</pre>
|
||
</div>
|
||
</div>
|
||
`;
|
||
document.body.appendChild(modal);
|
||
modal.onclick = function(e) {
|
||
if (e.target === modal) modal.remove();
|
||
};
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|