Complete workflow V3: Add Upload (A2→A3) and Rework (A5→A6) workflows

NEW: Upload Workflow (A2→A3)
- Load campaigns with status A2 (assets sent to agency)
- Select campaign and find upload target folder (Final Assets)
- Multi-file upload with drag-drop interface
- AssetUploader class with multipart/form-data support
- Upload files with metadata to DAM
- Update status to A3 after upload

NEW: Rework Workflow (A5→A6)
- Load campaigns with status A5 (rework needed from agency)
- Select campaign and get rework assets
- Download individual or bulk rework assets
- Beautiful metadata display
- Update status to A6 when rework assets received

Features:
- Three complete workflow tabs (Download, Upload, Rework)
- Status transitions: A1→A2, A2→A3, A5→A6
- Session-based workflow state management
- Clear workflow data button for each tab
- Campaign selection with visual feedback
- Download confirmed working (tested with real asset)
- OAuth2 auto-refresh throughout all workflows

Technical:
- AssetUploader class for multipart file uploads
- Proper metadata JSON structure for uploads
- Support for multiple file formats (JPG, PNG, PDF, AI, PSD, etc.)
- Error handling for each workflow step
- Beautiful UI with color-coded status badges

Ready for testing with real campaign data!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DJP 2025-10-17 16:43:26 -04:00
parent b8512bc8da
commit cf71bcfd96
2 changed files with 709 additions and 9 deletions

172
src/AssetUploader.php Normal file
View file

@ -0,0 +1,172 @@
<?php
require_once 'ApiClient.php';
/**
* AssetUploader - Handles file uploads to Ferrero DAM
*/
class AssetUploader
{
private $apiClient;
private $targetFolderId;
public function __construct(ApiClient $apiClient, $targetFolderId = null)
{
$this->apiClient = $apiClient;
$this->targetFolderId = $targetFolderId;
}
/**
* Upload a file to DAM with metadata
*
* @param string $filePath Local file path
* @param string $folderId Target folder ID (campaign folder)
* @param array $metadata Optional metadata to set
* @return array Upload result
*/
public function uploadFile($filePath, $folderId, $metadata = [])
{
if (!file_exists($filePath)) {
return [
'success' => false,
'error' => 'File not found: ' . $filePath
];
}
$filename = basename($filePath);
$mimeType = mime_content_type($filePath);
// Build multipart form data
$boundary = '----WebKitFormBoundary' . uniqid();
// Build asset representation JSON
$assetRepresentation = $this->buildAssetRepresentation($filename, $metadata);
// Build multipart body
$body = '';
// Add asset_representation part
$body .= "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"asset_representation\"\r\n";
$body .= "Content-Type: application/json\r\n\r\n";
$body .= json_encode($assetRepresentation) . "\r\n";
// Add parent_folder_id part
$body .= "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"parent_folder_id\"\r\n\r\n";
$body .= $folderId . "\r\n";
// Add file part
$body .= "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$filename}\"\r\n";
$body .= "Content-Type: {$mimeType}\r\n\r\n";
$body .= file_get_contents($filePath) . "\r\n";
$body .= "--{$boundary}--\r\n";
// Make upload request
$request = [
'method' => 'POST',
'url' => '/v6/assets',
'body' => $body
];
// Set multipart content-type header
$this->apiClient->setHeader('Content-Type', "multipart/form-data; boundary={$boundary}");
$response = $this->apiClient->executeRequest($request);
if ($response['success'] && $response['http_code'] == 201) {
$responseData = json_decode($response['body'], true);
return [
'success' => true,
'asset_id' => $responseData['asset_resource_list']['asset_resource'][0]['asset']['asset_id'] ?? null,
'filename' => $filename,
'response' => $responseData
];
}
return [
'success' => false,
'error' => 'Upload failed',
'http_code' => $response['http_code'],
'response' => $response['body']
];
}
/**
* Build asset representation for upload
*/
private function buildAssetRepresentation($filename, $metadata = [])
{
$assetRep = [
'asset_resource' => [
'asset' => [
'metadata' => [
'metadata_element_list' => []
]
]
]
];
// Add filename metadata
$assetRep['asset_resource']['asset']['metadata']['metadata_element_list'][] = [
'id' => 'ARTESIA.FIELD.ASSET NAME',
'type' => 'com.artesia.metadata.MetadataField',
'value' => [
'cascading_domain_value' => false,
'domain_value' => false,
'value' => [
'type' => 'string',
'value' => $filename
]
]
];
// Add custom metadata fields
foreach ($metadata as $fieldId => $fieldValue) {
$assetRep['asset_resource']['asset']['metadata']['metadata_element_list'][] = [
'id' => $fieldId,
'type' => 'com.artesia.metadata.MetadataField',
'value' => [
'cascading_domain_value' => false,
'domain_value' => false,
'value' => [
'type' => 'string',
'value' => $fieldValue
]
]
];
}
return $assetRep;
}
/**
* Upload multiple files
*/
public function uploadMultipleFiles($files, $folderId, $metadata = [])
{
$results = [
'total' => count($files),
'successful' => 0,
'failed' => 0,
'details' => []
];
foreach ($files as $file) {
$result = $this->uploadFile($file, $folderId, $metadata);
if ($result['success']) {
$results['successful']++;
} else {
$results['failed']++;
}
$results['details'][] = $result;
}
return $results;
}
}

View file

@ -24,6 +24,7 @@ require_once 'src/AssetDownloader.php';
require_once 'src/MetadataExtractor.php';
require_once 'src/StatusManager.php';
require_once 'src/ApiClient.php';
require_once 'src/AssetUploader.php';
$configV3 = new ConfigV3();
$errors = $configV3->validate();
@ -163,11 +164,158 @@ if ($_POST && $testRunner) {
$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
$uploadFolderId = findUploadFolder($testRunner, $campaignId, $configV3);
if ($uploadFolderId) {
$results['upload_folder_id'] = $uploadFolderId;
$success = "Found upload target folder";
} else {
$error = "Upload folder not found in campaign";
}
}
$currentTab = 'upload';
break;
case 'upload_files':
if (isset($_FILES['upload_files']) && isset($results['upload_folder_id'])) {
$uploadResults = uploadFiles($testRunner, $_FILES['upload_files'], $results['upload_folder_id']);
$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 {
$error = "Failed to update status";
}
}
$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;
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 {
$error = "Failed to update status";
}
}
$currentTab = 'rework';
break;
}
} catch (Exception $e) {
$error = "Action failed: " . $e->getMessage();
@ -509,6 +657,108 @@ function createStatusManager($testRunner)
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 uploadFiles($testRunner, $uploadedFiles, $folderId)
{
$apiClient = new ApiClient();
$configV3 = new ConfigV3();
$apiClient->setBaseUrl($configV3->getBaseUrl());
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
$oauth2Handler->setAccessible(true);
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
if ($oauth2HandlerInstance) {
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
}
$uploader = new AssetUploader($apiClient, $folderId);
$results = [
'total' => 0,
'successful' => 0,
'failed' => 0,
'details' => []
];
// Handle multiple file upload
if (isset($uploadedFiles['tmp_name'])) {
$fileCount = is_array($uploadedFiles['tmp_name']) ? count($uploadedFiles['tmp_name']) : 1;
$results['total'] = $fileCount;
for ($i = 0; $i < $fileCount; $i++) {
$tmpName = is_array($uploadedFiles['tmp_name']) ? $uploadedFiles['tmp_name'][$i] : $uploadedFiles['tmp_name'];
$fileName = is_array($uploadedFiles['name']) ? $uploadedFiles['name'][$i] : $uploadedFiles['name'];
$fileError = is_array($uploadedFiles['error']) ? $uploadedFiles['error'][$i] : $uploadedFiles['error'];
if ($fileError !== UPLOAD_ERR_OK) {
$results['details'][] = [
'success' => false,
'filename' => $fileName,
'error' => 'Upload error code: ' . $fileError
];
$results['failed']++;
continue;
}
$result = $uploader->uploadFile($tmpName, $folderId);
if ($result['success']) {
$results['successful']++;
} else {
$results['failed']++;
}
$results['details'][] = $result;
}
}
return $results;
}
$oauth2Status = $testRunner ? $testRunner->getOAuth2Status() : null;
$envInfo = $configV3->getEnvironmentInfo();
?>
@ -1076,18 +1326,132 @@ $envInfo = $configV3->getEnvironmentInfo();
<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
Load campaigns with status A2 (assets sent to agency), upload processed files, and update status to A3
</p>
<form method="POST">
<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 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>
<?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><span class="status-badge status-a2">A2 - Assets Sent to Agency</span></p>
</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 (Final Assets)</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>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="tab" value="upload">
<input type="hidden" name="action" value="upload_files">
<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"
style="padding: 10px; border: 2px dashed #667eea; border-radius: 6px; width: 100%; background: white;">
<p style="font-size: 13px; color: #666; margin-top: 10px;">
Accepted formats: JPG, PNG, GIF, PDF, AI, PSD, EPS, TIFF
</p>
</div>
<button type="submit" class="btn btn-success">📤 Upload Files to DAM</button>
</form>
<?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>Error: <?= htmlspecialchars($detail['error']) ?></small>
<?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 -->
@ -1097,15 +1461,159 @@ $envInfo = $configV3->getEnvironmentInfo();
Load campaigns with status A5 (rework needed), download assets for rework, and update status to A6
</p>
<form method="POST">
<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 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>
<?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['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><span class="status-badge status-a5">A5 - Rework Needed</span></p>
</div>
<?php endforeach; ?>
</div>
<form method="POST" id="select-campaign-a5-form">
<input type="hidden" name="tab" value="rework">
<input type="hidden" name="action" value="select_campaign_a5">
<input type="hidden" name="campaign_id" id="selected-campaign-a5-id">
<button type="submit" class="btn btn-success" id="select-campaign-a5-btn" disabled>
Select Campaign & Continue
</button>
</form>
<?php endif; ?>
<?php if (isset($results['selected_campaign_a5'])): ?>
<div class="alert alert-info" style="margin-top: 30px;">
<strong>Selected Campaign:</strong>
<?= htmlspecialchars($results['selected_campaign_a5']['campaign_name']) ?>
(<?= htmlspecialchars($results['selected_campaign_a5']['campaign_id']) ?>)
</div>
<form method="POST" style="margin-top: 20px;">
<input type="hidden" name="tab" value="rework">
<input type="hidden" name="action" value="get_rework_assets">
<button type="submit" class="btn btn-primary">Get Rework Assets</button>
</form>
<?php endif; ?>
<?php if (isset($results['rework_assets']) && !empty($results['rework_assets'])): ?>
<h3 style="margin-top: 30px;">Rework Assets (<?= count($results['rework_assets']) ?> files)</h3>
<form method="POST" style="margin: 20px 0;">
<input type="hidden" name="tab" value="rework">
<input type="hidden" name="action" value="download_all_rework">
<button type="submit" class="btn btn-success">📥 Download All Rework Assets</button>
</form>
<div class="asset-list">
<?php foreach ($results['rework_assets'] as $index => $asset): ?>
<?php
$assetName = extractFolderName($asset);
$assetId = $asset['asset_id'];
$metadataId = 'rework-metadata-' . $index;
?>
<div class="asset-item">
<div class="asset-info">
<strong><?= htmlspecialchars($assetName) ?></strong><br>
<small>ID: <?= htmlspecialchars($assetId) ?></small><br>
<small>Type: <?= htmlspecialchars($asset['mime_type'] ?? 'Unknown') ?></small>
<?php if (isset($asset['file_size'])): ?>
<small> | Size: <?= number_format($asset['file_size']) ?> bytes</small>
<?php endif; ?>
</div>
<div class="asset-actions">
<form method="POST" style="display: inline;">
<input type="hidden" name="tab" value="rework">
<input type="hidden" name="action" value="download_rework_asset">
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($assetId) ?>">
<input type="hidden" name="filename" value="<?= htmlspecialchars($assetName) ?>">
<button type="submit" class="btn btn-success">📥 Download</button>
</form>
<button class="btn btn-secondary"
onclick="toggleMetadata('<?= $metadataId ?>')">
📋 Metadata
</button>
</div>
</div>
<div id="<?= $metadataId ?>" class="metadata-display" style="display: none;">
<?php
$metadata = MetadataExtractor::extractAllMetadata($asset);
if (!empty($metadata)):
?>
<div style="font-size: 13px;">
<!-- Same metadata display as download tab -->
<?php if (isset($metadata['basic'])): ?>
<div style="background: white; padding: 12px; margin: 8px 0; border-radius: 4px; border-left: 4px solid #667eea;">
<strong>📋 Basic Info:</strong><br>
<div style="margin-top: 8px; display: grid; grid-template-columns: 150px 1fr; gap: 5px;">
<?php foreach ($metadata['basic'] as $key => $value): ?>
<?php if ($value !== null): ?>
<div style="color: #666;"><?= ucwords(str_replace('_', ' ', $key)) ?>:</div>
<div><strong><?= htmlspecialchars($value) ?></strong></div>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
<?php else: ?>
<p>No metadata available for this asset</p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<div style="margin-top: 30px; padding: 20px; background: #fff3cd; border-radius: 8px;">
<h4>⚠️ Update Status to A6</h4>
<p style="margin: 10px 0;">
Once rework assets are downloaded, update the campaign status to A6
(Assets to be reworked received by the Agency)
</p>
<form method="POST">
<input type="hidden" name="tab" value="rework">
<input type="hidden" name="action" value="update_status_to_a6">
<button type="submit" class="btn btn-success">Update Status: A5 A6</button>
</form>
</div>
<?php endif; ?>
<?php if (isset($results['last_rework_download'])): ?>
<?php $dl = $results['last_rework_download']; ?>
<div class="alert alert-<?= $dl['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
<?php if ($dl['success']): ?>
<strong> Download Successful:</strong> <?= htmlspecialchars($dl['filename']) ?>
<br><small>Size: <?= number_format($dl['size']) ?> bytes</small>
<?php else: ?>
<strong> Download Failed:</strong> <?= htmlspecialchars($dl['error']) ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if (isset($results['rework_bulk_download'])): ?>
<div class="alert alert-success" style="margin-top: 20px;">
<strong>Bulk Download Results:</strong>
<?= $results['rework_bulk_download']['successful'] ?> of <?= $results['rework_bulk_download']['total'] ?> rework assets downloaded
</div>
<?php endif; ?>
</div>
</div>
@ -1140,6 +1648,26 @@ $envInfo = $configV3->getEnvironmentInfo();
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;
}
</script>
</body>
</html>