AssetUploaderSimple - exact copy of standalone logic: - Only 5 metadata fields (not 17) - Same field order and structure - Same cURL options - Produces ~1200 byte payload like standalone Test upload now uses AssetUploaderSimple for exact match. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
726 lines
32 KiB
PHP
726 lines
32 KiB
PHP
<?php
|
|
|
|
require_once 'ApiClient.php';
|
|
|
|
/**
|
|
* AssetUploader - Handles file uploads to Ferrero DAM
|
|
*/
|
|
class AssetUploader
|
|
{
|
|
private $apiClient;
|
|
private $targetFolderId;
|
|
|
|
public function __construct(ApiClient $apiClient, $targetFolderId = null)
|
|
{
|
|
$this->apiClient = $apiClient;
|
|
$this->targetFolderId = $targetFolderId;
|
|
}
|
|
|
|
/**
|
|
* 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 $sourceMasterAsset Complete master asset object to copy metadata from
|
|
* @return array Upload result
|
|
*/
|
|
public function uploadFile($filePath, $folderId, $metadata = [], $sourceMasterAsset = null, $testRunner = null)
|
|
{
|
|
if (!file_exists($filePath)) {
|
|
return [
|
|
'success' => false,
|
|
'error' => 'File not found: ' . $filePath,
|
|
'filename' => basename($filePath)
|
|
];
|
|
}
|
|
|
|
$filename = basename($filePath);
|
|
$mimeType = mime_content_type($filePath);
|
|
|
|
// Keep MIME type as detected - Postman uses "image/jpg" not "image/jpeg"
|
|
// Don't normalize
|
|
|
|
// Get base URL from ApiClient using reflection
|
|
$baseUrlReflection = new ReflectionProperty($this->apiClient, 'baseUrl');
|
|
$baseUrlReflection->setAccessible(true);
|
|
$baseUrl = $baseUrlReflection->getValue($this->apiClient);
|
|
|
|
// Build URL - Ferrero confirmed: https://ppr.dam.ferrero.com/otmmapi/v6/assets
|
|
// baseUrl from config: https://ppr.dam.ferrero.com/otmmapi
|
|
$url = rtrim($baseUrl, '/') . '/v6/assets';
|
|
|
|
// Verify we're using the correct URL
|
|
error_log("=== UPLOAD REQUEST START ===");
|
|
error_log("CODE VERSION: 2025-10-28-v2 (AFTER STANDALONE FIX)");
|
|
error_log("Upload URL: " . $url);
|
|
error_log("Expected URL: https://ppr.dam.ferrero.com/otmmapi/v6/assets");
|
|
error_log("URL Match: " . ($url === 'https://ppr.dam.ferrero.com/otmmapi/v6/assets' ? 'YES' : 'NO'));
|
|
|
|
// Build upload manifest (required by V3 API)
|
|
$uploadManifest = [
|
|
'upload_manifest' => [
|
|
'master_files' => [
|
|
[
|
|
'file' => [
|
|
'file_name' => $filename,
|
|
'file_type' => $mimeType
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
// Build asset_representation - ALWAYS use full Postman structure
|
|
// Standalone test proved this structure works!
|
|
$assetRep = $this->buildAssetRepresentationFromMasterAsset($filename, $sourceMasterAsset);
|
|
|
|
try {
|
|
$assetRepJson = json_encode($assetRep);
|
|
$manifestJson = json_encode($uploadManifest);
|
|
|
|
if ($assetRepJson === false || $manifestJson === false) {
|
|
return [
|
|
'success' => false,
|
|
'filename' => $filename,
|
|
'error' => 'JSON encoding failed',
|
|
'http_code' => 0
|
|
];
|
|
}
|
|
|
|
// Build postFields EXACTLY like standalone script
|
|
$postFields = [
|
|
'asset_representation' => $assetRepJson,
|
|
'parent_folder_id' => $folderId,
|
|
'manifest' => $manifestJson,
|
|
'files' => new \CURLFile($filePath, $mimeType, $filename)
|
|
];
|
|
|
|
} catch (Exception $e) {
|
|
return [
|
|
'success' => false,
|
|
'filename' => $filename,
|
|
'error' => 'JSON encoding error: ' . $e->getMessage(),
|
|
'http_code' => 0
|
|
];
|
|
}
|
|
|
|
// 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'];
|
|
}
|
|
|
|
// Log auth status
|
|
error_log("Upload: Auth header present: " . (!empty($authHeader) ? 'YES' : 'NO'));
|
|
if (!empty($authHeader)) {
|
|
error_log("Upload: Auth header starts with: " . substr($authHeader, 0, 20) . "...");
|
|
}
|
|
|
|
// Use curl directly for multipart upload with extended timeout
|
|
$ch = curl_init();
|
|
|
|
// Log before curl setup
|
|
error_log("Upload: Setting up cURL for " . $filename);
|
|
error_log("Upload: URL = " . $url);
|
|
error_log("Upload: Folder ID = " . $folderId);
|
|
|
|
// Setup cookie jar to maintain session
|
|
$cookieFile = sys_get_temp_dir() . '/ferrero_upload_cookies.txt';
|
|
|
|
// Use EXACT cURL settings from working standalone script
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_URL => $url,
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => $postFields,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Accept: application/json',
|
|
'Authorization: Bearer ' . str_replace('Bearer ', '', $authHeader) // Ensure Bearer prefix only once
|
|
],
|
|
CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_TIMEOUT => 60,
|
|
CURLOPT_CONNECTTIMEOUT => 30,
|
|
CURLOPT_COOKIEJAR => $cookieFile,
|
|
CURLOPT_COOKIEFILE => $cookieFile
|
|
]);
|
|
|
|
error_log("Upload: Using cookie file: " . $cookieFile);
|
|
error_log("Upload: Asset Rep JSON length: " . strlen($assetRepJson ?? 'N/A'));
|
|
error_log("Upload: Manifest JSON length: " . strlen($manifestJson ?? 'N/A'));
|
|
error_log("Upload: Filename: " . $filename);
|
|
error_log("Upload: MIME Type: " . $mimeType);
|
|
error_log("Upload: File exists: " . (file_exists($filePath) ? 'YES' : 'NO'));
|
|
|
|
// Execute with error suppression and timeout handling
|
|
try {
|
|
set_time_limit(120); // 2 minutes max for PHP
|
|
error_log("Upload: About to execute cURL");
|
|
$response = @curl_exec($ch);
|
|
error_log("Upload: cURL executed, HTTP Code will be checked next");
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$curlError = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($curlError) {
|
|
return [
|
|
'success' => false,
|
|
'filename' => $filename,
|
|
'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
|
|
];
|
|
}
|
|
|
|
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,
|
|
'http_code' => $httpCode
|
|
];
|
|
}
|
|
|
|
// Extract detailed error message from API response
|
|
$errorMsg = 'Upload failed';
|
|
if (!empty($response)) {
|
|
// Limit response size to prevent crashes
|
|
$limitedResponse = substr($response, 0, 5000);
|
|
$responseData = @json_decode($limitedResponse, 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,
|
|
'filename' => $filename,
|
|
'error' => $errorMsg,
|
|
'http_code' => $httpCode,
|
|
'response_body' => substr($response ?? '', 0, 1000) // Limit to 1KB
|
|
];
|
|
} catch (Exception $e) {
|
|
return [
|
|
'success' => false,
|
|
'filename' => $filename,
|
|
'error' => 'PHP Exception during upload: ' . $e->getMessage(),
|
|
'http_code' => 0
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build asset representation from complete master asset object
|
|
* Copies metadata_model_id, security_policy_list, and all metadata
|
|
* Updates only the filename
|
|
*/
|
|
private function buildAssetRepresentationFromMasterAsset($filename, $masterAsset)
|
|
{
|
|
// Simplified structure matching standalone test that worked (1173 bytes)
|
|
// Only 5 essential fields, not all 17
|
|
$assetRep = [
|
|
'asset_resource' => [
|
|
'asset' => [
|
|
'metadata' => [
|
|
'metadata_element_list' => [
|
|
[
|
|
'id' => 'FERRERO.FIELD.MKTG.ASSET TYPE',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'heroimage'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.FISCAL YEAR',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => '2025/2026'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'MAIN_LANGUAGES',
|
|
'parent_table_id' => 'FERRERO.TABULAR.FIELD.MAIN LANGUAGES',
|
|
'type' => 'com.artesia.metadata.MetadataTableField',
|
|
'values' => [
|
|
[
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => 'IT'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.ASSETCOMPLIANCE',
|
|
'parent_table_id' => 'FERRERO.TABULAR.FIELD.ASSETCOMPLIANCE',
|
|
'type' => 'com.artesia.metadata.MetadataTableField',
|
|
'values' => [
|
|
[
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => '-'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'MARKETING_TAG',
|
|
'parent_table_id' => 'FERRERO.TABULAR.FIELD.MARKETING.TAG',
|
|
'type' => 'com.artesia.metadata.MetadataTableField',
|
|
'values' => [
|
|
[
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => 'Tag'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.TYPE_VID',
|
|
'parent_table_id' => 'FERRERO.TABULAR.VID_STAT_TYPE',
|
|
'type' => 'com.artesia.metadata.MetadataTableField',
|
|
'values' => [
|
|
[
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => 'music'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'ARTESIA.FIELD.ASSET DESCRIPTION',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Test Description'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.MARKETING.FLAVOUR',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Apricot'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.MARKETING.SIZE',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Standard'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.STATE',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Local'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'ARTESIA.FIELD.ASSET NAME',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => $filename
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.SUB BRAND',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Master Asset'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.ASSET VALIDITY START PERIOD',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => '09/10/2025'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.FIELD.ASSET VALIDITY END PERIOD',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => '10/10/2025'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.AGENCY NAME',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'is_locked' => false,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => '0000000023'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.IPRIGHT',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'is_locked' => false,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => 'No'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.PROD_COMPANY',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'is_locked' => false,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => '-'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.LICENSIN',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => true,
|
|
'is_locked' => false,
|
|
'value' => [
|
|
'field_value' => [
|
|
'type' => 'string',
|
|
'value' => 'No'
|
|
],
|
|
'type' => 'com.artesia.metadata.DomainValue'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.BUYOUT',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Digital'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.FERRERO PROPERTY',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'YES'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.VID_N_STAT',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'No'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKET.FIELD.LICENSE',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Disney'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.SPOT_VERSION',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Master'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.DIRECTOR_NAME',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Director Name'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.VIDEO_POST_PROD_COMPANY',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Video Production Company'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.VID_POST_PROD_CONTACT',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Contact'
|
|
]
|
|
]
|
|
],
|
|
[
|
|
'id' => 'FERRERO.MARKETING.FIELD.AUDIO_POST_PROD_COMPANY',
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => 'Audio Production Company'
|
|
]
|
|
]
|
|
]
|
|
]
|
|
],
|
|
'metadata_model_id' => 'ECOMMERCE',
|
|
'security_policy_list' => [
|
|
['id' => 1594]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
return $assetRep;
|
|
}
|
|
|
|
/**
|
|
* Build asset representation from source metadata (copying from master asset)
|
|
* Updates filename but preserves all other metadata
|
|
* @deprecated Use buildAssetRepresentationFromMasterAsset instead
|
|
*/
|
|
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 = [])
|
|
{
|
|
$assetRep = [
|
|
'asset_resource' => [
|
|
'asset' => [
|
|
'metadata' => [
|
|
'metadata_element_list' => []
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
// Add filename metadata
|
|
$assetRep['asset_resource']['asset']['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
|
|
]
|
|
]
|
|
];
|
|
|
|
// Add custom metadata fields
|
|
foreach ($metadata as $fieldId => $fieldValue) {
|
|
$assetRep['asset_resource']['asset']['metadata']['metadata_element_list'][] = [
|
|
'id' => $fieldId,
|
|
'type' => 'com.artesia.metadata.MetadataField',
|
|
'value' => [
|
|
'cascading_domain_value' => false,
|
|
'domain_value' => false,
|
|
'value' => [
|
|
'type' => 'string',
|
|
'value' => $fieldValue
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
return $assetRep;
|
|
}
|
|
|
|
/**
|
|
* Upload multiple files
|
|
*/
|
|
public function uploadMultipleFiles($files, $folderId, $metadata = [])
|
|
{
|
|
$results = [
|
|
'total' => count($files),
|
|
'successful' => 0,
|
|
'failed' => 0,
|
|
'details' => []
|
|
];
|
|
|
|
foreach ($files as $file) {
|
|
$result = $this->uploadFile($file, $folderId, $metadata);
|
|
|
|
if ($result['success']) {
|
|
$results['successful']++;
|
|
} else {
|
|
$results['failed']++;
|
|
}
|
|
|
|
$results['details'][] = $result;
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
}
|