Woocommerce - Mostrar el precio del producto de variación activa
Estoy usando botones de radio para las variantes de producto en WooCommerce. Cada variante del producto tiene su propio precio. Me gustaría que el precio de la variante se muestre después de que se seleccione un botón de radio. No estoy seguro de cómo pasar el variation_id activamente seleccionado a la función get_product_variation_price($variation_id).
Un ejemplo del código HTML del botón de radio se ve así en la salida HTML:
<input type="radio" class="radioselect" name="attribute_size" value="3,000+"
id="size_v_3,000+">
<label for="size_v_3,000+">3,000+</label>
Sin embargo, mis variaciones son números (creo que son números de post) como #12, #3041, etc.
Aquí está mi archivo variable.php completo:
<?php
/**
* Añadir al carrito producto variable
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.5.0
*
* Modificado para usar botones de radio en lugar de desplegables
* @author 8manos
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function print_attribute_radio( $checked_value, $value, $label, $name ) {
// Esto maneja la compatibilidad con versiones anteriores a 2.4.0 donde los atributos de texto no estaban sanitizados.
$checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
$input_name = 'attribute_' . esc_attr( $name ) ;
$esc_value = esc_attr( $value );
$id = esc_attr( $name . '_v_' . $value );
$filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
$super_filtered = explode(' ', $filtered_label);
printf( '<div><input type="radio" class="radioselect" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $super_filtered[0] );
}
global $product;
$attribute_keys = array_keys( $attributes );
do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo htmlspecialchars( json_encode( $available_variations ) ) ?>">
<?php do_action( 'woocommerce_before_variations_form' ); ?>
<?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
<p class="stock out-of-stock"><?php _e( 'Este producto está actualmente agotado y no disponible.', 'woocommerce' ); ?></p>
<?php else : ?>
<table class="variations" cellspacing="0">
<tbody>
<?php foreach ( $attributes as $name => $options ) : ?>
<tr>
<td class="label" style="margin-top: -10px;"><label for="<?php echo sanitize_title( $name ); ?>"><?php echo wc_attribute_label( $name ); ?></label></td>
<?php
$sanitized_name = sanitize_title( $name );
if ( isset( $_REQUEST[ 'attribute_' . $sanitized_name ] ) ) {
$checked_value = $_REQUEST[ 'attribute_' . $sanitized_name ];
} elseif ( isset( $selected_attributes[ $sanitized_name ] ) ) {
$checked_value = $selected_attributes[ $sanitized_name ];
} else {
$checked_value = '';
}
?>
<td class="value" style="margin-top: -30px;">
<?php
if ( ! empty( $options ) ) {
if ( taxonomy_exists( $name ) ) {
// Obtener términos si esto es una taxonomía - ordenados. También necesitamos los nombres.
$terms = wc_get_product_terms( $product->id, $name, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( ! in_array( $term->slug, $options ) ) {
continue;
}
print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
}
} else {
foreach ( $options as $option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
}
}
}
echo end( $attribute_keys ) === $name ? apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . __( 'Limpiar', 'woocommerce' ) . '</a>' ) : '';
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<div class="single_variation_wrap">
<?php do_action( 'woocommerce_before_single_variation' ); ?>
<?php
if ( has_action( 'woocommerce_single_variation' ) ) {
do_action( 'woocommerce_single_variation' );
} else {
// Compatibilidad con versiones anteriores a WC 2.4
?>
<div class="woocommerce-variation single_variation"></div>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php if ( ! $product->is_sold_individually() ) : ?>
<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
<?php endif; ?>
<button type="submit" class="single_add_to_cart_button button alt otto"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="0" />
</div>
<?php } ?>
<?php do_action( 'woocommerce_after_single_variation' ); ?>
</div>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_after_variations_form' ); ?>
<p>
<?php
function get_product_variation_price($variation_id) {
global $woocommerce;
$product = new WC_Product_Variation($variation_id);
return $product->get_price_html(); // Funciona. Usa esto si quieres el precio formateado
}
///Mostrar el precio de los botones de radio de variante activamente seleccionados
echo get_product_variation_price(11);
?>
</p>
</form>
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>

Logré encontrar una solución. Muestra el precio de la variante debajo o junto a los botones de radio.
Mostrar el precio de la variante (cuando se proporciona un ID):
function get_product_variation_price($variation_id) {
global $woocommerce;
$product = new WC_Product_Variation($variation_id);
return $product->get_price_html(); // Funciona. Usa esto si quieres el precio formateado
}
Encontrar el ID de la variante, enviarlo a la función get_product_variation_price y luego mostrar el precio:
///Mostrar el precio de los botones de radio de la variante seleccionada activamente
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
$product_price = get_product_variation_price($product_variation_id);
echo $product_price;
}
El bucle foreach para mostrar los botones de radio:
foreach ( $options as $option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
}
Bucle foreach de botones de radio modificado con clave de array
foreach ( $options as $key=>$option ) {...}
Bucle foreach combinado:
foreach ( $options as $key=>$option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
$product_variations = $product->get_available_variations();
$variation_product_id = $product_variations [$key]['variation_id'];
$product_price = get_product_variation_price($variation_product_id);
printf ('%1$s</div> ', $product_price);
}
Código completo:
<?php
/**
* Formulario de añadir al carrito para producto variable
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.5.0
*
* Modificado para usar botones de radio en lugar de desplegables
* @author 8manos
* Modificaciones adicionales para mostrar el precio debajo de los botones de radio
* @author GoodGuyTaj
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// INICIO obtener precio del producto
function get_product_variation_price($variation_id) {
global $woocommerce;
$product = new WC_Product_Variation($variation_id);
return $product->get_price_html(); // Funciona. Usa esto si quieres el precio formateado
}
// FIN obtener precio del producto
// INICIO Mostrar Botones de Radio
function print_attribute_radio( $checked_value, $value, $label, $name ) {
// Esto maneja la compatibilidad con versiones < 2.4.0 donde los atributos de texto no se sanitizaban.
$checked = sanitize_title( $checked_value ) === $checked_value ? checked( $checked_value, sanitize_title( $value ), false ) : checked( $checked_value, $value, false );
$input_name = 'attribute_' . esc_attr( $name ) ;
$esc_value = esc_attr( $value );
$id = esc_attr( $name . '_v_' . $value );
$filtered_label = apply_filters( 'woocommerce_variation_option_name', $label );
$super_filtered = explode(' ', $filtered_label);
printf( '<div><input type="radio" class="radioselect" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label>', $input_name, $esc_value, $id, $checked, $super_filtered[0] );
}
global $product;
$attribute_keys = array_keys( $attributes );
do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo htmlspecialchars( json_encode( $available_variations ) ) ?>">
<?php do_action( 'woocommerce_before_variations_form' ); ?>
<?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
<p class="stock out-of-stock"><?php _e( 'Este producto actualmente está agotado y no disponible.', 'woocommerce' ); ?></p>
<?php else : ?>
<table class="variations" cellspacing="0">
<tbody>
<?php foreach ( $attributes as $name => $options ) : ?>
<tr>
<td class="label" style="margin-top: -10px;"><label for="<?php echo sanitize_title( $name ); ?>"><?php echo wc_attribute_label( $name ); ?></label></td>
<?php
$sanitized_name = sanitize_title( $name );
if ( isset( $_REQUEST[ 'attribute_' . $sanitized_name ] ) ) {
$checked_value = $_REQUEST[ 'attribute_' . $sanitized_name ];
} elseif ( isset( $selected_attributes[ $sanitized_name ] ) ) {
$checked_value = $selected_attributes[ $sanitized_name ];
} else {
$checked_value = '';
}
?>
<td class="value" style="margin-top: -30px;">
<?php
if ( ! empty( $options ) ) {
if ( taxonomy_exists( $name ) ) {
// Obtener términos si es una taxonomía - ordenados. Necesitamos también los nombres.
$terms = wc_get_product_terms( $product->id, $name, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( ! in_array( $term->slug, $options ) ) {
continue;
}
print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
}
} else {
foreach ( $options as $key=>$option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
$product_variations = $product->get_available_variations();
$variation_product_id = $product_variations [$key]['variation_id'];
$product_price = get_product_variation_price($variation_product_id);
printf ('%1$s</div> ', $product_price);
}
}
}
echo end( $attribute_keys ) === $name ? apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . __( 'Limpiar', 'woocommerce' ) . '</a>' ) : '';
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<div class="single_variation_wrap">
<?php do_action( 'woocommerce_before_single_variation' ); ?>
<?php
if ( has_action( 'woocommerce_single_variation' ) ) {
do_action( 'woocommerce_single_variation' );
} else {
// Compatibilidad con versiones WC < 2.4
?>
<div class="woocommerce-variation single_variation"></div>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php if ( ! $product->is_sold_individually() ) : ?>
<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
<?php endif; ?>
<button type="submit" class="single_add_to_cart_button button alt otto"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="0" />
</div>
<?php } ?>
<?php do_action( 'woocommerce_after_single_variation' ); ?>
</div>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_after_variations_form' ); ?>
</form>
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
