Deeper into _product_attributes field

  • leomoon
    Participant
    4 years, 4 months ago #15899

    On tab 2.2., I cannot index a particular product attribute, but rather than just a whole of _product_attributes, values of which are in fact stored as attribute metas:

    $attributes_meta = get_post_meta($product->get_ID(), ‘_product_attributes’);
    $year_book_published = $attributes_meta[0][‘pa_year_published’][‘value’];

    In my case this would be an integer that would allow faucet range on when the book was published.

    Let me know if I should make this a feature request.

    wpsolr
    Keymaster
    4 years, 4 months ago #15900

    It can only be some custom php code, as nothing can detect that this custom field is in fact an array of custom fields to be indexed on their own.

    You can inspire from the ACF add-on, which uses a filter to add indexed fields from repeater fields.

    In wp-content/plugins/wpsolr-pro/wpsolr/pro/extensions/acf/class-wpsolr-plugin-acf.php:

    Make your fields appear in screen 2.2:

    add_filter( WPSOLR_Events::WPSOLR_FILTER_INDEX_CUSTOM_FIELDS, [
    	$this,
    	'get_index_custom_fields',
    ], 10, 2 );
    
    /**
     * Update custom fields list to be indexed
     * Replace _groupRepeater_0_repeatedFieldName by repeatedFieldName
     *
     * @param string[] $custom_fields
     * @param string $model_type
     *
     * @return string[]
     */
    function get_index_custom_fields( $custom_fields, $model_type ) {
    
    	if ( ! isset( $custom_fields ) ) {
    		$custom_fields = [];
    	}
    
    	$fields = $this->get_acf_fields();
    
    	$results = [];
    
    	$indexable_acf_fields = [
    		/**
    		 * ACF field types 'Content'
    		 */
    		self::ACF_FIELD_TYPE_CONTENT_WYSIWYG,
    		/**
    		 * ACF field types 'Layout'
    		 */
    		self::ACF_FIELD_TYPE_LAYOUT_TAB,
    		self::ACF_FIELD_TYPE_LAYOUT_CLONE,
    		/**
    		 * ACF field types 'Choice'
    		 */
    		self::ACF_FIELD_TYPE_CHOICE_TRUE_FALSE,
    		self::ACF_FIELD_TYPE_CHOICE_SELECT,
    		self::ACF_FIELD_TYPE_CHOICE_CHECKBOX,
    		self::ACF_FIELD_TYPE_CHOICE_RADIOBOX,
    		/**
    		 * ACF field types 'Basic'
    		 */
    		self::ACF_FIELD_TYPE_BASIC_TEXT,
    		self::ACF_FIELD_TYPE_BASIC_TEXTAREA,
    		self::ACF_FIELD_TYPE_BASIC_NUMBER,
    		self::ACF_FIELD_TYPE_BASIC_PASSWORD,
    		self::ACF_FIELD_TYPE_BASIC_URL,
    		self::ACF_FIELD_TYPE_BASIC_EMAIL,
    		/**
    		 * ACF field type 'jQuery'
    		 */
    		self::ACF_FIELD_TYPE_GOOGLE_MAP,
    		self::ACF_FIELD_TYPE_DATE_PICKER,
    		//self::ACF_FIELD_TYPE_DATE_TIME_PICKER,
    		//self::ACF_FIELD_TYPE_TIME_PICKER,
    	];
    
    	foreach ( $custom_fields as $custom_field_name ) {
    
    		$do_not_include = false;
    
    		if ( isset( $fields[ self::FIELD_PREFIX . $custom_field_name ] ) || isset( $fields[ $custom_field_name ] ) ) {
    
    			$field_key = isset( $fields[ self::FIELD_PREFIX . $custom_field_name ] ) ? $fields[ self::FIELD_PREFIX . $custom_field_name ] : $fields[ $custom_field_name ];
    			$field     = get_field_object( $field_key, false, false, false );
    
    			if ( $field ) {
    
    				$do_not_include = true;
    
    				if ( in_array( $field['type'], $indexable_acf_fields ) ) {
    
    					/**
    					 * Get the canonical form of a repeated field name, eventually.
    					 * Examples:
    					 * _xxxxx_0_field => field
    					 * __xxxxx_0__field => field
    					 * xxxxx_0_field => field
    					 * _xxxxx_10_field => field
    					 * _xxxxx_yy_field => _xxxxx_yy_field
    					 * xxxxx_yy_field => xxxxx_yy_field
    					 * field => field
    					 */
    					$repeated_field_name = preg_replace( '/(.*)_(\d*)_(.*)/', '$3', $custom_field_name );
    
    					if ( ! in_array( $repeated_field_name, $results, true ) ) {
    						// Add the non repeated field name, or the repeated field canonical name.
    						array_push( $results, $repeated_field_name );
    					}
    				}
    			}
    		}
    
    		if ( ! $do_not_include && ! in_array( $custom_field_name, $results, true ) ) {
    			// Add the non repeated field name, or the non ACF field name.
    			array_push( $results, $custom_field_name );
    		}
    	}
    
    	return $results;
    }
    

    Then set your fields value at index time:

    add_filter( WPSOLR_Events::WPSOLR_FILTER_POST_CUSTOM_FIELDS, [
    	$this,
    	'filter_custom_fields',
    ], 10, 2 );
    leomoon
    Participant
    4 years, 4 months ago #15905

    That works, thanks!

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.