Change dynamically store location - woocommerce

In order to have an accurate tax value by location during the checkout I would like to change dynamically my store location to the customer billing address. Is there a hook for that?
Thanks in advance

There are filters for store location that you can use to modify the output:
Base address first line: woocommerce_countries_base_address
Base address second line: woocommerce_countries_base_address_2
Base country: woocommerce_countries_base_country
Base state: woocommerce_countries_base_state
Base city: woocommerce_countries_base_city
Base postal code: woocommerce_countries_base_postcode
usage:
function custom_base_address( $base_address ){
//your custom code to change base_address first line
return $base_address
}
add_filter('woocommerce_countries_base_address', 'custom_base_address', 10, 1)
function custom_base_city( $base_address ){
//your custom code to change base state
return $base_address
}
add_filter('woocommerce_countries_base_state', 'custom_base_state', 10, 1)
And for customer billing address, you can get it from user meta. For example:
$address_1 = get_user_meta( $current_user->ID, 'billing_address_1', true );
$address_2 = get_user_meta( $current_user->ID, 'billing_address_2', true );
$city = get_user_meta( $current_user->ID, 'billing_city', true );
$postcode = get_user_meta( $current_user->ID, 'billing_postcode', true );
you can use these variables in a IF condition inside the custom_base_address function and get your desired custom base address

Related

how to change wordpress nickname settings default from username to name?

In wordpress in user edit page fields below exist :
username* : which must be unique
name
nickname* : which is by default made from username
List item
display name
I want to change that default to name
in this page the solution below was suggested which did not work for me
adding thses code at the end of function.php in my theme :
add_action( 'user_registration_after_register_user_action', 'ur_insert_nickname', 1, 3 );
function ur_insert_nickname( $valid_form_data, $form_id, $user_id ) {
$user_nickname = $valid_form_data['first_name']->value . ' ' . $valid_form_data['last_name']->value;
update_user_meta( $user_id, 'nickname', $user_nickname );
}
now does anyone has any suggestions?
Try this approach Tested in(admin backend)
add_action('user_register','my_function');
function my_function($user_id){
//do your stuff
$first_name = get_user_meta($user_id, 'first_name', true);
$last_name = get_user_meta($user_id, 'last_name', true);
$user_nickname = $first_name.' '.$last_name;
update_user_meta( $user_id, 'nickname', $user_nickname );
}

Update ACF select field data programmatically

I have a ACF select field with a field name of "sales_rep". It is populated with:
John Doe
Bart Simpson
Eric Cartman
The field is set to show on the "User Form" and only show when the "Current User Role" is an admin.
The field shows on each user page and I can manually change it to the sales rep I want and save it.
The issue is that I want to be able to programmatically update it whenever the user profile is saved. I will eventually add more code to determine the sales rep but I simplified the issue for this post.
Below is my code in functions.php:
Attempt 1: No error and no change to value
// Update sales rep
add_action( 'edit_user_profile_update', 'update_rep' );
add_action( 'personal_options_update', 'update_rep' );
function update_rep( $user_id )
{
update_user_meta( $user_id, 'sales_rep', 'Eric Cartman' );
}
Attempt 2: No error and no change to value
// Update sales rep
add_action( 'edit_user_profile_update', 'update_rep' );
add_action( 'personal_options_update', 'update_rep' );
function update_rep( $user_id )
{
$field_key = "sales_rep";
$value = array("Eric Cartman");
update_field( $field_key, $value, $user_id );
}
Seems like user_ prefix could fix the issue.
Try to get/update fields with user_ prefix.
F.e:
update_field( $field_key, $value, "user_$user_id" );
And for update_user_meta,
Calling delete_user_meta before could solve the problem.
User meta could have duplicate keys.
Try this one
delete_user_meta( $user_id, $field_key );
add_user_meta( $user_id, $field_key, $value );
I think #Andrii Kovalenko is right, user_ prefix could be your issue.
Also noticed you are saving acf field data as an array("Eric Cartman").
I am assuming your ACF select field predefined select options look like this...
John Doe
Bart Simpson
Eric Cartman
This should work for your acf option...
// is run when you edit YOUR profile, and save it
add_action('personal_options_update', 'handle_user_profile_update' );
// is run when you edit ANY OTHER profile and save it
add_action('edit_user_profile_update', 'handle_user_profile_update' );
// on user profile update function handler
function handle_user_profile_update($user_id) {
// update sales rep
update_sales_rep_field($user_id);
// add anymore on user update profile functions here...
}
// update sales rep field
function update_sales_rep_field($user_id) {
// our values
$value = 'Eric Cartman';
// update acf user field by user id
update_field('sales_rep', $value, 'user_' . $user_id);
}
Out of curiosity, are these sales reps actually users in your wordpress site?
If so you can dynamically populate the select sales_rep user field with sales rep users on your site like this...
function render_sales_rep_select_field($field) {
// reset sales_rep select field choices
$field['choices'] = [];
// get users with user role sales
$args = array(
'role' => 'sales', // your sales reps user role
'orderby' => 'user_nicename',
'order' => 'ASC'
);
// get user with args from above
$users = get_users( $args );
// for each sales rep user
foreach ( $users as $user ) {
// build our sales rep select field choices by user_id > full name
$field['choices'][$user->id] = $user->first_name . ' ' . $user->last_name
}
// return the select field
return $field;
}
// load user field with our custom select drop of sales rep users
add_filter('acf/load_field/name=sales_rep', 'render_sales_rep_select_field');
With this method you won't need to update the field when the user saves changes to their profile.
For example if you get_field like this...
// get user field sales rep array
get_field('sales_rep', 'user_' . $user_id ); // random user id
it will return an array of user_id and full name...
Array
(
[5] => Eric Cartman
)
In your acf user select field settings you will need select return both value and label.

Display Customer Billing Address and Billing City Instead of "Shipping" Label on WooCommerce Checkout

By using the woocommerce_shipping_package_name filter, I am looking to modify the label text to include, if the customer is logged in, the billing address and the billing city.
This is an example of the end result:
To be delivered to:
Main Street 1
New York
(without the extra rows in between)
I thought I had everything in place, but I'm getting an error.
Object of class WP_User could not be converted to int
I understand that a customer can register and then add a product to their cart and then go to checkout and if so -- there would be no billing address nor billing city. So, I really need to check if the meta is empty or not as well before proceeding to display the text (the expected output above).
Granted, I'm new at this and so.. asking for some help here.
My code so far:
add_filter( 'woocommerce_shipping_package_name', 'customer_address_city_with_shipping' );
function customer_address_city_with_shipping( $name ) {
// only for logged in customers
if (is_user_logged_in()){
// get the current customer
$user_id = wp_get_current_user();
// make sure it's a valid customer ID
if ($user_id == 0) return;
// customer billing address and city, how to check if it's empty or not?
$customer_address = get_user_meta( $user_id, 'shipping_address_1', true );
$customer_city = get_user_meta( $user_id, 'shipping_city', true );
// if logged in and if there's a billing address and billing city, let's go!
return 'To be delivered to:<br /><span style="font-weight:normal!important;">'.$customer_address.'<br />'.$customer_city.'';
} else {
// if not.. then don't
return 'Shipping & Delivery';
}
}
Thee are some mistakes in your code. try the following instead:
add_filter( 'woocommerce_shipping_package_name', 'customer_address_city_with_shipping' );
function customer_address_city_with_shipping( $name ) {
// only for logged in customers
if ( is_user_logged_in() && $user_id = get_current_user_id() ) {
// Get customer shipping address and city
$address = get_user_meta( $user_id, 'shipping_address_1', true );
$city = get_user_meta( $user_id, 'shipping_city', true );
if( !empty($address) && !empty($city) ) {
// Shipping address and city are not empty
return __('To be delivered to:') . '<br /><span style="font-weight:normal !important;">'
. $address . '<br />' . $city . '</span>';
} else {
// Shipping address and city are not defined
return 'Shipping & Delivery';
}
} else {
// User is not logged in
return 'Shipping & Delivery';
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.

Redirect user based on custom metadata, wordpress/woocommerce

I have added some custom metadata to wordpress per user and would like to redirect each user after login based on this custom metadata.
For instance i have a page called foo and another called bar. User one has a custom key (acCustomerName) in the metadata stating foo. And the other user has bar in his.
Depending on whats inside that field I would like to redirect the first user to http://example.tld/foo and the other to http://example.tld/bar.
I am able to retrieve this information perfectly fine and echo it out directly to test the function but are not able to retrieve that information inside the sencond function named forward_user and would like to know why.
Right now the user is redirected only to http://example.tld only. So it seems like the function does not get the $kundtyp string.
function kundtyp($Uuser) {
$key = 'acCustomerName';
$single = true;
return get_user_meta( $Uuser, $key, $single );
}
function forward_user( $redirect, $user ) {
$kundtyp = kundtyp($user);
$redirect_page_id = url_to_postid( $redirect );
$checkout_page_id = wc_get_page_id( 'checkout' );
if( $redirect_page_id == $checkout_page_id ) {
return $redirect;
}
return site_url( kundtyp( get_current_user_id() ) );
}
add_filter( 'woocommerce_login_redirect', 'forward_user', 1100, 2 );
Here is the updated code, you have to pass the ID of the user object to get_user_meta data function. You were passing the WP_User object to your function. I don't think you can use function get_current_user_id() because the global wp_user object has not been set yet. I checked it and it always returns 0 as the value. This would explain why they provide the $user variable in the filter.
function kundtyp($Uuser) {
$key = 'acCustomerName';
$single = true;
return get_user_meta( $Uuser->ID, $key, $single );
}
function forward_user( $redirect, $user ) {
$kundtyp = kundtyp($user);
$redirect_page_id = url_to_postid( $redirect );
$checkout_page_id = wc_get_page_id( 'checkout' );
if( $redirect_page_id == $checkout_page_id ) {
return $redirect;
}
return site_url( kundtyp( $user ) );
}
add_filter( 'woocommerce_login_redirect', 'forward_user', 1100, 2 );

Geocoding custom user meta in WordPress

I'm using User Front End Pro to provide a front end registration form. One line of that is for an address, and I want to use that to display a map of all users with Geo Mashup.
I have a custom field that saves to user meta called geocode_address, I need to then geocode it and output it to two separate fields Latitude and Longitude. I found this for geocoding custom post data, and have tried to amend it for user meta, but it is not working, and causes the registration to hang. What have I done wrong?
function geocode_address($user_id)
{
$custom_fields = get_user_meta();
if(isset($custom_fields["geocode_address"]) && !empty($custom_fields["geocode_address"][0]))
{
$resp = wp_remote_get( "http://maps.googleapis.com/maps/api/geocode/json?address=".urlencode($custom_fields["geocode_address"][0])."&sensor=false" );
if ( 200 == $resp['response']['code'] ) {
$body = $resp['body'];
$data = json_decode($body);
if($data->status=="OK"){
$latitude = $data->results[0]->geometry->location->lat;
$longitude = $data->results[0]->geometry->location->lng;
update_user_meta($user_id, "latitude", $latitude);
update_user_meta($user_id, "longitude", $longitude);
}
}
}
}
add_action('update_user_meta', 'geocode_address');
As a side note, Geomashup has a function to geocode a custom field, but when I enter "geocode address" it doesn't seem to work...
The action update_user_meta takes more arguments and the first one is not the User ID:
add_action('update_user_meta', 'geocode_address', 10, 4 );
function geocode_address( $meta_id, $user_id, $meta_key, $meta_value )
{
if( 'geocode_address' == $meta_key )
{
var_dump( $meta_value );
die();
}
}
Then, you're using get_user_meta() wrong, we need to pass at least the User ID: get_user_meta($user_id, $key = '', $single = false);. But I suspect it's not needed in your case.
As for the Geocode API, it returned a correct response when I tested with a random spanish address:
$address = "gran via, madrid";
$resp = wp_remote_get( "http://maps.googleapis.com/maps/api/geocode/json?address=".urlencode($address)."&sensor=false" );

Resources