I am using the code below and the aim and purpose is to block certain street addresses from being able to order. The code does not work (orders can still be made using any of the addresses blocked) though and I am wondering why.
Here is the code:
add_action( 'woocommerce_checkout_process', 'validate_address_for_spam_order' );
function validate_address_for_spam_order() {
$disableAddressList = array (
'Street name 1',
'Street name 2',
'Street name 3',
'Street name 4',
);
$billingAddress = isset( $_POST['billing_address_1'] ) ? trim( $_POST['billing_address_1'] ) : '';
$billingAddress = str_replace(array('-','_'),' ',$billingAddress);
$billingAddress = ucwords($billingAddress);
if (in_array($billingAddress, $disableAddressList))
{
wc_add_notice( __( 'Your error message here' ), 'error' );
}
}
Any help is highly appreciated.
The code you has is working fine except with some logical issues . I have checked the code and it didn't work for me in the following case
When address is Street Name 1 i.e, capital letters and small letters mixed in address ( Your array has Street name 1 and your php function only converts first Letter to Caps). So Street NAme 1, StReeT NaMe 1, STREEt Name1 on comparison gives false results.
So you will have to change the method of comparing addresses . I choose the following which is applicable in most string comparisons.
Write your disbaled address array in small letters
$disableAddressList = array (
'street name 1',
'street name 2',
'street name 3',
'street name 4',
);
Instead of ucwords(), use strtolower().
So the code will be
add_action( 'woocommerce_checkout_process', 'validate_address_for_spam_order' );
function validate_address_for_spam_order() {
$disableAddressList = array (
'street name 1',
'street name 2',
'street name 3',
'street name 4',
);
$billingAddress = isset( $_POST['billing_address_1'] ) ? trim( $_POST['billing_address_1'] ) : '';
$billingAddress = str_replace(array('-','_'),' ',$billingAddress);
$billingAddress = strtolower($billingAddress);
if (in_array($billingAddress, $disableAddressList))
{
wc_add_notice( __( 'Your error message here' ), 'error' );
}
}
Related
We sell computer parts at our woocommerce based website.
IT products become old very quickly, so I have thousands of End-Of-Life (EOL) products.
We update and check prices via REST API, so our system spend too much time for EOL products.
On the other hand, We don't want to delete or make them private because they bring big visitors from google search.
So, we think to add a custom status to product. Like EOL. So products will be listed on google but since we will update only Published status products it will not be problem.
I found below code but can't be sure it is correct. Because when I add this code and select EOL, It doesn't look as I want.
Before select EOL: https://prnt.sc/00qzWQV6saTp
After select EOL and save: https://prnt.sc/VkTzLq1S1EZP
Any advise?
register_post_status( 'custom-hide-product', array(
'label' => _x( 'EOL', 'post' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'EOL <span class="count">(%s)</span>', 'EOL <span class="count">(%s)</span>' ),
) );
add_action( 'admin_footer', 'display_hide_status_option' );
function display_hide_status_option() {
global $post;
$complete = '';
$label = '';
if ( $post->post_type === 'product' ) {
if ( $post->post_status === 'custom-hide-product' ) {
$selected = 'selected';
}
echo '<script>
jQuery(document).ready(function($){
$("select#post_status").append("<option value=\"custom-hide-product\" ' . $complete . '>EOL</option>");
$(".misc-pub-section label").append("' . $label . '");
});
</script>
';
}
}
$label is always empty in your code, it must be set if $post->post_status === 'custom-hide-product'.
And replace $(".misc-pub-section label").append("' . $label . '"); with $(".misc-pub-section #post-status-display").html("' . $label . '"); if $label is 'EOL'
I am using the following filter to add some more Schema related information to my product.
But for some German character , it is converted to Numeric code
add_filter( 'woocommerce_structured_data_product', 'filter__woocommerce_structured_data_product', 20, 2 );
function filter__woocommerce_structured_data_product( $schema, $product ) {
global $post;
$shipping_val = utf8_decode( get_post_meta( $post->ID, 'pro_shipping', true ) );
// Not working : CHF 10.–
$colour_val = utf8_decode( get_post_meta( $post->ID, 'pro_color', true ) );
// Not working : Aussen: rosa und blau (metallisch), Bordüre: grün, Innen: lila
$schema['shipping'] = array(
'#type' => 'Shipping',
'name' => $shipping_val ,
);
$schema['colour'] = array(
'#type' => 'Colour',
'name' => $colour_val ,
);
return $schema;
}
I have added comment , in that form actual data are stored in custom fields.
and I have added screen-shot , which convert actual data in numeric form
How do I solve this ?
Not sure why you've run utf8_decode function on those values, but you could use iconv function to convert them back to utf8.
So when you run utf8_decode it will convert your values to ISO-8859-1 characters.
utf8_decode: Converts a string with ISO-8859-1 characters encoded with UTF-8 to single-byte ISO-8859-1
We could use ISO-8859-1 in iconv function.
iconvDocs
For example, if you run the following code:
$german_word = "Bordüre: grün";
$utf8__decode_german_word = utf8_decode($german_word);
$utf8_german_word_main = iconv("ISO-8859-1", "utf-8//TRANSLIT//IGNORE", $utf8__decode_german_word);
echo $german_word . "<br>";
echo $utf8__decode_german_word . "<br>";
echo $utf8_german_word_main . "<br>";
Which will output this:
// $german_word result
Bordüre: grün
// $utf8__decode_german_word result
Bord�re: gr�n
// $utf8_german_word_main result
Bordüre: grün
So your entire code would be something like this:
add_filter("woocommerce_structured_data_product", "filter__woocommerce_structured_data_product", 20, 2);
function filter__woocommerce_structured_data_product($schema, $product)
{
global $post;
$shipping_val = utf8_decode(get_post_meta($post->ID, "pro_shipping", true));
$colour_val = utf8_decode(get_post_meta($post->ID, "pro_color", true));
$schema["shipping"] = array(
"#type" => "Shipping",
"name" => iconv("ISO-8859-1", "utf-8//TRANSLIT//IGNORE", $shipping_val),
);
$schema["colour"] = array(
"#type" => "Colour",
"name" => iconv("ISO-8859-1", "utf-8//TRANSLIT//IGNORE", $colour_val),
);
return $schema;
}
Let me know if you could get it to work.
Based on Using WC_Tax::get_tax_classes() to get all WooCommerce tax-classes answer to my previous question, I am trying to get the available tax rates from the defined tax-classes in WooCommerce.
I tried the following code:
$tax_classes = wc_get_product_tax_class_options();
foreach ( $tax_classes as $tax_class ) {
$taxes = WC_Tax::get_rates( $tax_class );
var_dump($taxes);
}
The var_dump exports are empty, but it looks like it interacts with the available classes.
/home/public_html/...etc
array (size=0)
empty
/home/public_html/...etc
array (size=0)
empty
/home/public_html/...etc
array (size=0)
empty
/home/public_html/...etc
array (size=0)
empty
/home/public_html/...etc
array (size=0)
empty
How do i get a array (in the backend admin-panel) with the available tax details: name, tax_rate etc?
Each tax class rates are defined in backend by location settings… so they depend on customer location. The tax rates can be applied differently to products and shipping.
For each tax class, you need to set tax rates by country or by shipping zone, depending on allowed purchase locations or zones (see the example below).
Use the following to display the available tax rates for the customer (based on its location):
$location = array(
'country' => WC()->customer->get_shipping_country() ? WC()->customer->get_shipping_country() : WC()->customer->get_billing_country(),
'state' => WC()->customer->get_shipping_state() ? WC()->customer->get_shipping_state() : WC()->customer->get_billing_state(),
'city' => WC()->customer->get_shipping_city() ? WC()->customer->get_shipping_city() : WC()->customer->get_billing_city(),
'postcode' => WC()->customer->get_shipping_postcode() ? WC()->customer->get_shipping_postcode() : WC()->customer->get_billing_postcode(),
);
$output = array(); // Initialiizing (for display)
// Loop through tax classes
foreach ( wc_get_product_tax_class_options() as $tax_class => $tax_class_label ) {
// Get the tax data from customer location and product tax class
$tax_rates = WC_Tax::find_rates( array_merge( $location, array( 'tax_class' => $tax_class ) ) );
// Finally we get the tax rate (percentage number) and display it:
if( ! empty($tax_rates) ) {
$rate_id = array_keys($tax_rates);
$rate_data = reset($tax_rates);
$rate_id = reset($rate_id); // Get the tax rate Id
$rate = $rate_data['rate']; // Get the tax rate
$rate_label = $rate_data['label']; // Get the tax label
$is_compound = $rate_data['compound']; // Is tax rate compound
$for_shipping = $rate_data['shipping']; // Is tax rate used for shipping
// set for display
$output[] = '<li class="tax-rate '.$tax_class.'">'.$tax_class_label.': <strong>'.$rate.'</strong> <small>(label: '.$rate_label.' | id: ' . $rate_id . ')</small></li>';
}
}
// Display
if ( ! empty($output) ) {
echo '<div><h4>' . __("Available Tax rates") . '</h4><ul>' . implode('', $output) . '</ul></div>';
}
You will get something like:
Related: Using WC_Tax::get_tax_classes() to get all WooCommerce tax-classes
Usage specifying a location
As it seems that you want to use it in backend as are asking in your comment, you need to specify a location to be able to get tax rates for that specific location.
So for example to get the tax rates set for France country ("FR" country code) you will replace the $location array by:
$location = array( 'country' => 'FR', 'state' => '', 'city' => '', 'postcode' => '' );
If there is no country specified, you will use an array with empty values like:
$location = array( 'country' => '', 'state' => '', 'city' => '', 'postcode' => '' );
I have a Wordpress site where each user is linked to an 'upline' user, with that upline user's ID stored in a custom meta field 'direct_upline'.
On a particular gravity form, I currently populate a hidden field with value of {user:direct_upline}.
For example, User A fills out the form. User A's direct_upline is User B. I would like to then populate User B's direct_upline, and so on (probable 10 levels deep).
Any idea how to most efficiently perform this? Below is a function to populate multiple fields in one function; I was thinking I may could do this in conjunction with $all_meta_for_user = get_user_meta( $user_id );
add_filter( 'gform_field_value', 'populate_fields', 10, 3 );
function populate_fields( $value, $field, $name ) {
$values = array(
'field_one' => 'value one',
'field_two' => 'value two',
'field_three' => 'value three',
);
return isset( $values[ $name ] ) ? $values[ $name ] : $value;
}
I have a search form consists of several "select" which list various terms of a taxonomy ('State'). By pressing the submit button, I pass the information to a search results page on which I build the query.
The problem is that I need to build the query dynamically because it is not obligatory to choose values for each of the "select". So some values are sent empty.
For example:
$country = $_POST["country"];
$city = $_POST["city"];
If $city is empty, the query should be like:
$my_query = new WP_Query(array(
'state' => $country
)
);
But if $country and $city are not empty, de query should be like:
$my_query = new WP_Query(array(
'state' => $country,
'state' => $city
)
);
How can I do it?
Thanks.
I would do this:
$city = isset($_POST['city']) ? $_POST['city'] : null;
$country = isset($_POST['country']) ? (isset($_POST['city']) ? ' ('. $_POST['country'] .')' : $_POST['country']) : null;
$state = $city . $country;
This code will show:
City and Country filled: Caracas (Venezuela)
Only City: Caracas
Only Country: Venezuela
And your query:
$my_query = new WP_Query(array(
'state' => $state,
)
);