Woocommerce Checkout - list cart contents but only from a specific category, plus show first product to be delivered

92 Views Asked by At

We sell meal box subscriptions, "Culture Boxes". Customers can also buy once-off, single boxes. It is possible to have both a subscription and multiple single boxes in the same cart.

At checkout, before the form, we have a row of notice boxes, each one conditional on the categories in the cart. Box #1 shows if youre getting a subscription, Box #2 if you're buying a single box.

We need a Box #3 to also show, displaying next delivery day/month/date, which pulls values from an ACF group on the backend options page.

This is our Box 1 & 2 code. (We are not proper PHP coders...)

add_action( 'woocommerce_before_checkout_form', 'jbc_list_subs_note1', 12 );
function jbc_list_subs_note1() {
    // set your products IDs here:
    $product_ids = array(16773);
    $bool = false;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $item = $cart_item['data'];
        if ( in_array( $item->id, $product_ids ) )
            $bool = true;
    }
    // If the special ID is detected in one items of the cart
    // It displays the message
    if ($bool)
        echo '<div class="jbc-check-subs-note1">
                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">You&#39;ll receive</p>
                </div>
    
                <div class="jbc-check-subs-note1-div2">
                    <p class="jbc-check-subs-note-text-mid-l"> 1 Culture Box</p>
                </div>

                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">each month until you cancel.</p> 
                </div>
                </div>';
}
?>
    
<?php 
add_action( 'woocommerce_before_checkout_form', 'jbc_list_subs_note2', 12 );
function jbc_list_subs_note2() {
    // set your special category name, slug or ID here:
    $special_cat = '168';
    $bool = false;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $item = $cart_item['data'];
        if ( has_term( $special_cat, 'product_cat', $item->id ) )
            $bool = true;
    }
    // If the special cat is detected in one items of the cart
    // It displays the message

    if ($bool)
        echo '<div class="jbc-check-subs-note2">
                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">You are ordering our</p>
                </div>
    
                <div class="jbc-check-subs-note2-div2">
                    <p class="jbc-check-subs-note-text-mid-l">Featured Box</p>
                </div>

                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">as a one-time purchase.</p> 
                </div>
                </div>';
}

Our current code for Box #3 is this (of course doesn't work):

<?php 
add_action( 'woocommerce_before_checkout_form', 'jbc_list_subs_note3', 12 );
function jbc_list_subs_note3() {

        echo '<div class="jbc-check-subs-note2">
                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">Our next deliveries are scheduled for</p>
                </div>
    
                <div class="jbc-check-subs-note2-div2">     
        
        <?php
$Delivery = get_field('JBC_order_delivery');
if( $Delivery ): ?>
    <div id="Delivery">
    <?php if ( have_rows( 'JBC_order_delivery', 'option' ) ) : ?>
    <?php while ( have_rows( 'JBC_order_delivery', 'option' ) ) : the_row(); ?>
        <?php the_sub_field( 'JBC_order_delivery-day' ); ?>
        <?php the_sub_field( 'JBC_order_delivery-month' ); ?>
        <?php the_sub_field( 'JBC_order_delivery-date' ); ?>
    <?php endwhile; ?>
<?php endif; 
?> 
</div>

                <div class="jbc-check-subs-note1-div1">
                    <p class="jbc-check-subs-note-txt-top-s">via courier</p> 
                </div>
                </div>';
}

What do we need to do get the ACF options field values to display within that Box #3?

1

There are 1 best solutions below

8
LoicTheAztec On

There are multiple mistakes in your code and you can merge the code in one function as you are using the same hook.

The main problem in your 3rd function is in get_field('JBC_order_delivery') where 'option' argument is missing. Also, check that you are using the correct ACF field slug name but not the label name (I can't really test your ACF fields).

Try the following revised code:

add_action( 'woocommerce_before_checkout_form', 'jbc_list_subs_notes', 12 );
function jbc_list_subs_notes() {
    // set your products IDs here:
    $targeted_product_ids = array(16773);
    $product_found = false;

    // set your special category name, slug or ID here:
    $targeted_categories = array(168);
    $category_found = false;

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $item ) {
        // Check for products Ids
        if ( in_array( $item['product_id'], $targeted_product_ids ) ) {
            $product_found = true;
        }
        // Check for products categories
        if ( has_term( $targeted_categories, 'product_cat', $item['product_id'] ) ) {
            $category_found = true;
        }
    }   
    // If the special ID is detected in one items of the cart
    // It displays the message
    if ( $product_found ) {
        echo '<div class="jbc-check-subs-note1">
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">You&#39;ll receive</p>
        </div>
        <div class="jbc-check-subs-note1-div2">
            <p class="jbc-check-subs-note-text-mid-l"> 1 Culture Box</p>
        </div>
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">each month until you cancel.</p> 
        </div>
        </div>';
    }

    // If the special cat is detected in one items of the cart
    // It displays the message
    if ( $category_found ) {
        echo '<div class="jbc-check-subs-note2">
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">You are ordering our</p>
        </div>
        <div class="jbc-check-subs-note2-div2">
            <p class="jbc-check-subs-note-text-mid-l">Featured Box</p>
        </div>
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">as a one-time purchase.</p> 
        </div>
        </div>';
    }

    // Delivery section
    $field_slug = 'JBC_order_delivery';

    if( get_field($field_slug, 'option') ) {
        echo '<div class="jbc-check-subs-note2">
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">Our next deliveries are scheduled for</p>
        </div>
        <div class="jbc-check-subs-note2-div2">
            <div id="Delivery">';

        if ( have_rows( $field_slug, 'option' ) ) : 
            while ( have_rows( $field_slug, 'option' ) ) : the_row();
                the_sub_field( $field_slug.'-day' ); 
                the_sub_field( $field_slug.'-month' );
                the_sub_field( $field_slug.'-date' ); 
            endwhile;
        endif; 
        echo '</div>
        <div class="jbc-check-subs-note1-div1">
            <p class="jbc-check-subs-note-txt-top-s">via courier</p> 
        </div>
        </div>';
    }
}

It should work.