Search code examples
phpwordpresswoocommercesession-variablesorders

Save WooCommerce custom Session Variables as order meta data


I'm trying to store custom session variables in database. Then, show them inside new order email and order details in WooCommerce Admin.

I have custom variables inside session:

add_action( 'init', 'oturum_degiskeni_olustur' );
function oturum_degiskeni_olustur () {
  // Early initialize customer session
  if ( isset(WC()->session) && ! WC()->session->has_session() ) {
      WC()->session->set_customer_session_cookie( true );
  }

  if ( isset( $_GET['konumu'] ) || isset( $_GET['masa_no'] ) ) {
      $konum = isset( $_GET['konumu'] )  ? esc_attr( $_GET['konumu'] )  : '';
      $masa  = isset( $_GET['masa_no'] ) ? esc_attr( $_GET['masa_no'] ) : '';

      // Set the session data
      WC()->session->set( 'custom_data', array( 'konum' => $konum, 'masa' => $masa ) );
  }
}

Firstly, I added custom variables to database with this code;

// Storing session variables for using them in order notifications
add_action( 'woocommerce_checkout_create_order', 'oturum_degiskeni_kaydet' );

function oturum_degiskeni_kaydet( $order, $data ) { 
  if ( $_POST['konumu'] ) update_meta_data( $order_id, '_konum', esc_attr( $_POST['konumu'] ) );
  if ( $_POST['masa_no'] ) update_meta_data( $order_id, '_masa', esc_attr( $_POST['masa_no'] ) );
}

Second, I added this variable's data to a new order email for admin.

// Show this session variables in new order email for admin 
add_action( 'woocommerce_email_after_order_table', 'konumu_emaile_ekle', 20, 4 );

function konumu_emaile_ekle( $order, $sent_to_admin, $plain_text, $email ) {
  if ( get_post_meta( $order->get_id(), '_konum', true ) ) echo '<p><strong>Konum :</strong> ' . get_post_meta( $order->get_id(), '_konum', true ) . '</p>';
  if ( get_post_meta( $order->get_id(), '_masa', true ) ) echo '<p><strong>Masa Numarası :</strong> ' . get_post_meta( $order->get_id(), '_masa', true ) . '</p>';
}

Last part of the code is shown session variables data in WooCommerce order page;

// Show session variable in woocommerce order page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'konumu_admine_ekle', 10, 1 );

function konumu_admine_ekle( $order ) {

 $order_id = $order->get_id();
 if ( get_post_meta( $order_id, '_konum', true ) ) echo '<p><strong>Konum :</strong> ' . get_post_meta( $order_id, '_konum', true ) . '</p>';
 if ( get_post_meta( $order_id, '_masa', true ) ) echo '<p><strong>Masa Numarası :</strong> ' . get_post_meta( $order_id, '_masa', true ) . '</p>';
}

But, it does not work. When customer made an order, it gave an error "We were unable to process your order, please try again."


Solution

  • Updated: There are some mistakes in your code when you are trying to save your custom data from session as order meta data and display it on emails and admin order pages…

    Your first function is correct (oturum_degiskeni_olustur)…

    Assuming that data is passed through URL like: website.com/?konumu=newyork&masa_no=12

    Here is the revisited code:

    // Unchanged
    add_action( 'init', 'oturum_degiskeni_olustur' );
    function oturum_degiskeni_olustur () {
        // Early initialize customer session
        if ( isset(WC()->session) && ! WC()->session->has_session() ) {
            WC()->session->set_customer_session_cookie( true );
        }
    
        if ( isset( $_GET['konumu'] ) || isset( $_GET['masa_no'] ) ) {
            $konum = isset( $_GET['konumu'] )  ? esc_attr( $_GET['konumu'] )  : '';
            $masa  = isset( $_GET['masa_no'] ) ? esc_attr( $_GET['masa_no'] ) : '';
    
            // Set the session data
            WC()->session->set( 'custom_data', array( 'konum' => $konum, 'masa' => $masa ) );
        }
    }
    
    // Save custom session data as order meta data
    add_action( 'woocommerce_checkout_create_order', 'oturum_degiskeni_kaydet' );
    function oturum_degiskeni_kaydet( $order ) {
        $data = WC()->session->get( 'custom_data' ); // Get custom data from session
    
        if ( isset($data['konum']) ) {
            $order->update_meta_data( '_konum', $data['konum'] );
        }
        
        if ( isset($data['masa']) ) {
            $order->update_meta_data( '_masa', $data['masa'] );
        }
        
        WC()->session->__unset( 'custom_data' ); // Remove session variable
    }
    
    // Show this session variables in new order email for admin and in woocommerce order page
    add_action( 'woocommerce_email_after_order_table', 'konumu_emaile_admine_ekle', 20 );
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'konumu_emaile_admine_ekle' );
    function konumu_emaile_admine_ekle( $order ) {
    
        if ( $konum = $order->get_meta( '_konum' ) )
            echo '<p><strong>Masa Numarası :</strong> ' . $konum . '</p>';
    
        if ( $masa = $order->get_meta( '_masa' ) )
            echo '<p><strong>Konum :</strong> ' . $masa . '</p>';
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and Works.

    On the email notification before customer details:

    enter image description here

    On admin order edit page (under billing phone):

    enter image description here

    Tested on WooCommerce 4.2+ under storefront theme