$ai_data['sequence'] ?? '', 'psa_molecular_weight' => ! empty( $pubchem_data['molecular_weight'] ) ? $pubchem_data['molecular_weight'] : ( $ai_data['molecular_weight'] ?? '' ), 'psa_molecular_formula' => ! empty( $pubchem_data['molecular_formula'] ) ? $pubchem_data['molecular_formula'] : ( $ai_data['molecular_formula'] ?? '' ), 'psa_aliases' => $ai_data['aliases'] ?? '', 'psa_mechanism' => $ai_data['mechanism'] ?? '', 'psa_overview' => $ai_data['overview'] ?? $ai_data['description'] ?? '', 'psa_category_label' => $ai_data['category_label'] ?? '', 'psa_origin' => $ai_data['origin'] ?? '', 'psa_research_apps' => $ai_data['research_benefits'] ?? ( $ai_data['research_applications'] ?? '' ), 'psa_safety_profile' => $ai_data['safety_side_effects'] ?? ( $ai_data['safety_profile'] ?? '' ), 'psa_dosage_info' => $ai_data['administration_dosing'] ?? ( $ai_data['dosage_info'] ?? '' ), 'psa_legal_regulatory' => $ai_data['legal_regulatory'] ?? '', 'psa_references' => $ai_data['references'] ?? '', 'psa_category' => $ai_data['category'] ?? '', 'psa_source' => ! empty( $pubchem_data ) ? 'pubchem' : 'ai-generated', 'psa_pubchem_cid' => $pubchem_data['cid'] ?? '', 'psa_half_life' => $ai_data['half_life'] ?? '', 'psa_stability' => $ai_data['stability'] ?? '', 'psa_solubility' => $ai_data['solubility'] ?? '', 'psa_vial_size_mg' => $ai_data['vial_size_mg'] ?? '', 'psa_storage_lyophilized' => $ai_data['storage_lyophilized'] ?? '', 'psa_storage_reconstituted' => $ai_data['storage_reconstituted'] ?? '', 'psa_typical_dose_mcg' => $ai_data['typical_dose_mcg'] ?? '', 'psa_cycle_parameters' => $ai_data['cycle_parameters'] ?? '', 'psa_amino_acid_count' => $amino_acid_count, ); $meta = apply_filters( 'psa_peptide_meta', $meta, $post_id, $ai_data, $pubchem_data ); foreach ( $meta as $key => $value ) { update_post_meta( $post_id, $key, $value ); } } /** * Auto-assign a peptide_category taxonomy term based on AI-returned category. * * @param int $post_id The peptide post ID. * @param array $ai_data AI-generated data containing 'category' or 'category_label'. */ public static function assign_category_term( int $post_id, array $ai_data ): void { $ai_category = $ai_data['category'] ?? $ai_data['category_label'] ?? ''; if ( empty( $ai_category ) ) { return; } // Why: AI returns varied labels ("GH Secretagogues", "Healing & Repair") that need // to map to our controlled vocabulary of taxonomy terms. $category_map = array( 'gh secretagogues' => 'growth-hormone', 'growth hormone' => 'growth-hormone', 'healing & repair' => 'tissue-repair', 'healing and repair' => 'tissue-repair', 'tissue repair' => 'tissue-repair', 'tissue healing' => 'tissue-repair', 'cytoprotective' => 'tissue-repair', 'melanocortin peptides' => 'dermatological', 'melanocortin' => 'dermatological', 'dermatological' => 'dermatological', 'metabolic & anti-aging' => 'metabolic', 'metabolic and anti-aging' => 'metabolic', 'metabolic' => 'metabolic', 'anti-aging' => 'aging-research', 'aging research' => 'aging-research', 'nootropic & neuroprotective' => 'immunology', 'nootropic' => 'immunology', 'neuroprotective' => 'immunology', 'immunology' => 'immunology', 'immune' => 'immunology', 'lipid metabolism' => 'lipid-metabolism', 'endocrine' => 'endocrine', ); $lower = strtolower( trim( $ai_category ) ); $slug = $category_map[ $lower ] ?? ''; // Fuzzy fallback: check if AI category contains any known slug keyword. if ( empty( $slug ) ) { foreach ( PSA_Post_Type::DEFAULT_CATEGORIES as $cat_slug => $cat_name ) { if ( stripos( $ai_category, $cat_name ) !== false || stripos( $ai_category, str_replace( '-', ' ', $cat_slug ) ) !== false ) { $slug = $cat_slug; break; } } } if ( ! empty( $slug ) ) { wp_set_object_terms( $post_id, $slug, 'peptide_category' ); } } /** * Derive amino acid count from sequence data or explicit AI field. * * @param array $ai_data AI-generated data. * @return string Amino acid count as string, or empty. */ private static function derive_amino_acid_count( array $ai_data ): string { $sequence = $ai_data['sequence'] ?? ''; $count = ''; if ( ! empty( $sequence ) ) { // Three-letter codes use dashes; single-letter codes are uppercase chars. $count = ( strpos( $sequence, '-' ) !== false ) ? (string) count( explode( '-', $sequence ) ) : (string) strlen( preg_replace( '/[^A-Z]/', '', $sequence ) ); } // AI may return this directly — prefer explicit value. if ( ! empty( $ai_data['amino_acid_count'] ) ) { $count = (string) intval( $ai_data['amino_acid_count'] ); } return $count; } }