Complete PHP-based workflow application for Ferrero DAM system: - OAuth2 authentication with automatic token management - Campaign discovery and filtering - Folder structure navigation - Asset download (individual and bulk) - Metadata extraction and display - Clean step-by-step web interface Status: Fully functional and production-ready 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
967 lines
No EOL
55 KiB
PHP
967 lines
No EOL
55 KiB
PHP
<?php
|
|
session_start();
|
|
|
|
// Clear any existing session data
|
|
if (isset($_GET['reset'])) {
|
|
session_destroy();
|
|
session_start();
|
|
header('Location: clean_workflow.php');
|
|
exit;
|
|
}
|
|
|
|
require_once 'src/TestRunner.php';
|
|
require_once 'src/CampaignFormatter.php';
|
|
require_once 'src/AssetDownloader.php';
|
|
require_once 'src/MetadataExtractor.php';
|
|
|
|
$config = [
|
|
'baseUrl' => '',
|
|
'apiKey' => '',
|
|
'timeout' => 120,
|
|
'headers' => [
|
|
'Content-Type' => 'application/json',
|
|
'Accept' => 'application/json'
|
|
]
|
|
];
|
|
|
|
$collectionPath = __DIR__ . '/Content Scaling Flow.postman_collection_Oliver(New).json';
|
|
|
|
$testRunner = null;
|
|
$error = null;
|
|
$campaigns = [];
|
|
$selectedCampaign = null;
|
|
$workflowStep = 1;
|
|
$workflowResults = [];
|
|
|
|
try {
|
|
if (file_exists($collectionPath)) {
|
|
$testRunner = new TestRunner($collectionPath, $config);
|
|
} else {
|
|
$error = "Postman collection file not found";
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "Error initializing test runner: " . $e->getMessage();
|
|
}
|
|
|
|
// Handle ONLY explicit user actions
|
|
if ($_POST && $testRunner) {
|
|
if ($_POST['action'] === 'load_campaigns') {
|
|
// Load campaigns from API
|
|
$requests = $testRunner->getAvailableRequests();
|
|
|
|
foreach ($requests as $index => $request) {
|
|
if (strpos($request['name'], 'Retrieve Localized Campaign Folders') !== false) {
|
|
$result = $testRunner->runSingleTest($request, $index);
|
|
|
|
if ($result['status'] === 'PASS') {
|
|
// Filter to only show "3 - Production & execution" campaigns
|
|
$filters = ['stage' => '3 - Production & execution'];
|
|
$campaigns = CampaignFormatter::getActionableCampaigns($result['response']['body'], $filters);
|
|
$message = "Successfully loaded " . count($campaigns) . " campaigns in '3 - Production & execution' stage";
|
|
} else {
|
|
$error = "Failed to load campaigns: " . ($result['response']['error'] ?? 'Unknown error');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'select_campaign') {
|
|
$selectedCampaignId = $_POST['selected_campaign_id'] ?? '';
|
|
if ($selectedCampaignId && !empty($_POST['campaigns_data'])) {
|
|
$allCampaigns = json_decode($_POST['campaigns_data'], true);
|
|
foreach ($allCampaigns as $campaign) {
|
|
if ($campaign['asset_id'] === $selectedCampaignId) {
|
|
$selectedCampaign = $campaign;
|
|
$_SESSION['selected_campaign'] = $campaign; // Store in session
|
|
$workflowStep = 2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'get_folders') {
|
|
// Get selected campaign from session or previous step
|
|
if (isset($_SESSION['selected_campaign'])) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
$campaignId = $selectedCampaign['asset_id'] ?? '';
|
|
if ($campaignId) {
|
|
$workflowResults['folders'] = getAssetFolders($testRunner, $campaignId);
|
|
$workflowStep = 2; // Stay on step 2
|
|
}
|
|
} else {
|
|
$error = "No campaign selected. Please go back to Step 1.";
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'download_asset') {
|
|
$assetId = $_POST['asset_id'] ?? '';
|
|
$filename = $_POST['filename'] ?? '';
|
|
|
|
if ($assetId && isset($_SESSION['selected_campaign'])) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
|
|
// Create downloader instance
|
|
$apiClient = new ApiClient();
|
|
$apiClient->setBaseUrl('https://ppr.dam.ferrero.com/otmmapi');
|
|
|
|
// Get OAuth2 token
|
|
if ($testRunner) {
|
|
$oauth2Status = $testRunner->getOAuth2Status();
|
|
if ($oauth2Status['enabled'] && ($oauth2Status['has_token'] ?? false)) {
|
|
try {
|
|
$token = $testRunner->refreshToken() ? 'refreshed' : 'existing';
|
|
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
|
$oauth2Handler->setAccessible(true);
|
|
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
|
if ($oauth2HandlerInstance) {
|
|
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "OAuth2 token error: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isset($error)) {
|
|
// Test the direct content endpoint first - CORRECT endpoint with 's'
|
|
$testRequest = [
|
|
'method' => 'GET',
|
|
'url' => "/v6/assets/{$assetId}/contents"
|
|
];
|
|
|
|
$testResponse = $apiClient->executeRequest($testRequest);
|
|
|
|
if ($testResponse['success'] && !empty($testResponse['body'])) {
|
|
// Direct download worked!
|
|
$safeFilename = preg_replace('/[^a-zA-Z0-9._-]/', '_', $filename ?: "asset_{$assetId}");
|
|
if (!pathinfo($safeFilename, PATHINFO_EXTENSION)) {
|
|
$safeFilename .= '.jpg'; // Default extension
|
|
}
|
|
|
|
if (!is_dir('downloads/')) {
|
|
mkdir('downloads/', 0755, true);
|
|
}
|
|
|
|
$fullPath = 'downloads/' . $safeFilename;
|
|
$bytesWritten = file_put_contents($fullPath, $testResponse['body']);
|
|
|
|
$workflowResults['download'] = [
|
|
'success' => $bytesWritten !== false,
|
|
'filename' => $safeFilename,
|
|
'filepath' => $fullPath,
|
|
'size' => $bytesWritten ?: 0,
|
|
'asset_id' => $assetId,
|
|
'download_url' => "/v6/assets/{$assetId}/contents",
|
|
'method' => 'direct_content_endpoint'
|
|
];
|
|
} else {
|
|
// Fall back to AssetDownloader
|
|
$downloader = new AssetDownloader($apiClient);
|
|
$result = $downloader->downloadAsset($assetId, $filename);
|
|
$result['direct_test'] = [
|
|
'attempted' => true,
|
|
'success' => false,
|
|
'http_code' => $testResponse['http_code'] ?? 0,
|
|
'error' => $testResponse['error'] ?? null,
|
|
'response_size' => strlen($testResponse['body'] ?? '')
|
|
];
|
|
$workflowResults['download'] = $result;
|
|
}
|
|
|
|
$workflowStep = 2; // Stay on step 2
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'download_folder') {
|
|
$folderAssetIds = $_POST['folder_asset_ids'] ?? [];
|
|
$folderName = $_POST['folder_name'] ?? 'folder_download';
|
|
|
|
if (!empty($folderAssetIds) && isset($_SESSION['selected_campaign'])) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
|
|
// Setup API client similar to single download
|
|
$apiClient = new ApiClient();
|
|
$apiClient->setBaseUrl('https://ppr.dam.ferrero.com/otmmapi');
|
|
|
|
if ($testRunner) {
|
|
$oauth2Status = $testRunner->getOAuth2Status();
|
|
if ($oauth2Status['enabled'] && ($oauth2Status['has_token'] ?? false)) {
|
|
try {
|
|
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
|
|
$oauth2Handler->setAccessible(true);
|
|
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
|
|
if ($oauth2HandlerInstance) {
|
|
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = "OAuth2 token error: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isset($error)) {
|
|
$downloader = new AssetDownloader($apiClient);
|
|
$result = $downloader->downloadMultipleAssets($folderAssetIds, $folderName);
|
|
$workflowResults['bulk_download'] = $result;
|
|
$workflowStep = 2; // Stay on step 2
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'explore_folder') {
|
|
$folderId = $_POST['folder_id'] ?? '';
|
|
$folderName = $_POST['folder_name'] ?? 'Unnamed';
|
|
if ($folderId && isset($_SESSION['selected_campaign'])) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
$workflowResults['folder_contents'] = getAssetsFromFolder($testRunner, $folderId);
|
|
$workflowResults['explored_folder_name'] = $folderName;
|
|
$workflowStep = 2; // Stay on step 2 but show folder contents
|
|
}
|
|
}
|
|
|
|
if ($_POST['action'] === 'explore_all_folders') {
|
|
$folderIds = $_POST['folder_ids'] ?? [];
|
|
if (!empty($folderIds) && isset($_SESSION['selected_campaign'])) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
$workflowResults['all_folder_contents'] = [];
|
|
|
|
foreach ($folderIds as $index => $folderId) {
|
|
$result = getAssetsFromFolder($testRunner, $folderId);
|
|
$workflowResults['all_folder_contents'][] = [
|
|
'folder_id' => $folderId,
|
|
'folder_name' => "Folder " . ($index + 1),
|
|
'result' => $result
|
|
];
|
|
}
|
|
$workflowStep = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
function getAssetFolders($testRunner, $campaignId) {
|
|
$requests = $testRunner->getAvailableRequests();
|
|
|
|
foreach ($requests as $index => $request) {
|
|
$name = strtolower($request['name']);
|
|
if (strpos($name, 'master asset folder') !== false && strpos($name, 'final asset') !== false) {
|
|
$modifiedRequest = $request;
|
|
$url = is_array($request['request']['url']) ? $request['request']['url']['raw'] : $request['request']['url'];
|
|
|
|
$url = str_replace('6930c59abea5bd4259b67f7647f65cd01d36278d', $campaignId, $url);
|
|
$baseUrl = 'https://ppr.dam.ferrero.com/otmmapi';
|
|
$url = str_replace('{{baseUrl}}', $baseUrl, $url);
|
|
|
|
if (is_array($modifiedRequest['request']['url'])) {
|
|
$modifiedRequest['request']['url']['raw'] = $url;
|
|
} else {
|
|
$modifiedRequest['request']['url'] = $url;
|
|
}
|
|
|
|
return $testRunner->runSingleTest($modifiedRequest, $index);
|
|
}
|
|
}
|
|
|
|
return ['status' => 'ERROR', 'message' => 'Asset folders request not found'];
|
|
}
|
|
|
|
function getAssetsFromFolder($testRunner, $folderId) {
|
|
$requests = $testRunner->getAvailableRequests();
|
|
|
|
foreach ($requests as $index => $request) {
|
|
$name = strtolower($request['name']);
|
|
if (strpos($name, 'all assets from') !== false) {
|
|
$modifiedRequest = $request;
|
|
$url = is_array($request['request']['url']) ? $request['request']['url']['raw'] : $request['request']['url'];
|
|
|
|
$url = preg_replace('/folders\/[^\/]+\//', "folders/{$folderId}/", $url);
|
|
$baseUrl = 'https://ppr.dam.ferrero.com/otmmapi';
|
|
$url = str_replace('{{baseUrl}}', $baseUrl, $url);
|
|
|
|
if (is_array($modifiedRequest['request']['url'])) {
|
|
$modifiedRequest['request']['url']['raw'] = $url;
|
|
} else {
|
|
$modifiedRequest['request']['url'] = $url;
|
|
}
|
|
|
|
return $testRunner->runSingleTest($modifiedRequest, $index);
|
|
}
|
|
}
|
|
|
|
return ['status' => 'ERROR', 'message' => 'Assets request not found'];
|
|
}
|
|
|
|
// Check if we have a selected campaign from session
|
|
if (isset($_SESSION['selected_campaign']) && !$selectedCampaign) {
|
|
$selectedCampaign = $_SESSION['selected_campaign'];
|
|
$workflowStep = 2;
|
|
}
|
|
|
|
$oauth2Status = $testRunner ? $testRunner->getOAuth2Status() : null;
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Clean Workflow - Ferrero Content Scaling</title>
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
}
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
padding: 30px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
}
|
|
.header {
|
|
text-align: center;
|
|
margin-bottom: 30px;
|
|
padding-bottom: 20px;
|
|
border-bottom: 2px solid #e0e0e0;
|
|
}
|
|
.section {
|
|
margin-bottom: 30px;
|
|
padding: 20px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
background-color: #fafafa;
|
|
}
|
|
.btn {
|
|
background-color: #007cba;
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
.btn:hover { background-color: #005a8b; }
|
|
.btn-success { background-color: #28a745; }
|
|
.error { color: #dc3545; background-color: #f8d7da; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
.success { color: #155724; background-color: #d4edda; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
.campaign-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
gap: 15px;
|
|
margin-top: 20px;
|
|
}
|
|
.campaign-card {
|
|
background: white;
|
|
border: 2px solid #dee2e6;
|
|
border-radius: 8px;
|
|
padding: 15px;
|
|
cursor: pointer;
|
|
transition: border-color 0.2s;
|
|
}
|
|
.campaign-card:hover { border-color: #007cba; }
|
|
.campaign-card.selected { border-color: #28a745; background-color: #f8fff9; }
|
|
.metadata-display { background: #f8f9fa; padding: 15px; border-radius: 6px; margin: 10px 0; }
|
|
.metadata-section { margin-bottom: 20px; }
|
|
.metadata-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; margin: 10px 0; }
|
|
.metadata-category { background: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
.permissions-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 5px; margin: 10px 0; }
|
|
.rendition-info { background: white; padding: 10px; border-radius: 4px; margin: 5px 0; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>🎯 Clean Content Scaling Workflow</h1>
|
|
<p>Simple, step-by-step campaign asset workflow</p>
|
|
<a href="?reset=1" style="color: #dc3545; text-decoration: none; font-size: 12px;">🔄 Reset Session</a>
|
|
</div>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="error"><strong>Error:</strong> <?= htmlspecialchars($error) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (isset($message)): ?>
|
|
<div class="success"><?= htmlspecialchars($message) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- OAuth2 Status -->
|
|
<?php if ($oauth2Status && $oauth2Status['enabled'] && ($oauth2Status['has_token'] ?? false)): ?>
|
|
<div class="success">✅ OAuth2 Token Active</div>
|
|
<?php else: ?>
|
|
<div class="error">❌ OAuth2 Token Issue</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Step 1: Load Campaigns -->
|
|
<?php if ($workflowStep == 1): ?>
|
|
<div class="section">
|
|
<h2>📋 Step 1: Load Campaigns</h2>
|
|
|
|
<?php if (empty($campaigns)): ?>
|
|
<p>Click the button below to load campaigns from the API using your Postman collection settings.</p>
|
|
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="load_campaigns">
|
|
<button type="submit" class="btn btn-success">Load "3 - Production & execution" Campaigns</button>
|
|
</form>
|
|
|
|
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin-top: 10px; font-size: 13px;">
|
|
This will load only campaigns in "3 - Production & execution" stage (should be about 12 campaigns).
|
|
</div>
|
|
|
|
<?php else: ?>
|
|
<p><strong>✅ Loaded <?= count($campaigns) ?> campaigns</strong></p>
|
|
|
|
<div class="campaign-grid">
|
|
<?php foreach ($campaigns as $campaign): ?>
|
|
<div class="campaign-card" onclick="selectCampaign('<?= htmlspecialchars($campaign['asset_id']) ?>', this)">
|
|
<h4><?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed') ?></h4>
|
|
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
|
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
|
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
|
<p><strong>Stage:</strong> <?= htmlspecialchars($campaign['stage'] ?? 'N/A') ?></p>
|
|
<p><strong>Asset ID:</strong> <code><?= htmlspecialchars($campaign['asset_id']) ?></code></p>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<form method="POST" id="campaign-selection-form">
|
|
<input type="hidden" name="action" value="select_campaign">
|
|
<input type="hidden" name="selected_campaign_id" id="selected-campaign-id">
|
|
<input type="hidden" name="campaigns_data" value="<?= htmlspecialchars(json_encode($campaigns)) ?>">
|
|
<button type="submit" class="btn btn-success" id="proceed-btn" disabled>Proceed to Step 2</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Step 2: Get Folders -->
|
|
<?php if ($workflowStep == 2 && $selectedCampaign): ?>
|
|
<div class="section">
|
|
<h2>📁 Step 2: Get Campaign Folders</h2>
|
|
|
|
<div style="background: #e8f4f8; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
|
|
<strong>Selected Campaign:</strong> <?= htmlspecialchars($selectedCampaign['campaign_name'] ?? 'Unknown') ?><br>
|
|
<strong>Campaign ID:</strong> <?= htmlspecialchars($selectedCampaign['campaign_id'] ?? 'N/A') ?><br>
|
|
<strong>Asset ID:</strong> <code><?= htmlspecialchars($selectedCampaign['asset_id']) ?></code>
|
|
</div>
|
|
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="get_folders">
|
|
<button type="submit" class="btn btn-success">Get Campaign Folders</button>
|
|
</form>
|
|
|
|
<?php if (isset($workflowResults['folders'])): ?>
|
|
<?php $result = $workflowResults['folders']; ?>
|
|
<div style="background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 20px; margin: 20px 0;">
|
|
<h3>Folder Results</h3>
|
|
<p><strong>Status:</strong> <?= $result['status'] ?></p>
|
|
<p><strong>HTTP Code:</strong> <?= $result['response']['http_code'] ?? 'N/A' ?></p>
|
|
<p><strong>URL:</strong> <?= htmlspecialchars($result['response']['url'] ?? 'N/A') ?></p>
|
|
|
|
<?php if ($result['status'] === 'PASS'): ?>
|
|
<?php
|
|
$data = json_decode($result['response']['body'], true);
|
|
$folders = $data['folder_children']['asset_list'] ?? [];
|
|
?>
|
|
<h4>Found <?= count($folders) ?> folder(s):</h4>
|
|
|
|
<?php if (count($folders) == 1): ?>
|
|
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
⚠️ <strong>Only 1 folder found.</strong> This campaign might not have the Master Assets folder we need.
|
|
<br>Try going back and selecting <strong>"LOCAL CAMPAIGN"</strong> (Campaign ID: C000000212) which had both folders.
|
|
</div>
|
|
<?php elseif (count($folders) >= 2): ?>
|
|
<div style="background: #d4edda; color: #155724; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
✅ <strong>Great!</strong> Found <?= count($folders) ?> folders - this campaign has proper folder structure.
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php foreach ($folders as $folder): ?>
|
|
<?php
|
|
// Better folder name extraction - try multiple name fields
|
|
$folderName = 'Unnamed';
|
|
|
|
// Try common name fields
|
|
$nameFields = [
|
|
'ARTESIA.FIELD.NAME',
|
|
'FERRERO.FIELD.CAMPAIGN_NAME',
|
|
'ARTESIA.FIELD.TITLE',
|
|
'FERRERO.FIELD.FOLDER_NAME',
|
|
'NAME'
|
|
];
|
|
|
|
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'])) {
|
|
$folderName = $field['value']['value']['value'];
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try standard fields
|
|
if ($folderName === 'Unnamed') {
|
|
$folderName = $folder['name'] ?? $folder['title'] ?? $folder['display_name'] ?? 'Folder';
|
|
}
|
|
|
|
// Add creation date to help identify
|
|
$createDate = substr($folder['date_imported'] ?? '', 0, 10); // Just date part
|
|
if ($folderName === 'Folder' || strlen($folderName) > 40) {
|
|
$folderName = "Folder (Created: {$createDate})";
|
|
}
|
|
?>
|
|
<div style="border: 1px solid #ddd; margin: 10px 0; padding: 15px; background: white; border-radius: 4px;">
|
|
<h4><?= htmlspecialchars($folderName) ?></h4>
|
|
<p><strong>Asset ID:</strong> <code><?= htmlspecialchars($folder['asset_id']) ?></code></p>
|
|
<p><strong>Type:</strong> <?= htmlspecialchars($folder['data_type'] ?? 'CONTAINER') ?></p>
|
|
<p><strong>Created:</strong> <?= htmlspecialchars($folder['date_imported'] ?? 'N/A') ?></p>
|
|
|
|
<form method="POST" style="display: inline; margin-right: 10px;">
|
|
<input type="hidden" name="action" value="explore_folder">
|
|
<input type="hidden" name="folder_id" value="<?= htmlspecialchars($folder['asset_id']) ?>">
|
|
<input type="hidden" name="folder_name" value="<?= htmlspecialchars($folderName) ?>">
|
|
<button type="submit" class="btn">Explore "<?= htmlspecialchars($folderName) ?>"</button>
|
|
</form>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<!-- Explore All Folders Button -->
|
|
<?php if (count($folders) > 1): ?>
|
|
<div style="margin-top: 20px; padding: 15px; background: #e8f4f8; border-radius: 4px;">
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="explore_all_folders">
|
|
<?php foreach ($folders as $folder): ?>
|
|
<input type="hidden" name="folder_ids[]" value="<?= htmlspecialchars($folder['asset_id']) ?>">
|
|
<?php endforeach; ?>
|
|
<button type="submit" class="btn btn-success">🔍 Explore All <?= count($folders) ?> Folders</button>
|
|
</form>
|
|
<p style="margin: 10px 0 0 0; font-size: 13px; color: #666;">
|
|
This will show contents of both folders side by side for comparison.
|
|
</p>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php else: ?>
|
|
<p><strong>Error:</strong> <?= htmlspecialchars($result['response']['error'] ?? 'Unknown error') ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Folder Contents -->
|
|
<?php if (isset($workflowResults['folder_contents'])): ?>
|
|
<?php $contentsResult = $workflowResults['folder_contents']; ?>
|
|
<div style="background: #f0f8ff; border: 1px solid #bee5eb; border-radius: 6px; padding: 20px; margin: 20px 0;">
|
|
<h3>📄 Folder Contents</h3>
|
|
<p><strong>Status:</strong> <?= $contentsResult['status'] ?></p>
|
|
<p><strong>HTTP Code:</strong> <?= $contentsResult['response']['http_code'] ?? 'N/A' ?></p>
|
|
|
|
<?php if ($contentsResult['status'] === 'PASS'): ?>
|
|
<?php
|
|
$contentsData = json_decode($contentsResult['response']['body'], true);
|
|
$assets = [];
|
|
|
|
// Check different possible structures
|
|
if (isset($contentsData['folder_children']['asset_list'])) {
|
|
$assets = $contentsData['folder_children']['asset_list'];
|
|
} elseif (isset($contentsData['items'])) {
|
|
$assets = $contentsData['items'];
|
|
} elseif (isset($contentsData['asset_list'])) {
|
|
$assets = $contentsData['asset_list'];
|
|
}
|
|
?>
|
|
|
|
<h4>Found <?= count($assets) ?> item(s) in this folder:</h4>
|
|
|
|
<?php if (!empty($assets)): ?>
|
|
<?php
|
|
$fileCount = 0;
|
|
$folderCount = 0;
|
|
$fileTypes = [];
|
|
|
|
foreach ($assets as $asset) {
|
|
if (($asset['data_type'] ?? '') === 'CONTAINER') {
|
|
$folderCount++;
|
|
} else {
|
|
$fileCount++;
|
|
$mimeType = $asset['mime_type'] ?? 'Unknown';
|
|
$fileTypes[$mimeType] = ($fileTypes[$mimeType] ?? 0) + 1;
|
|
}
|
|
}
|
|
?>
|
|
|
|
<div style="background: white; padding: 15px; border-radius: 4px; margin: 15px 0;">
|
|
<h5>📊 Summary:</h5>
|
|
<p><strong>📁 Subfolders:</strong> <?= $folderCount ?></p>
|
|
<p><strong>📄 Files:</strong> <?= $fileCount ?></p>
|
|
|
|
<?php if (!empty($fileTypes)): ?>
|
|
<p><strong>File Types:</strong></p>
|
|
<ul style="margin: 5px 0 0 20px;">
|
|
<?php foreach ($fileTypes as $type => $count): ?>
|
|
<li><?= htmlspecialchars($type) ?> (<?= $count ?> files)</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<h5>Individual Items:</h5>
|
|
<?php foreach ($assets as $index => $asset): ?>
|
|
<?php
|
|
$assetName = 'Unnamed Asset';
|
|
if (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'] === 'FERRERO.FIELD.CAMPAIGN_NAME' && isset($field['value']['value']['value'])) {
|
|
$assetName = $field['value']['value']['value'];
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($assetName === 'Unnamed Asset') {
|
|
$assetName = $asset['name'] ?? $asset['asset_id'] ?? 'Unknown';
|
|
}
|
|
?>
|
|
<div style="border: 1px solid #ddd; margin: 5px 0; padding: 10px; background: white; border-radius: 4px;">
|
|
<strong><?= $index + 1 ?>. <?= htmlspecialchars($assetName) ?></strong><br>
|
|
<strong>ID:</strong> <code><?= htmlspecialchars($asset['asset_id'] ?? 'N/A') ?></code><br>
|
|
<strong>Type:</strong> <?= htmlspecialchars($asset['data_type'] ?? 'Unknown') ?><br>
|
|
<?php if (isset($asset['mime_type'])): ?>
|
|
<strong>File Type:</strong> <?= htmlspecialchars($asset['mime_type']) ?><br>
|
|
<?php endif; ?>
|
|
<?php if (isset($asset['file_size'])): ?>
|
|
<strong>Size:</strong> <?= number_format($asset['file_size']) ?> bytes<br>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<p>This folder is empty.</p>
|
|
<?php endif; ?>
|
|
|
|
<?php else: ?>
|
|
<p><strong>Error:</strong> <?= htmlspecialchars($contentsResult['response']['error'] ?? 'Unknown error') ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- All Folders Contents Comparison -->
|
|
<?php if (isset($workflowResults['all_folder_contents'])): ?>
|
|
<div style="background: #f0f8ff; border: 1px solid #bee5eb; border-radius: 6px; padding: 20px; margin: 20px 0;">
|
|
<h3>📊 All Folders Comparison</h3>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px;">
|
|
<?php foreach ($workflowResults['all_folder_contents'] as $folderData): ?>
|
|
<?php
|
|
$result = $folderData['result'];
|
|
$folderId = $folderData['folder_id'];
|
|
$folderName = $folderData['folder_name'];
|
|
?>
|
|
|
|
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 15px;">
|
|
<h4>📁 <?= htmlspecialchars($folderName) ?></h4>
|
|
<p><strong>ID:</strong> <code><?= htmlspecialchars($folderId) ?></code></p>
|
|
<p><strong>Status:</strong> <?= $result['status'] ?></p>
|
|
|
|
<?php if ($result['status'] === 'PASS'): ?>
|
|
<?php
|
|
$data = json_decode($result['response']['body'], true);
|
|
$assets = [];
|
|
|
|
if (isset($data['folder_children']['asset_list'])) {
|
|
$assets = $data['folder_children']['asset_list'];
|
|
} elseif (isset($data['items'])) {
|
|
$assets = $data['items'];
|
|
}
|
|
|
|
$fileCount = 0;
|
|
$folderCount = 0;
|
|
$fileTypes = [];
|
|
|
|
foreach ($assets as $asset) {
|
|
if (($asset['data_type'] ?? '') === 'CONTAINER') {
|
|
$folderCount++;
|
|
} else {
|
|
$fileCount++;
|
|
$mimeType = $asset['mime_type'] ?? 'Unknown';
|
|
$fileTypes[$mimeType] = ($fileTypes[$mimeType] ?? 0) + 1;
|
|
}
|
|
}
|
|
?>
|
|
|
|
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
<strong>📊 Contents:</strong><br>
|
|
📁 Subfolders: <?= $folderCount ?><br>
|
|
📄 Files: <?= $fileCount ?><br>
|
|
|
|
<?php if (!empty($fileTypes)): ?>
|
|
<strong>File Types:</strong><br>
|
|
<?php foreach ($fileTypes as $type => $count): ?>
|
|
• <?= htmlspecialchars($type) ?> (<?= $count ?>)<br>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<?php if ($fileCount > 0): ?>
|
|
<div style="background: #d4edda; color: #155724; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
✅ <strong>This folder contains <?= $fileCount ?> files!</strong><br>
|
|
These are your source assets for content scaling.
|
|
</div>
|
|
|
|
<!-- Show actual filenames with download buttons -->
|
|
<div style="margin-top: 15px;">
|
|
<h6><strong>📄 File List with Download Options:</strong></h6>
|
|
|
|
<!-- Bulk Download Option -->
|
|
<?php
|
|
$downloadableAssets = [];
|
|
foreach ($assets as $asset) {
|
|
if (($asset['data_type'] ?? '') !== 'CONTAINER') {
|
|
$downloadableAssets[] = $asset['asset_id'];
|
|
}
|
|
}
|
|
?>
|
|
|
|
<?php if (!empty($downloadableAssets)): ?>
|
|
<div style="background: #d1ecf1; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
|
|
<form method="POST" style="display: inline;">
|
|
<input type="hidden" name="action" value="download_folder">
|
|
<input type="hidden" name="folder_name" value="<?= htmlspecialchars($folderName) ?>">
|
|
<?php foreach ($downloadableAssets as $assetId): ?>
|
|
<input type="hidden" name="folder_asset_ids[]" value="<?= htmlspecialchars($assetId) ?>">
|
|
<?php endforeach; ?>
|
|
<button type="submit" class="btn btn-success">📥 Download All <?= count($downloadableAssets) ?> Files</button>
|
|
</form>
|
|
<span style="font-size: 12px; color: #666; margin-left: 10px;">
|
|
Downloads all files to: downloads/<?= htmlspecialchars($folderName) ?>/
|
|
</span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Individual Files -->
|
|
<?php foreach ($assets as $asset): ?>
|
|
<?php if (($asset['data_type'] ?? '') !== 'CONTAINER'): ?>
|
|
<?php
|
|
$fileName = 'Unnamed File';
|
|
if (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'] === 'ARTESIA.FIELD.NAME' && isset($field['value']['value']['value'])) {
|
|
$fileName = $field['value']['value']['value'];
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($fileName === 'Unnamed File') {
|
|
$fileName = $asset['name'] ?? $asset['asset_id'] ?? 'Unknown';
|
|
}
|
|
?>
|
|
<div style="background: #f8f9fa; padding: 10px; margin: 5px 0; border-radius: 4px; border: 1px solid #dee2e6;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
<div style="font-family: monospace; font-size: 12px;">
|
|
📄 <strong><?= htmlspecialchars($fileName) ?></strong><br>
|
|
ID: <?= htmlspecialchars($asset['asset_id'] ?? 'N/A') ?><br>
|
|
Type: <?= htmlspecialchars($asset['mime_type'] ?? 'Unknown') ?>
|
|
<?php if (isset($asset['file_size'])): ?>
|
|
Size: <?= number_format($asset['file_size']) ?> bytes
|
|
<?php endif; ?>
|
|
</div>
|
|
<div>
|
|
<form method="POST" style="display: inline; margin-right: 5px;">
|
|
<input type="hidden" name="action" value="download_asset">
|
|
<input type="hidden" name="asset_id" value="<?= htmlspecialchars($asset['asset_id']) ?>">
|
|
<input type="hidden" name="filename" value="<?= htmlspecialchars($fileName) ?>">
|
|
<button type="submit" class="btn" style="background: #28a745; font-size: 12px; padding: 6px 10px;">📥 Download</button>
|
|
</form>
|
|
|
|
<button onclick="showMetadata('<?= htmlspecialchars($asset['asset_id']) ?>')" class="btn" style="background: #17a2b8; color: white; font-size: 12px; padding: 6px 10px;">📋 Metadata</button>
|
|
|
|
<!-- Hidden metadata div -->
|
|
<div id="metadata-<?= htmlspecialchars($asset['asset_id']) ?>" style="display: none; margin-top: 15px;">
|
|
<?= MetadataExtractor::formatMetadataForDisplay(MetadataExtractor::extractAllMetadata($asset)) ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php elseif ($folderCount > 0): ?>
|
|
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
📁 Contains <?= $folderCount ?> subfolders<br>
|
|
Assets might be nested deeper.
|
|
</div>
|
|
<?php else: ?>
|
|
<div style="background: #f8d7da; color: #721c24; padding: 10px; border-radius: 4px; margin: 10px 0;">
|
|
❌ This folder appears empty.
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php else: ?>
|
|
<p style="color: #dc3545;"><strong>Error exploring folder:</strong> <?= htmlspecialchars($result['response']['error'] ?? 'Unknown error') ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Download Results -->
|
|
<?php if (isset($workflowResults['download'])): ?>
|
|
<?php $downloadResult = $workflowResults['download']; ?>
|
|
<div style="background: <?= $downloadResult['success'] ? '#d4edda' : '#f8d7da' ?>; border: 1px solid <?= $downloadResult['success'] ? '#c3e6cb' : '#f5c6cb' ?>; border-radius: 6px; padding: 20px; margin: 20px 0;">
|
|
<h3><?= $downloadResult['success'] ? '✅' : '❌' ?> Asset Download Result</h3>
|
|
|
|
<?php if ($downloadResult['success']): ?>
|
|
<p><strong>✅ Download Successful!</strong></p>
|
|
<p><strong>File:</strong> <?= htmlspecialchars($downloadResult['filename']) ?></p>
|
|
<p><strong>Path:</strong> <?= htmlspecialchars($downloadResult['filepath']) ?></p>
|
|
<p><strong>Size:</strong> <?= number_format($downloadResult['size']) ?> bytes</p>
|
|
<p><strong>Asset ID:</strong> <code><?= htmlspecialchars($downloadResult['asset_id']) ?></code></p>
|
|
<?php else: ?>
|
|
<p><strong>❌ Download Failed</strong></p>
|
|
<p><strong>Error:</strong> <?= htmlspecialchars($downloadResult['error']) ?></p>
|
|
<?php if (isset($downloadResult['http_code'])): ?>
|
|
<p><strong>HTTP Code:</strong> <?= $downloadResult['http_code'] ?></p>
|
|
<?php endif; ?>
|
|
|
|
<!-- Debug Information - Always show for failures -->
|
|
<details style="margin-top: 15px;">
|
|
<summary><strong>🔍 Debug Information</strong></summary>
|
|
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin-top: 10px;">
|
|
|
|
<?php if (isset($downloadResult['debug_info'])): ?>
|
|
<h6>API Endpoint Attempts:</h6>
|
|
<?php foreach ($downloadResult['debug_info'] as $attempt): ?>
|
|
<div style="background: white; padding: 8px; margin: 5px 0; border-radius: 4px; border-left: 3px solid <?= $attempt['success'] ? '#28a745' : '#dc3545' ?>;">
|
|
<strong>Endpoint:</strong> <?= htmlspecialchars($attempt['endpoint']) ?><br>
|
|
<strong>Status:</strong> <?= $attempt['success'] ? 'SUCCESS' : 'FAILED' ?><br>
|
|
<strong>HTTP Code:</strong> <?= $attempt['http_code'] ?><br>
|
|
<strong>Response Size:</strong> <?= number_format($attempt['response_size']) ?> bytes<br>
|
|
<?php if ($attempt['error']): ?>
|
|
<strong>Error:</strong> <?= htmlspecialchars($attempt['error']) ?><br>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<div style="background: #fff3cd; padding: 10px; border-radius: 4px;">
|
|
<strong>⚠️ No API debug info available</strong><br>
|
|
Error occurred before API calls were made. This suggests:
|
|
<ul style="margin: 10px 0 0 20px;">
|
|
<li>Asset data structure issue</li>
|
|
<li>Missing required fields in asset metadata</li>
|
|
<li>OAuth2 authentication not properly configured</li>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</details>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Bulk Download Results -->
|
|
<?php if (isset($workflowResults['bulk_download'])): ?>
|
|
<?php $bulkResult = $workflowResults['bulk_download']; ?>
|
|
<div style="background: <?= $bulkResult['success'] ? '#d4edda' : '#f8d7da' ?>; border: 1px solid <?= $bulkResult['success'] ? '#c3e6cb' : '#f5c6cb' ?>; border-radius: 6px; padding: 20px; margin: 20px 0;">
|
|
<h3><?= $bulkResult['success'] ? '✅' : '❌' ?> Bulk Download Result</h3>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin: 15px 0;">
|
|
<div><strong>Total Assets:</strong> <?= $bulkResult['total_assets'] ?></div>
|
|
<div><strong>Successful:</strong> <?= $bulkResult['successful_downloads'] ?></div>
|
|
<div><strong>Failed:</strong> <?= $bulkResult['failed_downloads'] ?></div>
|
|
<div><strong>Total Size:</strong> <?= number_format($bulkResult['total_size']) ?> bytes</div>
|
|
</div>
|
|
|
|
<p><strong>Download Folder:</strong> <?= htmlspecialchars($bulkResult['download_folder']) ?></p>
|
|
|
|
<!-- Individual Results with Debug -->
|
|
<details style="margin-top: 15px;">
|
|
<summary><strong>View Individual Download Results & Debug Info</strong></summary>
|
|
<div style="margin-top: 10px;">
|
|
<?php foreach ($bulkResult['individual_results'] as $index => $result): ?>
|
|
<div style="background: white; padding: 10px; margin: 5px 0; border-radius: 4px; border-left: 4px solid <?= $result['success'] ? '#28a745' : '#dc3545' ?>;">
|
|
<strong>File <?= $index + 1 ?>:</strong>
|
|
<?php if ($result['success']): ?>
|
|
✅ <?= htmlspecialchars($result['filename']) ?> (<?= number_format($result['size']) ?> bytes)
|
|
<?php else: ?>
|
|
❌ Failed - <?= htmlspecialchars($result['error']) ?>
|
|
|
|
<!-- Debug info for failed downloads -->
|
|
<?php if (isset($result['debug_info'])): ?>
|
|
<div style="background: #f8f9fa; padding: 8px; margin-top: 8px; border-radius: 4px; font-size: 11px;">
|
|
<strong>Debug Info:</strong><br>
|
|
<?php foreach ($result['debug_info'] as $attempt): ?>
|
|
• <?= htmlspecialchars($attempt['endpoint']) ?> →
|
|
<?= $attempt['success'] ? 'SUCCESS' : 'FAILED' ?>
|
|
(HTTP <?= $attempt['http_code'] ?>, <?= $attempt['response_size'] ?> bytes)
|
|
<?php if ($attempt['error']): ?>
|
|
<br> Error: <?= htmlspecialchars($attempt['error']) ?>
|
|
<?php endif ?>
|
|
<br>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<!-- OAuth2 Status -->
|
|
<?php if (isset($bulkResult['oauth2_status'])): ?>
|
|
<div style="background: #e8f4f8; padding: 10px; margin-top: 10px; border-radius: 4px;">
|
|
<strong>OAuth2 Status During Download:</strong><br>
|
|
Enabled: <?= $bulkResult['oauth2_status']['enabled'] ? 'Yes' : 'No' ?><br>
|
|
Has Token: <?= ($bulkResult['oauth2_status']['has_token'] ?? false) ? 'Yes' : 'No' ?><br>
|
|
<?php if (isset($bulkResult['oauth2_status']['expires_at'])): ?>
|
|
Expires: <?= htmlspecialchars($bulkResult['oauth2_status']['expires_at']) ?><br>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<script>
|
|
function selectCampaign(campaignId, element) {
|
|
document.querySelectorAll('.campaign-card').forEach(card => {
|
|
card.classList.remove('selected');
|
|
});
|
|
|
|
element.classList.add('selected');
|
|
document.getElementById('selected-campaign-id').value = campaignId;
|
|
document.getElementById('proceed-btn').disabled = false;
|
|
}
|
|
|
|
function showMetadata(assetId) {
|
|
const metadataDiv = document.getElementById('metadata-' + assetId);
|
|
if (metadataDiv.style.display === 'none') {
|
|
metadataDiv.style.display = 'block';
|
|
} else {
|
|
metadataDiv.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function exploreFolder(folderId, folderName) {
|
|
alert('Explore folder: ' + folderName + ' (ID: ' + folderId + ')');
|
|
// TODO: Add folder exploration
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|