WooCommerce show custom column - wordpress

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)

Related

Woocommerce 'My orders' add/remove column

In the Woocommerce customer account, I'd like to remove the following columns:
Order number
Order total
And add a column to display attached files (thanks to the WooCommerce Attach Me! plugin). The developer gave me this information:
"To get all the order attachments use the following snippet:"
global $wcam_order_model;
$order_attachments = $wcam_order_model->get_attachments_metadata($order_id , array());
Where $order_id is the order id for which you want to retreive attachments. Then to get each attachment title use the following shippet:
foreach($order_attachments as $order_attachment)
$file_name = basename($order_attachment['absolute_path']);
I have found a tutorial here: https://www.skyverge.com/blog/adding-columns-woocommerce-orders-list/
But I can't get it work. As you imagine, I am not a developer :/
Thank you very much!
Put this in your functions.php
function sv_wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
if( 'order-number' === $key || 'order-total' === $key ) {
echo ' name '.$name . ' key ' . $key ;
continue;
}
$new_columns[ $key ] = $name;
/*if( 'order-date' === $key) {
$new_columns['order-number'] = __( 'Order', 'textdomain' );
$new_columns['order-rental-period'] = __( 'Rental Period', 'textdomain' );
$new_columns['order-detail'] = __( 'Order or Quotation Detail', 'textdomain' );
}*/
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'sv_wc_add_my_account_orders_column' );
return $new_columns;
}

Modify woocommerce orders.php columns

I am trying to modify the columns in the Woocommerce orders.php table. I would like to get rid of the TOTAL column as well as the DATE column and then I would like to add a new column with some custom information that’s specific to my store.
The following function used to work but has been deprecated since Woocommerce 2.6. So the question is, does anybody know how to delete/add columns to this table after 2.6?
function wc_get_account_orders_columns() {
$columns = apply_filters( 'woocommerce_account_orders_columns', array(
'order-number' => __( 'Order', 'woocommerce' ),
'order-date' => __( 'Date', 'woocommerce' ),
'order-status' => __( 'Status', 'woocommerce' ),
'order-total' => __( 'Total', 'woocommerce' ),
'order-actions' => ' ',
) );
// Deprecated filter since 2.6.0.
return apply_filters( 'woocommerce_my_account_my_orders_columns', $columns );
}
A friend of mine helped me out with this. Here is the function that I ended up using in case anybody finds it useful:
function new_orders_columns( $columns = array() ) {
// Hide the columns
if( isset($columns['order-total']) ) {
// Unsets the columns which you want to hide
unset( $columns['order-number'] );
unset( $columns['order-date'] );
unset( $columns['order-status'] );
unset( $columns['order-total'] );
unset( $columns['order-actions'] );
}
// Add new columns
$columns['order-number'] = __( 'Reserva', 'Text Domain' );
$columns['reservation-date'] = __( 'Para el día', 'Text Domain' );
$columns['reservation-people'] = __( 'Seréis', 'Text Domain' );
$columns['order-status'] = __( 'Estado de la reserva', 'Text Domain' );
$columns['order-actions'] = __( ' ', 'Text Domain' );
return $columns;
}
add_filter( 'woocommerce_account_orders_columns', 'new_orders_columns' );
Note that it is not necesary to first unset all the columns and then set them again like I did unless you want to change the order in which they apear or insert new columns between the existing ones.
In the other answers it is not mentioned how to populate a column with custom information. So, the complete algorithm is below:
Step 1. Add or remove
add_filter( 'manage_edit-shop_order_columns','your_function_name');
function your_function_name($columns)
{
// to remove just use unset
unset($columns['order_total']); // remove Total column
unset($columns['order_date']); // remove Date column
// now it is time to add a custom one
$columns['custom_column'] = "Column title";
return $columns;
}
Step 2. Fill with data
add_action( 'manage_shop_order_posts_custom_column' , 'your_function_name2' );
function your_function_name2( $column ) {
global $the_order; // you can use the global WP_Order object here
// global $post; // is also available here
if( $column == 'custom_column' ) {
// do stuff, ex: get_post_meta( $post->ID, 'key', true );
}
}
You can also check this tutorial for more examples.
This will help you.
add_filter( 'manage_edit-shop_order_columns','your_function_name',10 );
function your_function_name($columns)
{
unset($columns['order_total']);
unset($columns['order_date']);
return $columns;
}

Change title "Additional Information" in woocommerce

I want to change the title from the checkout page. But I just can change the label and the placeholder.
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = 'Please type your PO number here and we will add it to the invoice.';
$fields['order']['order_comments']['label'] = '';
return $fields;
}
https://docs.woocommerce.com/document/editing-product-data-tabs/#
/**
* Rename product data tabs
*/
add_filter( 'woocommerce_product_tabs', 'woo_rename_tabs', 98 );
function woo_rename_tabs( $tabs ) {
$tabs['description']['title'] = __( 'More Information' ); // Rename the description tab
$tabs['reviews']['title'] = __( 'Ratings' ); // Rename the reviews tab
$tabs['additional_information']['title'] = __( 'Product Data' ); // Rename the additional information tab
return $tabs;
}
As it stands there is not hook to change the section title. But here's the hack if you are desperate enough to make the modification.
Locate your template folder
Create a folder named 'checkout'
Locate the file form-shipping.php in the Woocommerce plugin foler under templates/checkout/
Copy file in step 3 to the folder created in step 2
Now you have superpowers over the checkout form
Edit this line:
<h3><?php _e( 'Additional Information', 'woocommerce' ); ?></h3>
This solution worked for me:
function ajg_relabel_additional_information_tab(){
return __( 'Specification', 'text-domain' );
}
add_filter('woocommerce_product_additional_information_heading', 'ajg_relabel_additional_information_tab');
function th_wc_order_review_strings( $translated_text, $text, $domain ) {
if(is_checkout()){
switch ($translated_text) {
case 'Billing details' :
$translated_text = __( 'Billing Info', 'woocommerce' );
break;
case 'Additional information':
$translated_text = __('New Field Name', 'woocommerce');
break;
case 'Your order':
$translated_text = __('My Order', 'woocommerce');
break;
case 'Product':
$translated_text = __('Your Product', 'woocommerce');
break;
}
}
return $translated_text;
}
add_filter( 'gettext', 'th_wc_order_review_strings', 20, 3 );
The documentation of Woocommerce is not complety...
https://docs.woocommerce.com/document/editing-product-data-tabs/
You would check condition about the callback before add or replace some value in array, otherwise the tab will display with nothing inside.
/**
* Filter product data tabs
*/
function filter_product_tabs( $tabs ) {
global $product;
if ( isset($tabs['description']['callback']) ) {
$tabs['description']['title'] = __( 'More Information' ); // Rename the description tab
$tabs['description']['priority'] = 5; // Description
}
if ( isset($tabs['additional_information']['callback']) ) {
$tabs['additional_information']['title'] = __( 'Product Data' ); // Rename the additional information tab
$tabs['additional_information']['priority'] = 10; // Additional information
}
if ( isset($tabs['reviews']['callback']) ) {
$tabs['reviews']['title'] = __( 'Review' ) . ' (' . $product->get_review_count() . ') '; // Rename the reviews tab
$tabs['reviews']['priority'] = 15; // Reviews
}
return $tabs;
}
add_filter( 'woocommerce_product_tabs', 'filter_product_tabs', 98 );
Why ? because the developper Woocommerce will check the content of array in the tab template
(version 3.8.0) (WC
/**
* Filter tabs and allow third parties to add their own.
*
* Each tab is an array containing title, callback and priority.
*
* #see woocommerce_default_product_tabs()
*/
$product_tabs = apply_filters( 'woocommerce_product_tabs', array() );
if ( ! empty( $product_tabs ) ) :
....
This worked for me if anyone is still after this change
//Shipping Weight custom tab name
add_filter( 'woocommerce_product_tabs', 'woo_rename_tabs', 98 );
function woo_rename_tabs( $tabs ) {
$tabs['additional_information']['title'] = __( 'Additional Information' ); // Rename the Additional Information text
return $tabs;
}

WooCommerce Conditionally add text below price on Products

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 );

Wordpress custom metabox input value with AJAX

I am using Wordpress 3.5, I have a custom post (sp_product) with a metabox and some input field. One of those input (sp_title).
I want to Search by the custom post title name by typing in my input (sp_title) field and when i press add button (that also in my custom meta box), It will find that post by that Title name and bring some post meta data into this Meta box and show into other field.
Here in this picture (Example)
Search
Click Button
Get some value by AJAX from a custom post.
Please give me a example code (just simple)
I will search a simple custom post Title,
Click a button
Get the Title of that post (that i search or match) with any other post meta value, By AJAX (jQuery-AJAX).
Please Help me.
I was able to find the lead because one of my plugins uses something similar to Re-attach images.
So, the relevant Javascript function is findPosts.open('action','find_posts').
It doesn't seem well documented, and I could only found two articles about it:
Find Posts Dialog Box
Using Built-in Post Finder in Plugins
Tried to implement both code samples, the modal window opens but dumps a -1 error. And that's because the Ajax call is not passing the check_ajax_referer in the function wp_ajax_find_posts.
So, the following works and it's based on the second article. But it has a security breach that has to be tackled, which is wp_nonce_field --> check_ajax_referer. It is indicated in the code comments.
To open the Post Selector, double click the text field.
The jQuery Select needs to be worked out.
Plugin file
add_action( 'load-post.php', 'enqueue_scripts_so_14416409' );
add_action( 'add_meta_boxes', 'add_custom_box_so_14416409' );
add_action( 'wp_ajax_find_posts', 'replace_default_ajax_so_14416409', 1 );
/* Scripts */
function enqueue_scripts_so_14416409() {
# Enqueue scripts
wp_enqueue_script( 'open-posts-scripts', plugins_url('open-posts.js', __FILE__), array('media', 'wp-ajax-response'), '0.1', true );
# Add the finder dialog box
add_action( 'admin_footer', 'find_posts_div', 99 );
}
/* Meta box create */
function add_custom_box_so_14416409()
{
add_meta_box(
'sectionid_so_14416409',
__( 'Select a Post' ),
'inner_custom_box_so_14416409',
'post'
);
}
/* Meta box content */
function inner_custom_box_so_14416409( $post )
{
?>
<form id="emc2pdc_form" method="post" action="">
<?php wp_nonce_field( 'find-posts', '_ajax_nonce', false); ?>
<input type="text" name="kc-find-post" id="kc-find-post" class="kc-find-post">
</form>
<?php
}
/* Ajax replacement - Verbatim copy from wp_ajax_find_posts() */
function replace_default_ajax_so_14416409()
{
global $wpdb;
// SECURITY BREACH
// check_ajax_referer( '_ajax_nonce' );
$post_types = get_post_types( array( 'public' => true ), 'objects' );
unset( $post_types['attachment'] );
$s = stripslashes( $_POST['ps'] );
$searchand = $search = '';
$args = array(
'post_type' => array_keys( $post_types ),
'post_status' => 'any',
'posts_per_page' => 50,
);
if ( '' !== $s )
$args['s'] = $s;
$posts = get_posts( $args );
if ( ! $posts )
wp_die( __('No items found.') );
$html = '<table class="widefat" cellspacing="0"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th class="no-break">'.__('Type').'</th><th class="no-break">'.__('Date').'</th><th class="no-break">'.__('Status').'</th></tr></thead><tbody>';
foreach ( $posts as $post ) {
$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
switch ( $post->post_status ) {
case 'publish' :
case 'private' :
$stat = __('Published');
break;
case 'future' :
$stat = __('Scheduled');
break;
case 'pending' :
$stat = __('Pending Review');
break;
case 'draft' :
$stat = __('Draft');
break;
}
if ( '0000-00-00 00:00:00' == $post->post_date ) {
$time = '';
} else {
/* translators: date format in table columns, see http://php.net/date */
$time = mysql2date(__('Y/m/d'), $post->post_date);
}
$html .= '<tr class="found-posts"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>';
$html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n\n";
}
$html .= '</tbody></table>';
$x = new WP_Ajax_Response();
$x->add( array(
'data' => $html
));
$x->send();
}
Javascript file open-posts.js
jQuery(document).ready(function($) {
// Find posts
var $findBox = $('#find-posts'),
$found = $('#find-posts-response'),
$findBoxSubmit = $('#find-posts-submit');
// Open
$('input.kc-find-post').live('dblclick', function() {
$findBox.data('kcTarget', $(this));
findPosts.open();
});
// Insert
$findBoxSubmit.click(function(e) {
e.preventDefault();
// Be nice!
if ( !$findBox.data('kcTarget') )
return;
var $selected = $found.find('input:checked');
if ( !$selected.length )
return false;
var $target = $findBox.data('kcTarget'),
current = $target.val(),
current = current === '' ? [] : current.split(','),
newID = $selected.val();
if ( $.inArray(newID, current) < 0 ) {
current.push(newID);
$target.val( current.join(',') );
}
});
// Double click on the radios
$('input[name="found_post_id"]', $findBox).live('dblclick', function() {
$findBoxSubmit.trigger('click');
});
// Close
$( '#find-posts-close' ).click(function() {
$findBox.removeData('kcTarget');
});
});

Resources