Search code examples
phpwoocommercemetadataadminorders

Add non-existing order metadata to extend WooCommerce admin orders search for specific products


I have a question following my previous questions: Add non-existing order metadata to extend WooCommerce admin orders search

I have two questions:

First: If I want this md5 value to be saved only when two of the products with IDs 120 and 260 are purchased by the customer, how can it be done? (that is, when the payment was successful and the purchase was completed, and if one of these two products with ID 120 and 260 or both products were in the customer's (successful) order, this md5 value should be stored)

  • an additional request for this question, can check if this md5 value was saved before for this customer, will the new value be saved? Because the md5 code is created based on the e-mail, and for a customer with a specific e-mail, a duplicate amount will definitely be obtained.

Second: How to execute the following code or execute a piece of PHP code after ordering two specific products, for example, with IDs 120 and 260?

$pro_message = 'Hi dear'
echo $pro_message. 'custom php code';

Solution

  • To make "this md5 value to be saved only when" specific products are in cart (or in order items), we need a reusable conditional function that will check items:

    // Conditional function: Check if specific products are in cart or order items
    function has_items_for_email_md5( $object_items ) {
        $found_120 = $found_260 = false; // Initializing
        
        foreach ( $object_items as $item ) {
            $product_id   = isset($item['product_id'])   ? $item['product_id']   : $item->get_product_id();
            $variation_id = isset($item['variation_id']) ? $item['variation_id'] : $item->get_variation_id();
    
            if ( in_array('120', [$product_id , $variation_id]) ) $found_120 = true;
            if ( in_array('260', [$product_id , $variation_id]) ) $found_260 = true;
        }
        return ( $found_120 && $found_260 );
    }
    

    Now we can make some small changes to our previous code, that will use this conditional function:

    // When order is created after checkout
    add_action( 'woocommerce_checkout_create_order', 'save_billing_email_md5', 20, 2 );
    function save_billing_email_md5( $order, $data ) {
        if ( ! has_items_for_email_md5( WC()->cart->get_cart() ) ) return;
    
        if( $billing_email = $order->get_billing_email() ) {
            $order->add_meta_data('_billing_email_md5', md5($billing_email));
        }
    }
    
    // When an order is manually created/updated in admin
    add_action( 'woocommerce_process_shop_order_meta', 'admin_save_billing_email_md5' );
    function admin_save_billing_email_md5( $order_id ) {
        $order = wc_get_order( $order_id );
    
        if ( ! has_items_for_email_md5( $order->get_items() ) ) return;
    
        if( $billing_email = $order->get_billing_email() ) {
            update_post_meta($order_id, '_billing_email_md5', md5($billing_email));
        }
    }
    

    The last function stay unchanged:

    add_filter( 'woocommerce_shop_order_search_fields', 'extending_admin_orders_search_field', 10, 1 );
    function extending_admin_orders_search_field( $meta_keys ){
        $meta_keys[] = '_billing_email';
        $meta_keys[] = '_billing_phone';
        $meta_keys[] = '_payment_method_title';
        $meta_keys[] = '_billing_email_md5'; // <=== HERE
    
        return $meta_keys;
    }
    

    It should work.


    Then to execute some code after purchasing those two specific products (IDs 120 and 260), we will use our conditional function as follows (from an order ID):

    $order = wc_get_order( $order_id ); // Get WC_Order object (if needed)
    
    if ( has_items_for_email_md5( $order->get_items() ) ) {
        $pro_message = __('Hi dear');
    
        echo $pro_message . __('custom php code');
    }