I have a custom field for a Woocommerce's product, and I want to display it's value in order emails.
As I'm using custom product submission form, I added this code for custom field below to create a custom field:
<?php
WCVendors_Pro_Form_Helper::select( array(
'post_id' => $object_id,
'class' => 'select2',
'id' => 'wcv_custom_product_ingredients',
'label' => __( 'What time?', 'wcvendors-pro' ),
'placeholder' => __( 'Pick a time', 'wcvendors-pro' ),
'wrapper_start' => '<div class="all-100">',
'wrapper_end' => '</div>',
'desc_tip' => 'true',
'description' => __( 'Pick a time', 'wcvendors-pro' ),
'options' => array( '12:00 midnight' => __('12:00 midnight', 'wcv_custom_product_ingredients'), '12:15 midnight'=> __('12:15 midnight', 'wcv_custom_product_ingredients') )
) );
?>
I also tried adding code below to functions.php, but this only displays "What time?" without value in order emails...
add_action('woocommerce_email_after_order_table', 'wcv_ingredients_email');
function wcv_ingredients_email() {
$output = get_post_meta( get_the_ID(), 'wcv_custom_product_ingredients', true );
echo 'What time? ' . $output . '<br>';
}
What could be the issue?
You are using the correct hook, but you just forgot the hook arguments in the hooked function.
Also as you are targeting a product custom field value, and as in an order you can have many items (products), the code below will display this value for each order item.
Try the code below, it works now:
// Tested on WooCommerce version 2.6.x and 3+ — For simple products only.
add_action('woocommerce_email_after_order_table', 'wcv_ingredients_email', 10, 4);
function wcv_ingredients_email( $order, $sent_to_admin, $plain_text, $email ){
foreach($order->get_items() as $item_values){
// Get the product ID for simple products (not variable ones)
$product_id = $item_values['product_id'];
$output = get_post_meta( $product_id, 'wcv_custom_product_ingredients', true );
echo 'What time? ' . $output . '<br>';
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Related
I recently created a custom field in functions.php to display a custom meta field in the Inventory tab for each product called barcode. What I now want to do is display the data onto my single product template using a PHP call. Here's first of all, the function to create the barcode data (which works):
function add_barcode(){
woocommerce_wp_text_input(
array(
'id' => '_barcode',
'label' => __( 'Barcode', 'your-plugin' ),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __( "Scan the product's barcode.", "your-plugin" )
)
);
}
add_action('woocommerce_product_options_inventory_product_data','add_barcode');
function add_barcode_save( $product ){
if( isset( $_POST['_barcode'] ) ) {
$product->update_meta_data( '_barcode', sanitize_text_field( $_POST['_barcode'] ) );
} else {
$product->delete_meta_data( '_barcode' );
}
}
add_action( 'woocommerce_admin_process_product_object', 'add_barcode_save' );
Here's the PHP I'm trying to generate that data onto the page:
$product = wc_get_product();
echo '<strong>Barcode: </strong>' .$product->get_attribute( 'barcode' );
All I get here is a blank area after the HTML portion. So what function will allow me to display the barcode text?
I am building my first woocommerce site, Im learning how to create custom fields for products. I would like to create a text field in general tab, save that field and display on the front end to customers.
Here is the code I used to display the text field in the general tab of products.
function prefix_add_text_input() {
$args = array(
'label' =>__('Serial Number', 'woocommerce'), // Text in the label in the editor.
'placeholder' => '', // Give examples or suggestions as placeholder
'class' => '',
'style' => '',
'wrapper_class' => '',
'value' => '', // if empty, retrieved from post_meta
'id' => 'serial_number', // required, will be used as meta_key
'name' => '', // name will be set automatically from id if empty
'type' => '',
'desc_tip' => 'true',
'data_type' => '',
'custom_attributes' => '', // array of attributes you want to pass
'description' => 'Enter the serial number on your rifle here'
);
woocommerce_wp_text_input( $args );
}
How do I get the field to save, and display on the front end. Ideally display in the tabs with product description?
Here below you will find the way to save your product custom field value and display it in the product description tab section:
// Add a Custom product Admin Field
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_product_general_field' );
function add_custom_product_general_field() {
echo '<div class="options_group">';
woocommerce_wp_text_input( array(
'id' => '_serial_number', // required, will be used as meta_key
'label' =>__('Serial Number', 'woocommerce'), // Text in the label in the editor.
'desc_tip' => 'true',
'description' => __('Enter the serial number on your rifle here', 'woocommerce')
) );
echo '</div>';
}
// Save the field value
add_action( 'woocommerce_admin_process_product_object', 'save_custom_product_general_field' );
function save_custom_product_general_field( $product ){
if( isset($_POST['_serial_number']) )
$product->update_meta_data( '_serial_number', sanitize_text_field( $_POST['_serial_number'] ) );
}
// Display the custom field value below product description tab
add_filter( 'the_content', 'display_product_serial_number' );
function display_product_serial_number( $content ) {
// Only for single product pages
if ( is_product() ) {
global $product;
if( $value = $product->get_meta( '_serial_number' ) ) {
$content .= '<p><strong>' . __("Serial number:", "woocommerce") . '<strong> ' . $value . '<p>';
}
}
return $content;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
In WooCommerce checkout page, I'm adding a custom field and everything works fine if I use woocommerce_after_checkout_billing_form hook or woocommerce_before_checkout_form hook.
The problem is that I need the field to be above the Billing Details title but when I use woocommerce_checkout_before_customer_details hook everything disappears (even the sidebar payment panel), only my custom field title is visible.
My code:
// Create Custom checkout Field
add_action('woocommerce_checkout_before_customer_details', 'create_custom_field');
function create_custom_field($checkout) {
global $woocommerce;
$cart = $woocommerce->cart->get_cart();
foreach($cart as $key => $value)
{
$bespoke = $woocommerce->cart->get_item_data($value);
if (strpos($bespoke, 'yes') !== false) {
echo '<div id="customise_checkout_field"><h3>' . __('Bespoke Details') . '</h3>';
woocommerce_form_field('bespoke_field', array(
'type' => 'textarea',
'class' => array('my-field-class form-row-wide'),
'label' => __('Tell us about your idea') ,
'placeholder' => __('Please explain what you want as detailed as possible...') ,
'required' => true,),
$checkout->get_value('bespoke_field'));
echo '</div>';
}
}
}
Any thoughts? Your guidance is truly appreciated.
$checkout doesn't exist for this hook, and then it's not defined. So It makes a blank page (an error). But you can use WC()->checkout as replacement.
The WC_cart method get_item_data() is deprecated and wc_get_formatted_cart_item_data() function replace it since Woocommerce version 3.3.
Also global $woocommerce and $woocommerce->cart are now replaced with simply WC()->cart.
Try this instead:
// Add a Custom checkout Field
add_action( 'woocommerce_checkout_before_customer_details', 'add_custom_checkout_field' );
function add_custom_checkout_field() {
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
$bespoke = wc_get_formatted_cart_item_data( $cart_item );
if ( strpos($bespoke, 'yes') !== false ) {
echo '<div id="customise_checkout_field">';
echo '<h3>' . __('Bespoke Details') . '</h3>';
woocommerce_form_field('bespoke_field', array(
'type' => 'textarea',
'class' => array('my-field-class form-row-wide'),
'label' => __( "Tell us about your idea", "woocommerce" ),
'placeholder' => __( "Please explain what you want as detailed as possible...", "woocommerce" ),
'required' => true,
), WC()->checkout->get_value('bespoke_field') );
echo '</div>';
}
}
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
So I've got the following code which makes me add a Barcode field to the Inventory Options of a product.
Now I also want to add this to each variations so I can easily add Variation Products when I scan the Barcode of the product via the WooCommerce Point of Sale plugin.
Here is what I got currently:
// Add Barcode field in simple product inventory options
add_action('woocommerce_product_options_sku','add_barcode',10,0);
function add_barcode(){
global $woocommerce,$post;
woocommerce_wp_text_input(
array(
'id' => '_barcode',
'label' => __('Barcode','woocommerce'),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __('Scan barcode.','woocommerce'),
'value' => get_post_meta($post->ID,'_barcode',true)
)
);
}
// Save Barcode field value for simple product inventory options
add_action('woocommerce_process_product_meta','save_barcode',10,1);
function save_barcode($post_id){
if(!empty($_POST['_barcode']))
update_post_meta($post_id,'_barcode',sanitize_text_field($_POST['_barcode']));
}
// Add a Barcode field in product variations options
add_action('woocommerce_product_after_variable_attributes','add_barcode_variations',10,3);
function add_barcode_variations($loop,$variation_data,$variation){
woocommerce_wp_text_input(
array(
'id' => '_barcode[' . $variation->ID . ']',
'label' => __('Variation Barcode','woocommerce'),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __('Scan barcode.','woocommerce'),
'value' => get_post_meta($variation->ID,'_barcode',true)
)
);
}
// Save Barcode field for product variations options
add_action( 'woocommerce_save_product_variation','save_barcode_variations',10,2);
function save_barcode_variations($post_id){
$barcode = $_POST['_barcode'][$post_id];
if(!empty($barcode)) update_post_meta($post_id,'_barcode',sanitize_text_field($barcode));
}
// Set POS Custom Code
add_filter('woocommerce_pos_barcode_meta_key','pos_barcode_field');
function pos_barcode_field(){
return '_barcode';
}
But the problem here is, that with that I now added a part for the variation, that if I update the product the main barcode field in the Inventory settings shows "Array" instead of the provided barcode.
I assume that this has something to do with the ID being the same for the variations as the original field other than the variationID at the end. The reason the ID requires to be the same as the WooCommerce POS plugin I'm using, is being filtered on that ID when I scan a product.
But currently can't figure out, to what I have to change to make both the Inventory Barcode Field and the Variation Barcode field to be saved properly.
As well as I'd like to add the variation field below the variation SKU field, but can't directly find the proper hook to do this.
Thanks in advance for further information.
In your last hooked function you have a missing argument, which is a similar to $loop argument in your 3rd function. So I have made little changes in your code:
// Add product Barcode custom field
add_action('woocommerce_product_options_sku','add_barcode_custom_field' );
function add_barcode_custom_field(){
woocommerce_wp_text_input( array(
'id' => '_barcode',
'label' => __('Barcode','woocommerce'),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __('This is the Scan barcode field for this product.','woocommerce')
) );
}
// Save product Barcode custom field
add_action( 'woocommerce_process_product_meta', 'save_barcode_custom_field', 10, 1 );
function save_barcode_custom_field( $post_id ){
if( isset($_POST['_barcode']) )
update_post_meta( $post_id, '_barcode', esc_attr( $_POST['_barcode'] ) );
}
// Add Variation Barcode custom field
add_action( 'woocommerce_variation_options_pricing', 'add_barcode_variation_custom_field', 10, 3 );
function add_barcode_variation_custom_field( $loop, $variation_data, $variation ){
$variation_barcode = get_post_meta($variation->ID,"_barcode", true );
if( ! $variation_barcode ) $variation_barcode = "";
woocommerce_wp_text_input( array(
'id' => '_barcode['.$loop.']',
'label' => __('Variation Barcode','woocommerce'),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __('This is the Scan barcode field for this variation.','woocommerce'),
'value' => get_post_meta($variation->ID,"_barcode", true ),
) );
}
// Save Variation Barcode custom field value
add_action( 'woocommerce_save_product_variation', 'save_barcode_variation_custom_field', 10, 2 );
function save_barcode_variation_custom_field( $variation_id, $i ){
if( isset($_POST['_barcode'][$i]) )
update_post_meta( $variation_id, '_barcode', sanitize_text_field($_POST['_barcode'][$i]) );
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for WooCommerce version 2.6+ and 3.0+
I have this situation - I made a changes in one of the woocommerce email templates, but I`m sure - these changes will be lost after next woocommerce update.
As I know, I should use theme functions to bypass this problem.
This is the code before changes:
echo '<ul class="wc-bacs-bank-details order_details bacs_details">' . PHP_EOL;
// BACS account fields shown on the thanks page and in emails
$account_fields = apply_filters( 'woocommerce_bacs_account_fields', array(
'account_number'=> array(
'label' => __( 'Account Number', 'woocommerce' ),
'value' => $bacs_account->account_number
),
'sort_code' => array(
'label' => $sortcode,
'value' => $bacs_account->sort_code
),
'iban' => array(
'label' => __( 'IBAN', 'woocommerce' ),
'value' => $bacs_account->iban
),
'bic' => array(
'label' => __( 'BIC', 'woocommerce' ),
'value' => $bacs_account->bic
)
), $order_id );
foreach ( $account_fields as $field_key => $field ) {
if ( ! empty( $field['value'] ) ) {
echo '<li class="' . esc_attr( $field_key ) . '">' . esc_attr( $field['label'] ) . ': <strong>' . wptexturize( $field['value'] ) . '</strong></li>' . PHP_EOL;
}
}
echo '</ul>';
Here is the custom account field code that I want to insert:
'merkis' => array(
'label' => $merkis,
'value' => $pasutijums
)
How can I insert my custom code without overriding that core file?
Thanks
Never Override core files and always use the WooCommerce included hooks to make code customizations.
If you haven't find the way to make this change through a custom hooked function, as you will see in your provided code, you can use woocommerce_bacs_account_fields filter hook to add your custom code, without overriding any WooCommerce core files.
So the code for adding a new field in BACS account fields, is going to be:
add_filter( 'woocommerce_bacs_account_fields', 'custom_bacs_account_field', 10, 2);
function custom_bacs_account_field( $account_fields, $order_id ) {
$account_fields['merkis' ] = array(
'label' => $merkis,
'value' => $pasutijums
);
return $account_fields;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works…