Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Add a custom text field to a WooCommerce Product
<?php
/**
* Plugin Name: Sample Customizable Product Field for WooCommerce
* Plugin URI: https://www.kathyisawesome.com/add-a-custom-field-to-woocommerce-product/
* Description: Add a custom text field to a WooCommerce Product
* Version: 1.1.0
* Author: Kathy Darling
* Author URI: http://kathyisawesome.com
* Requires at least: 5.2.0
* Tested up to: 5.2.2
* WC requires at least: 3.6.0
* WC tested up to: 3.7.0
*
* Text Domain: kia-plugin-textdomain
* Domain Path: /languages/
*
* Copyright: © 2022 Kathy Darling.
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*
*/
/**
* Display input on single product page
*/
function kia_custom_option() {
$value = isset( $_POST['_custom_option'] ) ? sanitize_text_field( $_POST['_custom_option'] ) : '';
printf( '<p><label>%s<input name="_custom_option" value="%s" /></label></p>', __( 'Enter your custom text', 'kia-plugin-textdomain' ), esc_attr( $value ) );
}
add_action( 'woocommerce_before_add_to_cart_button', 'kia_custom_option', 9 );
/**
* Validate when adding to cart
*
* @param bool $passed
* @param int $product_id
* @param int $quantity
* @return bool
*/
function kia_add_to_cart_validation( $passed, $product_id, $qty ) {
if ( isset( $_POST['_custom_option'] ) && sanitize_text_field( $_POST['_custom_option'] ) == '' ) {
$product = wc_get_product( $product_id );
wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter some custom text.', 'kia-plugin-textdomain' ), $product->get_title() ), 'error' );
return false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'kia_add_to_cart_validation', 10, 3 );
/**
* Add custom data to the cart item
*
* @param array $cart_item
* @param int $product_id
* @return array
*/
function kia_add_cart_item_data( $cart_item, $product_id ) {
if ( isset( $_POST['_custom_option'] ) ) {
$cart_item['custom_option'] = sanitize_text_field( $_POST['_custom_option'] );
}
return $cart_item;
}
add_filter( 'woocommerce_add_cart_item_data', 'kia_add_cart_item_data', 10, 2 );
/**
* Load cart data from session
*
* @param array $cart_item
* @param array $other_data
* @return array
*/
function kia_get_cart_item_from_session( $cart_item, $values ) {
if ( isset( $values['custom_option'] ) ) {
$cart_item['custom_option'] = $values['custom_option'];
}
return $cart_item;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'kia_get_cart_item_from_session', 20, 2 );
/**
* Get item data to display in cart
*
* @param array $other_data
* @param array $cart_item
* @return array
*/
function kia_get_item_data( $other_data, $cart_item ) {
if ( isset( $cart_item['custom_option'] ) ) {
$other_data[] = array(
'key' => __( 'Your custom text', 'kia-plugin-textdomain' ),
'display' => sanitize_text_field( $cart_item['custom_option'] )
);
}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'kia_get_item_data', 10, 2 );
/**
* Add meta to order item
*
* @param int $item_id
* @param string $cart_item_key
* @param array $item
*/
function kia_add_order_item_meta( $item, $cart_item_key, $values ) {
if ( ! empty( $values['custom_option'] ) ) {
$item->add_meta_data( 'custom_option', wc_clean( $values['custom_option'] ), true );
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'kia_add_order_item_meta', 10, 3 );
/**
* Restore custom field to product meta when product retrieved for order item.
* Meta fields will be automatically displayed if not prefixed with _
*
* @param WC_Product $product
* @param WC_Order_Item_Product $order_item
* @return array
*/
function kia_order_item_product( $product, $order_item ) {
if ( $order_item->get_meta( 'custom_option' ) ) {
$product->add_meta_data( 'custom_option', $order_item->get_meta( 'custom_option' ), true );
}
return $product;
}
add_filter( 'woocommerce_order_item_product', 'kia_order_item_product', 10, 2 );
/**
* Customize the display of the meta key in order tables.
*
* @param string $display_key
* @param obj[] $meta
* @param WC_Order_Item_Product $order_item
* @return string
*/
function kia_order_item_display_meta_key( $display_key, $meta, $order_item ) {
if ( $meta->key == 'custom_option' ) {
$display_key = __( 'Your custom text', 'kia-plugin-textdomain' );
}
return $display_key;
}
add_filter( 'woocommerce_order_item_display_meta_key', 'kia_order_item_display_meta_key', 10, 3 );
/**
* Order Again
*
* @param array $cart_item
* @param WC_Order_Item_Product $order_item
* @param WC_Order $order
* @return array
*/
function kia_order_again_cart_item_data( $cart_item, $order_item, $order ) {
if ( $order_item->get_meta( 'custom_option' ) ) {
$cart_item['custom_option'] = $order_item->get_meta( 'custom_option' );
}
return $cart_item;
}
add_filter( 'woocommerce_order_again_cart_item_data', 'kia_order_again_cart_item_data', 10, 3 );
@mitchellknight
Copy link

mitchellknight commented Apr 13, 2022

[13-Apr-2022 19:05:58 UTC] woocommerce_add_order_item_meta is deprecated since version 3.0.0! Use woocommerce_new_order_item instead.

It seems WooCommerce has deprecated the woocommerce_add_order_item_meta now. Any updates for compatibility with WooCommerce 3.0+?

Thank you for sharing this code!

@helgatheviking
Copy link
Author

helgatheviking commented Apr 14, 2022

@mitchellknight The fix was noted in https://www.kathyisawesome.com/add-a-custom-field-to-woocommerce-product/ but I have updated it here too. Needs to switch to the woocommerce_checkout_create_order_line_item hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment