Sync Woocommerce billing field after order placement - woocommerce

i'd added a hook to sync usermeta with Wc_billing_field when user update his profile
this is the code that id used to and works
add_filter( 'profile_update' , 'custom_update_checkout_fields', 10, 2 );
function custom_update_checkout_fields($user_id, $old_user_data ) {
$current_user = wp_get_current_user();
if($current_user->user_firstname != $current_user->billing_first_name)
update_user_meta($user_id, 'billing_first_name', $current_user->user_firstname);
if($current_user->user_lastname != $current_user->billing_last_name)
update_user_meta($user_id, 'billing_last_name', $current_user->user_lastname);
if($current_user->user_email != $current_user->billing_email)
update_user_meta($user_id, 'billing_email', $current_user->user_email);
if($current_user->company != $current_user->billing_company)
update_user_meta($user_id, 'billing_company', $current_user->company);
if($current_user->telefono != $current_user->billing_phone)
update_user_meta($user_id, 'billing_phone', $current_user->telefono);
if($current_user->vat != $current_user->billing_piva)
update_user_meta($user_id, 'billing_piva', $current_user->vat);
if($current_user->sdi != $current_user->billing_code_sdi)
update_user_meta($user_id, 'billing_code_sdi', $current_user->sdi);
}
I need also to reverse update from checkout to usermeta but next code update only first_name and last_name, no other fields are updated, giv me page error.
action( 'woocommerce_thankyou', 'update_usermeta_from_billing_checkout' );
function update_usermeta_from_billing_checkout( $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
update_user_meta( $user_id, 'first_name', $order->get_billing_first_name() );
update_user_meta( $user_id, 'last_name', $order->get_billing_last_name() );
update_user_meta( $user_id, 'vat', $order->get_billing_piva() );
update_user_meta( $user_id, 'sdi', $order->get_billing_code_sdi() );
update_user_meta( $user_id, 'telefono', $order->get_billing_phone() );
}
someone can help ? thanks

Related

Why is the WordPress user meta key not being created / meta value being accessed?

I am try to create a user meta key (with value) but only if the current user does not already have the meta key.
Then I want to get the user meta value.
Here is my code. I'm sure I'm doing something very stupid but when I run the code, either the logged in user's meta is not created or it is not fetched, as the result of $userCredit is always blank.
What have I done wrong?
$user_id = wp_get_current_user();
$meta_key = "ai_anna_credit";
$meta_value = 150;
$userCredit = get_user_meta( $user_id, $meta_key);
if ( $userCredit == "") {
update_user_meta( $user_id, $meta_key, $meta_value );
$userCredit = get_user_meta( $user_id, $meta_key);
}
wp_get_current_user() Retrieves the current user object. So you need to access "ID" from the object.
$user_id = wp_get_current_user()->ID;
Another, $userCredit = get_user_meta( $user_id, $meta_key ); returns array by default. If you want to get a single value then you need to add a third parameter $userCredit = get_user_meta( $user_id, $meta_key, true ); as per the get_user_meta.
Now try if it works for you or not.
$user_id = wp_get_current_user()->ID;
$meta_key = 'ai_anna_credit';
$meta_value = 150;
$userCredit = get_user_meta( $user_id, $meta_key, true );
if ( $userCredit == '' ) {
update_user_meta( $user_id, $meta_key, $meta_value );
$userCredit = get_user_meta( $user_id, $meta_key );
}

Verifying Userprofile "Uniqueness" of Meta Value at the time of creation for wordpress user custom field meta-key "association_id"

I have a custom user profile field "association_id". I can see the field the underlying wordpess db table (usermeta) with the 'meta_key' as "association_id" and the 'meta_value' whatever that I maintain for each user.
add_action( 'show_user_profile', 'rudr_profile_fields' );
add_action( 'edit_user_profile', 'rudr_profile_fields' );
function rudr_profile_fields( $user )
{
// let's get custom field values
$association_id = get_user_meta( $user->ID, 'association_id', true );
?>
<h3>Association Information</h3>
<table class="form-table">
<tr>
<th><label for="association_id">Association_ID</label></th>
<td>
<input type="text" name="association_id" id="association_id" value="<?php echo esc_attr( $association_id ) ?>" class="regular-text" />
<span class="description"><?php _e("Please enter your Association ID (For eg. if RCIC, your license number)."); ?></span>
</td>
</tr>
</table>
<?php
}
//avoid self to edit //
//add_action( 'personal_options_update', 'rudr_save_profile_fields' ); //
add_action( 'edit_user_profile_update', 'rudr_save_profile_fields' );
function rudr_save_profile_fields( $user_id ) {
if( ! isset( $_POST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_POST[ '_wpnonce' ], 'update-user_' . $user_id ) ) {
return;
}
if( ! current_user_can( 'edit_user', $user_id ) ) {
return;
}
/* HOLDING SPACE FOR ENHANCED SNIPPED */
//include in the list view of users
add_filter( 'manage_users_columns', 'column_register_association_id' );
add_filter( 'manage_users_custom_column', 'column_display_association_id', 10, 3 );
function column_register_association_id( $columns )
{
$columns['association_id'] = 'association_id';
return $columns;
}
function column_display_association_id( $value, $column_name, $user_id )
{
$user_info = get_user_meta( $user_id, 'association_id', true );
if($column_name == 'association_id') return $user_info;
return $value;
}
//Sort association_id column
function association_id_register_sortable( $columns ) {
$columns['association_id'] = 'association_id';
return $columns;
}
add_filter( 'manage_users_sortable_columns', 'association_id_register_sortable' );
function association_id_orderby( $vars ) {
if ( isset( $vars['orderby'] ) && 'association_id' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'association_id',
'orderby' => 'meta_value'
) );
}
return $vars;
}
add_filter( 'request', 'association_id_orderby' );
The preceding works fine and creates a meta key for storing meta value in the metadata wp table.
I want this custom user profile field value that I enter in the user admin page to be unique, verifying with the underlying wordpress database table. So I enhanced the code at the time of creation with the additional lines below. I tried these two snippets in the wordpress child theme, but it throws a critical error. I am on PHP version 8.
I tried two options below at the placeholder location in the above code, replacing the line below.
/* HOLDING SPACE FOR ENHANCED SNIPPED */
Option 1 that I tried.
$checkMeta=$wpdb->get_results("SELECT user_id FROM $wpdb->usermeta WHERE meta_key='association_id' AND meta_value=".$association_id,ARRAY_A);
if (empty($checkMeta)) {
update_user_meta( $user_id, 'association_id', sanitize_text_field( $_POST[ 'association_id' ] ) );
}
Option 2 that I tried.
$mysqli = new mysqli(SERVER, DBUSER, DBPASS, DATABASE); $result = $mysqli->query("SELECT user_id FROM usermeta WHERE meta_key='association_id' && meta_value=$association_id "); if($result->num_rows == 0) { // row not found, do stuff update_user_meta( $user_id, 'association_id', sanitize_text_field( $_POST[ 'association_id' ] ) ); } else { // row found, do stuff echo ' This ID is already used.'; } $mysqli->close();
Both failed to activate when I tried to create or change the 'association_field' value, throwing critical errors and aborting.

Cancel all user orders on subscription cancelled/expired

I want to develop a setup/code in which all the orders made by the user gets cancelled when the his subscription gets cancelled or expired. I am using Wordpress, Woocommerce and Woocommerce Subscriptions plugin.
I am trying to do by using something like this:
function my_cancelled_subscription( $user_id, $subscription_key ) {
//what code should I use here????
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription', 10, 2 );
Please help mee.....
I figured it out..........
function my_cancelled_subscription( $subscription ) {
$order_id = $subscription->get_parent_id();
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
$order->update_status( 'cancelled' );
$args = array(
'customer_id' => $user_id,
'status' => 'wc-completed',
);
$arrorders = wc_get_orders( $args );
foreach ($arrorders as $ord) {
$ord->update_status( 'cancelled' );
}
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription' );

How to calculate Custom order total in WooCommerce edit order?

Currently, I'm working on a WooCommerce (5.2.2) project. My client wants to create a custom input field for Advance payment in the Backend (not for customers) so that when my client received an advance payment from the customer (delivery purpose) they can add manually and order total auto adjust from the backend. So I've wright a code and create a custom field in the post meta table and use that meta table value to calculate the total order, it works but I have to refresh twice to get Order's total new value. here is my code and tell me how to fix it -
add_action( 'manage_shop_order_posts_custom_column' , array(&$this,'add_custom_column_content'), 11, 2 );
add_action( 'woocommerce_admin_order_totals_after_discount', array(&$this, 'vp_add_sub_total'), 10, 1);
add_action( 'woocommerce_process_shop_order_meta', array(&$this, 'save_order_custom_field_meta_data'), 12, 2 );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('_advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advancePayment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
//Display Advance Payment and calculate
function vp_add_sub_total( $the_order ) {
global $post, $the_order;
if ( empty( $the_order ) || $the_order->get_id() !== $post->ID ) {
$the_order = wc_get_order( $post->ID );
}
?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
</tr>
<?php
$getTotal = $the_order->get_total();
$updateTotal = $getTotal - get_post_meta($post->ID, "_advance_payment", true);
$the_order->set_total($updateTotal);
$the_order->save();
}
Note : I create a small plugin for this advance payment.
Video link for reference : https://www.awesomescreenshot.com/video/3589010?key=b26b5951753bfdc8a969b53f526a36d1
You need to calculate Advance Payment before display. you can use woocommerce_admin_order_item_headers action hook.
add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('_advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advancePayment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
function calculate_advance_payment( $the_order ) {
$getTotal = $the_order->get_total();
$updateTotal = $getTotal - get_post_meta($the_order->get_id(), "_advance_payment", true);
$the_order->set_total($updateTotal);
$the_order->save();
}
function vp_add_sub_total( $the_order ) {
global $post, $the_order; ?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
</tr><?php
}
I was looking for this solution. Unfortunately the solution posted above gave this error "Unsupported operand types: string - string". I used var_dump($getTotal); var_dump( $advanced_payment); to analyze the data. Since it's adding+ 2 numbers that are in a string add (int) or (float) before variable $variable. float is used when numbers contain a decimal. Use (int) for integers that are whole numbers. Example: (int)$variable , (float)$variable. Here's an article which helped me. Here's the modified solution which gave no errors and updated the order total.
add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advanced_payment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advanced_payment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
//global $order;
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, 'advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
function calculate_advance_payment( $order ) {
$order_id = $order->get_id();
$getTotal = $order->get_total();
$advanced_payment = get_post_meta($order_id, 'advance_payment', true);
$order_total = (float)$getTotal - (float)$advanced_payment;
$order->set_total( $order_total );
$order->save();
}
function vp_add_sub_total( $order ) {
global $post, $order;
?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "advance_payment", true));?></td>
</tr><?php
}

Restrict access to admin menu pages in wordpress

I am trying to find a way to limit access to some admin menu pages to specific admins.
So far I have managed to hide the pages from all admins who are not the primary admin but if they enter the URL for that page,they will be directed to that page.
add_action( 'admin_init', 'my_remove_menu_pages');
function my_remove_menu_pages() {
global $user_ID;
if ( current_user_can( 'administrator' ) && $user_ID !== 1 ) {
remove_menu_page( 'admin.php?page=settings' );
remove_menu_page( 'plugins.php' );
//remove_menu_page( 'authorhreview' );
}
}
I have been doing a lot of reading but I can't seem to come up with a solution.
Any help would be awesome.Thanks in advance.
Do not pass a role name to current_user_can(), as this is not guaranteed to work correctly..
See : https://core.trac.wordpress.org/ticket/22624
function appthemes_check_user_role( $role, $user_id = null ) {
if ( is_numeric( $user_id ) )
$user = get_userdata( $user_id );
else
$user = wp_get_current_user();
if ( empty( $user ) )
return false;
return in_array( $role, (array) $user->roles );
}
//example use for the current user
if ( appthemes_check_user_role( 'customer' )
_e( "You've got access dude!", 'appthemes' );
else
_e( "Sorry man, no luck.", 'appthemes' );
//example use for a specific user
$user_id = 23;
if ( appthemes_check_user_role( 'customer', $user_id )
_e( "You've got access dude!", 'appthemes' );
else
_e( "Sorry man, no luck.", 'appthemes' );

Resources