ferrero-opentext/workflow_v3.php

1037 lines
43 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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';
$configV3 = new ConfigV3();
$errors = $configV3->validate();
if (!empty($errors)) {
die("Configuration Error: " . implode(', ', $errors));
}
$config = [
'baseUrl' => $configV3->getBaseUrl(),
'timeout' => $configV3->get('api.timeout'),
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json'
]
];
$collectionPath = __DIR__ . '/' . $configV3->get('postman_collection');
$testRunner = null;
$error = null;
$success = null;
$currentTab = $_GET['tab'] ?? $_POST['tab'] ?? 'download';
try {
if (file_exists($collectionPath)) {
$testRunner = new TestRunner($collectionPath, $config);
} else {
$error = "Postman collection file not found: " . $collectionPath;
}
} catch (Exception $e) {
$error = "Error initializing: " . $e->getMessage();
}
// Initialize results storage
if (!isset($_SESSION['workflow_results'])) {
$_SESSION['workflow_results'] = [];
}
$results = &$_SESSION['workflow_results'];
// Handle POST actions
if ($_POST && $testRunner) {
$action = $_POST['action'] ?? '';
try {
switch ($action) {
case 'load_campaigns_a1':
$results['a1_campaigns'] = loadCampaignsByStatus($testRunner, 'A1');
$success = "Loaded " . count($results['a1_campaigns']) . " campaigns with status A1";
break;
case 'select_campaign_a1':
$campaignId = $_POST['campaign_id'] ?? '';
if ($campaignId && isset($results['a1_campaigns'])) {
foreach ($results['a1_campaigns'] as $campaign) {
if ($campaign['asset_id'] === $campaignId) {
$results['selected_campaign'] = $campaign;
$success = "Campaign selected: " . $campaign['campaign_name'];
break;
}
}
}
break;
case 'get_master_assets':
if (isset($results['selected_campaign'])) {
$campaignId = $results['selected_campaign']['asset_id'];
$masterFolderId = findMasterAssetsFolder($testRunner, $campaignId, $configV3);
if ($masterFolderId) {
$results['master_folder_id'] = $masterFolderId;
$results['master_assets'] = getAssetsFromFolder($testRunner, $masterFolderId);
$success = "Found Master Assets folder with " . count($results['master_assets']) . " assets";
} else {
$error = "Master Assets folder not found in campaign";
}
}
break;
case 'download_asset':
$assetId = $_POST['asset_id'] ?? '';
$filename = $_POST['filename'] ?? '';
if ($assetId && isset($results['selected_campaign'])) {
$result = downloadAsset($testRunner, $assetId, $filename, $results['selected_campaign']['campaign_id']);
$results['last_download'] = $result;
if ($result['success']) {
$success = "Downloaded: " . $result['filename'];
} else {
$error = "Download failed: " . $result['error'];
}
}
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;
$success = "Downloaded {$downloadResults['successful']} of {$downloadResults['total']} assets";
}
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 {
$error = "Failed to update status: " . ($statusResult['response']['error'] ?? 'Unknown error');
}
}
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 'load_campaigns_a5':
$results['a5_campaigns'] = loadCampaignsByStatus($testRunner, 'A5');
$success = "Loaded " . count($results['a5_campaigns']) . " campaigns with status A5";
$currentTab = 'rework';
break;
}
} catch (Exception $e) {
$error = "Action failed: " . $e->getMessage();
}
}
// Helper Functions
function loadCampaignsByStatus($testRunner, $status)
{
$statusManager = createStatusManager($testRunner);
$response = $statusManager->searchCampaignsByStatus($status);
if ($response['success']) {
$data = json_decode($response['body'], true);
return CampaignFormatter::getActionableCampaigns($response['body'], ['status' => $status]);
}
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)
{
$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());
}
// First, get asset metadata to find the rendition URL
$metadataRequest = [
'method' => 'GET',
'url' => "/v6/assets/{$assetId}?load_type=metadata"
];
$metadataResponse = $apiClient->executeRequest($metadataRequest);
$renditionUrl = null;
if ($metadataResponse['success']) {
$assetData = json_decode($metadataResponse['body'], true);
// Look for rendition URL in multiple possible locations
$asset = $assetData['asset'] ?? $assetData;
// Check asset_content_info.master_content.url
if (isset($asset['asset_content_info']['master_content']['url'])) {
$renditionUrl = $asset['asset_content_info']['master_content']['url'];
}
// Check asset_content_info array (first element)
elseif (isset($asset['asset_content_info'][0]['url'])) {
$renditionUrl = $asset['asset_content_info'][0]['url'];
}
// Check if asset_content_info is directly a content object
elseif (isset($asset['asset_content_info']['url'])) {
$renditionUrl = $asset['asset_content_info']['url'];
}
}
// Try direct download if no rendition URL found
if (!$renditionUrl) {
$renditionUrl = "/v6/assets/{$assetId}/contents";
}
$request = [
'method' => 'GET',
'url' => $renditionUrl
];
$response = $apiClient->executeRequest($request);
if ($response['success'] && !empty($response['body'])) {
// Check if response is an error JSON
$jsonCheck = json_decode($response['body'], true);
if ($jsonCheck && isset($jsonCheck['exception_body'])) {
return [
'success' => false,
'error' => $jsonCheck['exception_body']['message'] ?? 'File not found in storage',
'http_code' => $jsonCheck['exception_body']['http_response_code'] ?? 500,
'debug_message' => $jsonCheck['exception_body']['debug_message'] ?? '',
'tried_url' => $renditionUrl
];
}
$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);
}
$oauth2Status = $testRunner ? $testRunner->getOAuth2Status() : null;
$envInfo = $configV3->getEnvironmentInfo();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Content Scaling Workflow V3</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 { margin-bottom: 10px; }
.header p { opacity: 0.9; }
.env-info {
background: rgba(255,255,255,0.2);
padding: 10px;
border-radius: 4px;
margin-top: 15px;
font-size: 13px;
}
.tabs {
display: flex;
background: #f8f9fa;
border-bottom: 2px solid #dee2e6;
}
.tab {
flex: 1;
padding: 15px 20px;
text-align: center;
cursor: pointer;
border: none;
background: transparent;
font-size: 16px;
font-weight: 500;
color: #6c757d;
transition: all 0.3s;
}
.tab:hover { background: #e9ecef; }
.tab.active {
background: white;
color: #667eea;
border-bottom: 3px solid #667eea;
}
.tab-content {
padding: 30px;
display: none;
}
.tab-content.active { display: block; }
.alert {
padding: 12px 20px;
border-radius: 6px;
margin-bottom: 20px;
}
.alert-error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s;
margin-right: 10px;
margin-bottom: 10px;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover { background: #5568d3; }
.btn-success {
background: #28a745;
color: white;
}
.btn-success:hover { background: #218838; }
.btn-danger {
background: #dc3545;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.campaign-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;
margin: 20px 0;
}
.campaign-card {
background: #f8f9fa;
border: 2px solid #dee2e6;
border-radius: 8px;
padding: 20px;
cursor: pointer;
transition: all 0.3s;
}
.campaign-card:hover {
border-color: #667eea;
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}
.campaign-card.selected {
border-color: #28a745;
background: #f8fff9;
}
.campaign-card h3 {
color: #333;
margin-bottom: 10px;
}
.campaign-card p {
margin: 5px 0;
font-size: 14px;
color: #666;
}
.asset-list {
background: #f8f9fa;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
}
.asset-item {
background: white;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 15px;
margin: 10px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.asset-info {
flex: 1;
}
.asset-actions {
display: flex;
gap: 10px;
}
.metadata-display {
background: #e9ecef;
padding: 15px;
border-radius: 6px;
margin-top: 10px;
font-size: 12px;
font-family: monospace;
max-height: 300px;
overflow-y: auto;
display: none;
}
.status-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 600;
}
.status-a1 { background: #fff3cd; color: #856404; }
.status-a2 { background: #cfe2ff; color: #084298; }
.status-a3 { background: #d1e7dd; color: #0f5132; }
.status-a5 { background: #f8d7da; color: #842029; }
.status-a6 { background: #e2d9f3; color: #432874; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🎯 Content Scaling Workflow V3</h1>
<p>Status-based workflow management for Ferrero DAM</p>
<div class="env-info">
<strong>Environment:</strong> <?= htmlspecialchars($envInfo['description']) ?>
(<?= htmlspecialchars($envInfo['name']) ?>)
<br>
<strong>Base URL:</strong> <?= htmlspecialchars($envInfo['baseUrl']) ?>
</div>
</div>
<?php if ($error): ?>
<div style="padding: 20px;">
<div class="alert alert-error">
<strong>❌ Error:</strong> <?= htmlspecialchars($error) ?>
</div>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div style="padding: 20px;">
<div class="alert alert-success">
<strong>✅ Success:</strong> <?= htmlspecialchars($success) ?>
</div>
</div>
<?php endif; ?>
<?php if ($oauth2Status && $oauth2Status['enabled']): ?>
<div style="padding: 20px; padding-bottom: 0;">
<div class="alert alert-<?= ($oauth2Status['has_token'] ?? false) ? 'success' : 'error' ?>">
<?= ($oauth2Status['has_token'] ?? false) ? '✅ OAuth2 Token Active' : '❌ OAuth2 Token Issue' ?>
<?php if (($oauth2Status['has_token'] ?? false) && isset($oauth2Status['expires_at'])): ?>
- Expires: <?= htmlspecialchars($oauth2Status['expires_at']) ?>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<div class="tabs">
<button class="tab <?= $currentTab === 'download' ? 'active' : '' ?>"
onclick="switchTab('download')">
📥 Download Workflow (A1→A2)
</button>
<button class="tab <?= $currentTab === 'upload' ? 'active' : '' ?>"
onclick="switchTab('upload')">
📤 Upload Workflow (A2→A3)
</button>
<button class="tab <?= $currentTab === 'rework' ? 'active' : '' ?>"
onclick="switchTab('rework')">
🔄 Rework Workflow (A5→A6)
</button>
</div>
<!-- Download Workflow Tab -->
<div id="tab-download" class="tab-content <?= $currentTab === 'download' ? 'active' : '' ?>">
<h2>📥 Download Workflow: A1 → A2</h2>
<p style="color: #666; margin: 10px 0 20px 0;">
Load campaigns with status A1, download master assets, and update status to A2
</p>
<form method="POST" style="display: inline-block;">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="load_campaigns_a1">
<button type="submit" class="btn btn-primary">Load Campaigns with Status A1</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['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><span class="status-badge status-a1">A1 - Ready for Localization</span></p>
</div>
<?php endforeach; ?>
</div>
<form method="POST" id="select-campaign-form">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="select_campaign_a1">
<input type="hidden" name="campaign_id" id="selected-campaign-id">
<button type="submit" class="btn btn-success" id="select-campaign-btn" disabled>
Select Campaign & Continue
</button>
</form>
<?php endif; ?>
<?php if (isset($results['selected_campaign'])): ?>
<div class="alert alert-info" style="margin-top: 30px;">
<strong>Selected Campaign:</strong>
<?= htmlspecialchars($results['selected_campaign']['campaign_name']) ?>
(<?= htmlspecialchars($results['selected_campaign']['campaign_id']) ?>)
<br>
<small><strong>Asset ID:</strong> <code><?= htmlspecialchars($results['selected_campaign']['asset_id']) ?></code></small>
<br>
<a href="debug_assets.php?action=get_folders&campaign_id=<?= urlencode($results['selected_campaign']['asset_id']) ?>"
target="_blank" style="color: #667eea; font-size: 12px;">
🔍 Debug folder structure for this campaign
</a>
</div>
<form method="POST" style="margin-top: 20px;">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="get_master_assets">
<button type="submit" class="btn btn-primary">Get Master Assets</button>
</form>
<?php endif; ?>
<?php if (isset($results['master_assets']) && !empty($results['master_assets'])): ?>
<h3 style="margin-top: 30px;">Master Assets (<?= count($results['master_assets']) ?> files)</h3>
<form method="POST" style="margin: 20px 0;">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="download_all_assets">
<button type="submit" class="btn btn-success">📥 Download All Assets</button>
</form>
<div class="asset-list">
<?php foreach ($results['master_assets'] as $index => $asset): ?>
<?php
$assetName = extractFolderName($asset);
$assetId = $asset['asset_id'];
$metadataId = 'metadata-' . $index; // Use index instead of asset_id for simpler ID
?>
<div class="asset-item">
<div class="asset-info">
<strong><?= htmlspecialchars($assetName) ?></strong><br>
<small>ID: <?= htmlspecialchars($assetId) ?></small><br>
<small>Type: <?= htmlspecialchars($asset['mime_type'] ?? 'Unknown') ?></small>
<?php if (isset($asset['file_size'])): ?>
<small> | Size: <?= number_format($asset['file_size']) ?> bytes</small>
<?php endif; ?>
</div>
<div class="asset-actions">
<form method="POST" style="display: inline;">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="download_asset">
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($assetId) ?>">
<input type="hidden" name="filename" value="<?= htmlspecialchars($assetName) ?>">
<button type="submit" class="btn btn-success">📥 Download</button>
</form>
<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;">
<!-- Basic Info -->
<?php if (isset($metadata['basic'])): ?>
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #667eea;">
<strong>📋 Basic Info:</strong><br>
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
<?php foreach ($metadata['basic'] as $key => $value): ?>
<?php if ($value !== null): ?>
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
<div><strong><?= htmlspecialchars($value) ?></strong></div>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Content Info -->
<?php if (isset($metadata['content'])): ?>
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #28a745;">
<strong>🖼️ Content Info:</strong><br>
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
<?php foreach ($metadata['content'] as $key => $value): ?>
<?php if ($value !== null && $value !== -1): ?>
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
<div><strong><?= is_string($value) ? htmlspecialchars($value) : $value ?></strong></div>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- Custom Fields by Category -->
<?php if (isset($metadata['custom_fields'])): ?>
<?php foreach ($metadata['custom_fields'] as $category => $fields): ?>
<?php if (!empty($fields)): ?>
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #ffc107;">
<summary style="cursor: pointer; font-weight: 600; color: #333;">
📁 <?= htmlspecialchars($category) ?> (<?= count($fields) ?> fields)
</summary>
<div style="margin-top: 8px; display: grid; grid-template-columns: 200px 1fr; gap: 5px;">
<?php foreach ($fields as $fieldName => $fieldData): ?>
<div style="color: #666; padding-top: 4px;"><?= htmlspecialchars($fieldName) ?>:</div>
<div style="padding-top: 4px;">
<strong>
<?php
if (is_array($fieldData['value'])) {
echo htmlspecialchars(implode(', ', $fieldData['value']));
} else {
echo htmlspecialchars($fieldData['value']);
}
?>
</strong>
</div>
<?php endforeach; ?>
</div>
</details>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
<!-- Permissions -->
<?php if (isset($metadata['permissions'])): ?>
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #dc3545;">
<summary style="cursor: pointer; font-weight: 600; color: #333;">🔐 Permissions</summary>
<div style="margin-top: 8px; columns: 2;">
<?php foreach ($metadata['permissions'] as $perm => $value): ?>
<div style="padding: 2px 0;">
<?= $value ? '✅' : '❌' ?> <?= htmlspecialchars(preg_replace('/Permission$/', '', $perm)) ?>
</div>
<?php endforeach; ?>
</div>
</details>
<?php endif; ?>
<!-- Renditions -->
<?php if (isset($metadata['renditions'])): ?>
<details style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #17a2b8;">
<summary style="cursor: pointer; font-weight: 600; color: #333;">🎨 Renditions (<?= count($metadata['renditions']) ?>)</summary>
<div style="margin-top: 8px;">
<?php foreach ($metadata['renditions'] as $rendName => $rendData): ?>
<div style="background: #f8f9fa; padding: 8px; margin: 4px 0; border-radius: 3px;">
<strong><?= htmlspecialchars($rendName) ?></strong><br>
<small>Size: <?= number_format($rendData['content_size'] ?? 0) ?> bytes |
<?= $rendData['width'] ?? 0 ?>x<?= $rendData['height'] ?? 0 ?>px |
<?= htmlspecialchars($rendData['mime_type'] ?? 'N/A') ?></small>
</div>
<?php endforeach; ?>
</div>
</details>
<?php endif; ?>
</div>
<?php else: ?>
<p>No metadata available for this asset</p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<div style="margin-top: 30px; padding: 20px; background: #fff3cd; border-radius: 8px;">
<h4>⚠️ Update Status to A2</h4>
<p style="margin: 10px 0;">
Once all assets are downloaded (or attempted), update the campaign status to A2
(Selected Master Assets sent to Agency)
</p>
<p style="margin: 10px 0; font-size: 13px; color: #856404;">
<strong>Note:</strong> If files don't exist in storage (test environment), you can still
update the status to test the workflow progression.
</p>
<form method="POST">
<input type="hidden" name="tab" value="download">
<input type="hidden" name="action" value="update_status_to_a2">
<button type="submit" class="btn btn-success">Update Status: A1 → A2</button>
</form>
</div>
<?php endif; ?>
<?php if (isset($results['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 endif; ?>
</div>
<?php endif; ?>
<?php if (isset($results['bulk_download'])): ?>
<div class="alert alert-<?= $results['bulk_download']['successful'] === $results['bulk_download']['total'] ? 'success' : 'error' ?>"
style="margin-top: 20px;">
<strong>Bulk Download Results:</strong>
<?= $results['bulk_download']['successful'] ?> of <?= $results['bulk_download']['total'] ?> assets downloaded successfully
<?php if ($results['bulk_download']['failed'] > 0): ?>
<br><small><?= $results['bulk_download']['failed'] ?> files failed (may not exist in storage)</small>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<!-- Upload Workflow Tab -->
<div id="tab-upload" class="tab-content <?= $currentTab === 'upload' ? 'active' : '' ?>">
<h2>📤 Upload Workflow: A2 → A3</h2>
<p style="color: #666; margin: 10px 0 20px 0;">
Load campaigns with status A2, upload processed assets, and update status to A3
</p>
<form method="POST">
<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 with Status A2</button>
</form>
<div class="alert alert-info" style="margin-top: 20px;">
<strong> Coming Soon:</strong> Upload functionality will be implemented in next phase
</div>
</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">
<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 with Status A5</button>
</form>
<div class="alert alert-info" style="margin-top: 20px;">
<strong> Coming Soon:</strong> Rework workflow will be implemented in next phase
</div>
</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';
}
}
</script>
</body>
</html>