Fix status updates and enhance workflow with proper error handling
Major improvements to workflow_v3.php and supporting classes:
**Status Updates (A1→A2, A2→A3, A5→A6):**
- Fix StatusManager to use correct PATCH endpoint: /v6/folders/{id}
- Add lock_strategy=optimistic parameter to prevent locking errors
- Update request body structure to use edited_folder format
- Status updates now working correctly
**Status Field Extraction:**
- Fix CampaignFormatter to extract CONTENT.SCALING.STATUS field
- Handle domain values with field_value.value path
- Now correctly filters campaigns by status (A1, A2, A5, etc.)
**Error Handling:**
- Extract and display actual API error messages
- Show HTTP status codes in all error messages
- Add expandable debug panels with full API responses
- Enhanced upload error reporting with detailed diagnostics
**Campaign Search:**
- Update to use Postman collection requests directly (avoids 503 errors)
- Fix URL encoding (rawurlencode instead of urlencode)
- Add comprehensive debug output showing OAuth status and API responses
- Search now attempts Postman request first, falls back to manual query
**Upload Improvements:**
- Rewrite AssetUploader to use native PHP CURLFile for multipart uploads
- Add support for additional file types: .mov, .mp4, .avi, .zip, .txt, .doc, .xlsx
- Increase max upload size to 100MB for video files
- Simplify asset_representation to minimal structure
- Add infrastructure to inherit metadata from master assets
**Testing Features:**
- Add "Reset to A1" button for testing workflow iterations
- Add debug mode to view all campaigns and their metadata
- Show Content Scaling Status on all campaign cards
- Display filtering debug info (total vs filtered counts)
**UI Improvements:**
- Rename buttons to clarify "Content Scaling Status" terminology
- Add status badges to campaign cards showing current status
- Better visual feedback for successful/failed operations
Current Status: Workflow A1→A2 fully working. Upload A2→A3 ready for testing
once DAM server recovers from HTTP 503 errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
cf71bcfd96
commit
156f9ae51d
6 changed files with 545 additions and 93 deletions
BIN
IMG_8922.jpeg
BIN
IMG_8922.jpeg
Binary file not shown.
|
Before Width: | Height: | Size: 3 MiB |
|
|
@ -75,8 +75,8 @@ class ConfigV3
|
|||
|
||||
// Upload configuration
|
||||
'uploads' => [
|
||||
'allowed_extensions' => ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'ai', 'psd', 'eps'],
|
||||
'max_file_size' => 50 * 1024 * 1024, // 50MB
|
||||
'allowed_extensions' => ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'ai', 'psd', 'eps', 'tif', 'tiff', 'mov', 'mp4', 'avi', 'zip', 'txt', 'doc', 'docx', 'xls', 'xlsx'],
|
||||
'max_file_size' => 100 * 1024 * 1024, // 100MB (for video files)
|
||||
'preserve_filenames' => true
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -18,85 +18,169 @@ class AssetUploader
|
|||
|
||||
/**
|
||||
* Upload a file to DAM with metadata
|
||||
* Uses PHP's native multipart/form-data with CURLFile
|
||||
*
|
||||
* @param string $filePath Local file path
|
||||
* @param string $folderId Target folder ID (campaign folder)
|
||||
* @param array $metadata Optional metadata to set
|
||||
* @param array $sourceMetadata Full metadata structure from master asset to copy
|
||||
* @return array Upload result
|
||||
*/
|
||||
public function uploadFile($filePath, $folderId, $metadata = [])
|
||||
public function uploadFile($filePath, $folderId, $metadata = [], $sourceMetadata = null)
|
||||
{
|
||||
if (!file_exists($filePath)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'File not found: ' . $filePath
|
||||
'error' => 'File not found: ' . $filePath,
|
||||
'filename' => basename($filePath)
|
||||
];
|
||||
}
|
||||
|
||||
$filename = basename($filePath);
|
||||
$mimeType = mime_content_type($filePath);
|
||||
|
||||
// Build multipart form data
|
||||
$boundary = '----WebKitFormBoundary' . uniqid();
|
||||
// Get base URL from ApiClient using reflection
|
||||
$baseUrlReflection = new ReflectionProperty($this->apiClient, 'baseUrl');
|
||||
$baseUrlReflection->setAccessible(true);
|
||||
$baseUrl = $baseUrlReflection->getValue($this->apiClient);
|
||||
|
||||
// Build asset representation JSON
|
||||
$assetRepresentation = $this->buildAssetRepresentation($filename, $metadata);
|
||||
// Build URL
|
||||
$url = rtrim($baseUrl, '/') . '/v6/assets';
|
||||
|
||||
// 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
|
||||
// Build minimal asset representation with just the name
|
||||
$minimalAssetRep = [
|
||||
'asset_resource' => [
|
||||
'asset' => [
|
||||
'name' => $filename,
|
||||
'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
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Set multipart content-type header
|
||||
$this->apiClient->setHeader('Content-Type', "multipart/form-data; boundary={$boundary}");
|
||||
$postFields = [
|
||||
'asset_representation' => json_encode($minimalAssetRep),
|
||||
'parent_folder_id' => $folderId,
|
||||
'file' => new \CURLFile($filePath, $mimeType, $filename)
|
||||
];
|
||||
|
||||
$response = $this->apiClient->executeRequest($request);
|
||||
// Get authorization header
|
||||
$authHeader = '';
|
||||
$headersReflection = new ReflectionProperty($this->apiClient, 'headers');
|
||||
$headersReflection->setAccessible(true);
|
||||
$headers = $headersReflection->getValue($this->apiClient);
|
||||
if (isset($headers['Authorization'])) {
|
||||
$authHeader = $headers['Authorization'];
|
||||
}
|
||||
|
||||
if ($response['success'] && $response['http_code'] == 201) {
|
||||
$responseData = json_decode($response['body'], true);
|
||||
// Use curl directly for multipart upload
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $postFields,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Accept: application/json',
|
||||
'Authorization: ' . $authHeader
|
||||
],
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_TIMEOUT => 120
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
return [
|
||||
'success' => false,
|
||||
'filename' => $filename,
|
||||
'error' => 'CURL error: ' . $error,
|
||||
'http_code' => 0
|
||||
];
|
||||
}
|
||||
|
||||
if ($httpCode == 201) {
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'asset_id' => $responseData['asset_resource_list']['asset_resource'][0]['asset']['asset_id'] ?? null,
|
||||
'filename' => $filename,
|
||||
'response' => $responseData
|
||||
'http_code' => $httpCode
|
||||
];
|
||||
}
|
||||
|
||||
// Extract detailed error message from API response
|
||||
$errorMsg = 'Upload failed';
|
||||
if (!empty($response)) {
|
||||
$responseData = json_decode($response, true);
|
||||
if ($responseData && isset($responseData['exception_body'])) {
|
||||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||||
} elseif ($responseData && isset($responseData['error'])) {
|
||||
$errorMsg = $responseData['error'];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Upload failed',
|
||||
'http_code' => $response['http_code'],
|
||||
'response' => $response['body']
|
||||
'filename' => $filename,
|
||||
'error' => $errorMsg,
|
||||
'http_code' => $httpCode,
|
||||
'response_body' => $response
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build asset representation for upload
|
||||
* Build asset representation from source metadata (copying from master asset)
|
||||
* Updates filename but preserves all other metadata
|
||||
*/
|
||||
private function buildAssetRepresentationFromSource($filename, $sourceMetadata)
|
||||
{
|
||||
// Copy the entire metadata structure from the source
|
||||
$assetRep = [
|
||||
'asset_resource' => [
|
||||
'asset' => [
|
||||
'metadata' => $sourceMetadata,
|
||||
'name' => $filename
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Update the ASSET NAME field if it exists in the metadata
|
||||
if (isset($sourceMetadata['metadata_element_list'])) {
|
||||
foreach ($sourceMetadata['metadata_element_list'] as &$category) {
|
||||
if (isset($category['metadata_element_list'])) {
|
||||
foreach ($category['metadata_element_list'] as &$field) {
|
||||
if ($field['id'] === 'ARTESIA.FIELD.ASSET NAME') {
|
||||
$field['value']['value']['value'] = $filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $assetRep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build asset representation for upload (fallback when no source metadata)
|
||||
*/
|
||||
private function buildAssetRepresentation($filename, $metadata = [])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -186,33 +186,43 @@ class CampaignFormatter
|
|||
if (!isset($asset['metadata']['metadata_element_list'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
foreach ($asset['metadata']['metadata_element_list'] as $category) {
|
||||
if (!isset($category['metadata_element_list'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
foreach ($category['metadata_element_list'] as $element) {
|
||||
if ($element['id'] === $fieldId && isset($element['value']['value']['value'])) {
|
||||
return $element['value']['value']['value'];
|
||||
// Check if this is the field we're looking for
|
||||
if ($element['id'] === $fieldId) {
|
||||
// Handle domain values (like CONTENT.SCALING.STATUS)
|
||||
if (isset($element['value']['value']['field_value']['value'])) {
|
||||
return $element['value']['value']['field_value']['value'];
|
||||
}
|
||||
// Handle regular string fields
|
||||
if (isset($element['value']['value']['value'])) {
|
||||
return $element['value']['value']['value'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle tabular fields (like brand, market)
|
||||
if (isset($element['metadata_element_list'])) {
|
||||
foreach ($element['metadata_element_list'] as $tableField) {
|
||||
if ($tableField['id'] === $fieldId && isset($tableField['value']['value']['value'])) {
|
||||
return $tableField['value']['value']['value'];
|
||||
}
|
||||
|
||||
// Handle domain values
|
||||
if ($tableField['id'] === $fieldId && isset($tableField['value']['value']['field_value']['value'])) {
|
||||
return $tableField['value']['value']['display_value'] ?? $tableField['value']['value']['field_value']['value'];
|
||||
if ($tableField['id'] === $fieldId) {
|
||||
// Handle domain values in tables
|
||||
if (isset($tableField['value']['value']['field_value']['value'])) {
|
||||
return $tableField['value']['value']['field_value']['value'];
|
||||
}
|
||||
// Handle regular values in tables
|
||||
if (isset($tableField['value']['value']['value'])) {
|
||||
return $tableField['value']['value']['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -238,9 +248,10 @@ class CampaignFormatter
|
|||
'fiscal_year' => self::getMetadataValue($asset, 'FERRERO.FIELD.CAMPAIGN FISCAL YEAR'),
|
||||
'stage' => self::getMetadataValue($asset, 'FERRERO.FIELD.SG.STAGE'),
|
||||
'campaign_type' => self::getMetadataValue($asset, 'FERRERO.FIELD.CAMPAIGN TYPE'),
|
||||
'status' => self::getMetadataValue($asset, 'CONTENT.SCALING.STATUS'),
|
||||
'asset_data' => $asset
|
||||
];
|
||||
|
||||
|
||||
// Apply user-selected filters
|
||||
if (self::matchesFilters($campaign, $filters)) {
|
||||
$actionableCampaigns[] = $campaign;
|
||||
|
|
@ -256,35 +267,42 @@ class CampaignFormatter
|
|||
if (empty($filters)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Status filter (for Content Scaling workflow)
|
||||
if (!empty($filters['status']) && $filters['status'] !== 'all') {
|
||||
if ($campaign['status'] !== $filters['status']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage filter
|
||||
if (!empty($filters['stage']) && $filters['stage'] !== 'all') {
|
||||
if ($campaign['stage'] !== $filters['stage']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Campaign type filter
|
||||
if (!empty($filters['campaign_type']) && $filters['campaign_type'] !== 'all') {
|
||||
if ($campaign['campaign_type'] !== $filters['campaign_type']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Brand filter
|
||||
if (!empty($filters['brand']) && $filters['brand'] !== 'all') {
|
||||
if ($campaign['brand'] !== $filters['brand']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Market filter
|
||||
if (!empty($filters['market']) && $filters['market'] !== 'all') {
|
||||
if ($campaign['market'] !== $filters['market']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,15 +25,22 @@ class StatusManager
|
|||
*/
|
||||
public function updateCampaignStatus($folderId, $newStatus)
|
||||
{
|
||||
// Build metadata update request
|
||||
// Build metadata update request according to V3 API spec
|
||||
// Uses PATCH method with edited_folder structure
|
||||
$metadataUpdate = [
|
||||
'metadata_to_update' => [
|
||||
'metadata_element' => [
|
||||
[
|
||||
'id' => $this->statusFieldId,
|
||||
'value' => [
|
||||
'edited_folder' => [
|
||||
'data' => [
|
||||
'metadata' => [
|
||||
[
|
||||
'id' => $this->statusFieldId,
|
||||
'type' => 'com.artesia.metadata.MetadataField',
|
||||
'value' => [
|
||||
'value' => $newStatus
|
||||
'cascading_domain_value' => false,
|
||||
'domain_value' => true,
|
||||
'value' => [
|
||||
'type' => 'string',
|
||||
'value' => $newStatus
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
@ -42,9 +49,15 @@ class StatusManager
|
|||
];
|
||||
|
||||
$request = [
|
||||
'method' => 'POST',
|
||||
'url' => "/v6/folders/{$folderId}/metadata",
|
||||
'body' => json_encode($metadataUpdate)
|
||||
'method' => 'PATCH',
|
||||
'url' => "/v6/folders/{$folderId}?lock_strategy=optimistic",
|
||||
'header' => [
|
||||
['key' => 'Content-Type', 'value' => 'application/json'],
|
||||
['key' => 'Accept', 'value' => 'application/json']
|
||||
],
|
||||
'body' => [
|
||||
'raw' => json_encode($metadataUpdate)
|
||||
]
|
||||
];
|
||||
|
||||
$response = $this->apiClient->executeRequest($request);
|
||||
|
|
@ -186,6 +199,75 @@ class StatusManager
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search ALL campaigns (without status filter)
|
||||
* Stores the TestRunner instance to use actual Postman requests
|
||||
*
|
||||
* @return array API response with all campaigns
|
||||
*/
|
||||
public function searchAllCampaigns($testRunner = null)
|
||||
{
|
||||
// If TestRunner provided, try to use actual Postman request first
|
||||
if ($testRunner) {
|
||||
$requests = $testRunner->getAvailableRequests();
|
||||
|
||||
foreach ($requests as $index => $request) {
|
||||
$name = strtolower($request['name']);
|
||||
// Find the "Retrieve Localized Campaign Folders" request
|
||||
if (strpos($name, 'retrieve localized campaign') !== false ||
|
||||
strpos($name, 'localized campaign folders') !== false) {
|
||||
|
||||
// Run the actual Postman request
|
||||
$result = $testRunner->runSingleTest($request, $index);
|
||||
|
||||
if ($result['status'] === 'PASS') {
|
||||
return [
|
||||
'success' => true,
|
||||
'http_code' => 200,
|
||||
'body' => $result['response']['body'],
|
||||
'url' => 'From Postman Collection'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Build our own search query
|
||||
$searchCondition = [
|
||||
'search_condition_list' => [
|
||||
'search_condition' => [
|
||||
[
|
||||
'type' => 'com.artesia.search.SearchScalarCondition',
|
||||
'metadata_field_id' => 'ARTESIA.FIELD.CONTAINER TYPE NAME',
|
||||
'relational_operator_id' => 'ARTESIA.OPERATOR.CHAR.CONTAINS',
|
||||
'value' => 'GLOBALCAMPAING',
|
||||
'display_value' => 'L7+ - CAMPAIGN',
|
||||
'left_paren' => '(',
|
||||
'right_paren' => ')'
|
||||
],
|
||||
[
|
||||
'type' => 'com.artesia.search.SearchScalarCondition',
|
||||
'metadata_field_id' => 'FERRERO.FIELD.CAMPAIGN TYPE',
|
||||
'relational_operator_id' => 'ARTESIA.OPERATOR.CHAR.CONTAINS',
|
||||
'relational_operator_name' => 'contains',
|
||||
'value' => 'Local Adaptation',
|
||||
'relational_operator' => 'and'
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Use rawurlencode to avoid + signs (use %20 for spaces)
|
||||
$searchConditionEncoded = rawurlencode(json_encode($searchCondition));
|
||||
|
||||
$request = [
|
||||
'method' => 'GET',
|
||||
'url' => "/v6/search/text?load_type=metadata&search_config_id=18&search_condition_list={$searchConditionEncoded}"
|
||||
];
|
||||
|
||||
return $this->apiClient->executeRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search campaigns by status
|
||||
*
|
||||
|
|
@ -228,7 +310,8 @@ class StatusManager
|
|||
]
|
||||
];
|
||||
|
||||
$searchConditionEncoded = urlencode(json_encode($searchCondition));
|
||||
// Use rawurlencode to avoid + signs (use %20 for spaces)
|
||||
$searchConditionEncoded = rawurlencode(json_encode($searchCondition));
|
||||
|
||||
$request = [
|
||||
'method' => 'GET',
|
||||
|
|
|
|||
303
workflow_v3.php
303
workflow_v3.php
|
|
@ -72,6 +72,40 @@ if ($_POST && $testRunner) {
|
|||
|
||||
try {
|
||||
switch ($action) {
|
||||
case 'debug_all_campaigns':
|
||||
// Check OAuth status first
|
||||
$oauth2Status = $testRunner->getOAuth2Status();
|
||||
$results['oauth_debug'] = [
|
||||
'has_token' => $oauth2Status['has_token'] ?? false,
|
||||
'expires_at' => $oauth2Status['expires_at'] ?? 'Unknown'
|
||||
];
|
||||
|
||||
$statusManager = createStatusManager($testRunner);
|
||||
$response = $statusManager->searchAllCampaigns($testRunner);
|
||||
|
||||
if ($response['success']) {
|
||||
$data = json_decode($response['body'], true);
|
||||
$campaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||||
$results['debug_campaigns'] = $campaigns;
|
||||
$results['debug_raw'] = $data;
|
||||
$results['debug_search_response'] = [
|
||||
'http_code' => $response['http_code'],
|
||||
'url' => $response['url'] ?? 'N/A',
|
||||
'total_results' => $data['search_result_resource']['search_result']['total_hit_count'] ?? 0,
|
||||
'response_body_preview' => substr($response['body'] ?? '', 0, 500)
|
||||
];
|
||||
$success = "Found " . count($campaigns) . " campaigns total (without status filter)";
|
||||
} else {
|
||||
$error = "Debug search failed: HTTP " . ($response['http_code'] ?? 'N/A') . " - " . ($response['error'] ?? 'Unknown error');
|
||||
$results['debug_search_response'] = [
|
||||
'http_code' => $response['http_code'],
|
||||
'url' => $response['url'] ?? 'N/A',
|
||||
'error' => $response['error'] ?? 'Unknown',
|
||||
'response_preview' => substr($response['body'] ?? '', 0, 500)
|
||||
];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'load_campaigns_a1':
|
||||
$results['a1_campaigns'] = loadCampaignsByStatus($testRunner, 'A1');
|
||||
$success = "Loaded " . count($results['a1_campaigns']) . " campaigns with status A1";
|
||||
|
|
@ -136,10 +170,40 @@ if ($_POST && $testRunner) {
|
|||
if (isset($results['master_assets']) && isset($results['selected_campaign'])) {
|
||||
$downloadResults = downloadAllAssets($testRunner, $results['master_assets'], $results['selected_campaign']['campaign_id']);
|
||||
$results['bulk_download'] = $downloadResults;
|
||||
// Store master assets metadata for later upload reference
|
||||
$results['master_assets_metadata'] = $results['master_assets'];
|
||||
$success = "Downloaded {$downloadResults['successful']} of {$downloadResults['total']} assets";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'reset_to_a1':
|
||||
$campaignId = $_POST['campaign_id'] ?? '';
|
||||
if ($campaignId) {
|
||||
$statusManager = createStatusManager($testRunner);
|
||||
$statusResult = $statusManager->updateCampaignStatus($campaignId, 'A1');
|
||||
|
||||
if ($statusResult['success']) {
|
||||
$success = "Campaign reset to A1 status for testing";
|
||||
// Clear session data so we can start fresh
|
||||
unset($results['selected_campaign']);
|
||||
unset($results['selected_campaign_a2']);
|
||||
unset($results['master_assets_metadata']);
|
||||
} else {
|
||||
$errorMsg = "Unknown error";
|
||||
if (isset($statusResult['response']['body'])) {
|
||||
$responseData = json_decode($statusResult['response']['body'], true);
|
||||
if ($responseData && isset($responseData['exception_body'])) {
|
||||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||||
} elseif ($responseData && isset($responseData['error'])) {
|
||||
$errorMsg = $responseData['error'];
|
||||
}
|
||||
}
|
||||
$error = "Failed to reset to A1 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||||
}
|
||||
}
|
||||
$currentTab = $_POST['tab'] ?? 'download';
|
||||
break;
|
||||
|
||||
case 'update_status_to_a2':
|
||||
if (isset($results['selected_campaign'])) {
|
||||
$statusManager = createStatusManager($testRunner);
|
||||
|
|
@ -153,7 +217,19 @@ if ($_POST && $testRunner) {
|
|||
$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');
|
||||
// Extract error details from API response
|
||||
$errorMsg = "Unknown error";
|
||||
if (isset($statusResult['response']['body'])) {
|
||||
$responseData = json_decode($statusResult['response']['body'], true);
|
||||
if ($responseData && isset($responseData['exception_body'])) {
|
||||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||||
} elseif ($responseData && isset($responseData['error'])) {
|
||||
$errorMsg = $responseData['error'];
|
||||
}
|
||||
}
|
||||
$error = "Failed to update status to A2 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||||
// Store full result for debugging
|
||||
$results['status_update_error'] = $statusResult;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -196,7 +272,10 @@ if ($_POST && $testRunner) {
|
|||
|
||||
case 'upload_files':
|
||||
if (isset($_FILES['upload_files']) && isset($results['upload_folder_id'])) {
|
||||
$uploadResults = uploadFiles($testRunner, $_FILES['upload_files'], $results['upload_folder_id']);
|
||||
// Use master assets metadata if available (from A1 campaign downloads)
|
||||
$masterMetadata = $results['master_assets_metadata'] ?? null;
|
||||
|
||||
$uploadResults = uploadFiles($testRunner, $_FILES['upload_files'], $results['upload_folder_id'], $masterMetadata);
|
||||
$results['upload_results'] = $uploadResults;
|
||||
|
||||
if ($uploadResults['successful'] > 0) {
|
||||
|
|
@ -220,7 +299,18 @@ if ($_POST && $testRunner) {
|
|||
$results['status_update_a3'] = $statusResult;
|
||||
$success = "Campaign status updated to A3: Localized Asset received from Agency";
|
||||
} else {
|
||||
$error = "Failed to update status";
|
||||
// Extract error details from API response
|
||||
$errorMsg = "Unknown error";
|
||||
if (isset($statusResult['response']['body'])) {
|
||||
$responseData = json_decode($statusResult['response']['body'], true);
|
||||
if ($responseData && isset($responseData['exception_body'])) {
|
||||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||||
} elseif ($responseData && isset($responseData['error'])) {
|
||||
$errorMsg = $responseData['error'];
|
||||
}
|
||||
}
|
||||
$error = "Failed to update status to A3 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||||
$results['status_update_a3_error'] = $statusResult;
|
||||
}
|
||||
}
|
||||
$currentTab = 'upload';
|
||||
|
|
@ -311,7 +401,18 @@ if ($_POST && $testRunner) {
|
|||
$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";
|
||||
// Extract error details from API response
|
||||
$errorMsg = "Unknown error";
|
||||
if (isset($statusResult['response']['body'])) {
|
||||
$responseData = json_decode($statusResult['response']['body'], true);
|
||||
if ($responseData && isset($responseData['exception_body'])) {
|
||||
$errorMsg = $responseData['exception_body']['message'] ?? $responseData['exception_body']['debug_message'] ?? 'API Error';
|
||||
} elseif ($responseData && isset($responseData['error'])) {
|
||||
$errorMsg = $responseData['error'];
|
||||
}
|
||||
}
|
||||
$error = "Failed to update status to A6 (HTTP {$statusResult['http_code']}): {$errorMsg}";
|
||||
$results['status_update_a6_error'] = $statusResult;
|
||||
}
|
||||
}
|
||||
$currentTab = 'rework';
|
||||
|
|
@ -326,12 +427,25 @@ if ($_POST && $testRunner) {
|
|||
|
||||
function loadCampaignsByStatus($testRunner, $status)
|
||||
{
|
||||
// Search for ALL Local Adaptation campaigns (without status filter in API)
|
||||
// Then let CampaignFormatter filter by status in PHP
|
||||
$statusManager = createStatusManager($testRunner);
|
||||
$response = $statusManager->searchCampaignsByStatus($status);
|
||||
$response = $statusManager->searchAllCampaigns($testRunner);
|
||||
|
||||
if ($response['success']) {
|
||||
$data = json_decode($response['body'], true);
|
||||
return CampaignFormatter::getActionableCampaigns($response['body'], ['status' => $status]);
|
||||
// Get ALL campaigns first
|
||||
$allCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], []);
|
||||
|
||||
// Debug: Store all campaigns to see their statuses
|
||||
global $results;
|
||||
$results['debug_all_campaigns_count'] = count($allCampaigns);
|
||||
$results['debug_status_filter'] = $status;
|
||||
|
||||
// Now filter by status
|
||||
$filteredCampaigns = CampaignFormatter::getActionableCampaigns($response['body'], ['status' => $status]);
|
||||
$results['debug_filtered_count'] = count($filteredCampaigns);
|
||||
|
||||
return $filteredCampaigns;
|
||||
}
|
||||
|
||||
return [];
|
||||
|
|
@ -702,7 +816,7 @@ function findUploadFolder($testRunner, $campaignId, $configV3)
|
|||
return null;
|
||||
}
|
||||
|
||||
function uploadFiles($testRunner, $uploadedFiles, $folderId)
|
||||
function uploadFiles($testRunner, $uploadedFiles, $folderId, $masterAssetsMetadata = null)
|
||||
{
|
||||
$apiClient = new ApiClient();
|
||||
$configV3 = new ConfigV3();
|
||||
|
|
@ -744,7 +858,14 @@ function uploadFiles($testRunner, $uploadedFiles, $folderId)
|
|||
continue;
|
||||
}
|
||||
|
||||
$result = $uploader->uploadFile($tmpName, $folderId);
|
||||
// Extract metadata from master asset if available
|
||||
$assetMetadata = null;
|
||||
if ($masterAssetsMetadata && is_array($masterAssetsMetadata)) {
|
||||
// Try to find matching master asset by filename or use first one
|
||||
$assetMetadata = $masterAssetsMetadata[0]['metadata'] ?? null;
|
||||
}
|
||||
|
||||
$result = $uploader->uploadFile($tmpName, $folderId, [], $assetMetadata);
|
||||
|
||||
if ($result['success']) {
|
||||
$results['successful']++;
|
||||
|
|
@ -1054,7 +1175,13 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A1)</button>
|
||||
</form>
|
||||
|
||||
<form method="POST" style="display: inline-block;">
|
||||
<input type="hidden" name="tab" value="download">
|
||||
<input type="hidden" name="action" value="debug_all_campaigns">
|
||||
<button type="submit" class="btn btn-secondary">🔍 Debug: Load ALL Campaigns (no filter)</button>
|
||||
</form>
|
||||
|
||||
<?php if (!empty($results)): ?>
|
||||
|
|
@ -1065,6 +1192,84 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['debug_campaigns']) || isset($results['debug_search_response'])): ?>
|
||||
<div class="alert alert-<?= ($results['debug_search_response']['http_code'] ?? 0) == 503 ? 'error' : 'info' ?>" style="margin-top: 30px;">
|
||||
<h3>🔍 Debug Results: Found <?= count($results['debug_campaigns'] ?? []) ?> Campaigns</h3>
|
||||
|
||||
<?php if (isset($results['oauth_debug'])): ?>
|
||||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||||
<strong>OAuth Status:</strong>
|
||||
<?= $results['oauth_debug']['has_token'] ? '✅ Token Active' : '❌ No Token' ?> |
|
||||
Expires: <?= htmlspecialchars($results['oauth_debug']['expires_at']) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['debug_search_response'])): ?>
|
||||
<p style="font-size: 13px; margin: 10px 0; padding: 10px; background: white; border-radius: 4px;">
|
||||
<strong>API Response:</strong> HTTP <?= $results['debug_search_response']['http_code'] ?>
|
||||
<?php if ($results['debug_search_response']['http_code'] == 503): ?>
|
||||
<span style="color: #dc3545; font-weight: bold;">- Service Unavailable (Server may be down or OAuth token expired)</span>
|
||||
<?php endif; ?>
|
||||
<br>
|
||||
<strong>Total results from API:</strong> <?= $results['debug_search_response']['total_results'] ?? 0 ?><br>
|
||||
<strong>URL:</strong> <code style="font-size: 11px;"><?= htmlspecialchars($results['debug_search_response']['url']) ?></code>
|
||||
<?php if (isset($results['debug_search_response']['response_body_preview'])): ?>
|
||||
<details style="margin-top: 10px;">
|
||||
<summary style="cursor: pointer;">View Response Body</summary>
|
||||
<pre style="font-size: 11px; background: #f8f9fa; padding: 10px; margin-top: 5px;"><?= htmlspecialchars($results['debug_search_response']['response_body_preview']) ?></pre>
|
||||
</details>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($results['debug_campaigns'])): ?>
|
||||
<p>Showing ALL campaigns without status filter to see their metadata fields:</p>
|
||||
|
||||
<?php foreach ($results['debug_campaigns'] as $idx => $campaign): ?>
|
||||
<details style="margin: 15px 0; background: white; padding: 15px; border-radius: 6px;">
|
||||
<summary style="cursor: pointer; font-weight: 600;">
|
||||
Campaign <?= $idx + 1 ?>: <?= htmlspecialchars($campaign['campaign_name'] ?? 'Unnamed') ?>
|
||||
(<?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?>)
|
||||
- Content Scaling Status: <span class="status-badge status-<?= strtolower($campaign['status'] ?? 'unknown') ?>"><?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></span>
|
||||
</summary>
|
||||
<div style="margin-top: 15px;">
|
||||
<p><strong>Asset ID:</strong> <?= htmlspecialchars($campaign['asset_id']) ?></p>
|
||||
<p><strong>Campaign ID:</strong> <?= htmlspecialchars($campaign['campaign_id'] ?? 'N/A') ?></p>
|
||||
<p><strong>Content Scaling Status:</strong> <?= htmlspecialchars($campaign['status'] ?? 'NOT FOUND') ?></p>
|
||||
<p><strong>Brand:</strong> <?= htmlspecialchars($campaign['brand'] ?? 'N/A') ?></p>
|
||||
<p><strong>Market:</strong> <?= htmlspecialchars($campaign['market'] ?? 'N/A') ?></p>
|
||||
|
||||
<form method="POST" style="margin-top: 15px; display: inline-block;">
|
||||
<input type="hidden" name="tab" value="download">
|
||||
<input type="hidden" name="action" value="reset_to_a1">
|
||||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||||
<button type="submit" class="btn btn-danger" onclick="return confirm('Reset campaign <?= htmlspecialchars($campaign['campaign_name']) ?> to A1 status?')">
|
||||
🔄 Reset to A1 (for testing)
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<details style="margin-top: 10px;">
|
||||
<summary style="cursor: pointer; font-size: 13px;">View Full Raw Metadata</summary>
|
||||
<pre style="background: #f0f0f0; padding: 10px; border-radius: 4px; overflow: auto; max-height: 400px; font-size: 11px; margin-top: 10px;"><?= htmlspecialchars(json_encode($campaign, JSON_PRETTY_PRINT)) ?></pre>
|
||||
</details>
|
||||
</div>
|
||||
</details>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<p style="margin-top: 15px;">No campaigns returned from API (check OAuth status and response body above)</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['debug_all_campaigns_count'])): ?>
|
||||
<div class="alert alert-info" style="margin-top: 20px;">
|
||||
<strong>🔍 Debug Info:</strong><br>
|
||||
Found <?= $results['debug_all_campaigns_count'] ?> total campaigns before filtering<br>
|
||||
Filtering for Content Scaling Status: "<?= htmlspecialchars($results['debug_status_filter']) ?>"<br>
|
||||
Campaigns after filtering: <?= $results['debug_filtered_count'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['a1_campaigns']) && !empty($results['a1_campaigns'])): ?>
|
||||
<h3 style="margin-top: 30px;">Found <?= count($results['a1_campaigns']) ?> Campaigns</h3>
|
||||
<div class="campaign-grid">
|
||||
|
|
@ -1076,7 +1281,7 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a1"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Ready for Localization</span></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
|
@ -1272,6 +1477,37 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['status_update_error'])): ?>
|
||||
<div class="alert alert-error" style="margin-top: 20px;">
|
||||
<strong>⚠️ Status Update Debug Information:</strong>
|
||||
<details style="margin-top: 10px;">
|
||||
<summary style="cursor: pointer; font-weight: 600;">View detailed error information</summary>
|
||||
<div style="margin-top: 10px; font-size: 12px; font-family: monospace;">
|
||||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||||
<strong>HTTP Status Code:</strong> <?= htmlspecialchars($results['status_update_error']['http_code']) ?>
|
||||
</div>
|
||||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||||
<strong>Folder ID:</strong> <?= htmlspecialchars($results['status_update_error']['folder_id']) ?>
|
||||
</div>
|
||||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||||
<strong>Target Status:</strong> <?= htmlspecialchars($results['status_update_error']['new_status']) ?>
|
||||
</div>
|
||||
<?php if (isset($results['status_update_error']['response']['body'])): ?>
|
||||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||||
<strong>API Response Body:</strong>
|
||||
<pre style="margin-top: 5px; white-space: pre-wrap; word-wrap: break-word;"><?= htmlspecialchars($results['status_update_error']['response']['body']) ?></pre>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($results['status_update_error']['response']['url'])): ?>
|
||||
<div style="background: #f8f9fa; padding: 10px; border-radius: 4px; margin: 5px 0;">
|
||||
<strong>Request URL:</strong> <?= htmlspecialchars($results['status_update_error']['response']['url']) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($results['last_download'])): ?>
|
||||
<?php $dl = $results['last_download']; ?>
|
||||
<div class="alert alert-<?= $dl['success'] ? 'success' : 'error' ?>" style="margin-top: 20px;">
|
||||
|
|
@ -1332,7 +1568,7 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A2)</button>
|
||||
</form>
|
||||
|
||||
<?php if (!empty($results) && $currentTab === 'upload'): ?>
|
||||
|
|
@ -1354,7 +1590,16 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a2"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Assets Sent to Agency</span></p>
|
||||
|
||||
<form method="POST" style="margin-top: 10px;" onclick="event.stopPropagation();">
|
||||
<input type="hidden" name="tab" value="upload">
|
||||
<input type="hidden" name="action" value="reset_to_a1">
|
||||
<input type="hidden" name="campaign_id" value="<?= htmlspecialchars($campaign['asset_id']) ?>">
|
||||
<button type="submit" class="btn btn-danger" style="font-size: 12px; padding: 8px 12px;" onclick="return confirm('Reset <?= htmlspecialchars($campaign['campaign_name']) ?> to A1 for testing?')">
|
||||
🔄 Reset to A1
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
|
@ -1391,6 +1636,19 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
</div>
|
||||
|
||||
<h3 style="margin-top: 30px;">Upload Processed Files</h3>
|
||||
|
||||
<?php if (isset($results['master_assets_metadata'])): ?>
|
||||
<div class="alert alert-success" style="margin-bottom: 20px;">
|
||||
✅ Master asset metadata detected - uploads will inherit metadata from downloaded assets
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-info" style="margin-bottom: 20px;">
|
||||
ℹ️ <strong>Note:</strong> For best results, complete the full workflow in one session:
|
||||
Download (A1) → Update to A2 → Upload (A2)
|
||||
<br><small>This preserves master asset metadata for the uploaded files.</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="tab" value="upload">
|
||||
<input type="hidden" name="action" value="upload_files">
|
||||
|
|
@ -1400,10 +1658,10 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
Select files to upload:
|
||||
</label>
|
||||
<input type="file" name="upload_files[]" multiple
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.ai,.psd,.eps,.tif,.tiff"
|
||||
accept=".jpg,.jpeg,.png,.gif,.pdf,.ai,.psd,.eps,.tif,.tiff,.mov,.mp4,.avi,.zip,.txt,.doc,.docx,.xls,.xlsx"
|
||||
style="padding: 10px; border: 2px dashed #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
|
||||
Accepted formats: Images (JPG, PNG, GIF, TIFF), Documents (PDF, AI, PSD, EPS), Video (MOV, MP4, AVI), Archives (ZIP), Office (DOC, XLS, TXT)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -1428,7 +1686,16 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<br><small>Asset ID: <?= htmlspecialchars($detail['asset_id'] ?? 'N/A') ?></small>
|
||||
<?php else: ?>
|
||||
❌ <?= htmlspecialchars($detail['filename'] ?? 'Unknown') ?>
|
||||
<br><small>Error: <?= htmlspecialchars($detail['error']) ?></small>
|
||||
<br><small style="color: #dc3545;"><strong>Error:</strong> <?= htmlspecialchars($detail['error']) ?></small>
|
||||
<?php if (isset($detail['http_code'])): ?>
|
||||
<br><small>HTTP Code: <?= $detail['http_code'] ?></small>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($detail['response_body']) && !empty($detail['response_body'])): ?>
|
||||
<details style="margin-top: 5px;">
|
||||
<summary style="cursor: pointer; font-size: 11px;">View API Response</summary>
|
||||
<pre style="font-size: 10px; background: #f8f9fa; padding: 5px; margin-top: 5px; max-height: 200px; overflow: auto;"><?= htmlspecialchars($detail['response_body']) ?></pre>
|
||||
</details>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
|
@ -1464,7 +1731,7 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<button type="submit" class="btn btn-primary">Load Campaigns (Content Scaling Status = A5)</button>
|
||||
</form>
|
||||
|
||||
<?php if (!empty($results) && $currentTab === 'rework'): ?>
|
||||
|
|
@ -1486,7 +1753,7 @@ $envInfo = $configV3->getEnvironmentInfo();
|
|||
<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>
|
||||
<p><strong>Content Scaling Status:</strong> <span class="status-badge status-a5"><?= htmlspecialchars($campaign['status'] ?? 'N/A') ?> - Rework Needed</span></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue