Can't get custom fields of a woocommerce product - php

i am trying to get the custom fields with this function and multiply by the product price. I am getting the product price but when printing the custom fields, i am only getting zeros.. i dont understand why, i had tryed get_metadata() and get_post_custom() too.. but nothing works
function filter_woocommerce_cart_product_subtotal( $product_subtotal, $product, $quantity, $instance ) {
$fields = get_post_meta(get_the_id(), false);
$add_on = $product->get_price()*$fields[0] + $product->get_price()*$fields[1] + $product-
>get_price()*0.75*$fields[2];
return $product_subtotal + $add_on;
};
add_filter( 'woocommerce_cart_product_subtotal', 'filter_woocommerce_cart_product_subtotal', 10, 4 );
I have tryed to get single fields too but always getting zeros.
I can get the custom fields in function below and save it in a global variable but when i try to access the global variable in the function above, i get zero again.
function tour_product_add_on_cart_item_data( $cart_item, $product_id, $cart ){
/*
if( isset( $_POST['time_add_on'] ) ) {
$cart_item['time_add_on'] = sanitize_text_field( $_POST['time_add_on'] );
}
*/
if( isset( $_POST['date_add_on'] ) ) {
$cart_item['date_add_on'] = sanitize_text_field( $_POST['date_add_on'] );
}
if( isset( $_POST['place_add_on'] ) ) {
$cart_item['place_add_on'] = sanitize_text_field( $_POST['place_add_on'] );
}
if( isset( $_POST['adult_add_on'] ) ) {
$cart_item['adult_add_on'] = sanitize_text_field( $_POST['adult_add_on'] );
}
if( isset( $_POST['child_add_on'] ) ) {
$cart_item['child_add_on'] = sanitize_text_field( $_POST['child_add_on'] );
}
if( isset( $_POST['infant_add_on'] ) ) {
$cart_item['infant_add_on'] = sanitize_text_field( $_POST['infant_add_on'] );
}
$product = wc_get_product($product_id);
$GLOBALS["fee"] = $_POST['adult_add_on']*$product->get_price() +
$_POST['child_add_on']*$product->get_price() + $_POST['infant_add_on']*0.75*$product->get_price();
return $cart_item;
}

get_post_meta() second parameter is the meta key value. So you should use for example
$date_add_on = get_post_meta(get_the_id(), 'date_add_on')

So, i have resolved this issue. When you add a custom field to a woocommerce product or a wordpress post, you have to update it's meta data. Here is a good tutorial of every step you have to follow to add a custom field.
HOW TO ADD WOOCOMMERCE CUSTOM FIELDS TO A PRODUCT

Related

Save Post and Add Post Meta Executing Twice

I'm trying to add or update two post meta on saving a post. Add if it's a new post and update if existing, but this function creates four in the database instead of two meta.
add_action( 'save_post', 'add_rewards');
global $WCFM, $WCFMmp;
function add_rewards ($product_id){
if($product_id){
$post_type = get_post_type($product_id);
if($post_type == 'product'){
$product = wc_get_product( $product_id );
$reg_price = $product->get_regular_price();
$sal_price = $product->get_sale_price();
$pric = $product->get_price();
add_post_meta($product_id,'main_reward', $reg_price);
add_post_meta($product_id,'sub_reward', $sal_price);
}
}
}
As it explains in the save_post manual, you should use save_post_{$post->post_type} which minimizes the save_post calls on other post types. It's also a good idea to check for autosave.
Also, if you use update_post_meta instead of add_post_meta you'll end up with only one instance of each. As it explains in the manual for that function, it says:
If the meta field for the post does not exist, it will be added and its ID returned.
Can be used in place of add_post_meta().
add_action( 'save_post_product', 'so71077799_add_rewards', 99, 1 );
function so71077799_add_rewards( $product_id ) {
// Check to see if we are autosaving, if so, exit.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( isset( $_POST['_regular_price'] ) ) {
update_post_meta( $product_id, 'main_reward', number_format( floatval( $_POST['_regular_price'] ), '2' ) );
}
if ( isset( $_POST['_sale_price'] ) ) {
update_post_meta( $product_id, 'sub_reward', number_format( floatval( $_POST['_sale_price'] ), '2' ) );
}
}

Woocommerce redirect after checkout based on product custom field

So i have custom text field meta in the product so that if has a url i would like to redirect users to a custom TY page after checkout. Here is my code and not redirecting!!
add_action('template_redirect', 'my_redirect_after_purchase');
function my_redirect_after_purchase() {
global $post, $wp;
$my_redirect = get_post_meta( get_the_ID(), '_my_redirect', true ); // This has the redirect URL entered in the field tested and working
if ( '' !== $my_redirect ) { // am checking here if the field is not empty
if (!empty($wp->query_vars['order-received'])) {
wp_redirect(esc_url($my_redirect));
exit;
}
}
}
I have tried few other ways but no luck too. Am guessing the query for order-recieved runs after and thus the meta returns empty?
How should i go about this? Thanks
First, you have to get order items using wc_get_order then you can get meta based on product id. Try the below code.
add_action('template_redirect', 'my_redirect_after_purchase');
function my_redirect_after_purchase() {
/* return if we are not on order-received page */
if( !is_wc_endpoint_url( 'order-received' ) || empty( $_GET['key'] ) ) {
return;
}
$order_id = wc_get_order_id_by_order_key( $_GET['key'] );
$order = wc_get_order( $order_id );
foreach( $order->get_items() as $item ) {
$my_redirect = get_post_meta( $item['product_id'] , '_my_redirect', true );
if( $my_redirect != '' ){
wp_redirect( $my_redirect );
exit;
}
}
}

Add single custom field and its static value to all Woocommerce product variations

I am trying to add a custom field and a static value to all of my variable products in Woocommerce. I have gone through other questions but they relate to creating whole new variations. I just need to add/update custom field to existing variaitons. Here is the thing I need to add in each variation postmeta: add_post_meta($variation_id, '_wc_facebook_product_image_source', 'parent_product'); I dont know how to execute for each loop for all variations.
I need to do this is because we have thousands of products being imported through a data feed (Dropshipping site). And this custom field is used to send data to Facebook for Catalogue. We need to hook an action that whenever a new variable product is added, all of it's variation has custom field in postmeta added with value as 'parent_product'. I have already added this filter to change the data for simple products. And is working perfect for all simple products. But the problem is that variable products having variations dont get this custom field.
Here is my code for simple products:
add_filter ('facebook_for_woocommerce_integration_prepare_product', 'fix_image_url', 100, 2);
function fix_image_url( $product_data, $product_id ){
if( empty( $product_data ) || empty( $product_id ) )
{
return $product_data;
}
$product_image = get_post_meta( $product_id, "_bdroppy_url", true );
if( isset( $product_image['img_url'] ) && !empty($product_image['img_url'] ) ) {
$image_override = get_post_meta($product_id, 'fb_product_image', true);
$image_option_override = get_post_meta($product_id, '_wc_facebook_product_image_source', true);
if ( empty($image_override ) )
{
add_post_meta($product_id, 'fb_product_image', $product_image['img_url'] );
}
if ( !empty($image_override ) )
{
update_post_meta($product_id, 'fb_product_image', $product_image['img_url'] );
}
if ( empty($image_option_override) )
{
add_post_meta($product_id, '_wc_facebook_product_image_source', 'custom');
}
if ( !empty($image_option_override) && $image_option_override = 'product' )
{
update_post_meta($product_id, '_wc_facebook_product_image_source', 'custom');
}
}
return $product_data;}
Would be too grateful for your help!
I think i found the answer to add for each loop of variations:
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_visible_children() as $variation_id ) {
//gets the product variation based on its id but not used here
$get_product_variation = wc_get_product( $variation_id );
$image_option_override_var = get_post_meta($variation_id, '_wc_facebook_product_image_source', true);
if ( empty($image_option_override_var) )
{
add_post_meta($variation_id, '_wc_facebook_product_image_source', 'parent_product');
}
if ( !empty($image_option_override_var) && $image_option_override = 'product' )
{
update_post_meta($variation_id, '_wc_facebook_product_image_source', 'parent_product');
}
}}

Add, update or remove product custom field in WooCommerce

I use the following lines to save a Value to the database. I have one question regarding this code, when I delete input it still keeps it. The only way to delete that is to put (space) as input.
$field_key_pills_1 = 'custom_text_field_category_pills';
if ( isset( $_POST[$field_key_pills_1] ) && ! empty( $_POST[$field_key_pills_1] ) ) {
$attribute_pills_1 = wc_get_product( $post_id );
$attribute_pills_1->update_meta_data( $field_key_pills_1, sanitize_text_field( $_POST[$field_key_pills_1] ) );
$attribute_pills_1->save();
} else {
$attribute_pills_1 = wc_get_product( $post_id );
$attribute_pills_1 = delete_post_meta( $post_id, 'custom_text_field_category_pills' );
}
Please give me any tip that you think, can solve this problem.
Try instead the following revisited code using WC_Data delete_meta_data() method to remove product meta data (meta key + value):
$key_pills_1 = 'custom_text_field_category_pills';
$product_pills1 = wc_get_product( $post_id );
// Check that the product and the product input field exists
if ( is_a($product_pills1, 'WC_Product') && isset($_POST[$key_pills_1]) {
if ( ! empty($_POST[$key_pills_1]) ) {
$product_pills1->update_meta_data( $key_pills_1, sanitize_text_field($_POST[$key_pills_1]) ); // Set or update
} else {
$product_pills1->delete_meta_data( $key_pills_1 ); // remove
}
$product_pills1->save(); // Sync and save to database
}
It should work.

Save and display a custom field as order item meta data in WooCommerce

In woocommerce, I have maisd wome customizations and I can add a custom text field in my products, Display the values in cart and checkout (see the screenshots below).
Text field in product page:
Value in the cart:
Value in the checkout:
But I can not get it to appear in the purchase details or in the administration section (see the screenshots below).
Checkout details without the value:
Administration orders without the value:
In my code below, could someone tell what I am doing wrong?
The code that I use in my functions.php file:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$id = $product->get_id();
// Get the field name of InputText1
$InputText1Name = get_post_meta($id, 'InputText1', true);
if ((!empty(get_post_meta($id, $InputText1, true)))){
echo '<div id="InputText1">';
echo '<label>'.__($InputText1Name).'</label> <input type="text" name="$InputText1V">';
echo '</div>';
}
}
// Store custom field
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['$InputText1V'] ) ) {
$cart_item_data[ '$InputText1V' ] = $_REQUEST['$InputText1V'];
/* below statement make sure every add to cart action as unique line item */
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
// Render meta on cart and checkout
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ){
// Get the product id inside the cart
foreach( WC()->cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
}
// Get the field name of InputText1
$InputText1Name = get_post_meta($product_id, 'InputText1', true);
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['$InputText1V'] ) ) {
$custom_items[] = array( "name" => $InputText1Name, "value" => $cart_item['$InputText1V'] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
// Display as order meta
function my_field_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values['$InputText1V'] ) ) {
wc_add_order_item_meta( $product_id, "$InputText1V", $values['$InputText1V'] );
}
}
// 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['$InputText1V']) update_post_meta( $order_id, '$InputText1Name', esc_attr($_POST['$InputText1V']));
}
// Update the user meta with field value
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['$InputText1V']) update_user_meta( $user_id, '$InputText1V', esc_attr($_POST['$InputText1V']) );
}
add_filter( 'woocommerce_hidden_order_itemmeta', 'hide_order_item_meta_fields' );
// 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 ){
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
echo '<p><strong>'.__($InputText1V).':</strong> ' . get_post_meta( $order_id, $InputText1V, true ) . '</p>';
}
function hide_order_item_meta_fields( $fields ) {
$fields[] = 'current_view';
$fields[] = 'custom_image';//Add all meta keys to this array,so that it will not be displayed in order meta box
return $fields;
}
add_action( 'woocommerce_after_order_itemmeta', 'order_meta_customized_display',10, 3 );
function order_meta_customized_display( $item_id, $item, $product ){
$order_product_id = $item['product_id'];
$field1name = get_post_meta($order_product_id, 'InputText1', true);
echo'<br>';
print_r($InputText1V);
echo'<br>';
echo $field1name;
echo ': ';
}
There are errors and missing things in your code. You don't need all that functions too and you should really avoid to use $ (and if you can capitals) in your custom field slugs (or in key slugs and even in function names) in your code.
I have tested and revisited your code. Here is what you need and can remove everything else:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$product_id = $product->get_id();
// Get the field name of InputText1
$label = get_post_meta($product_id, 'InputText1', true);
if( ! empty( $label ) ){
echo '<div id="InputText1">
<label>'.$label.':</label> <input type="text" name="custom_slug" value="">
</div>';
}
}
// Store custom field label and value in cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_slug'] ) ) {
$cart_item_data['custom_data']['label'] = get_post_meta($product_id, 'InputText1', true);
$cart_item_data['custom_data']['value'] = sanitize_text_field( $_REQUEST['custom_slug'] );
$cart_item_data['custom_data']['ukey'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Display items custom fields label and value in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item ){
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['custom_data'] ) ) {
$custom_items[] = array(
'name' => $cart_item['custom_data']['label'],
'value' => $cart_item['custom_data']['value'],
);
}
return $custom_items;
}
// Save item custom fields label and value as order item meta data
add_action('woocommerce_add_order_item_meta','save_in_order_item_meta', 10, 3 );
function save_in_order_item_meta( $item_id, $values, $cart_item_key ) {
if( isset( $values['custom_data'] ) ) {
wc_add_order_item_meta( $item_id, $values['custom_data']['label'], $values['custom_data']['value'] );
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
This way you will get the display in Order received, Order view, Edit order (admin) and email notifications…

Categories