Search code examples
phpwordpresswoocommercecategoriesorders

Conditional display based on product category in processing order email template


I am working on the code of customer-processing-order.php WooCommerce email Template.

I want to display the code below, only if an order item has a defined product category of ordered item.

<p><?php _e( "Your order has been received and is now being processed. Your order details are shown below for your reference:", 'woocommerce' ); ?></p>

Something like:

if($categ="demo1"){
<p><?php _e( "Your order has been received and is now being processed. Some text here:", 'woocommerce' ); ?></p>
} 

Here is an extract of the template code:

<?php
/**
 * Customer processing order email
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-processing-order.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see         https://docs.woocommerce.com/document/template-structure/
 * @author      WooThemes
 * @package     WooCommerce/Templates/Emails
 * @version     2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>

<p><?php _e( "Your order has been received and is now being processed. Your order details are shown below for your reference:", 'woocommerce' ); ?></p>

<?php

/**
 * @hooked WC_Emails::order_details() Shows the order details table.
 * @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
 * @since 2.5.0
 */
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::order_meta() Shows order meta data.
 */
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::customer_details() Shows customer details
 * @hooked WC_Emails::email_address() Shows email address
 */
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );

How can I do this?

Thanks


Solution

  • Here it's what you are expecting. I use the WordPress native conditional function has_term(). This function accept term IDs, term names or term slugs, in a string for a single term or in an array for multiple terms.

    You will have to define your category or your categories (see the comment in both codes).

    Here is the customized template code (for one category):

    <?php
    /**
     * Customer processing order email
     *
     * This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-processing-order.php.
     *
     * HOWEVER, on occasion WooCommerce will need to update template files and you
     * (the theme developer) will need to copy the new files to your theme to
     * maintain compatibility. We try to do this as little as possible, but it does
     * happen. When this occurs the version of the template file will be bumped and
     * the readme will list any important changes.
     *
     * @see         https://docs.woocommerce.com/document/template-structure/
     * @author      WooThemes
     * @package     WooCommerce/Templates/Emails
     * @version     2.5.0
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
        exit;
    }
    
    //Define below your category (ID, slug or name)
    $category = 'my_category';
    
    $has_category = false;
    foreach( $order->get_items() as $order_item ) {
        if( has_term( $category, 'product_cat', $order_item["product_id"] ) ) {
            $has_category = true;
            break;
        }
    }
    
    /**
     * @hooked WC_Emails::email_header() Output the email header
     */
    
    do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
    
    <?php
    // Here is your conditional statement based on a defined product category
    if( $has_category ){
        echo '<p>'. __( "Your order has been received and is now being processed. Some text here:", 'woocommerce' ) .'</p>';
    } else {
        echo '<p>'. __( "Your order has been received and is now being processed. Your order details are shown below for your reference:", 'woocommerce' ) .'</p>';
    }
    ?>
    
    <?php
    
    /**
     * @hooked WC_Emails::order_details() Shows the order details table.
     * @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
     * @since 2.5.0
     */
    do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
    
    # ... etc ...
    

    If you have multiple categories, the code will be very similar:

    //Define below your categories in the array (IDs, slugs or names)
    $categories = array('my_category1', 'my_category2', 'my_category3');
    
    $has_category = false;
    foreach( $order->get_items() as $order_item ) {
    
        if( has_term( $categories, 'product_cat', $order_item["product_id"] ) ) {
            $has_category = true;
            break;
        }
    }
    

    All code is tested and working.


    Reference: WordPress Function Reference — has_term()