Disable master assets fetching in upload - causes PHP crashes

Upload workflow issues:
- Master asset metadata structures too large for PHP to process
- Causes session storage crashes and HTTP 500 errors
- Temporarily disabled master assets fetching
- Upload folder finding still works

Current upload status:
- ALL file extensions (.tif, .jpg, .png) rejected by API
- Error: "Cannot import asset having restricted file extension"
- Tested with minimal payloads (just manifest + folder + file)
- Suggests server-level restrictions or account permissions issue

Awaiting client confirmation on:
- API upload permissions for user account
- Allowed file extensions for API uploads
- Alternative upload methods if API is restricted

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DJP 2025-10-24 11:17:26 -04:00
parent 3a41a4f964
commit 0ebdf5c755
2 changed files with 135 additions and 86 deletions

View file

@ -74,23 +74,35 @@ class AssetUploader
]
];
// Build minimal asset_representation - just name and security policy
// NO metadata structure, NO metadata_model_id - just bare essentials
$minimalRep = [
'asset_resource' => [
'asset' => [
'name' => $filename,
'security_policy_list' => [['id' => 1594]]
]
]
];
// Build asset_representation
if ($sourceMasterAsset) {
// Use master asset's full metadata structure
$assetRep = $this->buildAssetRepresentationFromMasterAsset($filename, $sourceMasterAsset);
$postFields = [
'asset_representation' => json_encode($minimalRep),
'manifest' => json_encode($uploadManifest),
'parent_folder_id' => $folderId,
'files' => new \CURLFile($filePath, $mimeType, $filename)
];
$postFields = [
'asset_representation' => json_encode($assetRep),
'manifest' => json_encode($uploadManifest),
'parent_folder_id' => $folderId,
'files' => new \CURLFile($filePath, $mimeType, $filename)
];
} else {
// No master asset - minimal representation (will likely fail)
$minimalRep = [
'asset_resource' => [
'asset' => [
'name' => $filename,
'security_policy_list' => [['id' => 1594]]
]
]
];
$postFields = [
'asset_representation' => json_encode($minimalRep),
'manifest' => json_encode($uploadManifest),
'parent_folder_id' => $folderId,
'files' => new \CURLFile($filePath, $mimeType, $filename)
];
}
// Get authorization header
$authHeader = '';
@ -101,7 +113,7 @@ class AssetUploader
$authHeader = $headers['Authorization'];
}
// Use curl directly for multipart upload
// Use curl directly for multipart upload with extended timeout
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
@ -113,19 +125,31 @@ class AssetUploader
'Authorization: ' . $authHeader
],
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 120
CURLOPT_TIMEOUT => 300, // 5 minutes
CURLOPT_CONNECTTIMEOUT => 30
]);
$response = curl_exec($ch);
// Execute with error suppression to prevent crashes
set_time_limit(300); // Give PHP 5 minutes
$response = @curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
$curlError = curl_error($ch);
curl_close($ch);
if ($error) {
if ($curlError) {
return [
'success' => false,
'filename' => $filename,
'error' => 'CURL error: ' . $error,
'error' => 'CURL error: ' . $curlError,
'http_code' => 0
];
}
if ($response === false) {
return [
'success' => false,
'filename' => $filename,
'error' => 'Upload request failed - no response received',
'http_code' => 0
];
}
@ -168,45 +192,31 @@ class AssetUploader
*/
private function buildAssetRepresentationFromMasterAsset($filename, $masterAsset)
{
// Extract key fields from master asset
$metadataModelId = $masterAsset['metadata_model_id'] ?? null;
$securityPolicies = $masterAsset['security_policy_list'] ?? null;
$metadata = $masterAsset['metadata'] ?? [];
// Extract ONLY the critical IDs - no metadata structure at all
$metadataModelId = $masterAsset['metadata_model_id'] ?? 'ECOMMERCE';
// Debug: Log what we're using
error_log("Upload Debug - Metadata Model ID: " . ($metadataModelId ?? 'NULL'));
error_log("Upload Debug - Master Asset Keys: " . implode(', ', array_keys($masterAsset)));
// Simplify security policies to just IDs
$securityPolicyIds = [];
if (isset($masterAsset['security_policy_list'])) {
foreach ($masterAsset['security_policy_list'] as $policy) {
$securityPolicyIds[] = ['id' => $policy['id'] ?? 1594];
}
}
if (empty($securityPolicyIds)) {
$securityPolicyIds = [['id' => 1594]];
}
// Build asset representation WITHOUT metadata_model_id
// The metadata structure itself contains the model info
// Build minimal asset representation - NO metadata structure to avoid crash
$assetRep = [
'asset_resource' => [
'asset' => [
'name' => $filename,
'metadata' => $metadata,
'security_policy_list' => $securityPolicies ?: [['id' => 1594]]
'metadata_model_id' => $metadataModelId,
'security_policy_list' => $securityPolicyIds
]
]
];
// DO NOT include metadata_model_id - it causes file extension restrictions
// The metadata structure already has the model ID embedded in metadata.id
// Update the ARTESIA.FIELD.ASSET NAME field in metadata if it exists
if (isset($metadata['metadata_element_list'])) {
foreach ($assetRep['asset_resource']['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.ASSET NAME') {
if (isset($field['value']['value']['value'])) {
$field['value']['value']['value'] = $filename;
}
}
}
}
}
}
return $assetRep;
}

View file

@ -263,15 +263,10 @@ if ($_POST && $testRunner) {
if ($uploadFolderId) {
$results['upload_folder_id'] = $uploadFolderId;
$success = "Found upload target folder";
// ALSO get Master Assets to copy their metadata
$masterFolderId = findMasterAssetsFolder($testRunner, $campaignId, $configV3);
if ($masterFolderId) {
$results['master_assets_for_upload'] = getAssetsFromFolder($testRunner, $masterFolderId);
$success = "Found upload folder and " . count($results['master_assets_for_upload']) . " master assets for metadata reference";
} else {
$success = "Found upload target folder (no master assets found)";
}
// TODO: Master assets fetching disabled - causes PHP crashes due to metadata size
// Will re-enable once upload file extension issue is resolved
} else {
$error = "Upload folder not found in campaign";
}
@ -281,34 +276,38 @@ if ($_POST && $testRunner) {
case 'upload_files':
if (isset($_FILES['upload_files']) && isset($results['upload_folder_id'])) {
// Get selected master asset metadata if user chose one
$selectedMasterAsset = null;
$masterMetadataIndex = $_POST['master_metadata_index'] ?? '';
// Get selected master asset lightweight data
$selectedMasterAssetLight = null;
$masterMetadataIndex = $_POST['master_metadata_index'] ?? '0';
// Use master_assets_for_upload (fetched in Upload workflow)
// Use master_assets_for_upload (lightweight version)
if ($masterMetadataIndex !== '' && isset($results['master_assets_for_upload'][$masterMetadataIndex])) {
$selectedMasterAsset = $results['master_assets_for_upload'][$masterMetadataIndex];
$selectedMasterAssetLight = $results['master_assets_for_upload'][$masterMetadataIndex];
} elseif (isset($results['master_assets_for_upload']) && !empty($results['master_assets_for_upload'])) {
// If no selection, use first master asset as default
$selectedMasterAsset = $results['master_assets_for_upload'][0];
$selectedMasterAssetLight = $results['master_assets_for_upload'][0];
}
// Use the lightweight master asset data directly
// Full metadata fetch causes crashes - we only need model ID and security policies
$selectedMasterAsset = $selectedMasterAssetLight;
// Store debug info about selected master asset and uploaded file
if ($selectedMasterAsset) {
$uploadFileName = is_array($_FILES['upload_files']['name']) ? $_FILES['upload_files']['name'][0] : $_FILES['upload_files']['name'];
$uploadTmpName = is_array($_FILES['upload_files']['tmp_name']) ? $_FILES['upload_files']['tmp_name'][0] : $_FILES['upload_files']['tmp_name'];
$uploadMimeType = file_exists($uploadTmpName) ? mime_content_type($uploadTmpName) : 'Unknown';
$uploadFileName = is_array($_FILES['upload_files']['name']) ? $_FILES['upload_files']['name'][0] : $_FILES['upload_files']['name'];
$uploadTmpName = is_array($_FILES['upload_files']['tmp_name']) ? $_FILES['upload_files']['tmp_name'][0] : $_FILES['upload_files']['tmp_name'];
$uploadMimeType = file_exists($uploadTmpName) ? mime_content_type($uploadTmpName) : 'Unknown';
$results['upload_debug'] = [
'selected_master_asset_id' => $selectedMasterAsset['asset_id'] ?? 'N/A',
'selected_master_name' => extractFolderName($selectedMasterAsset),
'metadata_model_id' => $selectedMasterAsset['metadata_model_id'] ?? 'NOT FOUND',
'has_security_policies' => isset($selectedMasterAsset['security_policy_list']) ? 'YES' : 'NO',
'master_mime_type' => $selectedMasterAsset['mime_type'] ?? 'Unknown',
'upload_filename' => $uploadFileName,
'upload_detected_mime' => $uploadMimeType
];
}
$results['upload_debug'] = [
'selected_master_asset_id' => $selectedMasterAsset['asset_id'] ?? 'N/A',
'selected_master_name' => $selectedMasterAsset['name'] ?? 'N/A',
'metadata_model_id' => $selectedMasterAsset['metadata_model_id'] ?? 'NOT FOUND',
'has_security_policies' => isset($selectedMasterAsset['security_policy_list']) ? 'YES' : 'NO',
'security_policy_count' => isset($selectedMasterAsset['security_policy_list']) ? count($selectedMasterAsset['security_policy_list']) : 0,
'master_mime_type' => $selectedMasterAsset['mime_type'] ?? 'Unknown',
'upload_filename' => $uploadFileName,
'upload_detected_mime' => $uploadMimeType,
'upload_folder_id' => $results['upload_folder_id']
];
$uploadResults = uploadFiles($testRunner, $_FILES['upload_files'], $results['upload_folder_id'], $selectedMasterAsset);
$results['upload_results'] = $uploadResults;
@ -913,6 +912,36 @@ function findUploadFolder($testRunner, $campaignId, $configV3)
return null;
}
function fetchFullAssetMetadata($testRunner, $assetId)
{
$apiClient = new ApiClient();
$configV3 = new ConfigV3();
$apiClient->setBaseUrl($configV3->getBaseUrl());
// Get OAuth2 token
$oauth2Handler = new ReflectionProperty($testRunner, 'oauth2Handler');
$oauth2Handler->setAccessible(true);
$oauth2HandlerInstance = $oauth2Handler->getValue($testRunner);
if ($oauth2HandlerInstance) {
$apiClient->setHeader('Authorization', $oauth2HandlerInstance->getAuthHeader());
}
// Fetch full asset with metadata
$request = [
'method' => 'GET',
'url' => "/v6/assets/{$assetId}?load_type=full"
];
$response = $apiClient->executeRequest($request);
if ($response['success']) {
$data = json_decode($response['body'], true);
return $data['asset'] ?? null;
}
return null;
}
function uploadFiles($testRunner, $uploadedFiles, $folderId, $selectedMasterAsset = null)
{
$apiClient = new ApiClient();
@ -955,8 +984,8 @@ function uploadFiles($testRunner, $uploadedFiles, $folderId, $selectedMasterAsse
continue;
}
// Pass the entire selected master asset (not just metadata)
$result = $uploader->uploadFile($tmpName, $folderId, [], $selectedMasterAsset);
// Pass the entire selected master asset (not just metadata) and TestRunner
$result = $uploader->uploadFile($tmpName, $folderId, [], $selectedMasterAsset, $testRunner);
if ($result['success']) {
$results['successful']++;
@ -1742,7 +1771,6 @@ $envInfo = $configV3->getEnvironmentInfo();
</p>
<?php foreach ($results['master_assets_for_upload'] as $idx => $masterAsset): ?>
<?php $masterAssetName = extractFolderName($masterAsset); ?>
<div style="background: white; border: 2px solid #dee2e6; border-radius: 6px; padding: 15px; margin: 10px 0;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input type="radio" name="selected_master_metadata" value="<?= $idx ?>"
@ -1750,11 +1778,18 @@ $envInfo = $configV3->getEnvironmentInfo();
<?= $idx === 0 ? 'checked' : '' ?>
style="margin-right: 10px; transform: scale(1.3);">
<div>
<strong><?= htmlspecialchars($masterAssetName) ?></strong><br>
<strong><?= htmlspecialchars($masterAsset['name'] ?? 'Unknown') ?></strong><br>
<small>Asset ID: <?= htmlspecialchars($masterAsset['asset_id']) ?></small><br>
<small>Type: <?= htmlspecialchars($masterAsset['mime_type'] ?? 'Unknown') ?></small>
<?php if (isset($masterAsset['metadata_model_id'])): ?>
<br><small>Metadata Model: <?= htmlspecialchars($masterAsset['metadata_model_id']) ?></small>
<br><small style="color: #28a745;"> Model: <?= htmlspecialchars($masterAsset['metadata_model_id']) ?></small>
<?php else: ?>
<br><small style="color: #dc3545;">⚠️ No Metadata Model ID</small>
<?php endif; ?>
<?php if (isset($masterAsset['security_policy_list'])): ?>
<br><small style="color: #28a745;"> <?= count($masterAsset['security_policy_list']) ?> Security Policies</small>
<?php else: ?>
<br><small style="color: #dc3545;">⚠️ No Security Policies</small>
<?php endif; ?>
</div>
</label>
@ -1794,12 +1829,16 @@ $envInfo = $configV3->getEnvironmentInfo();
<strong>🔍 Upload Debug Info:</strong><br>
<strong>Your File:</strong> <?= htmlspecialchars($results['upload_debug']['upload_filename']) ?>
(<?= htmlspecialchars($results['upload_debug']['upload_detected_mime']) ?>)<br>
<strong>Target Folder ID:</strong> <?= htmlspecialchars($results['upload_debug']['upload_folder_id']) ?><br>
<hr style="margin: 10px 0;">
<strong>Using Metadata From:</strong> <?= htmlspecialchars($results['upload_debug']['selected_master_name']) ?><br>
Master Asset ID: <?= htmlspecialchars($results['upload_debug']['selected_master_asset_id']) ?><br>
Metadata Model ID: <strong><?= htmlspecialchars($results['upload_debug']['metadata_model_id']) ?></strong><br>
Has Security Policies: <?= $results['upload_debug']['has_security_policies'] ?><br>
Master MIME Type: <?= htmlspecialchars($results['upload_debug']['master_mime_type']) ?>
Has Security Policies: <?= $results['upload_debug']['has_security_policies'] ?> (<?= $results['upload_debug']['security_policy_count'] ?> policies)<br>
Master MIME Type: <?= htmlspecialchars($results['upload_debug']['master_mime_type']) ?><br>
<hr style="margin: 10px 0;">
<strong>Sending:</strong> asset_representation (model ID + security policies only) + manifest + parent_folder_id + files<br>
<small>Note: Full metadata too large to send - using model ID inheritance instead</small>
</div>
<?php endif; ?>