feat: Add product attribute inclusion settings and enhance context handling in AI prompts

This commit is contained in:
2026-01-16 19:19:00 +00:00
parent 7b9f26e966
commit 43ddbddd11
7 changed files with 248 additions and 8 deletions

View File

@@ -338,7 +338,7 @@ class Groq_AI_Prompt_Builder {
return $normalized;
}
public function build_product_context_block( $post_id, $fields, $image_mode = 'url', $image_limit = 3 ) {
public function build_product_context_block( $post_id, $fields, $image_mode = 'url', $image_limit = 3, $settings = null ) {
$post_id = absint( $post_id );
if ( ! $post_id ) {
@@ -368,8 +368,14 @@ class Groq_AI_Prompt_Builder {
}
}
if ( ! empty( $fields['attributes'] ) ) {
$attributes = $this->get_product_attributes_text( $post_id );
$attribute_includes = [];
if ( is_array( $settings ) && isset( $settings['product_attribute_includes'] ) && is_array( $settings['product_attribute_includes'] ) ) {
$attribute_includes = array_values( array_unique( array_map( 'sanitize_key', $settings['product_attribute_includes'] ) ) );
}
$include_attributes = ! empty( $attribute_includes ) || ! empty( $fields['attributes'] );
if ( $include_attributes ) {
$attributes = $this->get_product_attributes_text( $post_id, $attribute_includes );
if ( $attributes ) {
$parts[] = sprintf( __( 'Attributen: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $attributes );
}
@@ -833,7 +839,7 @@ class Groq_AI_Prompt_Builder {
return substr( $text, 0, $limit );
}
private function get_product_attributes_text( $post_id ) {
private function get_product_attributes_text( $post_id, $attribute_includes = [] ) {
if ( ! function_exists( 'wc_get_product' ) ) {
return '';
}
@@ -850,14 +856,27 @@ class Groq_AI_Prompt_Builder {
return '';
}
$attribute_includes = is_array( $attribute_includes ) ? array_values( array_unique( array_map( 'sanitize_key', $attribute_includes ) ) ) : [];
$include_all = empty( $attribute_includes ) || in_array( '__all__', $attribute_includes, true );
$include_custom = $include_all || in_array( '__custom__', $attribute_includes, true );
$lines = [];
foreach ( $attributes as $attribute ) {
if ( $attribute->is_taxonomy() ) {
$terms = wc_get_product_terms( $post_id, $attribute->get_name(), [ 'fields' => 'names' ] );
$taxonomy_name = sanitize_key( (string) $attribute->get_name() );
if ( ! $include_all && ! in_array( $taxonomy_name, $attribute_includes, true ) ) {
continue;
}
$terms = wc_get_product_terms( $post_id, $taxonomy_name, [ 'fields' => 'names' ] );
$value = implode( ', ', array_map( 'sanitize_text_field', (array) $terms ) );
$label = wc_attribute_label( $attribute->get_name() );
$label = wc_attribute_label( $taxonomy_name );
} else {
if ( ! $include_custom ) {
continue;
}
$options = $attribute->get_options();
$value = implode( ', ', array_map( 'sanitize_text_field', (array) $options ) );
$label = sanitize_text_field( $attribute->get_name() );

View File

@@ -33,6 +33,7 @@ class Groq_AI_Settings_Manager {
'store_context' => '',
'default_prompt' => '',
'max_output_tokens' => 2048,
'product_attribute_includes' => [],
'term_bottom_description_meta_key' => '',
'groq_api_key' => '',
'openai_api_key' => '',
@@ -74,6 +75,10 @@ class Groq_AI_Settings_Manager {
$limit = isset( $settings['image_context_limit'] ) ? $this->sanitize_image_context_limit_value( $settings['image_context_limit'] ) : 3;
$settings['image_context_limit'] = $limit;
$settings['product_attribute_includes'] = $this->sanitize_product_attribute_includes(
isset( $settings['product_attribute_includes'] ) ? $settings['product_attribute_includes'] : []
);
return $settings;
}
@@ -90,6 +95,7 @@ class Groq_AI_Settings_Manager {
'store_context' => '',
'default_prompt' => '',
'max_output_tokens' => 2048,
'product_attribute_includes' => [],
'term_bottom_description_meta_key' => '',
'groq_api_key' => '',
'openai_api_key' => '',
@@ -151,6 +157,7 @@ class Groq_AI_Settings_Manager {
'store_context' => sanitize_textarea_field( $input['store_context'] ),
'default_prompt' => sanitize_textarea_field( $input['default_prompt'] ),
'max_output_tokens' => $max_output_tokens,
'product_attribute_includes' => $this->sanitize_product_attribute_includes( isset( $raw_input['product_attribute_includes'] ) ? $raw_input['product_attribute_includes'] : [] ),
'term_bottom_description_meta_key' => sanitize_key( (string) $input['term_bottom_description_meta_key'] ),
'groq_api_key' => sanitize_text_field( $input['groq_api_key'] ),
'openai_api_key' => sanitize_text_field( $input['openai_api_key'] ),
@@ -177,6 +184,33 @@ class Groq_AI_Settings_Manager {
];
}
private function sanitize_product_attribute_includes( $value ) {
if ( ! is_array( $value ) ) {
return [];
}
$clean = [];
foreach ( $value as $item ) {
$item = sanitize_key( (string) $item );
if ( '' === $item ) {
continue;
}
// Allow special tokens and attribute taxonomies.
if ( in_array( $item, [ '__all__', '__custom__' ], true ) || 0 === strpos( $item, 'pa_' ) ) {
$clean[] = $item;
}
}
$clean = array_values( array_unique( $clean ) );
// Hard cap to avoid overly large option payloads.
if ( count( $clean ) > 200 ) {
$clean = array_slice( $clean, 0, 200 );
}
return $clean;
}
public function get_context_field_definitions() {
if ( null === $this->context_field_definitions ) {
$this->context_field_definitions = [