WooCommerce Conditionally add text below price on Products - wordpress

Trying to set a custom text message below a WooCommerce product, using the woocommerce_get_price_html filter with a conditional to ceratin products in an array - but it is applying the $addedtext variable to all products, where am I going wrong here?
add_filter( 'woocommerce_get_price_html', 'custom_price_message' );
function custom_price_message( $price ) {
if( is_product (array( 799,796,792)) ) {
$addedtext = '(Upfront Paid in Full Price)';
return $price . '<br /><span class="price-disclaimer">' . $addedtext . '</span>';
}
else {
return $price;
}
}

//add meta box to each product which will take status to add text or not
function add_events_metaboxes() {
add_meta_box('wpt_events_product', 'Add text to product', 'wpt_events_products', 'product', 'side', 'default');
}
add_action( 'add_meta_boxes', 'add_events_metaboxes' );
function wpt_events_products() {
//checkbox to select add text or not
echo '<input id="wp_add_text_to_woo_product" name="text_enable" type="checkbox"></input>';
}
//function will update post meta on save post button
function my_project_updated_post_meta( $post_id ) {
update_post_meta($post_id, 'enable_text', $_POST['text_enable']);
}
add_action( 'save_post', 'my_project_updated_post_meta' );
//function will check for perticular product for which check box is set and assign text for them.
function custom_price_message( $price ) {
$args = array('post_type' => 'product', 'nopaging' => true);
$product_query = new WP_Query($args);
$posts = $product_query->get_posts();
foreach ($posts as $post) {
$text_status = get_post_meta($post->ID,'enable_text',true);
if($text_status == "on") {
$addedtext = '(Upfront Paid in Full Price)';
return $price . '<br /><span class="price-disclaimer">' . $addedtext . '</span>';
}
else {
return $price;
}
}
}
add_filter( 'woocommerce_get_price_html', 'custom_price_message' );

Got this from woo support - works well
add_filter( 'woocommerce_get_price_html', 'custom_price_message' );
function custom_price_message($price) {
global $post;
$product_id = $post->ID;
$my_product_array = array( 799,796,792);
if (in_array($product_id, $my_product_array)) {
$addedtext = '(Upfront Paid in Full Price)';
return $price . '<br /><span class="price-disclaimer">' . $addedtext . '</span>';
}
else {
return $price;
}
}

Not only do the previous code answers fail to persist the checkbox state, they also update all prices, not just individual products. Try this code below instead:
//add meta box to each product which will take status to add text or not
function add_events_metaboxes() {
add_meta_box('wpt_events_product', 'Add \'From only\' text to product', 'wpt_events_products', 'product', 'advanced', 'default');
}
add_action( 'add_meta_boxes', 'add_events_metaboxes' );
function wpt_events_products($post) {
$text_status = get_post_meta( $post->ID, 'enable_text', true) ;
//checkbox to select add text or not
echo '<input id="wp_add_text_to_woo_product" name="text_enable" type="checkbox" '. checked('on', $text_status, false) .'></input>';
}
//function will update post meta on save post button
function my_project_updated_post_meta( $post_id ) {
update_post_meta($post_id, 'enable_text', $_POST['text_enable']);
}
add_action( 'save_post', 'my_project_updated_post_meta' );
//function will check for perticular product for which check box is set and assign text for them.
function custom_price_message( $price, $product ) {
$text_status = get_post_meta( $product->get_id(), 'enable_text', true) ;
if($text_status == "on") {
$addedtext = 'From only ';
return '<span class="price-prefix-text">' . $addedtext . '</span>' . $price;
}
return $price;
}
add_filter( 'woocommerce_get_price_html', 'custom_price_message', 10, 2 );

Related

Change shipping cost depending on ACF field and exclude certain shipping methods

I'm trying to add an extra shipping cost for all the additional shipping fees that aren't calculated from the third party shipping
company:
//add additional extra cost to shipping except for local pickup
add_filter( 'woocommerce_package_rates', 'shipping_extra_cost' );
function shipping_extra_cost( $rates ) {
foreach($rates as $key => $rate ) {
$rates[$key]->cost = $rates[$key]->cost + get_field('extra_cost', "51");
}
return $rates;
}
But then the additional fee is also added on local shipping
which is wrong.
I can't work with WC shipping classes because that messes with the third party shipping calculation program.
Is there a way I can check if "local pickup" exists and then exclude the extra fee from it?
You can exclude 1 or more shipping methods by using $rate->method_id
Note: because get_field() only applies when using the ACF plugin I replaced it with a fixed number, adjust to your needs
So you get:
function filter_woocommerce_package_rates( $rates, $package ) {
//$field = get_field( 'extra_cost', '51' );
$field = 50;
// Multiple can be added, separated by a comma
$exclude = array( 'local_pickup' );
// Loop through
foreach ( $rates as $rate_key => $rate ) {
// Targeting
if ( ! in_array( $rate->method_id, $exclude ) ) {
// Set the new cost
$rates[$rate_key]->cost += $field;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates','filter_woocommerce_package_rates', 10, 2 );
For debugging purposes you can temporarily use:
function filter_woocommerce_cart_shipping_method_full_label( $label, $method ) {
// Getters
$id = $method->id;
$method_id = $method->method_id;
// Output
$label .= '<span style="color:red; font-size:20px; display:block;">Id = ' . $id . '</span>';
$label .= '<span style="color:red; font-size:20px; display:block;">Method id = ' . $method_id . '</span>';
return $label;
}
add_filter( 'woocommerce_cart_shipping_method_full_label', 'filter_woocommerce_cart_shipping_method_full_label', 10, 2 );
Result:

Woocommerce emails template update and grab a custom field from order_details [duplicate]

On my WooCommerce based site, I recently added some code to display the shipping methods and prices for each order on the "Edit Order" page. Now, I would like to try and add those same fields to the "New Order" email template that gets sent to the admin. This is what I've got so far:
// Capture the available shipping methods, and costs:
function action_woocommerce_checkout_update_order_meta( $order_id ) {
// Get shipping packages
$packages = WC()->shipping()->get_packages();
// Set array
$rate_labels = array();
$rate_costs = array();
// Loop through packages
foreach ( $packages as $key => $package ) {
// Loop through package rates
foreach( $package['rates'] as $rate_id => $rate ) {
// Push to array
$rate_labels[] = $rate->get_label();
$rate_costs[] = $rate->get_cost();
}
}
// NOT empty
if ( ! empty ( $rate_labels ) ) {
// Update post meta
update_post_meta( $order_id, '_available_shipping_methods', $rate_labels );
update_post_meta( $order_id, '_available_shipping_method_cost', $rate_costs );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'action_woocommerce_checkout_update_order_meta', 10, 1 );
// Make it display on the edit order page:
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
// Get meta
$rate_labels = $order->get_meta( '_available_shipping_methods' );
$rate_costs = $order->get_meta( '_available_shipping_method_cost' );
$methods = array ( $rate_labels, $rate_costs );
// True
if ( $rate_labels ) {
// Loop
echo '<p><strong>Shipping Methods: </strong>';
foreach(array_combine($rate_labels, $rate_costs) as $rate_label => $rate_cost) {
echo '<p>' . $rate_label . ' - $' . $rate_cost . '</p>';
}
}
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
Adding on to that, this is what I have been trying to get working, with no luck so far:
// Add it to the new order email template
add_filter( 'woocommerce_new_order', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $rate_labels, $sent_to_admin, $order ) {
$rate_labels = $order->get_meta( '_available_shipping_methods' );
$rate_costs = $order->get_meta( '_available_shipping_method_cost' );
$methods = array ( $rate_labels, $rate_costs );
if ( $rate_labels ) {
// Loop
echo '<p><strong>Shipping Methods: </strong>';
foreach(array_combine($rate_labels, $rate_costs) as $rate_label => $rate_cost) {
echo '<p>' . $rate_label . ' - $' . $rate_cost . '</p>';
}
}
}
Use instead the following for example:
add_action( 'woocommerce_email_after_order_table', 'wc_email_new_order_custom_meta_data', 10, 4);
function wc_email_new_order_custom_meta_data( $order, $sent_to_admin, $plain_text, $email ){
// On "new order" email notifications
if ( 'new_order' === $email->id ){
$rate_labels = $order->get_meta( '_available_shipping_methods' );
$rate_costs = $order->get_meta( '_available_shipping_method_cost' );
$methods = array ( $rate_labels, $rate_costs );
if ( $rate_labels ) {
// Loop
echo '<p><strong>Shipping Methods: </strong>';
foreach(array_combine($rate_labels, $rate_costs) as $rate_label => $rate_cost) {
echo '<p>' . $rate_label . ' - $' . $rate_cost . '</p>';
}
}
}
}
It should work.

Save and display product selected custom data in WooCommerce

I use the code, that on the product editing page shows the checkbox "Roast Level". When the manager clicks on this checkbox, a select box appears on the page of a single product, allowing the customer to select "Roast Level".
When selecting and adding a product to the cart, the selected value appears in the cart itself. This value is also shown on the checkout page, on the "Thank You" page, in the order, on the email notification, and on the order editing page in the admin panel.
Here is the code:
// Display Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'roast_custom_field_add');
function roast_custom_field_add() {
global $post;
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_roast_checkbox',
'label' => __('Roast Level', 'woocommerce'),
'description' => __('Enable roast level!', 'woocommerce')
)
);
}
// Save Checkbox Field
add_action('woocommerce_process_product_meta', 'roast_custom_field_save');
function roast_custom_field_save($post_id) {
// Custom Product Checkbox Field
$roast_checkbox = isset($_POST['_roast_checkbox']) ? 'yes' : 'no';
update_post_meta($post_id, '_roast_checkbox', esc_attr($roast_checkbox));
}
// Display Select Box
add_action('woocommerce_before_add_to_cart_button', 'add_roast_custom_field', 0);
function add_roast_custom_field() {
global $product;
// If is single product page and have the "roast_checkbox" enabled we display the field
if (is_product() && $product->get_meta('_roast_checkbox') === 'yes') {
echo '<div>';
woocommerce_form_field('roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '');
echo '</div>';
}
}
// Add as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 10, 3);
function add_custom_cart_item_data($cart_item_data, $product_id, $variation_id) {
if (isset($_POST['roast_custom_options'])) {
$cart_item_data['roast_option'] = wc_clean($_POST['roast_custom_options']);
}
return $cart_item_data;
}
// Add custom fields values under cart item name in cart
add_filter('woocommerce_cart_item_name', 'roast_custom_field', 10, 3);
function roast_custom_field($item_name, $cart_item, $cart_item_key) {
if (!is_cart())
return $item_name;
if (isset($cart_item['roast_option'])) {
$item_name. = '<br /><div class="my-custom-class"><strong>'.__("Roast Level", "woocommerce").
':</strong> '.$cart_item['roast_option'].
'</div>';
}
return $item_name;
}
// Display roast custom fields values under item name in checkout
add_filter('woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 3);
function roast_custom_checkout_cart_item_name($item_qty, $cart_item, $cart_item_key) {
if (isset($cart_item['roast_option'])) {
$item_qty. = '<br /><div class="my-custom-class"><strong>'.__("Roast Level", "woocommerce").
':</strong> '.$cart_item['roast_option'].
'</div>';
}
return $item_qty;
}
// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_fitting_color', 10, 4);
function save_order_item_product_fitting_color($item, $cart_item_key, $values, $order) {
if (isset($values['_roast_option'])) {
$key = __('Roast Level', 'woocommerce');
$value = $values['_roast_option'];
$item->update_meta_data($key, $value);
}
}
This code works well in the Storefront theme, but for some reason, it does not work in the theme I bought on Themeforest. Developers can not help, they say that I need to contact the person who wrote this code. And that's why...
I also use code that works in the Storefront and in the purchased theme. Here it is - Show custom fields on the order editing page in WooCommerce
, those. It works great in these two themes.
As I understand it, this is due to the syntax "echo". In the form of "Roast Level" this syntax is, therefore the form is shown. When displaying selected data in the cart or on the checkout page, this syntax is not.
UPDATE
Here is the code that doesn't work without "echo":
// Add custom fields values under cart item name in cart
add_filter('woocommerce_cart_item_name', 'roast_custom_field', 10, 3);
function roast_custom_field($item_name, $cart_item, $cart_item_key) {
if (!is_cart())
return $item_name;
if (isset($cart_item['roast_option'])) {
$item_name. = '<br /><div class="my-custom-class"><strong>'.__("Roast Level", "woocommerce").
':</strong> '.$cart_item['roast_option'].
'</div>';
}
return $item_name;
}
// Display roast custom fields values under item name in checkout
add_filter('woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 3);
function roast_custom_checkout_cart_item_name($item_qty, $cart_item, $cart_item_key) {
if (isset($cart_item['roast_option'])) {
$item_qty. = '<br /><div class="my-custom-class"><strong>'.__("Roast Level", "woocommerce").
':</strong> '.$cart_item['roast_option'].
'</div>';
}
return $item_qty;
}
// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_fitting_color', 10, 4);
function save_order_item_product_fitting_color($item, $cart_item_key, $values, $order) {
if (isset($values['_roast_option'])) {
$key = __('Roast Level', 'woocommerce');
$value = $values['_roast_option'];
$item->update_meta_data($key, $value);
}
}
I ask to change my code so that it has the syntax "echo", so that the selected data is output using "echo". I will be glad for your help!
Following Code should Work
/*---------------------------------------------------------------
*Display Select Box
---------------------------------------------------------------*/
add_action( 'woocommerce_before_add_to_cart_button', 'add_roast_custom_field', 0 );
function add_roast_custom_field() {
global $product;
// If is single product page and have the "roast_checkbox" enabled we display the field
if ( is_product() && $product->get_meta( '_roast_checkbox' ) === 'yes' ) {
echo '<div class="roast_select">';
$select = woocommerce_form_field( 'roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'return' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '' );
echo $select;
echo '</div>';
}
}
/*---------------------------------------------------------------
* Add as custom cart item data
---------------------------------------------------------------*/
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 10, 21 );
function add_custom_cart_item_data($cart_item_data, $product_id, $variation_id ){
if( isset( $_POST['roast_custom_options'] ) ) {
$cart_item_data['roast_option'] = wc_clean( $_POST['roast_custom_options'] );
}
return $cart_item_data;
}
/*---------------------------------------------------------------
* Add custom fields values under cart item name in cart
---------------------------------------------------------------*/
add_filter( 'woocommerce_cart_item_name', 'roast_custom_field', 10, 21 );
function roast_custom_field( $item_name, $cart_item, $cart_item_key ) {
if( ! is_cart() )
return $item_name;
if( isset($cart_item['roast_option']) ) {
$item_name .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . '</div>';
}
return $item_name;
}
/*---------------------------------------------------------------
* Display roast custom fields values under item name in checkout
---------------------------------------------------------------*/
add_filter( 'woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 21 );
function roast_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( isset($cart_item['roast_option']) ) {
$item_qty .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . 'гр.</div>';
}
return $item_qty;
}
/*---------------------------------------------------------------
* Save chosen slelect field value to each order item as custom meta data and display it everywhere
---------------------------------------------------------------*/
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_fitting_color', 10, 21 );
function save_order_item_product_fitting_color( $item, $cart_item_key, $values, $order ) {
if( isset($values['roast_option']) ) {
$key = __('Roast Level', 'woocommerce');
$value = $values['roast_option'];
$item->update_meta_data( $key, $value ,$item->get_id());
}
}
/*--------------------------------------------------------------------
The following code played the important role in your theme
Your add to cart form takes the values when user clicks on add to cart button
After it ajax runs and takes the values from the butoons custom attribute
like data-product_id, data-roast_custom_options So i have added it using jquery
check the code and your site. All the codesprovided by me working now.
--------------------------------------------------------------------*/
add_action('wp_footer','add_footer_script');
function add_footer_script(){
?>
<script>
jQuery('#roast_custom_options').on('change',function(){
var roast_level = jQuery(this).val();
/*console.log(roast_level); */
var button = jQuery(this).closest('form').find('.add_to_cart_button'); console.log(button);
jQuery(button).attr('data-roast_custom_options',roast_level);
});
</script>
<?php
}

Multiple select product using select2 for wordpress plugin option page

I am trying to implement multiple select product using select2 . the list come up using getproductsearch this ajax action i did earlier but i failed to save it. I did this feature before for post-meta and product-category but failed for plugin option page. I am not sure what i am doing wrong.
please help.
class FeatureSale {
private $feature_sale_options;
public function __construct() {
add_action( 'admin_menu', array( $this, 'feature_sale_add_plugin_page' ) );
add_action( 'admin_init', array( $this, 'feature_sale_page_init' ) );
}
public function feature_sale_add_plugin_page() {
add_submenu_page(
'exclutips-settings',
'Feature & Sale', // page_title
'Feature & Sale', // menu_title
'manage_options', // capability
'feature-sale', // menu_slug
array( $this, 'feature_sale_create_admin_page' ) // function
);
}
public function feature_sale_create_admin_page() {
$this->feature_sale_options = get_option( 'feature_sale_option_name' ); ?>
<div class="wrap">
<div class="catbox-area-admin" style="width: 500px;background: #fff;padding: 27px 50px;">
<h2>Feature & Sale</h2>
<p></p>
<?php settings_errors(); ?>
<form method="post" action="options.php">
<?php
settings_fields( 'feature_sale_option_group' );
do_settings_sections( 'feature-sale-admin' );
submit_button();
?>
</form>
</div>
</div>
<?php }
public function feature_sale_page_init() {
register_setting(
'feature_sale_option_group', // option_group
'feature_sale_option_name', // option_name
array( $this, 'feature_sale_sanitize' ) // sanitize_callback
);
add_settings_section(
'feature_sale_setting_section', // id
'', // title
array( $this, 'feature_sale_section_info' ), // callback
'feature-sale-admin' // page
);
add_settings_field(
'vpm_sale_product', // id
'VPM Sale Product', // title
array( $this, 'vpm_sale_product_callback' ), // callback
'feature-sale-admin', // page
'feature_sale_setting_section' // section
);
add_settings_field(
'vpm_featured_product', // id
'VPM Featured Product', // title
array( $this, 'vpm_featured_product_callback' ), // callback
'feature-sale-admin', // page
'feature_sale_setting_section' // section
);
}
public function feature_sale_sanitize($input) {
$sanitary_values = array();
if ( isset( $input['vpm_sale_product'] ) ) {
$sanitary_values['vpm_sale_product'] = $input['vpm_sale_product'];
}
if ( isset( $input['vpm_featured_product'] ) ) {
$sanitary_values['vpm_featured_product'] = $input['vpm_featured_product'];
}
return $sanitary_values;
}
public function feature_sale_section_info() {
}
//Output the HTML for the metabox.
public function vpm_sale_product_callback() {
global $post;
// Nonce field to validate form request came from current site
wp_nonce_field( basename( __FILE__ ), 'vpm_sale_product_nonce' );
$html = '';
// always array because we have added [] to our <select> name attribute
$feature_sale_options = get_option( 'feature_sale_option_name' ); // Array of All Options
$vpm_sale_product = $feature_sale_options['vpm_sale_product'];
$html .= '<p><select id="vpm_sale_product" name="vpm_sale_product[]" multiple="multiple" style="width:99%;max-width:25em;">';
if( $vpm_sale_product ) {
foreach( $vpm_sale_product as $post_id ) {
$title = get_the_title( $post_id );
// if the post title is too long, truncate it and add "..." at the end
$title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
$html .= '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
}
}
$html .= '</select></p>';
echo $html;
//==========================================
}
//* Output the HTML for the metabox.
public function vpm_featured_product_callback() {
global $post;
// Nonce field to validate form request came from current site
wp_nonce_field( basename( __FILE__ ), 'vpm_featured_product_nonce' );
$html = '';
// always array because we have added [] to our <select> name attribute
$feature_sale_options = get_option( 'feature_sale_option_name' ); // Array of All Options
$vpm_featured_product = $feature_sale_options['vpm_featured_product'];
$html .= '<p><select id="vpm_featured_product" name="vpm_featured_product[]" multiple="multiple" style="width:99%;max-width:25em;">';
if( $vpm_featured_product ) {
foreach( $vpm_featured_product as $post_id ) {
$title = get_the_title( $post_id );
// if the post title is too long, truncate it and add "..." at the end
$title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
$html .= '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
}
}
$html .= '</select></p>';
echo $html;
echo $vpm_featured_product;
//==========================================
?>
<script>
(function ($) {
'use strict';
$(function () {
//--------------------------------------------------------------------------
// multiple select with AJAX search
$('#vpm_featured_product,#vpm_sale_product').select2({
ajax: {
url: ajaxurl, // AJAX URL is predefined in WordPress admin
dataType: 'json',
delay: 250, // delay in ms while typing when to perform a AJAX search
data: function (params) {
return {
q: params.term, // search query
action: 'getproductsearch' // AJAX action for admin-ajax.php
};
},
processResults: function( data ) {
var options = [];
if ( data ) {
// data is the array of arrays, and each of them contains ID and the Label of the option
$.each( data, function( index, text ) { // do not forget that "index" is just auto incremented value
options.push( { id: text[0], text: text[1] } );
});
}
return {
results: options
};
},
cache: true
},
minimumInputLength: 3 // the minimum of symbols to input before perform a search
});
//----------------------------------------------------------------------------------------
});
})(jQuery);
</script>
<?php
}
}
if ( is_admin() )
$feature_sale = new FeatureSale();
The problem is that these select tags are not using the correct name value:
<select id="vpm_sale_product" name="vpm_sale_product[]"...>
<select id="vpm_featured_product" name="vpm_featured_product[]"...>
And the proper name values are: (based on your register_setting() call)
<select id="vpm_sale_product" name="feature_sale_option_name[vpm_sale_product][]"...>
<select id="vpm_featured_product" name="feature_sale_option_name[vpm_featured_product][]"...>
And although after correcting the above issue, the form data would be saved properly, the fifth parameter (i.e. the menu/page slug) passed to add_submenu_page() should match the fourth parameter passed to add_settings_section() and add_settings_field(), and also the one passed to do_settings_sections(). In your add_submenu_page() call, the menu/page slug is feature-sale, but with the other three functions, you set it to feature-sale-admin.
And using wp_nonce_field() is recommended, but in your case, it's not necessary since you're submitting to wp-admin/options.php. Unless of course, you want to check that prior to WordPress saving the options. But even so, I believe one nonce field is good. :)

WooCommerce show custom column

I want to show a additional column in the backend of WooCommerce (in Orders overview).
The column should contain a custom field, which i have defined (delivery date).
How to do this?
In case someone still needs it - instructions on how to add new columns in Woocommerce orders list. No need in unsetting the default columns, just add this in your functions.php and your code will be valid for updates.
1. Define columns position and names
add_filter( 'manage_edit-shop_order_columns', 'MY_COLUMNS_FUNCTION' );
function MY_COLUMNS_FUNCTION($columns){
$new_columns = (is_array($columns)) ? $columns : array();
unset( $new_columns['order_actions'] );
//edit this for you column(s)
//all of your columns will be added before the actions column
$new_columns['MY_COLUMN_ID_1'] = 'MY_COLUMN_1_TITLE';
$new_columns['MY_COLUMN_ID_2'] = 'MY_COLUMN_2_TITLE';
//stop editing
$new_columns['order_actions'] = $columns['order_actions'];
return $new_columns;
}
2. For each custom column, show the values
add_action( 'manage_shop_order_posts_custom_column', 'MY_COLUMNS_VALUES_FUNCTION', 2 );
function MY_COLUMNS_VALUES_FUNCTION($column){
global $post;
$data = get_post_meta( $post->ID );
//start editing, I was saving my fields for the orders as custom post meta
//if you did the same, follow this code
if ( $column == 'MY_COLUMN_ID_1' ) {
echo (isset($data['MY_COLUMN_1_POST_META_ID']) ? $data['MY_COLUMN_1_POST_META_ID'] : '');
}
if ( $column == 'MY_COLUMN_ID_2' ) {
echo (isset($data['MY_COLUMN_2_POST_META_ID']) ? $data['MY_COLUMN_2_POST_META_ID'] : '');
}
//stop editing
}
3. (optional) Function to make the columns sortable
add_filter( "manage_edit-shop_order_sortable_columns", 'MY_COLUMNS_SORT_FUNCTION' );
function MY_COLUMNS_SORT_FUNCTION( $columns ) {
$custom = array(
//start editing
'MY_COLUMN_ID_1' => 'MY_COLUMN_1_POST_META_ID',
'MY_COLUMN_ID_2' => 'MY_COLUMN_2_POST_META_ID'
//stop editing
);
return wp_parse_args( $custom, $columns );
}
To add new column coupon in woo-commerce order table and get all coupon code according to order. you need to copy and paste in you function.php.
add_filter('manage_edit-shop_order_columns', 'custom_shop_order_column', 11);
function custom_shop_order_column($columns) {
//add columns
$columns['my-column1'] = __('Coupons Code', 'theme_slug');
return $columns;
}
// adding the data for each orders by column (example)
add_action('manage_shop_order_posts_custom_column', 'cbsp_credit_details', 10, 2);
function cbsp_credit_details($column) {
global $post, $woocommerce, $the_order;
$order_id = $the_order->id;
switch ($column) {
case 'my-column1' :
// $myVarOne = wc_get_order_item_meta( $order_id, 15, true );
if ($the_order->get_used_coupons()) {
$coupons_count = count($the_order->get_used_coupons());
foreach ($the_order->get_used_coupons() as $coupon) {
echo $coupon;
$i++;
}
echo '</p>';
}
// echo $myVarOne;
break;
}
}
Try this, you will get your solution just write below code on your function.php file.
add_filter( 'manage_edit-shop_order_columns','your_function_name',10 );
function your_function_name($columns){
$columns['delivery_date'] = __('Delivery date','textdomain');
return $columns;
}
add_action( 'manage_shop_order_posts_custom_column','your_other_function_name',20 );
function your_other_function_name($column)
{
swith($column)
{
case 'delivery_date': // your custom code here and do what you want.
}
}
The following works for WooCommerce 2.6.2.
You should look into two new hooks:
woocommerce_admin_order_item_headers, invoked once when orders table header is generated
woocommerce_admin_order_item_values, invoked once per every item inside the order
1. Define columns headers
add_filter('woocommerce_admin_order_item_headers', 'so13683162_headers');
function so13683162_headers($order) {
echo "<th>FIELD1</th>";
}
2. Populate values in rows
add_filter('woocommerce_admin_order_item_values', 'so13683162_values');
function so13683162_values($product) {
if (isset($product -> id)) {
$attrs = get_post_meta($product -> id, "_product_attributes", true);
echo "<td>" . $attrs["FIELD1"]["value"] . "</td>";
}
}
I came across Woocommerce now. Have added a custom field Personal Registration Number - and now wanted it to be displayed in the Order overview page.
I've manage to add the column - but still couldn't get the value of the custom field for each order.
Here is what I did:
// Removed Existing Order Page collumns
remove_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
// Added My own filter to Show the PRN - Personal Registration field
add_filter('manage_edit-shop_order_columns', 'omak_edit_order_columns');
// The omak_edit_order_columns definition
/*** Taken from admin/post_types/shop_order.php ***/
function omak_edit_order_columns($columns){
global $woocommerce;
$columns = array();
$columns["cb"] = "<input type=\"checkbox\" />";
$columns["order_status"] = __( 'Status', 'woocommerce' );
$columns["order_title"] = __( 'Order', 'woocommerce' );
$columns["order_prn"] = __( 'PRN', 'woocommerce' ); // This is the line which added the column after the Title Column
$columns["billing_address"] = __( 'Billing', 'woocommerce' );
$columns["shipping_address"] = __( 'Shipping', 'woocommerce' );
$columns["total_cost"] = __( 'Order Total', 'woocommerce' );
$columns["order_comments"] = '<img alt="' . esc_attr__( 'Order Notes', 'woocommerce' ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/order-notes_head.png" class="tips" data-tip="' . __( 'Order Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["note"] = '<img src="' . $woocommerce->plugin_url() . '/assets/images/note_head.png" alt="' . __( 'Customer Notes', 'woocommerce' ) . '" class="tips" data-tip="' . __( 'Customer Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["order_date"] = __( 'Date', 'woocommerce' );
$columns["order_actions"] = __( 'Actions', 'woocommerce' );
return $columns;
}
Let me know if it helps you...
I am left to deal with how to get its values for each Order.
As commented: the function definition exists in shop_order.php in WooCommerce plugin.
Let me know if anybody sorts it out.. or knows how to do it.
Thanks,
(sorry, was busy in something so couldn't read back to check for errors)

Resources