Wordpress add meta key to Cart item - wordpress

as I am trying to add one extra data so that I can fetch and filter the data according to the meta after successfull payment. Let me explain using code.
$cart_data = array(
'product_id' => $product_id,
'payment_type' => 'subscription',
'**what_is_being_promoted**' => $promoting,
);
WC()->cart->add_to_cart($product_id, 1, null, null, $cart_item_data);
now i would like to read the key 'what_is_being_promoted' in classifier_update_user_data_upon_payment hook.
how to achieve that.

You can use below filters/action to add additional data to cart item:
//Add custom cart item data
function zwtadd_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
if( isset( $_POST['what_is_being_promoted'] ) ) {
$cart_item_data['zwt_field'] = sanitize_text_field( $_POST['what_is_being_promoted'] );
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'zwtadd_cart_item_data', 10, 3 );
//Display custom item data in the cart
function zwt_get_item_data( $item_data, $cart_item_data ) {
if( isset( $cart_item_data['zwt_field'] ) ) {
$item_data[] = array(
'key' => __( 'Is promoted', 'text-domain' ),
'value' => wc_clean( $cart_item_data['zwt_field'] )
);
}
return $item_data;
}
add_filter( 'woocommerce_get_item_data', 'zwt_get_item_data', 10, 2 );
//Add custom meta to order
function zwt_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
if( isset( $values['zwt_field'] ) ) {
$item->add_meta_data(__( 'Is promoted', 'text-domain' ), $values['zwt_field'], true);
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'zwt_checkout_create_order_line_item', 10, 4 );
Above code will add data to cart item, display data to cart and same will display in the order.

Related

Save multiple datas in order WooCommerce

I have two customs fields in my product (image and texte), I all ready show it in the cart but when the order is complete, i can't find how can I show both in the admin order (I can show one of two ^^)
Here is the code :
// Add custom fields data as the cart item custom data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_fields_data_as_custom_cart_item_data', 10, 2 );
function add_custom_fields_data_as_custom_cart_item_data($cart_item, $product_id){
if( isset($_FILES['image']) && !empty($_FILES['image']) && !empty($_POST['nom_pp']) ) {
$upload = wp_upload_bits( $_FILES['image']['name'], null, file_get_contents( $_FILES['image']['tmp_name'] ) );
$filetype = wp_check_filetype( basename( $upload['file'] ), null );
$upload_dir = wp_upload_dir();
$upl_base_url = is_ssl() ? str_replace('http://', 'https://', $upload_dir['baseurl']) : $upload_dir['baseurl'];
$base_name = basename( $upload['file'] );
$cart_item['file_upload'] = array(
'guid' => $upl_base_url .'/'. _wp_relative_upload_path( $upload['file'] ), // Url
'file_type' => $filetype['type'], // File type
'file_name' => $base_name, // File name
'title' => ucfirst( preg_replace('/\.[^.]+$/', '', $base_name ) ), // Title
);
$cart_item['nom_pp'] = $_POST['nom_pp'];
$cart_item['unique_key'] = md5( microtime().rand() ); // Avoid merging items
}
return $cart_item;
}
// Display custom cart item data in cart (optional)
add_filter('woocommerce_get_item_data', 'njengah_custom_item_data', 10, 2);
function njengah_custom_item_data($cart_item_data, $cart_item) {
if ( isset($cart_item['file_upload']['title']) ){
$cart_item_data[] = array(
'name' => __( 'Mon image ', 'woocommerce' ),
'value' => str_pad($cart_item['file_upload']['title'], 16, 'X', STR_PAD_LEFT) . '…',
);
}
if ( isset($cart_item['nom_pp']) ){
$cart_item_data[] = array(
'name' => __( 'Nom du papier peint ', 'woocommerce' ),
'value' => $cart_item['nom_pp'],
);
}
return $cart_item_data;
}
// Save Image data as order item meta data
add_action( 'woocommerce_checkout_create_order_line_item', 'njengah_field_update_order_item_meta', 20, 4 );
function njengah_field_update_order_item_meta( $item, $cart_item_key, $values, $order ) {
if ( isset($values['file_upload']) && isset($values['nom_pp']) ){
$item->update_meta_data($item, '_img_file', $values['file_upload']);
$item->update_meta_data($item, '_nom_pp', $values['nom_pp']);
}
}
// Admin orders: Display a linked button + the link of the image file
add_action( 'woocommerce_after_order_itemmeta', 'njengah_image_link_after_order_itemmeta', 10, 3 );
function njengah_image_link_after_order_itemmeta( $item_id, $item, $product ) {
// Only in backend for order line items (avoiding errors)
if( is_admin() && $item->is_type('line_item') && $file_data = $item->get_meta('_img_file') && $file_data = $item->get_meta('_nom_pp') ){
echo '<p>'.__("Voir l'image") . '</p>'; // Optional
echo '<p><code>'.$file_data['guid'].'</code></p>'; // Optional
echo '<p>'.$file_data['nom_pp'].'</p>'; // Optional
}
}
I think I need to edit the order meta data, but I don't know how can I do it :)

WP add to cart and save item meta programmatically [duplicate]

This question already has answers here:
Woocommerce Ajax add to cart programmatically
(2 answers)
Closed 1 year ago.
I want to add product along with meta data in cart with programming.
Here is my code. But its not adding any meta data but only adding product in cart.
$genre = 10;
$item_id = WC()->cart->add_to_cart( $product_id, 1, false, false, [ 'genre_id' => $genre, 'genre' => 'Test' ] );
WC()->cart->cart_contents[$item_id]['genre_id'] = $genre;
WC()->cart->cart_contents[$item_id]['genre'] = 'Test';
WC()->cart->calculate_totals();
WC()->cart->set_session();
WC()->cart->maybe_set_cart_cookies();
Also added few hooks, that are also not adding meta data.
add_action( 'woocommerce_before_calculate_totals', 'change_cart_item_price', 30, 1 );
function change_cart_item_price( $cart ) {
foreach ( $cart->get_cart() as $cart_item ) {
//if( isset($cart_item['genre_id']) ){
$cart_item['data']->add_meta_data( 'genre_id', $cart_item['genre_id'] );
$cart_item['data']->add_meta_data( 'genre', 'Test' );
//}
}
}
add_filter( 'woocommerce_get_item_data', function ( $item_data, $cart_item_data ) {
//if( isset( $cart_item_data['genre'] ) ) {
$item_data[] = array(
'key' => 'Genre',
'value' => 'Test'
);
//}
return $item_data;
}, 10, 2 );
add_action( 'woocommerce_checkout_create_order_line_item', function( $item, $cart_item_key, $values, $order ) {
//if( isset( $values['genre'] ) ) {
$item->add_meta_data(
'Genre',
'Test',
true
);
//}
}, 10, 4 );
Can you please verify where I'm wrong. I got these code from online search.
You can use below action/filter to add additional data to cart item:
//Add custom cart item data
function zwtadd_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
if( isset( $_POST['what_is_being_promoted'] ) ) {
$cart_item_data['zwt_field'] = sanitize_text_field( $_POST['genre_id'] );
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'zwtadd_cart_item_data', 10, 3 );
//Display custom item data in the cart
function zwt_get_item_data( $item_data, $cart_item_data ) {
if( isset( $cart_item_data['zwt_field'] ) ) {
$item_data[] = array(
'key' => __( 'Genre id', 'text-domain' ),
'value' => wc_clean( $cart_item_data['zwt_field'] )
);
}
return $item_data;
}
add_filter( 'woocommerce_get_item_data', 'zwt_get_item_data', 10, 2 );
//Add custom meta to order
function zwt_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
if( isset( $values['zwt_field'] ) ) {
$item->add_meta_data(__( 'Genre id', 'text-domain' ), $values['zwt_field'], true);
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'zwt_checkout_create_order_line_item', 10, 4 );
Above code will add data to cart item, display data to cart and same will display in the order.

Add custom select field with validation to WooCommerce checkout page if certain products are in cart

I wish to add a custom select field with validation to the WooCommerce checkout page if certain products are in cart.
With my current code I retrieve the value of my custom WooCommerce form field. However, it display "array" at the order page.
I have an select field which have an option of 1 and 0. Upon selection of the select field, i want it to display either 1 or 0 at the order page but im unable to do so.
Please guide me on what should i do with my current codes:
//AMBASSADOR CUSTOM CHECKOUT FIELDS, CONTENT add marketplace for sameday TEST
add_action( 'woocommerce_after_checkout_billing_form', 'aym_custom_checkout_field' );
function aym_custom_checkout_field( $checkout ) {
//Check if Product in Cart
$prod_in_cart_17563 = aym_is_conditional_product_in_cart_17563( 212 );
if ( $prod_in_cart_17563 === true ) {
$domain = 'wocommerce';
$default = 'Y';
woocommerce_form_field( '_my_field_name', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'label' => __( 'Market Place - Please Select Y to complete this order' ),
'required' => true,
'options' => array(
'Y' => __('1'),
'N' => __('0')
),'default' => $default),
$checkout->get_value( '_my_field_name' ) );
}
}
//AMBSSADOR BUNDLE add marketplace for same day pa rt 2
function aym_is_conditional_product_in_cart_17563( $product_id ) {
//Check to see if user has product in cart
global $woocommerce;
//flag no product in cart
$prod_in_cart_17563 = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id === $product_id ) {
//product is in cart!
$prod_in_cart_17563 = true;
}
}
return $prod_in_cart_17563;
}
//process orders in order page
// Custom checkout fields validation
add_action( 'woocommerce_checkout_process', 'custom_checkout_field_process' );
function custom_checkout_field_process() {
if ( isset($_POST['_my_field_name']) && empty($_POST['_my_field_name']) )
wc_add_notice( __( 'Please fill in "My 1st new field".' ), 'error' );
}
// Save custom checkout fields the data to the order
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_meta', 10, 2 );
function custom_checkout_field_update_meta( $order, $data ){
if( isset($_POST['_my_field_name']) && ! empty($_POST['_my_field_name']) )
$order->update_meta_data( '_my_field_name', sanitize_text_field( $_POST['_my_field_name'] ) );
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['_my_field_name']) update_post_meta( $order_id, 'My Field', esc_attr($_POST['_my_field_name']));
}
// View fields in Edit Order Page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_fields_value_admin_order', 10, 1 );
function display_custom_fields_value_admin_order( $order ){
// Display the delivery option
if( $delivery_option = $order->get_meta('_my_field_name') )
echo '<p><strong>'.__('Delivery type').':</strong> ' . $delivery_option . '</p>';
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ) {
if( $selectoption = $order->get_meta('_my_field_name') ) {
//$value = wc_get_hearaboutus_options()[$selectoptions];
$meta= get_post_meta( $post->ID, $selectoption, true );
$myvalues = unserialize( $meta );
echo '<p><strong>'.__('Market_Place').':</strong> ' . $myvalues . '</p>';
}
}
I have partly rewritten / modified your code with some (extra) features
The ability to check for multiple product IDs in the shopping cart
The custom field is only added if a certain product id is in the shopping cart
The possibility to check out if the custom field is not present (product ID is NOT in cart)
No possibility to checkout as long as the value 'Y' is not selected from the custom select menu (Product ID is IN cart)
Explanation via comment tags added in the code
// Add custom 'select' field after checkout billing form (if product ID is in cart)
function action_woocommerce_after_checkout_billing_form( $checkout ) {
// Check if Product in Cart
// Multiple product IDs can be entered, separated by a comma
$product_in_cart = is_product_in_cart( array( 212, 30, 815 ) );
// True
if ( $product_in_cart ) {
$domain = 'woocommerce';
$default = 'Y';
woocommerce_form_field( '_my_field_name', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'label' => __( 'Market Place - Please Select Y to complete this order', $domain ),
'required' => true,
'options' => array(
'Y' => __( 'Y', $domain ),
'N' => __( 'N', $domain ),
),
'default' => $default,
), $checkout->get_value( '_my_field_name' ) );
}
}
add_action( 'woocommerce_after_checkout_billing_form', 'action_woocommerce_after_checkout_billing_form', 10, 1 );
// Function to check if a certain product ID is in cart
function is_product_in_cart( $targeted_ids ) {
// Flag no product in cart
$flag = false;
// WC Cart NOT null
if ( ! is_null( WC()->cart ) ) {
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
// Check cart item for defined product Ids
if ( in_array( $cart_item['product_id'], $targeted_ids ) ) {
// Product is in cart
$flag = true;
// Break loop
break;
}
}
}
return $flag;
}
// Custom checkout 'select' field validation
function action_woocommerce_checkout_process() {
// Isset
if ( isset( $_POST['_my_field_name'] ) ) {
$domain = 'woocommerce';
$my_field_name = $_POST['_my_field_name'];
// Empty
if ( empty ( $my_field_name ) ) {
wc_add_notice( __( 'Please Select Y to complete this order', $domain ), 'error' );
}
// NOT empty but value is 'N'
if ( ! empty ( $my_field_name ) && $my_field_name == 'N' ) {
wc_add_notice( __( 'Please Select Y to complete this order', $domain ), 'error' );
}
}
}
add_action( 'woocommerce_checkout_process', 'action_woocommerce_checkout_process', 10, 0 );
// Save custom checkout 'select' field
function action_woocommerce_checkout_create_order( $order, $data ) {
// Isset
if ( isset( $_POST['_my_field_name'] ) ) {
$my_field_name = $_POST['_my_field_name'];
// NOT empty & equal to 'Y'
if ( ! empty( $my_field_name ) && $my_field_name == 'Y' ) {
$order->update_meta_data( '_my_field_name', sanitize_text_field( $my_field_name ) );
}
}
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );
// Display the custom 'select' field value on admin order pages after billing adress
function action_woocommerce_admin_order_data_after_billing_address( $order ) {
$domain = 'woocommerce';
// Get meta
$my_field_name = $order->get_meta( '_my_field_name' );
// NOT empty
if ( ! empty ( $my_field_name ) ) {
echo '<p><strong>' . __( 'Delivery type', $domain ) . ':</strong> ' . $order->get_meta( '_my_field_name' ) . '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'action_woocommerce_admin_order_data_after_billing_address', 10, 1 );
// Display the custom 'select' field value on 'order received' and 'order view' pages (frontend)
function action_woocommerce_order_details_after_order_table( $order ) {
$domain = 'woocommerce';
// Get meta
$my_field_name = $order->get_meta( '_my_field_name' );
// NOT empty
if ( ! empty ( $my_field_name ) ) {
echo '<p><strong>' . __( 'Delivery type', $domain ) . ':</strong> ' . $order->get_meta( '_my_field_name' ) . '</p>';
}
}
add_action( 'woocommerce_order_details_after_order_table', 'action_woocommerce_order_details_after_order_table', 10, 1 );

Woocommerce - Calculate Exta Fee Based on Amount of People

I've added in a function for a custom field on the product general options:
// Add Custom Field to Product under General
function create_extra_fee_field() {
$args = array(
'id' => 'park_fee',
'label' => __( 'Natl Park Entrance Fee', 'tranq-lsx-child' ),
'class' => 'tranq-custom-field',
'desc_tip' => true,
'description' => __( 'This sets the Fee that will be added to the car.', 'tranq-lsx-child' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'create_extra_fee_field' );
// Save Custom Field Data
function save_extra_fee_field( $post_id ) {
$product = wc_get_product( $post_id );
$title = isset( $_POST['park_fee'] ) ? $_POST['park_fee'] : '';
$product->update_meta_data( 'park_fee', sanitize_text_field( $title ) );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'save_extra_fee_field' );
I would like to add this as an extra fee to the Cart Totals which multiplied based on the amount of Person/People that were selected from the Woocommerce Bookings.
Something like this:
// Calculate Extra Fee Based on Amount of People.
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
function add_custom_fees( WC_Cart $cart ){
$park_fee = get_post_meta($item['product_id'] , 'park_fee', true);
foreach( $cart->get_cart() as $item ){
$fees += $item[ 'park_fee' ] * 14706;
}
if( $fees != 0 ){
$cart->add_fee( 'Park Fee', $fees);
}
}
How do I go about in achieving this? Any Links to a walkthrough would be greatly appreciated.
I've added this and it seems to work:
// Add Custom Field to Cart Totals
function woo_add_cart_fee() {
global $woocommerce;
foreach( WC()->cart->get_cart() as $cart_item ){
// Get the WC_Product object (instance)
$product = $cart_item['data'];
$product_id = $product->get_id(); // get the product ID
$custom_field_value = get_post_meta( $product->get_id(), 'park_fee', true );
$person = array_sum( $cart_item['booking']['_persons'] );
}
$additional_fee_name = "Natl Park Entrance Fee";
$extra_fee = $custom_field_value * $person;
$addedFee = false;
// first check to make sure it isn’t already there
foreach ( $woocommerce->cart->get_fees() as $_fee )
{
if ($_fee->id == sanitize_title($additional_fee_name) )
{
$_fee->amount = (float) esc_attr( $extra_fee );
}
}
if (!$addedFee)
{
$woocommerce->cart->add_fee( __($additional_fee_name, "woocommerce"),
$extra_fee, $additional_fee_taxable );
}
}
add_action( "woocommerce_before_calculate_totals", "woo_add_cart_fee" );

ACF, post object in woocommerce Cart

I hope it's a dumb question, but I can't find a smart solution at the moment.
I've got a custom field in my products page - which is a Relationship field - and I'd like to display a field of my RF for every product in my cart page.
More specifically: I have a product associated with a brand. The brand has a 'shipping time' field.
At the moment my function is partially working, in the sense that it displays the request value, but ONLY for the first item in the cart.
That's my code in function.php
add_filter( 'woocommerce_get_item_data', 'wc_add_shipping_to_cart', 10, 2 );
function wc_add_shipping_to_cart( $cart_data, $cart_item )
{
$custom_shipping = array();
if( !empty( $cart_data ) )
$custom_shipping = $cart_data;
// Get the product ID
$product_id = $cart_item['product_id'];
$custom_field_value = get_post_meta( $product_id, 'brand_select', true );
$display_brand_shipping = get_field('shipping_time_brand', $custom_field_value);
if( $custom_field_value = get_post_meta( $product_id, 'brand_select', true ) )
$custom_shipping[] = array(
'name' => __( 'Shipping', 'woocommerce' ),
'value' => $display_brand_shipping,
'display' => $display_brand_shipping,
);
return $custom_shipping; }
Could you help me?
Your code is not testable as is not possible to reproduce your issue related to product custom field and ACF fields, but it can be simplified this way:
add_filter( 'woocommerce_get_item_data', 'wc_add_shipping_to_cart', 10, 2 );
function wc_add_shipping_to_cart( $cart_item_data, $cart_item )
{
if( $brand_select = get_post_meta( $cart_item['product_id'], 'brand_select', true ) ) {
if( $shipping_time = get_field('shipping_time_brand', $brand_select ) ) {
$cart_item_data[] = array(
'name' => __( 'Shipping', 'woocommerce' ),
'value' => $shipping_time,
);
}
}
return $cart_item_data;
}
Code goes in function.php file of your active child theme (or active theme).

Resources