pdo = new PDO( 'pgsql:host=localhost;port=5433;dbname=ferrero_tracking', 'ferrero_user', 'ferrero_pass_2025' ); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); error_log("DatabaseClient: Connected to PostgreSQL"); } catch (PDOException $e) { error_log("DatabaseClient: Connection failed: " . $e->getMessage()); $this->pdo = null; } } /** * Get the PDO connection * @return PDO|null */ public function getConnection() { return $this->pdo; } /** * Store master asset in database */ public function storeMasterAsset($trackingId, $assetData, $boxFileId = null, $boxUrl = null, $uploadFolderId = null) { if (!$this->pdo) { return ['success' => false, 'error' => 'Database not connected']; } try { // Extract metadata from DAM asset $metadata = $this->extractMetadataFields($assetData); // Debug log what we extracted error_log("DatabaseClient: Extracted metadata: " . json_encode($metadata)); error_log("DatabaseClient: Upload folder ID: " . ($uploadFolderId ?? 'NULL')); // Insert using all available columns INCLUDING full_metadata $stmt = $this->pdo->prepare(" INSERT INTO master_assets ( tracking_id, opentext_id, original_filename, file_extension, brand_code, brand_name, country_code, language_code, asset_type, file_size_bytes, mime_type, width_px, height_px, upload_directory, description, full_metadata, status ) VALUES ( :tracking_id, :opentext_id, :original_filename, :file_extension, :brand_code, :brand_name, :country_code, :language_code, :asset_type, :file_size_bytes, :mime_type, :width_px, :height_px, :upload_directory, :description, :full_metadata, :status ) ON CONFLICT (tracking_id) DO UPDATE SET upload_directory = EXCLUDED.upload_directory, brand_code = EXCLUDED.brand_code, country_code = EXCLUDED.country_code, language_code = EXCLUDED.language_code, width_px = EXCLUDED.width_px, height_px = EXCLUDED.height_px, description = EXCLUDED.description, full_metadata = EXCLUDED.full_metadata "); $pathInfo = pathinfo($assetData['name'] ?? 'unknown'); // Store FULL metadata JSON in dedicated column (NO TRUNCATION) $metadataJson = json_encode($assetData); // Keep description simple and readable (Box info only) $description = "Box File ID: {$boxFileId}\nBox URL: {$boxUrl}\nDAM Asset ID: " . ($assetData['asset_id'] ?? 'Unknown'); error_log("DatabaseClient: Storing full metadata - size: " . strlen($metadataJson) . " bytes"); $stmt->execute([ ':tracking_id' => $trackingId, ':opentext_id' => $assetData['asset_id'] ?? 'unknown', ':original_filename' => $pathInfo['filename'], ':file_extension' => '.' . ($pathInfo['extension'] ?? ''), ':brand_code' => $metadata['brand_code'], ':brand_name' => $metadata['brand_name'], ':country_code' => $metadata['country_code'], ':language_code' => $metadata['language_code'], ':asset_type' => $metadata['asset_type'], ':file_size_bytes' => $assetData['file_size'] ?? null, ':mime_type' => $assetData['mime_type'] ?? null, ':width_px' => $metadata['width_px'], ':height_px' => $metadata['height_px'], ':upload_directory' => $uploadFolderId, // Final Assets folder ID ':description' => $description, ':full_metadata' => $metadataJson, // COMPLETE metadata as JSONB ':status' => 'active' ]); error_log("DatabaseClient: Stored asset " . $trackingId); return ['success' => true, 'tracking_id' => $trackingId]; } catch (PDOException $e) { error_log("DatabaseClient: Insert failed: " . $e->getMessage()); return ['success' => false, 'error' => $e->getMessage()]; } } /** * Extract metadata fields from DAM asset */ private function extractMetadataFields($assetData) { $fields = [ 'brand_code' => null, 'brand_name' => null, 'country_code' => null, 'language_code' => null, 'asset_type' => null, 'width_px' => null, 'height_px' => null ]; // Debug: Log what keys exist in assetData error_log("DatabaseClient: AssetData keys: " . implode(', ', array_keys($assetData))); // Check if metadata field exists if (isset($assetData['metadata']['metadata_element_list'])) { error_log("DatabaseClient: Metadata field EXISTS with " . count($assetData['metadata']['metadata_element_list']) . " categories"); } else { error_log("DatabaseClient: Metadata field MISSING or wrong structure"); } // Extract width/height from master_content_info (not asset_content_info) if (isset($assetData['master_content_info'])) { $fields['width_px'] = $assetData['master_content_info']['width'] ?? null; $fields['height_px'] = $assetData['master_content_info']['height'] ?? null; error_log("DatabaseClient: Width/Height from master_content_info: " . ($fields['width_px'] ?? 'NULL') . 'x' . ($fields['height_px'] ?? 'NULL')); } // Fallback to asset_content_info if master_content_info doesn't exist elseif (isset($assetData['asset_content_info']['master_content'])) { $content = $assetData['asset_content_info']['master_content']; $fields['width_px'] = $content['width'] ?? null; $fields['height_px'] = $content['height'] ?? null; error_log("DatabaseClient: Width/Height from asset_content_info: " . ($fields['width_px'] ?? 'NULL') . 'x' . ($fields['height_px'] ?? 'NULL')); } else { error_log("DatabaseClient: No content_info found for dimensions"); } // Extract from metadata fields if (isset($assetData['metadata']['metadata_element_list'])) { foreach ($assetData['metadata']['metadata_element_list'] as $categoryIndex => $category) { if (!isset($category['metadata_element_list'])) { error_log("DatabaseClient: Category " . $categoryIndex . " has no metadata_element_list"); continue; } error_log("DatabaseClient: Category " . $categoryIndex . " has " . count($category['metadata_element_list']) . " elements"); foreach ($category['metadata_element_list'] as $element) { $fieldId = $element['id'] ?? ''; // Extract SUB BRAND (exists in asset metadata) if ($fieldId === 'FERRERO.FIELD.SUB BRAND') { $fields['brand_name'] = $this->getFieldValue($element); if ($fields['brand_name']) { $fields['brand_code'] = strtoupper(substr($fields['brand_name'], 0, 3)); error_log("DatabaseClient: Extracted SUB BRAND: " . $fields['brand_name']); } } // Extract MAIN LANGUAGES for language code if ($fieldId === 'MAIN_LANGUAGES' || $fieldId === 'FERRERO.TABULAR.FIELD.MAIN LANGUAGES') { // This is a tabular field - check for values if (isset($element['values']) && is_array($element['values']) && count($element['values']) > 0) { $langValue = $this->getFieldValue($element['values'][0]); if ($langValue) { $fields['language_code'] = strtolower(substr($langValue, 0, 2)); error_log("DatabaseClient: Extracted language: " . $fields['language_code']); } } } // Extract MKTG.ASSET TYPE if ($fieldId === 'FERRERO.FIELD.MKTG.ASSET TYPE') { $assetType = $this->getFieldValue($element); if ($assetType) { $fields['asset_type'] = strtoupper(substr($assetType, 0, 3)); // First 3 chars error_log("DatabaseClient: Extracted asset type: " . $fields['asset_type']); } } // Check for tabular fields (for language extraction) if (isset($element['metadata_element_list']) && $fieldId === 'FERRERO.TABULAR.FIELD.MAIN LANGUAGES') { foreach ($element['metadata_element_list'] as $tableField) { // Extract language from tabular field if (isset($tableField['values']) && is_array($tableField['values'])) { foreach ($tableField['values'] as $langValue) { $lang = $this->getFieldValue($langValue); if ($lang) { $fields['language_code'] = strtolower(substr($lang, 0, 2)); error_log("DatabaseClient: Extracted language from tabular: " . $fields['language_code']); break; } } } } } } } } return $fields; } /** * Get field value from metadata element (handles both domain and regular values) */ private function getFieldValue($element) { $fieldId = $element['id'] ?? 'unknown'; // Handle domain values (with field_value) if (isset($element['value']['value']['field_value']['value'])) { $value = $element['value']['value']['field_value']['value']; error_log("DatabaseClient: getFieldValue({$fieldId}) = {$value} (domain value)"); return $value; } // Handle regular string fields if (isset($element['value']['value']['value'])) { $value = $element['value']['value']['value']; error_log("DatabaseClient: getFieldValue({$fieldId}) = {$value} (regular value)"); return $value; } // Log when we can't find a value if (isset($element['value'])) { error_log("DatabaseClient: getFieldValue({$fieldId}) - value exists but structure unknown"); error_log("DatabaseClient: Value structure: " . json_encode($element['value'])); } else { error_log("DatabaseClient: getFieldValue({$fieldId}) - no value field at all"); } return null; } /** * Check if database is available */ public function isConnected() { return $this->pdo !== null; } }