I’m creating a comparison table, the problem I’m having is that I don’t know how to get the product attribute name and value as an array.
This function is for fields
function fields( $products = array() ) {
$fields = array(
'thumbnail' => esc_html__( 'Image', 'woocommerce' ),
'name' => esc_html__( 'Product', 'woocommerce' ),
'sku' => esc_html__( 'SKU', 'woocommerce' ),
'price' => esc_html__( 'Price', 'woocommerce' ),
'rating' => esc_html__( 'Rating', 'woocommerce' ),
);
$fields = array_filter( $fields );
foreach ( $fields as $key => $value ) {
if ( isset( $this->default_fields[ $key ] ) ) {
$fields[ $key ] = $this->default_fields[ $key ];
} elseif ( taxonomy_exists( $key ) ) {
$fields[ $key ] = wc_attribute_label( $key );
}
}
if ( ! empty( $products ) ) {
foreach ( $products as $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product ) {
continue;
}
if ( $product instanceof WC_Product_Variation ) {
$parent_product = wc_get_product( $product->get_parent_id() );
$attrs = $parent_product->get_attributes();
} else {
$attrs = $product->get_attributes();
}
foreach ( $attrs as $key => $value ) {
$key = urldecode( $key );
if ( ! isset( $value['is_taxonomy'] ) || ( $value['is_taxonomy'] && ! array_key_exists( $key, $fields ) ) || ( $value['is_taxonomy'] ) || ( ! $value['is_taxonomy'] ) ) {
continue;
}
$fields[ $key ] = wc_attribute_label( $key, $product );
}
}
}
return $fields;
}
This is the code that I put in the comparison sheet
<?php foreach ( $fields as $field => $name ) : ?>
<tr class="<?php echo ! in_array( $field, $different, true ) ? esc_attr( $field ) : esc_attr( $field ) . ' different'; ?>">
<th>
<?php echo esc_html( $name ); ?>
</th>
<?php
$index = 0;
foreach ( $products as $product_id => $product ) :
// Set td class.
$product_class = ( ( 0 === ( $index % 2 ) ) ? 'odd' : 'even' ) . ' product_' . $product_id;
if ( 'stock' === $field ) {
$availability = $product->get_availability();
$product_class .= ' ' . ( empty( $availability['class'] ) ? 'in-stock' : $availability['class'] );
}
?>
<td class="<?php echo esc_attr( $product_class ); ?>">
<?php
switch ( $field ) {
default:
echo empty( $product->fields[ $field ] ) ? '-' : do_shortcode( $product->fields[ $field ] );
break;
}
?>
</td>
<?php
++ $index;
endforeach
?>
</tr>
<?php endforeach; ?>
thumbnail, name, sku, price, rating values ​​of each product are correctly displayed on the comparison page. But I don’t know how to display the attribute name and value of the products, For example, I have a attribute named pa_gender, and if I put it in the first code as shown below, it displays that attribute correctly.
$fields = array(
'thumbnail' => esc_html__( 'Image', 'woocommerce' ),
'name' => esc_html__( 'Product', 'woocommerce' ),
'sku' => esc_html__( 'SKU', 'woocommerce' ),
'price' => esc_html__( 'Price', 'woocommerce' ),
'rating' => esc_html__( 'Rating', 'woocommerce' ),
'pa_gender' => esc_html__( 'Gender', 'woocommerce' ),
);
But well, I may have thousands of attributes or want to add them, so I can’t enter them all, how can I loop inside the field array and list them all as an array?
update : For example, I want it to be like this, but it gives an error.
$fields = array(
'thumbnail' => esc_html__( 'Image', 'woocommerce' ),
'name' => esc_html__( 'Product', 'woocommerce' ),
'sku' => esc_html__( 'SKU', 'woocommerce' ),
'price' => esc_html__( 'Price', 'woocommerce' ),
'rating' => esc_html__( 'Rating', 'woocommerce' ),
foreach ( wc_get_attribute_taxonomies() as $attribute ) {
'pa_' . $attribute->attribute_name => esc_html__( 'pa_name', 'woocommerce' ),
}
);
My knowledge of programming is little, so if my question is a beginner, please don’t diss.
2
Answers
2 arrays can be combined using the
array_merge()
function.Our first array is as below, which is used for information other than product attributes :
Our second array is used to get the attributes of the products :
Well, now these 2 arrays can be combined and converted into one array :
After much effort, I came to this conclusion.
You can’t call a
foreach
statement within the definition of the array.So first, you need to define
$fields
:Then insert the additional values, based on the foreach logic:
Alternatively (but only if it suits the way you will use
$fields
later), you might want to structure your array a bit differently, so you’re not using the pa_ prefix, but instead have a nested array: