dominotrix
dominotrix

Reputation: 367

How can I use WooCommerce hooks that have parameters along with other functions?

This hook has some parameters $item_data, $cart_item, that the hook woocommerce_get_item_data needs to have in order to work.

function display_cart_item_custom_meta_data( $item_data, $cart_item ) {
  $adults = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_0']);
  $children = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_1']);
  $infants = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_2']);
  $number = $adults + $children + $infants;
  $number = array_sum(str_split($number));
}
add_filter( 'woocommerce_get_item_data', 'display_cart_item_custom_meta_data', 9, 2 );

What the above function does, is checking the cart for 3 custom values. These values are:

3 adults
2 children
1 infant

And the variable $number is being split so that we can remove the words and just keep the sum number, which in this example is 6. Next, we need to register a text field to show at the Checkout page, like this:

function my_custom_checkout_field( $checkout ) {
  $persons = $number;
  for ($i=1; $i <= $persons; $i++){
    echo '<div id="my_custom_checkout_field' . $i . '"><h2>Person #' . $i . '</h2>';
    woocommerce_form_field( 'my_field_name' . $i, array(
      'type'          => 'text',
      'class'         => array('my-field-class' . $i . ' form-row-wide'),
      'label'         => __('Fill in this field'),
      'placeholder'   => __('Enter something'),
        'required'          => true
    ), $checkout->get_value( 'my_field_name' . $i ));
    echo '</div>';
  }
}
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

The above function is simply registering a text field that the client has to fill. This field is the name of each passenger. But the total number of fields registered needs to be the same as the first function (in our example 6).

So using the for loop, we can run the registration for the text field 6 times, or in general n times depending on what the variable $number's value is set.

The error that I get is a PHP Notice: Notice: Undefined variable: number.

Upvotes: 0

Views: 635

Answers (1)

businessbloomer
businessbloomer

Reputation: 1132

I assume you already have 3 custom fields on the single product page (adults children infants) and that values are loaded upon add to cart as $cart_item meta.

If that's already working like that, on the checkout page you simply need to loop over cart items, read $cart_item meta and see what's inside. If yes, you can then display your N fields.

I'd combine your two functions, without the need of using 'woocommerce_get_item_data'. I assume there can be more than one item in the cart, so I will be calculating the max value from $numbers. I also assume your $number code to calculate the total is working:

function bbloomer_custom_checkout_fields( $checkout ) {
  
  // loop over cart items and calc $numbers 
  $numbers = array();
  foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
     if ( $cart_item['tmpost_data']['tmcp_select_0'] && $cart_item['tmpost_data']['tmcp_select_1'] && $cart_item['tmpost_data']['tmcp_select_2'] ) {
        $adults = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_0']);
        $children = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_1']);
        $infants = preg_replace('/\W\w+\s*(\W*)$/', '$1', $cart_item['tmpost_data']['tmcp_select_2']);
        $number = $adults + $children + $infants;
        $numbers[] = array_sum(str_split($number));
     }
  }
  $persons = max( $numbers );
  for ($i=1; $i <= $persons; $i++){
    echo '<div id="my_custom_checkout_field' . $i . '"><h2>Person #' . $i . '</h2>';
    woocommerce_form_field( 'my_field_name' . $i, array(
      'type'          => 'text',
      'class'         => array('my-field-class' . $i . ' form-row-wide'),
      'label'         => __('Fill in this field'),
      'placeholder'   => __('Enter something'),
        'required'          => true
    ), $checkout->get_value( 'my_field_name' . $i ));
    echo '</div>';
  }
}

add_action( 'woocommerce_after_order_notes', 'bbloomer_custom_checkout_fields' );

Upvotes: 1

Related Questions