'', '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; ?> Clean Workflow - Ferrero Content Scaling

🎯 Clean Content Scaling Workflow

Simple, step-by-step campaign asset workflow

🔄 Reset Session
Error:
✅ OAuth2 Token Active
❌ OAuth2 Token Issue

📋 Step 1: Load Campaigns

Click the button below to load campaigns from the API using your Postman collection settings.

This will load only campaigns in "3 - Production & execution" stage (should be about 12 campaigns).

✅ Loaded campaigns

Campaign ID:

Brand:

Market:

Stage:

Asset ID:

📁 Step 2: Get Campaign Folders

Selected Campaign:
Campaign ID:
Asset ID:

Folder Results

Status:

HTTP Code:

URL:

Found folder(s):

⚠️ Only 1 folder found. This campaign might not have the Master Assets folder we need.
Try going back and selecting "LOCAL CAMPAIGN" (Campaign ID: C000000212) which had both folders.
= 2): ?>
Great! Found folders - this campaign has proper folder structure.
40) { $folderName = "Folder (Created: {$createDate})"; } ?>

Asset ID:

Type:

Created:

1): ?>

This will show contents of both folders side by side for comparison.

Error:

📄 Folder Contents

Status:

HTTP Code:

Found item(s) in this folder:

📊 Summary:

📁 Subfolders:

📄 Files:

File Types:

    $count): ?>
  • ( files)
Individual Items:
$asset): ?>
.
ID:
Type:
File Type:
Size: bytes

This folder is empty.

Error:

📊 All Folders Comparison

📁

ID:

Status:

📊 Contents:
📁 Subfolders:
📄 Files:
File Types:
$count): ?> • ()
0): ?>
This folder contains files!
These are your source assets for content scaling.
📄 File List with Download Options:
Downloads all files to: downloads//
📄
   ID:
   Type:    Size: bytes
0): ?>
📁 Contains subfolders
Assets might be nested deeper.
❌ This folder appears empty.

Error exploring folder:

Asset Download Result

✅ Download Successful!

File:

Path:

Size: bytes

Asset ID:

❌ Download Failed

Error:

HTTP Code:

🔍 Debug Information
API Endpoint Attempts:
Endpoint:
Status:
HTTP Code:
Response Size: bytes
Error:
⚠️ No API debug info available
Error occurred before API calls were made. This suggests:
  • Asset data structure issue
  • Missing required fields in asset metadata
  • OAuth2 authentication not properly configured

Bulk Download Result

Total Assets:
Successful:
Failed:
Total Size: bytes

Download Folder:

View Individual Download Results & Debug Info
$result): ?>
File : ( bytes) ❌ Failed -
Debug Info:
(HTTP , bytes)
  Error:
OAuth2 Status During Download:
Enabled:
Has Token:
Expires: