WooCommerce: Pre-select and restrict to one state and city on checkout - php

I'm setting up a store that only sells to one city. I'm trying to figure out how I can restrict the city option to a pre-filled field.
I've already limited the country and using the following code in my functions.php:
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'PK'; // country code
}
function change_default_checkout_state() {
return 'SD'; // state code
}
And I've pre-selected the state using the following:
add_filter( 'woocommerce_states', 'bbloomer_custom_woocommerce_states' );
function bbloomer_custom_woocommerce_states( $states ) {
$states['PK'] = array(
'SD' => 'Sindh',
);
return $states;
}
But... Now comes the city and I am lost. I've tried using $fields['billing']['billing_city'] as well as $fields['billing']['billing_city']['value'] to no avail.
I want the customer to be limited to Karachi. I am not very familiar with WooCommerce filters, so I need help on achieving this.

Since woocommerce 3, default_checkout_country and default_checkout_state filter hooks are now deprecated and replaced.
Also in your last function, if you want to restrict just to one city, you should not include your city in the array of states. Instead you should return only one possible value.
So this will be your code:
// default checkout country
add_filter( 'default_checkout_billing_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_shipping_country', 'change_default_checkout_country' );
function change_default_checkout_country() {
return 'PK'; // country code
}
// default checkout state
add_filter( 'default_checkout_billing_state', 'change_default_checkout_state' );
add_filter( 'default_checkout_shipping_state', 'change_default_checkout_state' );
function change_default_checkout_state() {
return 'SD'; // state code
}
// Setting one state only
add_filter( 'woocommerce_states', 'custom_woocommerce_state', 10, 1 );
function custom_woocommerce_state( $states ) {
// Returning a unique state
return array('PK' => array('SD' => 'Sindh'));
}
// Only one city at checkout
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields', 10, 1 );
function custom_checkout_fields( $fields ) {
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = array('Karachi' => 'Karachi');
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = array('Karachi' => 'Karachi');
return $fields;
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for wooCommerce versions 3+
Once added the code above and saved, you will need in WooCommerce > Settings > General to set locations this way:
Then you will get something like this on checkout:
Both dropdown have only one value… So you get what you are expecting.

Related

Keep state field as a dropdown when one allowed country on Woocommerce

I thought this would be easy but I'm not getting the results I want. Basically I have 2 countries in woocommerce CA and US. I'm trying to remove one conditionally, and I can do that with the following code below. However, when I go from 2 countries to 1, the dropdown menu still appears. An odd thing I'm noticing with the below code as well, is that if I go into my Woocommerce settings, then the country that is removed with this code is also removed from the "Sell to specific countries" options.... not sure what's going on. Thanks in advance.
add_filter( 'woocommerce_countries', 'custom_woocommerce_countries_limit');
function custom_woocommerce_countries_limit( $countries ) {
/*
will place a conditional here if x then remove country
*/
unset($countries['CA']);
$countries = array(
'US' => __( 'United States', 'woocommerce' )
);
return $countries;
}
EDIT: Using this hook may be close to the answer, but when I use this one, The states don't turn into a dropdown...?
add_filter( 'woocommerce_countries_allowed_countries', 'custom_woocommerce_countries_limit');
You can use woocommerce_countries_allowed_countries filter hook, but you should need some additional code to force the state fields to be a state dropdown (select field):
add_filter( 'woocommerce_countries_allowed_countries', 'filter_allowed_countries_conditionally');
function filter_allowed_countries_conditionally( $countries ) {
// will place a conditional here if x then remove country
if( true ) {
$countries = array( 'US' => __( 'United States', 'woocommerce' ) );
} else {
$countries = array( 'CA' => __( 'Canada', 'woocommerce' ) );
}
return $countries;
}
// Force billing state field type to be a dropdown
add_filter( 'woocommerce_billing_fields', 'filter_billing_state_fields', 100, 1 );
function filter_billing_state_fields( $fields ) {
$fields['billing_state']['type'] = 'state';
return $fields;
}
// Force shipping state field type to be a dropdown
add_filter( 'woocommerce_shipping_fields', 'filter_shipping_state_fields', 100, 1 );
function filter_shipping_state_fields( $fields ) {
$fields['shipping_state']['type'] = 'state';
return $fields;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Remove postcode from Woocommerce cart shipping calculator

In Woocommerce, I have been able to remove postcode checkout field using this code:
add_filter( 'woocommerce_default_address_fields', 'custom_override_default_address_fields' );
function custom_override_default_address_fields( $address_fields ) {
unset($address_fields['postcode']);
return $address_fields;
}
How can I remove the postcode field from the shipping calculator in cart page?
This can be done adding the following:
add_filter( 'woocommerce_shipping_calculator_enable_postcode', '__return_false' );
Code goes in function.php file of your active child theme (or active theme). tested and works.
add_filter( 'woocommerce_default_address_fields', 'custom_override_address_fields', 999, 1 );
function custom_override_address_fields( $address_fields ) {
// set as not required
$address_fields['postcode']['required'] = false;
// remove validation
unset( $address_fields['postcode']['validate'] );
return $address_fields;
}
(this is the real code that devalidates the postcode)

Add value to custom column on customer's orders page in woocommerce

I was trying to add new column to the orders page of the customer's recent orders table, the new column should show the details of the product like product name & description.
Tried different solution, was fortunate to add column name but not able to add the value to the column.
Here is my code:
add_filter( 'woocommerce_account_orders_columns', 'new_orders_columns' );
function new_orders_columns( $columns = array() ) {
// Hide the columns
if( isset($columns['order-total']) ) {
unset( $columns['order-status'] );
unset( $columns['order-total'] );
unset( $columns['order-actions'] );
}
// Add new columns
//this is my custom column order details
$columns['order-detail'] = __( 'Details', 'woocommerce' );
$columns['order-status'] = __( 'Status', 'woocommerce' );
$columns['order-total'] = __( 'Total', 'woocommerce' );
$columns['order-actions'] = __( ' ');
return $columns;
}
Screenshot of the result:
You are very near…
1) Insert a new column in a specific location (another way):
add_filter( 'woocommerce_account_orders_columns', 'add_custom_account_orders_column', 10, 1 );
function add_custom_account_orders_column( $columns ) {
$ordered_columns = array();
// Inserting a new column in a specific location
$ordered_columns['order-number'] = $columns['order-number'];
$ordered_columns['order-date'] = $columns['order-date'];
$ordered_columns['order-details'] = __( 'Details', 'woocommerce' ); // <== New column
$ordered_columns['order-status'] = $columns['order-status'];
$ordered_columns['order-total'] = $columns['order-total'];
$ordered_columns['order-actions'] = $columns['order-actions'];
return $ordered_columns;
}
Code goes in function.php file of your active child theme (or active theme).
tested and works.
2) Display data in this new column (editing myaccount/orders.php template):
You will need to override through your active child theme, the myaccount/orders.php WooCommerce template.
At line 56 (just after 'order-number' code) you will insert the following and you will be able to add some specific content:
<?php elseif ( 'order-details' === $column_id ) : ?>
<?php
// HERE GOES YOUR CUSTOM CODE (DISPLAYED CONTENT)
?>
You can use the available WC_Order object $order…
How to get WooCommerce order details
Accepted answer is only partially correct. Adding the column via filter is fine, but populating the column is better done via a action hook. This is clean and matches best with column being added via filter. While editing the orders.php page via child theme works, it will lead to future effort to maintain after updates to woocommerce change this page making child theme version out of date.
To add your content to the column create an action hook along side the filter in functions.php. (or better yet in a plugin!)
add_action( 'woocommerce_my_account_my_orders_column_order-detail' , 'your_function_name2',10,1 );
//'woocommerce_my_account_my_orders_column_<column_id>'
function your_function_name2( $order ) {
// do stuff, ex: get_post_meta( $post->ID, 'key', true );
}
add_filter( 'woocommerce_account_orders_columns', 'new_orders_columns',10,1 );
function new_orders_columns( $columns) {
// Add new column. Kept simple to play nice with other filters.
$columns['order-detail'] = __( 'Details', 'woocommerce' );
return $columns;
}
see this similar question, best answer by Misha
Try to use this code
<?php
// ------------------
// 1. Register new endpoint to use for My Account page
// Note: Resave Permalinks or it will give 404 error
function bbloomer_add_premium_support_endpoint() {
add_rewrite_endpoint( 'premium-support', EP_ROOT | EP_PAGES );
}
add_action( 'init', 'bbloomer_add_premium_support_endpoint' );
// ------------------
// 2. Add new query var
function bbloomer_premium_support_query_vars( $vars ) {
$vars[] = 'premium-support';
return $vars;
}
add_filter( 'query_vars', 'bbloomer_premium_support_query_vars', 0 );
// ------------------
// 3. Insert the new endpoint into the My Account menu
function bbloomer_add_premium_support_link_my_account( $items ) {
$items['premium-support'] = 'Premium Support';
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'bbloomer_add_premium_support_link_my_account' );
// ------------------
// 4. Add content to the new endpoint
function bbloomer_premium_support_content() {
echo '<h3>Premium WooCommerce Support</h3><p>Welcome to the WooCommerce support area. As a premium customer, you can submit a ticket should you have any WooCommerce issues with your website, snippets or customization. <i>Please contact your theme/plugin developer for theme/plugin-related support.</i></p>';
echo do_shortcode( ' /* your shortcode here */ ' );
}
add_action( 'woocommerce_account_premium-support_endpoint', 'bbloomer_premium_support_content' );

Woocommerce remove asterisk from required fields on checkout page

Is there a way to remove the required asterisk from a billing field on the checkout page in php? I have the following code which isn't working.
add_filter( 'woocommerce_checkout_fields' , 'customize_fields' );
function customize_fields( $fields ) {
$fields['billing']['billing_address_2']['required'] = false;
return $fields;
}
It would probably be easier to do with CSS, and be cleaner and better for screen-readers:
.woocommerce-checkout abbr.required {
display: none;
}
The .woocommerce-checkout is a body class that is only appended to the checkout page so it won't affect any other woo page that might have the .required class in an abbr element.
To make the field not required with a function:
// Hook in
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
// Our hooked in function - $address_fields is passed via the filter!
function custom_override_default_address_fields( $address_fields ) {
$address_fields['address_2']['required'] = false;
return $address_fields;
}
There are two filters to manage checkout fields. You can use woocommerce_checkout_fields filter to make field "not-required", but the red asterisk will not be removed.
When dealing with default address fields with woocommerce_checkout_fields filter, some of your changes will not take effect, because woocommerce_default_address_fields filter and its default values may override your changes.
Only partly functional code:
function custom_override_checkout_fields( $fields ) {
$fields['billing']['billing_address_1']['required'] = false ;
return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
Address field (#1) is not required anymore, but still has red asterisk.
Fully functional code:
function custom_override_default_address_fields( $address_fields ) {
$address_fields['address_1'][ 'required' ] = false;
return $address_fields;
}
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
Now this field is not required, and red asterisk is gone.
Documentation says that "In some specific cases you will need to use the woocommerce_default_address_fields filter. This filter is applied to all billing and shipping default fields."
You have to add the following code to your functions.php file. The example below is for postal code:
/* Seteaza campul Cod postal ne-obligatoriu */
add_filter( 'woocommerce_billing_fields', 'wc_npr_filter_postcode', 10, 1 );
function wc_npr_filter_postcode( $address_fields ) {
$address_fields['billing_postcode']['required'] = false;
return $address_fields;
}
/* End - Seteaza campul Cod postal ne-obligatoriu */

Force WooCommerce to sell and ship to ONLY one state

How do I force WooCommerce to sell and ship to only one state?
I can select a country but I can't find any way to allow selling and shipping only to one state/region.
Let's say I've selected only Canada and I want to sell only in Ontario. How can I achieve that? I probably have to add something to function.php to filter the states, but I don't know where to look for it...
Thanks!
I've found this solution, but probably it's not the "cleanest" way to achieve this.
Any suggestion?
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'CA'; // country code
}
function change_default_checkout_state() {
return 'ON'; // state code
}
add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
function custom_woocommerce_states( $states ) {
$states['CA'] = array(
'ON' => 'Ontario',
);
return $states;
}

Categories