I was working on implementing my own pre-order system, where I set a is_preorder custom field for each product.
I was trying to modify the WooCommerce's Is_Purchasable option so that, if the product has pre-order status and it's already passed the pre-order deadline, it shouldn't be able to be purchased. I've tried a bunch of ways, but nothing seems working.
Here's something that I did (rough idea)
add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable');
function preorder_is_purchasable() {
// this is a field added using 'Advance Custom Fields' plugin
$is_preorder = get_field('is_preorder');
if($is_preorder && "not yet passed deadline")
return true;
else
return false;
}
I don't just wanna disable the add_to_cart button, I also want to disable the functionality (should prompt error if user tried to add product by hardcoding in url).
How should I go on with this?
===========================================================================
Here's my final code:
add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable', 10, 2);
function preorder_is_purchasable( $is_purchasable, $object ) {
// this is a field added using 'Advance Custom Fields' plugin
$is_preorder = get_field('is_preorder', $object->id);
// if product is Pre-Order
if($is_preorder)
{
$today = date('Ymd');
// another field added using 'Advance Custom Fields' plugin
$preorder_deadline = get_field('preorder_deadline', $object->id);
if($today <= $preorder_deadline) // if not yet pass deadline
return true;
else
return false;
}
else
return $is_purchasable; // normal
Update 2019: please see dev_masta answer for correct solution nowadays.
Not sure if it solves the issue as this has to be tested on your own custom set up. But you're using get_field wrong: if it is not used inside a Loop, you should provide the post ID.
Analyzing the filter woocommerce_is_purchasable, we see that it takes two parameters, a boolean (is_purchasable) and an object (WC_Product).
Try this:
add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable', 10, 2);
function preorder_is_purchasable( $is_purchasable, $object ) {
// this is a field added using 'Advance Custom Fields' plugin
$is_preorder = get_field('is_preorder', $object->id);
if($is_preorder && $is_purchasable)
return true;
else
return false;
}
The accepted answer is a bit outdated today.
Instead of using $object->id you should use $object->get_id(), otherwise you'll get a PHP notice about incorrect use.
function disable_purchased_products( $is_purchasable, $object ){
// custom function to get the array of purchased products ID's
$already_purchased = get_purchased_products();
if( in_array( $object->get_id(), $already_purchased ) ){
return false;
} else {
return $is_purchasable;
}
}
add_filter( 'woocommerce_is_purchasable', 'disable_purchased_products', 10, 2 );
I hope this will help someone, I've seen this (outdated) code all around the net..
Related
I am using WooCommerce Subscription and One Page Checkout plugins.
I am able to unset billing first name and last name (and even set 'required' attribute to false, so both fields are successively removed from my One page checkout.
But when I fill all other fields and I place order, it displays a validation error notice: "Billing First Name and Last Name are required" and I am not really sure how to solve this problem?
Maybe it has been set again from some functions or so? How I can solve this?
To remove billing first name and last name without any issues in checkout page, try to use the following instead:
// 1. Make required fields optional
add_filter( 'woocommerce_default_address_fields', 'customize_default_address_checkout_fields', 1000 );
function customize_default_address_checkout_fields( $fields ) {
if( is_checkout() ) {
$fields['first_name']['required'] = $fields['last_name']['required'] = false;
}
return $fields;
}
// 2. Remove unneeded billing fields
add_filter( 'woocommerce_billing_fields', 'customize_billing_checkout_fields', 1000 );
function customize_billing_checkout_fields( $fields ) {
if( is_checkout() ) {
unset($fields['billing_first_name'], $fields['billing_last_name']);
}
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works…
It should works with One Page Checkout plugin too.
Have you tried removing it manually via child function.php as below?
add_filter( 'woocommerce_checkout_fields' , ' custom_remove_checkout_fields ' );
function custom_remove_checkout_fields( $fields ) {
unset($fields['billing']['billing_first_name']);
unset($fields['billing']['billing_last_name']);
return $fields;
}
I have solved the issue already.
The root cause is because one plugin always required Billing First Name and Last Name so I use this tip below to passby the problem:
I included this code into function.php of the theme:
add_filter('woocommerce_billing_fields', 'my_woocommerce_billing_fields');
function my_woocommerce_billing_fields($fields) {
$fields['billing_first_name']['default'] = 'newSubscriber';
$fields['billing_first_name']['custom_attributes']['readonly'] = TRUE;
$fields['billing_last_name']['default'] = 'newSubscriber';
$fields['billing_last_name']['custom_attributes']['readonly'] = TRUE;
return $fields;
}
So now your first name and your last name is always set as 'newSubscriber', it will pass the validation and now you hide it from dislaying using css:
p#billing_first_name_field, p#billing_last_name_field {
display: none;
}
paste these css into appearance -> Theme-> yourtheme-> additional css and save it.
So now everything would work as charm.
Hope it would help somebody struggling with the problem.
I have just purchased the plugin Checkout Field Editor for WooCommerce from Theme High.
I need to create a custom display rule condition for fields.
They provide the filters hook:
apply_filters( 'thwcfe_show_field', $show, $field_name );
I have tried the following code, but it does not work.
Can someone help?
function display( $field_name='test' ) {
$show =true;
return $show;
}
add_filter('thwcfe_show_field', 'display');
The true / false options works but I can't make it specific to the $field_name = 'test'.
You are not using this filter in a correct way… First there are 2 arguments for the hooked function (one is missing).
To restrict the filter to a specific field name, you need an IF statement and between $field_name and the value to be tested, you need to use == or === comparison operators, but not =.
So your code is going to be:
add_filter('thwcfe_show_field', 'display_test_field', 10, 2 );
function display_test_field( $show, $field_name ) {
if ( 'test' === $field_name ) {
$show = true;
}
return $show;
}
where 10 is the hook priority and 2 the number of arguments for this hook.
It should better work now.
Documented WordPress add_filter() function
I use a filter provided by Woocommerce Composite Products plugin to update quantities of products in a set. When I am logged in this filter works as intended, but when I am not logged in the quantities are not updated.
I use the following code:
add_filter( 'woocommerce_composited_product_quantity', 'update_quantity', 10, 6);
function update_quantity($qty_value, $min_quantity, $max_quantity, $product, $component_id, $composite_product)
{
$category = $_POST['soort'];
$retrieve_data = WC()->session->get( 'quantities' );
$postname = $product->post->post_name;
if($postname == 'product-basis') {
return 1;
}
else if (strpos($postname, 'product-')) {
return 1;
} else {
$value = is_numeric($retrieve_data[$category][$postname]) && $retrieve_data[$category][$postname] > 0 ? $retrieve_data[$category][$postname] : 1;
return (int)$value;
}
}
The values of $soort_verwarming and $retrieve_data are available, which led me thinking that the filter is somehow not working when a user is not logged in.
$retrieve_data[$category][$postname] corresponds to a number which should be returned for each product and update its quantity.
Are there reasons why add_filter would not work for not logged in users?
Adding this to my header fixed the problem for me:
WC()->session->set_customer_session_cookie(true);
I used Wordpress session somewhere else to save some data that I needed to update the quantities with.
My guess is that this session was not being set for customers that are logged out, which explains why it was working when I was logged in.
Any additional info if needed:
https://docs.woothemes.com/wc-apidocs/source-class-WC_Session_Handler.html#73-91
Probably a very simple question but it leaves me clueless..
On the web if found the following code for searching a custom field on the order page. What If I wanted to scope another field?
add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_order_total' );
function woocommerce_shop_order_search_order_total( $search_fields ) {
$search_fields[] = 'woochimp_field';
return $search_fields;
}
Thanks
$search_fields[] Is an Array as it turns out. Every time you use $search_fields[] = 'woochimp_field'; you add to the array and makes you able to search more custom fields.
add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_order_total' );
function woocommerce_shop_order_search_order_total( $search_fields ) {
$search_fields[] = 'woochimp_field';
$search_fields[] = 'woochimp_field_2'; //example
return $search_fields;
}
I'm trying to override, or simply customize, the admin orders list view.
I understood the method to customize is render_shop_order_columns in includes/admin/class-wc-admin-post-types.php but I cannot remove the action (method) from theme functions.php neither by a custom plugin in the plugins_loaded hook: always get bool(false) on
var_dump(remove_action( 'manage_shop_order_posts_custom_column', array( $GLOBALS['wc_admin_post_type'], 'render_shop_order_columns' ) ));
I see there is the woocommerce_order_item_name filter, but if I add a picture there (that's what I need), I get a wrong output since it is used in the title attribute of link to product too.
Could anyone please advice?
Thank you!
I was getting a wrong way...
Maybe the right one is to unset the column and add your own.
See here:
https://wordpress.org/support/topic/hooking-and-adding-new-column-on-woocommerce-order-admin-page
basically:
add_filter('manage_edit-shop_order_columns', 'show_custom_product_column', 15);
function show_custom_column($columns) {
$new_columns = (is_array($columns)) ? $columns : array();
//remove column
unset($new_columns['column_to_unset']);
//add custom column
$new_columns['custom_column'] = __( 'Translation', 'woocommerce' );
return $new_columns;
}
add_action('manage_shop_order_posts_custom_column', 'my_custom_column', 10, 2);
function my_custom_column($column) {
global $post, $woocommerce, $the_order;
switch ($column) {
case 'custom_column' :
// Custom code
break;
}
}