Search code examples
phpwoocommercecartcheckoutemail-notifications

Display a custom text based on product category in WooCommerce cart, thankyou and emails


As the title suggests, I would like to show a custom text in WooCommerce cart, based on the product category added by the customer

Here is the code:

// Add a function to show custom text on the cart page
add_action( 'woocommerce_before_cart', 'show_custom_text' );

// Define the function
function show_custom_text() {
  // Get the current cart
  $cart = WC()->cart;
  
  // Check if the cart is empty
  if ( $cart->is_empty() ) {
    return;
  }
  
  // Create an associative array with the product categories and related texts to display
  $categories_and_texts = array(
    '1' => 'This is text 1',
    '2' => 'This is text 2',
    '3' => 'This is text 3',
    // Add more categories and lyrics here
  );
  
  // Create an empty array to store the categories in the cart
  $categories_in_cart = array();
  
  // Iterate over all the items in the cart
  foreach ( $cart->get_cart() as $cart_item ) {
    // Get the current product
    $product = $cart_item['data'];
    
    // Get product categories
    $product_categories = wp_get_post_terms( $product->get_id(), 'product_cat' );
    
    // Iterate over all product categories
    foreach ( $product_categories as $product_category ) {
      // Get the category slug
      $category_slug = $product_category->slug;
      
      // Check if the category is among those defined in the associative array
      if ( array_key_exists( $category_slug, $categories_and_texts ) ) {
        // Add the category to the array of categories in the cart, if not already present
        if ( ! in_array( $category_slug, $categories_in_cart ) ) {
          $categories_in_cart[] = $category_slug;
        }
      }
    }
  }
  
  // Check if there are any categories in the cart
  if ( ! empty( $categories_in_cart ) ) {
    // Show a message before custom texts
    echo '<p>Attention, you have added products from the following categories to your cart:</p>';
    
    // Iterate over all the categories in the cart
    foreach ( $categories_in_cart as $category ) {
      // Show the text corresponding to the category
      echo '<p>' . $categories_and_texts[$category] . '</p>';
    }
  }
}

But it doesn't seem to work.

Any help is appreciated.

I'd like to show the text also in the Thankyou page and on email notifications.


Solution

  • The following revisited code will display custom texts based on product categories (slugs) on cart, checkout, order received (thankyou) and email notifications.

    The code (your settings in the first function):

    // Settings: Add category term slug(s) and their respective text below
    function load_category_settings() {
        return array(
            array( 
                'terms' => array('accessories'), // Here your term(s) slug(s)
                'text'  => __("This is the custom text for Accessories", "woocommerce"), // Here the corresponding text
            ),
            array( 
                'terms' => array('tshirt', 'hoodie', 'shirt' ), // Here your term(s) slug(s)
                'text'  => __("This is the custom text for T-shirts, Hoodies, Shirts", "woocommerce"), // Here the corresponding text
            ),
        );
    }
    
    // Utility function: Check cart or order items for categories
    function check_item_for_categories( $items, $term_slugs = array() ) {
        foreach ( $items as $item ) {
            $product_id = isset($item['product_id']) ? $item['product_id'] : $item->get_product_id();
            foreach ( load_category_settings() as $key => $values ) {
                foreach ( $values['terms'] as $term_slug  ) {
                    if( has_term($term_slug , 'product_cat', $product_id ) ) {
                        $term_slugs[$key][] = $term_slug ;
                    }
                }
            }
        }
        return $term_slugs;
    }
    
    // Utility function: Display custom texts based on item categories
    function display_texts_for_categories( $term_slugs ) {
        $data = load_category_settings();
        $html =  __("Attention, you have added products from the following categories to your cart", "woocommerce") . ':<br>';
    
        foreach ( $term_slugs as $key => $terms ) {
            $html .= $data[$key]['text'] . '<br>';
        }
        return $html;
    }
    
    
    // Display on cart and checkout
    add_action( 'woocommerce_before_cart', 'cart_checkout_show_custom_text', 10 ); // For cart page
    add_action( 'woocommerce_before_checkout_form', 'cart_checkout_show_custom_text', 5 ); // For checkout page
    function cart_checkout_show_custom_text() {
        $cart = WC()->cart; // Get the current cart
      
        // Check if the cart is empty
        if ( ! $cart->is_empty() ) {
            $term_slugs = check_item_for_categories( $cart->get_cart() );
    
            if( count($term_slugs) > 0 ) {
                wc_print_notice( display_texts_for_categories( $term_slugs ), 'notice' );
            }
        }
    }
    
    // Display on Order received (thankyou) page
    add_action( 'woocommerce_before_thankyou', 'thankyou_show_custom_text', 10 ); // For checkout page
    function thankyou_show_custom_text( $order_id ) {
        $order = wc_get_order($order_id); // Get the current order object
      
        // Check if the cart is empty
        $term_slugs = check_item_for_categories( $order->get_items() );
        if( count($term_slugs) > 0 ) {
            wc_print_notice( display_texts_for_categories( $term_slugs ), 'notice' );
        }
    }
    
    // Display custom fields data on email notifications
    add_action( 'woocommerce_email_order_details', 'display_on_email_notifications', 5, 1 );
    function display_on_email_notifications( $order ) {
        $term_slugs = check_item_for_categories( $order->get_items() );
    
        if ( ! empty($term_slugs) ) {
            $title = __('Information', 'woocommerce');
    
            echo '<style>
            .message table{width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
                color: #737373; border: 1px solid #e4e4e4; margin-bottom:8px;}
            .message table th, .message table td{text-align: left; border-top-width: 4px;
                color: #737373; border: 1px solid #e4e4e4; padding: 12px; width:58%;}
            .message table td{text-align: left; border-top-width: 4px; color: #737373; border: 1px solid #e4e4e4; padding: 12px;}
            </style>';
    
            echo '<div class="message"><h2>'.$title.'</h2>
            <table cellspacing="0" cellpadding="6"><tbody>
            <tr"><td>'.display_texts_for_categories( $term_slugs ).'</td></tr>
            </tbody></table></div><br>';
        }
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.