Estoy usando Woocommerce Subscriptions y Woocommerce All Prducts for Subscriptions para ofrecer productos de suscripción en mi sitio de WordPress Woocommerce. Esto funciona muy bien, pero quiero que mis clientes seleccionen su esquema de suscripción en una página separada, después de haber creado su cuadro de suscripción, donde pueden elegir entre cada 3 semanas (3_semana), cada 4 semanas (4_semana), cada 5 semanas (5_week), y cada 6 semanas (6_week), así:

Ahora he creado un formulario con botones de radio, que envía una variable de clave de esquema de suscripción a mi backend, que luego quiero usar para actualizar los artículos de mi carrito de suscripción.
Los esquemas de suscripción son manejados por el complemento Todos los productos para suscripciones y he revisado el archivo /woocommerce-all-products-for-subscriptions/includes/class-wcs-att-cart.php. Encontré estas funciones que pensé que serían relevantes para mí para actualizar el esquema de los artículos de mi carrito:
/**
* Returns the active subscription scheme key of a cart item, or false if the cart item is a one-time purchase.
*
* @since 2.0.0
*
* @return string
*/
public static function get_subscription_scheme( $cart_item ) {
$active_scheme = isset( $cart_item[ 'wcsatt_data' ][ 'active_subscription_scheme' ] ) ? $cart_item[ 'wcsatt_data' ][ 'active_subscription_scheme' ] : null;
return $active_scheme;
}
/**
* Get the posted cart-item subscription scheme.
*
* @since 2.1.0
*
* @param string $cart_item_key
* @return string
*/
public static function get_posted_subscription_scheme( $cart_item_key ) {
$posted_subscription_scheme_key = null;
$key = 'convert_to_sub';
$posted_subscription_scheme_option = isset( $_POST[ 'cart' ][ $cart_item_key ][ $key ] ) ? wc_clean( $_POST[ 'cart' ][ $cart_item_key ][ $key ] ) : null;
if ( null !== $posted_subscription_scheme_option ) {
$posted_subscription_scheme_key = WCS_ATT_Product_Schemes::parse_subscription_scheme_key( $posted_subscription_scheme_option );
}
return $posted_subscription_scheme_key;
}
/**
* Add scheme data to cart items that can be purchased on a recurring basis.
*
* @param array $cart_item
* @param int $product_id
* @param int $variation_id
* @return array
*/
public static function add_cart_item_data( $cart_item, $product_id, $variation_id ) {
if ( self::is_supported( array_merge( $cart_item, array( 'product_id' => $product_id ) ) ) && ! isset( $cart_item[ 'wcsatt_data' ] ) ) { // Might be set - @see 'WCS_ATT_Order::restore_cart_item_from_order_item'.
$posted_subscription_scheme_key = WCS_ATT_Product_Schemes::get_posted_subscription_scheme( $product_id );
$cart_item[ 'wcsatt_data' ] = array(
'active_subscription_scheme' => $posted_subscription_scheme_key,
);
}
return $cart_item;
}
/**
* Applies a saved subscription key to a cart item.
* @see 'WCS_ATT_Product_Schemes::set_subscription_scheme'.
*
* @since 2.0.0
*
* @param array $cart_item
* @return array
*/
public static function apply_subscription_scheme( $cart_item ) {
if ( self::is_supported( $cart_item ) ) {
$scheme_to_apply = self::get_subscription_scheme( $cart_item );
if ( null !== $scheme_to_apply ) {
// Attempt to apply scheme.
WCS_ATT_Product_Schemes::set_subscription_scheme( $cart_item[ 'data' ], $scheme_to_apply );
// Grab the applied scheme.
$applied_scheme = WCS_ATT_Product_Schemes::get_subscription_scheme( $cart_item[ 'data' ] );
// If the scheme was not applied sucessfully, then it was probably deleted, or something fishy happened.
if ( $scheme_to_apply !== $applied_scheme ) {
// In this case, simply ensure that no scheme is set on the object and handle the mismatch later.
WCS_ATT_Product_Schemes::set_subscription_scheme( $cart_item[ 'data' ], null );
}
}
}
return apply_filters( 'wcsatt_cart_item', $cart_item );
}
/**
* Update the subscription scheme saved on a cart item when chosing a new option.
*
* @param boolean $updated
* @return boolean
*/
public static function update_cart_item_data( $updated ) {
$schemes_changed = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item[ 'wcsatt_data' ] ) ) {
$posted_subscription_scheme_key = self::get_posted_subscription_scheme( $cart_item_key );
if ( null !== $posted_subscription_scheme_key ) {
$existing_subscription_scheme_key = isset( $cart_item[ 'wcsatt_data' ][ 'active_subscription_scheme' ] ) ? $cart_item[ 'wcsatt_data' ][ 'active_subscription_scheme' ] : null;
if ( $posted_subscription_scheme_key !== $existing_subscription_scheme_key ) {
WC()->cart->cart_contents[ $cart_item_key ][ 'wcsatt_data' ][ 'active_subscription_scheme' ] = $posted_subscription_scheme_key;
$schemes_changed = true;
}
}
}
}
if ( $schemes_changed ) {
self::apply_subscription_schemes( WC()->cart );
}
return true;
}
Esta es mi función personalizada hasta ahora:
// Save Subscription Scheme key from form and update cart items subscription scheme.
add_action( 'elementor_pro/forms/new_record', function( $record, $handler ) {
$form_name = $record->get_form_settings( 'form_name' );
if ( 'Subscription Scheme' !== $form_name ) {
return;
}
$form_data = $record->get_formatted_data();
WC()->session->set( 'subscription_scheme', $form_data['Scheme'] );
$new_subscription_scheme_key = WC()->session->get('subscription_scheme');
global $woocommerce;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item[ 'wcsatt_data' ] ) ) {
$scheme_to_add = $new_subscription_scheme_key;
error_log("Scheme to apply for cart item key " . $cart_item_key . " is " . $scheme_to_add);
if ( null !== $scheme_to_add ) {
error_log("Scheme is not null, it can be applied to cart item key " . $cart_item_key);
error_log("Active subscription scheme before changes for cart item key: " . $cart_item_key . " is " . $cart_item[ 'wcsatt_data' ] ['active_subscription_scheme']);
$cart_item[ 'wcsatt_data' ] = array(
'active_subscription_scheme' => $scheme_to_add,
);
}
WC()->session->save_data();
error_log("Active subscription scheme after changes for cart item key: " . $cart_item_key . " is " . $cart_item[ 'wcsatt_data' ] ['active_subscription_scheme']);
}
}
}, 30, 2 );
Esto es lo que hice para probar la función: agregar 3 artículos de suscripción en el carrito. El artículo 1 y 2 se agregaron al carrito con el esquema 4_semana y el artículo 3 con el esquema 6_semana. Primero envío el esquema de 3 semanas en el formulario, luego envío el esquema de 5 semanas. Este es el registro de errores resultante (formateado para facilitar la lectura):
RUN 1:
[16-Jul-2022 15:05:32 UTC] Scheme to apply for cart item key aaf39e079f4e62ffd17ef1337958354f is 3_week
[16-Jul-2022 15:05:32 UTC] Scheme is not null, it can be applied to cart item key aaf39e079f4e62ffd17ef1337958354f
[16-Jul-2022 15:05:32 UTC] Active subscription scheme before changes for cart item key: aaf39e079f4e62ffd17ef1337958354f is 4_week
[16-Jul-2022 15:05:32 UTC] Active subscription scheme after changes for cart item key: aaf39e079f4e62ffd17ef1337958354f is 3_week
[16-Jul-2022 15:05:32 UTC] Scheme to apply for cart item key f5c452dc9267db95d7ecbcc3588b52c6 is 3_week
[16-Jul-2022 15:05:32 UTC] Scheme is not null, it can be applied to cart item key f5c452dc9267db95d7ecbcc3588b52c6
[16-Jul-2022 15:05:32 UTC] Active subscription scheme before changes for cart item key: f5c452dc9267db95d7ecbcc3588b52c6 is 4_week
[16-Jul-2022 15:05:32 UTC] Active subscription scheme after changes for cart item key: f5c452dc9267db95d7ecbcc3588b52c6 is 3_week
[16-Jul-2022 15:05:32 UTC] Scheme to apply for cart item key 8427cec082968c5ea2e40aecbf80bb30 is 3_week
[16-Jul-2022 15:05:32 UTC] Scheme is not null, it can be applied to cart item key 8427cec082968c5ea2e40aecbf80bb30
[16-Jul-2022 15:05:32 UTC] Active subscription scheme before changes for cart item key: 8427cec082968c5ea2e40aecbf80bb30 is 6_week
[16-Jul-2022 15:05:32 UTC] Active subscription scheme after changes for cart item key: 8427cec082968c5ea2e40aecbf80bb30 is 3_week
RUN 2:
[16-Jul-2022 15:05:35 UTC] Scheme to apply for cart item key aaf39e079f4e62ffd17ef1337958354f is 5_week
[16-Jul-2022 15:05:35 UTC] Scheme is not null, it can be applied to cart item key aaf39e079f4e62ffd17ef1337958354f
[16-Jul-2022 15:05:35 UTC] Active subscription scheme before changes for cart item key: aaf39e079f4e62ffd17ef1337958354f is 4_week
[16-Jul-2022 15:05:35 UTC] Active subscription scheme after changes for cart item key: aaf39e079f4e62ffd17ef1337958354f is 5_week
[16-Jul-2022 15:05:35 UTC] Scheme to apply for cart item key f5c452dc9267db95d7ecbcc3588b52c6 is 5_week
[16-Jul-2022 15:05:35 UTC] Scheme is not null, it can be applied to cart item key f5c452dc9267db95d7ecbcc3588b52c6
[16-Jul-2022 15:05:35 UTC] Active subscription scheme before changes for cart item key: f5c452dc9267db95d7ecbcc3588b52c6 is 4_week
[16-Jul-2022 15:05:35 UTC] Active subscription scheme after changes for cart item key: f5c452dc9267db95d7ecbcc3588b52c6 is 5_week
[16-Jul-2022 15:05:35 UTC] Scheme to apply for cart item key 8427cec082968c5ea2e40aecbf80bb30 is 5_week
[16-Jul-2022 15:05:35 UTC] Scheme is not null, it can be applied to cart item key 8427cec082968c5ea2e40aecbf80bb30
[16-Jul-2022 15:05:35 UTC] Active subscription scheme before changes for cart item key: 8427cec082968c5ea2e40aecbf80bb30 is 6_week
[16-Jul-2022 15:05:35 UTC] Active subscription scheme after changes for cart item key: 8427cec082968c5ea2e40aecbf80bb30 is 5_week
Almacené con éxito el esquema de suscripción enviado en el formulario, y el esquema de suscripción para cada elemento del carrito parece actualizarse durante la ejecución de la función, pero no se guarda en el backend, ya que cada elemento del carrito comienza con su esquema de suscripción original en cada prueba de funcionamiento.
¿Qué puedo hacer para que el esquema de suscripción actualizado para cada artículo del carrito se quede en el backend?
.