Woocommerce - add field to Check pay method - woocommerce

I'd like to add a field on Check Payment that allows the order processor to insert a check number...please help! Check payment orders will only be entered by staff, not the public.
Add Field Here
I've searched all over and I'm stumped.

As per my understanding of your question, I have created this snippet which will help you with your requirement.
// add a field on the check payment type
add_filter( 'woocommerce_gateway_description', 'custom_check_payment_field', 10, 2 );
function custom_check_payment_field( $description, $payment_id ) {
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
$current_user_role = (array) $user->roles;
if ( 'cheque' === $payment_id && $current_user_role[0] == 'administrator') {
ob_start();
echo '<div class="cheque-field">';
woocommerce_form_field(
'customer_cheque_number',
array(
'type' => 'text',
'label' => __( 'Enter cheque number', 'woocommerce' ),
'class' => array( 'form-row-wide' ),
'required' => true,
),
''
);
echo '<div>';
$description .= ob_get_clean();
}
}
return $description;
}
// save check number in meta/database
add_action( 'woocommerce_checkout_create_order', 'save_customer_cheque_number_order_meta', 10, 2 );
function save_customer_cheque_number_order_meta( $order, $data ) {
if ( isset( $_POST['customer_cheque_number'] ) && ! empty( $_POST['customer_cheque_number'] ) ) {
$order->update_meta_data( '_customer_cheque_number', esc_attr( $_POST['customer_cheque_number'] ) );
}
}
// show check number on orders page (OPTONAL)
add_action( 'woocommerce_get_order_item_totals', 'display_customer_cheque_number_on_order_totals', 10, 3 );
function display_customer_cheque_number_on_order_totals( $total_rows, $order, $tax_display ) {
if ( $order->get_payment_method() === 'cheque' && $customer_cheque_number = $order->get_meta( '_customer_cheque_number' ) ) {
$sorted_total_rows = array();
foreach ( $total_rows as $key_row => $total_row ) {
$sorted_total_rows[ $key_row ] = $total_row;
if ( $key_row === 'payment_method' ) {
$sorted_total_rows['customer_cheque_number'] = array(
'label' => __( 'Cheque number', 'woocommerce' ),
'value' => esc_html( $customer_cheque_number ),
);
}
}
$total_rows = $sorted_total_rows;
}
return $total_rows;
}
// add meta box on orders on woocommerce backend
add_action( 'add_meta_boxes', 'add_meta_boxes_callback' );
if ( ! function_exists( 'add_meta_boxes_callback' ) ) {
function add_meta_boxes_callback() {
add_meta_box( 'shop_order_fields', __( 'Cheque number', 'woocommerce' ), 'orders_cheque_number_custom_meta', 'shop_order', 'side', 'core' );
}
}
// show meta field with entered check number
if ( ! function_exists( 'orders_cheque_number_custom_meta' ) ) {
function orders_cheque_number_custom_meta() {
global $post;
$check_number = get_post_meta( $post->ID, '_customer_cheque_number', true ) ? get_post_meta( $post->ID, '_customer_cheque_number', true ) : '';
?>
<input type="text" style="width:250px;margin-top:15px" readonly name="readonly_check_number" value="<?php echo $check_number; ?>"></p>
<?php
}
}

Related

How to remove item from cart via ajax edd

I want to remove item from cart via ajax and I'm using Easy Digital Downloads plugin so is there any clue for that.
I already found below code but don't know how to use it as I made customizations to my custom theme by overriding templates.
function edd_ajax_remove_from_cart() {
if ( ! isset( $_POST['nonce'] ) ) {
edd_debug_log( __( 'Missing nonce when removing an item from the cart. Please read the following for more information: https://easydigitaldownloads.com/development/2018/07/05/important-update-to-ajax-requests-in-easy-digital-downloads-2-9-4', 'easy-digital-downloads' ), true );
}
if ( isset( $_POST['cart_item'] ) && isset( $_POST['nonce'] ) ) {
$cart_item = absint( $_POST['cart_item'] );
$nonce = sanitize_text_field( $_POST['nonce'] );
$nonce_verified = wp_verify_nonce( $nonce, 'edd-remove-cart-widget-item' );
if ( false === $nonce_verified ) {
$return = array( 'removed' => 0 );
} else {
edd_remove_from_cart( $cart_item );
$return = array(
'removed' => 1,
'subtotal' => html_entity_decode( edd_currency_filter( edd_format_amount( edd_get_cart_subtotal() ) ), ENT_COMPAT, 'UTF-8' ),
'total' => html_entity_decode( edd_currency_filter( edd_format_amount( edd_get_cart_total() ) ), ENT_COMPAT, 'UTF-8' ),
'cart_quantity' => html_entity_decode( edd_get_cart_quantity() ),
);
if ( edd_use_taxes() ) {
$cart_tax = (float) edd_get_cart_tax();
$return['tax'] = html_entity_decode( edd_currency_filter( edd_format_amount( $cart_tax ) ), ENT_COMPAT, 'UTF-8' );
}
}
$return = apply_filters( 'edd_ajax_remove_from_cart_response', $return );
echo json_encode( $return );
}
edd_die();
}
Here is my Current delete item code inside overrided template inside edd_templates/checkout_cart.php file.
<a class="edd_cart_remove_item_btn" href="<?php echo esc_url( wp_nonce_url( edd_remove_item_url( $key ), 'edd-remove-from-cart-' . sanitize_key( $key ), 'edd_remove_from_cart_nonce' ) ); ?>"></a>
But it refresh cart page when I click on x(delete) in cart but I want to remove item using ajax any help will be appreciated.

Print styled HTML as custom field output from admin meta box fields in WooCommerce

I have this code, based on Display custom field values of product variations to custom product tab in WooCommerce to display 3 custom field on WooCommerce variations.
In that fields I want to insert text with HTML tags and show it in shortcode with all HTML styling (tables etc...) but current code doesn't output styled text but raw text with printed HTML tags:
<div>some text etc...</div><a>some link</a>
Any suggestions what I did wrong here?
/* Add custom field input # Product Data > Variations > Single Variation */
add_action( 'woocommerce_variation_options', 'add_custom_field_cage_code_to_variations', 10, 3 );
function add_custom_field_cage_code_to_variations( $loop, $variation_data, $variation ) {
echo '<div class="cage_code_options_group options_group">';
woocommerce_wp_text_input( array(
'id' => 'cage_code[' . $loop . ']',
'label' => __( 'One-line description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code', true )
));
woocommerce_wp_textarea_input( array(
'id' => 'cage_code_part_number[' . $loop . ']',
'label' => __( 'Short Description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code_part_number', true )
));
woocommerce_wp_textarea_input( array(
'id' => 'cage_code_niin_nsn_number[' . $loop . ']',
'label' => __( 'Long description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code_niin_nsn_number', true )
));
echo '</div>';
}
/* Save custom field on product variation save */
add_action( 'woocommerce_save_product_variation', 'magazine_save_custom_field_variations', 10, 2 );
function magazine_save_custom_field_variations( $variation_id, $i ) {
$cage_code = $_POST['cage_code'][$i];
if ( isset( $cage_code ) ) update_post_meta( $variation_id, 'cage_code', esc_attr(
$cage_code ) );
$cage_code_part_number = $_POST['cage_code_part_number'][$i];
if ( isset( $cage_code ) ) update_post_meta( $variation_id, 'cage_code_part_number',
esc_attr( $cage_code_part_number ) );
$cage_code_niin_nsn_number = $_POST['cage_code_niin_nsn_number'][$i];
if ( isset( $cage_code_niin_nsn_number ) ) update_post_meta( $variation_id,
'cage_code_niin_nsn_number', esc_attr( $cage_code_niin_nsn_number ) );
}
function woo_cage_code_info_tab_content() {
global $product;
if ( $product->is_type( 'variable' ) ) {
// Loop through the variation IDs
foreach( $product->get_children() as $key => $variation_id ) {
// Get an instance of the WC_Product_Variation Object
$variation = wc_get_product( $variation_id );
// Get meta
$cage_code = $variation->get_meta( 'cage_code' );
$cage_code_part_number = $variation->get_meta( 'cage_code_part_number' );
$cage_code_niin_nsn_number = $variation->get_meta(
'cage_code_niin_nsn_number' );
// Output
echo '<div class="woo_cage_code_info_tab_content
woo_cage_code_info_tab_content-' . $variation_id .'">';
if ( $cage_code ) {
echo '<p>' . $cage_code . '</p>';
}
echo '</div>';
}
?>
<script>
jQuery(document).ready(function($) {
// Hide all
$( '.woo_cage_code_info_tab_content' ).css( 'display', 'none' );
// Change
$( 'input.variation_id' ).change( function() {
// Hide all
$( '.woo_cage_code_info_tab_content' ).css( 'display', 'none' );
if( $( 'input.variation_id' ).val() != '' ) {
var var_id = $( 'input.variation_id' ).val();
// Display current
$( '.woo_cage_code_info_tab_content-' + var_id ).css( 'display', 'block' );
}
});
});
</script>
<?php
}
}
add_shortcode('woo_cage_code_info_tab_content', 'woo_cage_code_info_tab_content');
Your code contains some minor mistakes. You can use woocommerce_wp_text_input() or woocommerce_wp_textarea_input() without issues.
However, do not use esc_attr() when saving because it's for escaping HTML attributes (I assume that you as admin only have access to the backend fields) OR if you do use it, convert HTML entities back to characters at the output. In this answer I have used wp_kses_post() and wp_unslash()
The woocommerce_admin_process_variation_object replaces the outdated woocommerce_save_product_variation hook
So you get:
// Add field(s)
function action_woocommerce_variation_options( $loop, $variation_data, $variation ) {
echo '<div class="cage_code_options_group options_group">';
woocommerce_wp_text_input(
array(
'id' => 'cage_code[' . $loop . ']',
'label' => __( 'One-line description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code', true )
)
);
woocommerce_wp_textarea_input(
array(
'id' => 'cage_code_part_number[' . $loop . ']',
'label' => __( 'Short Description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code_part_number', true )
)
);
woocommerce_wp_textarea_input(
array(
'id' => 'cage_code_niin_nsn_number[' . $loop . ']',
'label' => __( 'Long description', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, 'cage_code_niin_nsn_number', true )
)
);
echo '</div>';
}
add_action( 'woocommerce_variation_options', 'action_woocommerce_variation_options', 10, 3 );
// Save
function action_woocommerce_admin_process_variation_object( $variation, $i ) {
// Isset
if ( isset( $_POST['cage_code'][$i] ) ) {
// Store
$cage_code = wp_kses_post( wp_unslash( $_POST['cage_code'][$i] ) );
// Update
$variation->update_meta_data( 'cage_code', $cage_code );
}
// Isset
if ( isset( $_POST['cage_code_part_number'][$i] ) ) {
// Store
$cage_code_part_number = wp_kses_post( wp_unslash( $_POST['cage_code_part_number'][$i] ) );
// Update
$variation->update_meta_data( 'cage_code_part_number', $cage_code_part_number );
}
// Isset
if ( isset( $_POST['cage_code_niin_nsn_number'][$i] ) ) {
// Store
$cage_code_niin_nsn_number = wp_kses_post( wp_unslash( $_POST['cage_code_niin_nsn_number'][$i] ) );
// Update
$variation->update_meta_data( 'cage_code_niin_nsn_number', $cage_code_niin_nsn_number );
}
}
add_action( 'woocommerce_admin_process_variation_object', 'action_woocommerce_admin_process_variation_object', 10, 2 );
Then I have no idea why you would use a shortcode versus a hook to render, like I did this in my answer. This can be any hook as long as it applies to the single product page:
// Display
function filter_woocommerce_product_tabs( $tabs ) {
// Adds the new tab
$tabs['cage_code_information_tab'] = array(
'title' => __( 'Cage Code Information', 'woocommerce' ),
'priority' => 50,
'callback' => 'woo_cage_code_info_tab_content'
);
return $tabs;
}
add_filter( 'woocommerce_product_tabs', 'filter_woocommerce_product_tabs', 100, 1 );
function woo_cage_code_info_tab_content() {
global $product;
if ( $product->is_type( 'variable' ) ) {
// Loop through the variation IDs
foreach( $product->get_children() as $key => $variation_id ) {
// Get an instance of the WC_Product_Variation Object
$variation = wc_get_product( $variation_id );
// Get meta
$cage_code = $variation->get_meta( 'cage_code' );
$cage_code_part_number = $variation->get_meta( 'cage_code_part_number' );
$cage_code_niin_nsn_number = $variation->get_meta( 'cage_code_niin_nsn_number' );
// Output
echo '<div class="woo_cage_code_info_tab_content woo_cage_code_info_tab_content-' . $variation_id .'">';
if ( $cage_code ) {
echo '<p>Cage code: ' . $cage_code . '</p>';
}
if ( $cage_code_part_number ) {
echo '<p>Cage code part number: ' . $cage_code_part_number . '</p>';
}
if ( $cage_code_niin_nsn_number ) {
echo '<p>Cage code niin nsn_number: ' . $cage_code_niin_nsn_number . '</p>';
}
echo '</div>';
}
?>
<script>
jQuery(document).ready(function($) {
// Hide all
$( '.woo_cage_code_info_tab_content' ).css( 'display', 'none' );
// Change
$( 'input.variation_id' ).change( function() {
// Hide all
$( '.woo_cage_code_info_tab_content' ).css( 'display', 'none' );
if( $( 'input.variation_id' ).val() != '' ) {
var var_id = $( 'input.variation_id' ).val();
// Display current
$( '.woo_cage_code_info_tab_content-' + var_id ).css( 'display', 'block' );
}
});
});
</script>
<?php
}
}

woocommerce checkout custom fields update order meta

based on this https://stackoverflow.com/a/49163797/7783506 by #LoicTheAztec I was able to create the custom fields on flat rate shipping method, I could find the data on MySQL, but it was not showing on the order detail, email.
How do I add this to order details and email? here's the code that i use based on that post
// Add custom fields to a specific selected shipping method
add_action( 'woocommerce_after_shipping_rate', 'carrier_custom_fields', 20, 2 );
function carrier_custom_fields( $method, $index ) {
if( ! is_checkout()) return; // Only on checkout page
$customer_carrier_method = 'flat_rate:4';
if( $method->id != $customer_carrier_method ) return; // Only display for "local_pickup"
$chosen_method_id = WC()->session->chosen_shipping_methods[ $index ];
// If the chosen shipping method is 'legacy_local_pickup' we display
if($chosen_method_id == $customer_carrier_method ):
echo '<div class="custom-carrier">';
woocommerce_form_field( 'ds_name' , array(
'type' => 'text',
'class' => array('form-row-wide ds-name'),
'required' => true,
'placeholder' => 'Nama Toko',
), WC()->checkout->get_value( 'ds_name' ));
woocommerce_form_field( 'ds_number' , array(
'type' => 'text',
'class' => array('form-row-wide ds-number'),
'required' => true,
'placeholder' => 'Kode Booking',
), WC()->checkout->get_value( 'ds_number' ));
echo '</div>';
endif;
}
// Check custom fields validation
add_action('woocommerce_checkout_process', 'carrier_checkout_process');
function carrier_checkout_process() {
if( isset( $_POST['ds_name'] ) && empty( $_POST['ds_name'] ) )
wc_add_notice( ( "Anda belum memasukkan Nama Toko" ), "error" );
if( isset( $_POST['ds_number'] ) && empty( $_POST['ds_number'] ) )
wc_add_notice( ( "Anda belum memasukkan nomor kode booking" ), "error" );
}
// Save custom fields to order meta data
add_action( 'woocommerce_checkout_update_order_meta', 'carrier_update_order_meta', 30, 1 );
function carrier_update_order_meta( $order_id ) {
if( isset( $_POST['ds_name'] ))
update_post_meta( $order_id, '_ds_name', sanitize_text_field( $_POST['ds_name'] ) );
if( isset( $_POST['ds_number'] ))
update_post_meta( $order_id, '_ds_number', sanitize_text_field( $_POST['ds_number'] ) );
}
found the solution, removing _ (underscore) on update_post_meta then it show on order edit.
// Save custom fields to order meta data
add_action( 'woocommerce_checkout_update_order_meta', 'carrier_update_order_meta', 30, 1 );
function carrier_update_order_meta( $order_id ) {
if( isset( $_POST['ds_name'] ))
update_post_meta( $order_id, 'ds_name', sanitize_text_field( $_POST['ds_name'] ) );
if( isset( $_POST['ds_number'] ))
update_post_meta( $order_id, 'ds_number', sanitize_text_field( $_POST['ds_number'] ) );
}

Add extra filed in custom post type

This is my code
// Our custom post type function
function create_posttype_ticket() {
register_post_type( 'ticket',
array(
'labels' => array(
'name' => __( 'Ticket' ),
'singular_name' => __( 'Ticket' )
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'thumbnail', 'author'),
'rewrite' => array('slug' => 'ticket'),
)
);
}
// Hooking up our function to theme setup
add_action( 'init', 'create_posttype_ticket' );
I want add some more label/text box in custom post type
Movie : Release Date
Movie : Cast
any idea
Add the below code in function.php or in your plugin file.
This code will create some custom fields in your custom post type.
function movie_detail_meta_box(){
add_meta_box(
'movie_detail_box_id', // Unique ID
'Movie Details', // Box title
'render_movie_detail_meta_box_html',
'ticket', // Post type
'normal',
'low'
);
}
add_action('add_meta_boxes', 'movie_detail_meta_box');
function render_movie_detail_meta_box_html($post){
$meta = get_post_meta( $post->ID );
wp_nonce_field( 'movie_detail_metabox', 'movie_detail_metabox_nonce' );
$val_movie_name = ( isset( $meta['movie_name'][0] ) && '' !== $meta['movie_name'][0] ) ? $meta['movie_name'][0] : '';
$val_movie_release = ( isset( $meta['movie_release'][0] ) && '' !== $meta['movie_release'][0] ) ? $meta['movie_release'][0] : '';
$val_movie_cast = ( isset( $meta['movie_cast'][0] ) && '' !== $meta['movie_cast'][0] ) ? $meta['movie_cast'][0] : '';
// print_r("<p>val_autoplayTime-".$val_autoplayTime."<p/>");
echo "<div class='movie_meta_fields_container'>";
echo '<p><label for="movie_name"><b>Movie Name: </b></label><input type="text" name="movie_name" id="movie_name" style="width:100%;" value="'. esc_attr( $val_movie_name ) .'"></p>';
echo '<p><label for="movie_release"><b>Movie Release: </b></label><input type="text" name="movie_release" id="movie_release" style="width:100%;" value="'. esc_attr( $val_movie_release ) .'"></p>';
echo '<p><label for="movie_cast"><b>Movie Cast: </b></label><input type="text" name="movie_cast" id="movie_cast" style="width:100%;" value="'. esc_attr( $val_movie_cast ) .'"></p>';
echo "</div>";
}
function movie_detail_save_metadata($post_id){
// Check if our nonce is set.
if ( ! isset( $_POST['movie_detail_metabox_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['movie_detail_metabox_nonce'] ), 'movie_detail_metabox' ) ) { // Input var okay.
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
}
else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// OK, it's safe for us to save the data now.
// Make sure that it is set.
if ( !isset($_POST['movie_name']) || !isset($_POST['movie_release']) || !isset($_POST['movie_cast']) ) {
return;
}
$fields = ['movie_name','movie_release','movie_cast'];
foreach ($fields as $field) {
if (array_key_exists($field, $_POST)){
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
}
}
add_action('save_post', 'movie_detail_save_metadata');
Feel free to ask, if you got stuck anywhere.

Can not save multiple product variation fields

When I save the first product variation fields they are saved, but when I try to save the second, third, forth and further they do not get saved.
I am filling out the SKU for every product variation as well, so it should work. But obv it is something I am missing here? This is the latest WordPress and latest WooCommerce version.
//Display Fields
add_action( 'woocommerce_product_after_variable_attributes', 'variable_fields', 10, 3 );
//Save variation fields
add_action( 'woocommerce_save_product_variation', 'save_variable_fields', 10, 1 );
/**
* Create new fields for variations
*
*/
function variable_fields( $loop, $variation_data, $variation ) {
?>
<tr>
<td>
<?php
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_textarea['.$loop.']',
'label' => __( 'Contains', 'woocommerce' ),
'placeholder' => '',
'description' => __( '<br />Contains', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_textarea', true ),
)
);
?>
</td>
</tr>
<tr>
<td>
<?php
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_textarea_2['.$loop.']',
'label' => __( 'Observation message', 'woocommerce' ),
'placeholder' => '',
'description' => __( '<br />Observation message', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_textarea_2', true ),
)
);
?>
</td>
</tr>
<?php
}
/**
* Save new fields for variations
*
*/
function save_variable_fields( $post_id ) {
if (isset( $_POST['variable_sku'] ) ) :
$variable_sku = $_POST['variable_sku'];
$variable_post_id = $_POST['variable_post_id'];
// Textarea
$_textarea = $_POST['_textarea'];
for ( $i = 0; $i < sizeof( $variable_sku ); $i++ ) :
$variation_id = (int) $variable_post_id[$i];
if ( isset( $_textarea[$i] ) ) {
update_post_meta( $variation_id, '_textarea', stripslashes( $_textarea[$i] ) );
}
endfor;
// Textarea
$_textarea_2 = $_POST['_textarea_2'];
for ( $i = 0; $i < sizeof( $variable_sku ); $i++ ) :
$variation_id = (int) $variable_post_id[$i];
if ( isset( $_textarea_2[$i] ) ) {
update_post_meta( $variation_id, '_textarea_2', stripslashes( $_textarea_2[$i] ) );
}
endfor;
endif;
}
I've modified action & function for saving:
//Save variation fields
add_action( 'woocommerce_save_product_variation', 'save_variable_fields', 10, 2 );
/**
* Save new fields for variations
*
*/
function save_variable_fields( $variation_id, $i ) {
if ( empty( $variation_id ) ) return;
if ( isset( $_POST['_textarea'][$i] ) ) {
update_post_meta( $variation_id, '_textarea', stripslashes( $_POST['_textarea'][$i] ) );
}
if ( isset( $_POST['_textarea_2'][$i] ) ) {
update_post_meta( $variation_id, '_textarea_2', stripslashes( $_POST['_textarea_2'][$i] ) );
}
}

Resources