Hide billing fields Woocommerce for existing clients - php

I am trying to hide all checkout-fields for WP Woocommerce on the checkout page for clients who are logged in (so their info is already stored from previous orders). I am using this code, but I get errors for missing fields on pressing the checkout/finalize button.
/*remove billing fields for logged in users*/
add_filter( 'woocommerce_checkout_fields' , 'hide_billing_detail_checkout' );
function hide_billing_detail_checkout( $fields ) {
if( is_user_logged_in() ){
unset($fields['billing']);
$fields['billing'] = array();
}
return $fields;
}
I see the unset code is probably emptying everything. I would like all fields to be just hidden visually for logged in users. Any ideas?

After some testing I managed to get it done myself. For whoever needs it:
add_action( 'wp_head', 'include_styles' );
function include_styles() {
if ( is_checkout() ) {
if( is_user_logged_in() ){
echo '
<style>
.woocommerce-billing-fields {
display: none;
}
</style>
';
}
}
}

Related

WooCommerce custom create account checkbox on checkout

We just moved and merged the WooCommerce account password field on the checkout page from the "Account" group to the "Billing" field group. This works nicely. Also, we create a new checkbox field and add this to the billing section. Without that, the "Create an account" checkbox will still be at the default position. To do so, we created a new checkbox with jQuery.
Thanks to the following articles:
How to move the create account checkbox on Woocommerce checkout page
Reordering checkout fields in WooCommerce 3
With our current code, the moved password field is always visible. We want to have it the same way as WooCommerce default works. This means the password field should only be visible when the checkbox is active. WooCommerce by default has an excellent hide & Show CSS in place. However, I'm not able to use the identical CSS (or maybe script?!).
How can we connect the custom checkbox with the account password field?
// Move Account password field into billing section
function move_password_field($checkout_fields){
// Move Account Password into Billing
$checkout_fields['billing']['account_password'] = $checkout_fields['account']['account_password'];
// Remove Password from Billing
unset($checkout_fields['account']['account_password']);
return $checkout_fields;
}
add_filter('woocommerce_checkout_fields', 'move_password_field', 999);
// CSS rules
add_action( 'woocommerce_before_checkout_billing_form', 'move_checkout_create_an_account_css' );
function move_checkout_create_an_account_css() {
if( ! is_user_logged_in() ) :
?><style>
.woocommerce-account-fields label.woocommerce-form__label-for-checkbox {display: none !important;}
#account_cb_field {margin-top: 32px;}
#account_cb_field input {margin-right: 6px;}
</style>
<?php
endif;
}
// Add a checkbox to billing section
add_filter( 'woocommerce_checkout_fields', 'move_checkout_create_an_account_checkbox' );
function move_checkout_create_an_account_checkbox( $fields ) {
if( ! is_user_logged_in() ) {
// Make email field on half on left side
$fields['billing']['billing_email']['class'] = array('form-row-wide');
// Custom checkbox on half right side
$fields['billing']['account_cb'] = array(
'type' => 'checkbox',
'label' => __("Create an account?", "woocommerce"),
'class' => array('form-row-wide'),
);
}
return $fields;
}
// remove "(optional)" from the new checkbox
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
// Only on checkout page
if ( is_checkout() && ! is_wc_endpoint_url() && $key === 'account_cb' ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
// The jQuery code
add_action( 'wp_footer', 'move_checkout_create_an_account_js' );
function move_checkout_create_an_account_js() {
if ( ! is_user_logged_in() && is_checkout() && ! is_wc_endpoint_url() ) :
?><script>
(function($){
$('input[name=account_cb]').on( 'click', function() {
$('input[name=createaccount]').trigger('click');
});
})(jQuery);
</script>
<?php
endif;
}

Make "Ship to different address" mandatory if specific products are in WooCommerce cart [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm trying to add a snipped to activate the "Ship to other address" open by default, when a specific product is in the checkout.
I found Enable 'Ship to a different address' check box for specific products in Woocommerce related answer thread which is working perfectly!
However, it should not be possible to unselect the check box "Ship to other address". If a specific product is in the checkout, then providing a different shipping address is required.
Goal: Gray-out the "Ship to other address" checkbox for those specific products.
I just changed in the code $products_ids = array(10800, 11907); to feet my needs.
I already tried to unhook the function but then the whole code does not work. So I'm searching the best way to gray-out that checkbox but keep the code above fully working.
If I have understood, you want to keep your code functionality, disabling the checkbox.
The best thing is to hide the checkbox first. Then to avoid the shipping address to be shown or hidden by clicking on the checkbox label, jQuery will remove it when it is checked.
The php code (and inline CSS):
// Hide the checkbox (inline CSS) - Only on checkout page
add_filter( 'wp_head', 'shipping_address_checkbox_ccs' );
function shipping_address_checkbox_ccs() {
if( is_checkout() && ! is_wc_endpoint_url() ) {
?><style>body.checkout-hide-checkbox #ship-to-different-address-checkbox { display:none; } body.checkout-hide-checkbox #ship-to-different-address label { cursor: default; }</style><?php
}
}
// Conditional function
function mandatory_shipping_address(){
$products_ids = array(10800, 11907);
$found = $others_found = false;
foreach ( WC()->cart->get_cart() as $cart_item ){
if ( in_array( $cart_item['data']->get_id(), $products_ids ) ){
$found = true;
} else {
$others_found = true;
}
}
return $found && ! $others_found ? true : false;
}
// Conditionally Enable checkbox (checked)
add_filter( 'woocommerce_ship_to_different_address_checked', 'filter_cart_needs_shipping_address');
function filter_cart_needs_shipping_address( $checked ) {
return mandatory_shipping_address() ? true : $checked;
}
// Conditionally Add a body class - Only on checkout page
add_filter( 'body_class', 'shipping_address_checkbox_body_class' );
function shipping_address_checkbox_body_class( $classes ) {
if( is_checkout() && ! is_wc_endpoint_url() && mandatory_shipping_address() ) {
$classes[] = 'checkout-hide-checkbox';
}
return $classes;
}
The jQuery code:
// Remove the checkbox when is checked - Only on checkout page
add_action( 'template_redirect', 'cart_needs_shipping_address_js');
function cart_needs_shipping_address_js() {
if( is_checkout() && ! is_wc_endpoint_url() ) :
wc_enqueue_js( "jQuery( function($){
var a = '#ship-to-different-address-checkbox';
if( $(a).is(':checked') ) {
$(a).remove(); // Remove checkbox
}
});");
endif;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
So when checkbox is checked you will get (for your defined products):
You could add a custom class to the checkout body tag when there are products in the cart.
So with a CSS rule you can hide the "Ship to a different address?" checkbox.
Using this answer:
Enable 'Ship to a different address' check box for specific products in Woocommerce
You can take the code and create a new custom function (returns the same result as before, the function has not been modified except the product ids):
function check_if_product_is_in_cart() {
$products_ids = array( 10800, 11907 );
$found = $others_found = false;
foreach ( WC()->cart->get_cart() as $cart_item ){
if (in_array( $cart_item['data']->get_id(), $products_ids ) ){
$found = true;
} else {
$others_found = true;
}
}
if ( $found && ! $others_found ) {
return true;
} else {
return false;
}
}
Then you can enable or disable the checkbox based on the result of the function:
add_filter( 'woocommerce_ship_to_different_address_checked', 'filter_cart_needs_shipping_address');
function filter_cart_needs_shipping_address( $checked ) {
return check_if_product_is_in_cart();
}
Finally you can use the same function to add the custom class to the checkout body tag:
add_filter( 'body_class', 'add_body_class' );
function add_body_class( $classes ) {
if ( ! is_checkout() ) {
return $classes;
}
if ( check_if_product_is_in_cart() ) {
$classes[] = 'hide_ship_to_different_address_checkbox';
}
return $classes;
}
At this point you just have to add the CSS rules in the style sheet of your active theme:
Make WooCommerce checkout shipping fields visible and remove "Ship to different address?" checkbox
The code has been tested and works. Add it to your active theme's functions.php.

Redirection for non checkout guest allowed in WooCommerce

After Allow guest checkout for specific products only in WooCommerce answer to my previous question, the following code redirect users to login page:
add_action( 'template_redirect', 'checkout_redirect_non_logged_to_login_access');
function checkout_redirect_non_logged_to_login_access() {
if( is_checkout() && !is_user_logged_in()){
wp_redirect( get_permalink( get_option('woocommerce_myaccount_page_id') ) );
exit;
}
}
But I have some products which allows guest checkout (see the linked question/answer above). So how could I fix my code for the products which allows guest checkout to disable that code redirection?
You can replace my previous answer code with the following:
// Custom conditional function that checks if checkout registration is required
function is_checkout_registration_required() {
if ( ! WC()->cart->is_empty() ) {
// Loop through cart items
foreach ( WC()->cart->get_cart() as $item ) {
// Check if there is any item in cart that has not the option "Guest checkout allowed"
if ( get_post_meta( $item['product_id'], '_allow_guest_checkout', true ) !== 'yes' ) {
return true; // Found: Force checkout user registration and exit
}
}
}
return false;
}
add_filter( 'woocommerce_checkout_registration_required', 'change_tax_class_user_role', 900 );
function change_tax_class_user_role( $registration_required ) {
return is_checkout_registration_required();
}
Then your current question code will be instead:
add_action( 'template_redirect', 'checkout_redirect_non_logged_to_login_access');
function checkout_redirect_non_logged_to_login_access() {
if( is_checkout() && !is_user_logged_in() && is_checkout_registration_required() ){
wp_redirect( get_permalink( get_option('woocommerce_myaccount_page_id') ) );
exit;
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.

How do I add CSS only for certain user roles?

On all posts, I'm trying to hide the Update button, which is contained within this box:
<div id="postbox-container-1" class="postbox-container">
I only want to hide this box and button for a certain user role, 'Bookings Viewer', which I have created. Here is my code so far:
//Hides the update button for the Booking Viewer user role
add_action( 'wp', 'hide_update_booking_viewer' );
function hide_update_booking_viewer()
{
$user = wp_get_current_user();
if ( in_array( 'Bookings Viewer', (array) $user->roles ) ) { ?>
<style type="text/css" media="screen">
#postbox-container-1 {display:none;}
</style><?
}
}
Currently the code, which I've placed into functions.php, seems to have no effect. What am I doing wrong?
Try with a different hook:
function hide_update_booking_viewer() {
$user = wp_get_current_user();
if ( in_array( 'Bookings Viewer', (array) $user->roles ) ) {
'<style>
#postbox-container-1 {display:none !important;}
</style>'
} }
add_action( 'wp_head', 'hide_update_booking_viewer' );
This should output the styles into the head section of your webpage for the user "Bookings Viewer" if you registered the user role correctly.
But, as suggested in this post, it is better to rely on capabilities of the user rather than on it's name.
Example:
function hide_update_booking_viewer_1() {
if ( current_user_can( 'read' ) ) {
'<style>
#postbox-container-1 {display:none !important;}
</style>'
} }
add_action( 'wp_head', 'hide_update_booking_viewer_1' );
A list of capabilities and role types can be found here.
I've managed to work out the answer for myself - I was adding the action to the wrong hook. wp_head is for the 'front-end' website, so we need to use 'admin_head'. I also echoed out the CSS. Finally, '#publishing-action' refers to the Update button, which is what I was trying to hide specifically.
//Hides the update button for the Booking Viewer user role
function hide_update_booking_viewer()
{
$user = wp_get_current_user();
if ( in_array( 'bookings_viewer', (array) $user->roles ) ) {
echo('<style type="text/css" media="screen">
#publishing-action {display:none; !important}
</style>');
}
}
add_action( 'admin_head', 'hide_update_booking_viewer' );

Woocommerce hide payment gateway for user roles

Hey guys I have a cash on delivery payment method on my wordpress/woocomerce website that I want to hide from the customer user role and non-logged in users.
I've been searching up and down and the only thing I found close was this bit of code.
function paypal_disable_manager( $available_gateways )
{global $woocommerce;
if ( isset( $available_gateways['paypal'] ) && current_user_can('customer') ) {
unset( $available_gateways['paypal'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways','paypal_disable_manager' );
Would someone be able to help me modify this code to make it work for my use. Thank you in advance!
Have mention the code which is tried and tested for you. It works well. Lemme know if the same works for you too.
function wdm_disable_cod( $available_gateways ) {
//check whether the avaiable payment gateways have Cash on delivery and user is not logged in or he is a user with role customer
if ( isset($available_gateways['cod']) && (current_user_can('customer') || ! is_user_logged_in()) ) {
//remove the cash on delivery payment gateway from the available gateways.
unset($available_gateways['cod']);
}
return $available_gateways;
}
add_filter('woocommerce_available_payment_gateways', 'wdm_disable_cod', 99, 1);
<?php
//--- Filter for remove any payment gateway as per the user role selected --
add_filter('woocommerce_available_payment_gateways','filter_gateways',1);
function filter_gateways($gateways){
global $woocommerce, $current_user;
if ( is_user_logged_in() ) {
$userRole = implode(',',$current_user->roles);
if($userRole == 'my_user_role'){
//-- Remove casho on delivery if following user have logged in
unset($gateways['cod']);
}
}else{
//-- Hide COD if user not logged in
unset($gateways['cod']);
}
return $gateways;
}
?>
//-- Try this one, I have already make use of this code against minimum order limit

Categories