diff --git a/src/AssetUploader.php b/src/AssetUploader.php index 5442f01..a63639f 100644 --- a/src/AssetUploader.php +++ b/src/AssetUploader.php @@ -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; } diff --git a/workflow_v3.php b/workflow_v3.php index 9f28deb..6ba9977 100644 --- a/workflow_v3.php +++ b/workflow_v3.php @@ -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();
$masterAsset): ?> -