Hello! I'm trying to create a product that is hidden from the website publicly but that can be invoiced (manually).
If I set the product's Visibility to "Private" it doesn't show up when I try to "Add Order" as a [line item] choice (even searchable).
If I set it instead to "Password Protected" the product shows up within the store (it says password protected next to it, but its thumbnail is still visible, so this isn't an option).
I found a plugin that may help, but I'm unclear as to what exactly its capable of and they haven't responded to my repeated requests for explanation: http://presspermit.com/
Does anyone have any other ideas?
Thanks,
Liz
http://www.ellencellijewelry.com
Kyle answers:
You may want to consider filters that remove them from the shop page and search results. Something like a specific product category (e.g. 'manual-only') and then add a filter like this to remove it from the shop page:
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! is_admin() && is_shop() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'manual-only' ),
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Kyle comments:
On top of that, you may want to consider a plugin like [[LINK href="http://codecanyon.net/item/woocommerce-prices-by-user-role/8562616"]]http://codecanyon.net/item/woocommerce-prices-by-user-role/8562616[[/LINK]] that will only allow previously registered users of certain roles (so you could give your invoiced user(s) a certain role) to purchase them as an extra layer of security beyond just removing them from public view.
Liz comments:
I like this idea of a category for reserved products.
I have several functions (like "Latest" products view) that will try to pull up any "published" pages. Is there a simple way using filters to tell it to exclude this category from ANY function (except the back end invoicing I'm trying to do).
Also, the theme I'm using doesn't always want to play nicely with my child theme and accept its changes so this would be an experiment. I've had to put "! important" next to every style change.
I don't want to add a filter directly to the theme itself to negate the option of EVER updating.
Kyle comments:
The pre_get_posts filter will allow you to manipulate filters sitewide, but you must be very careful when messing with it and do your homework after you put them in to check around your site to make sure it didn't hit anywhere you didn't want.
These lines:
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! is_admin() && is_shop() ) {
Are what segregates the code to affecting the shop page only. So if you took all of those out except the !is_admin() part to keep everything visible in the back end. You would be able to start filtering it out elsewhere as well.
Like you mentioned though, some times these things to play nice - and pre_get_posts is certainly one of those things, so you may have to play with it a bit. As far as making it future proof, you can drop it into a simple plugin that will act like a functions.php file for you to keep your custom functions in.
Liz comments:
This is really helpful info, thanks.
I got a little lost when you said "these lines (...) are what segregates the code to affecting the shop page only."
Also, I've never created a plugin from scratch like you mentioned. Are there any links to give me some guidance? Or do you mind explaining that a little more?
Kyle comments:
You're welcome, happy to help
Those three lines are conditionals, that remove the filter from anywhere that isn't the shop page. So the removing them will let the code be applied everywhere. So if you stripped it down to this:
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! is_admin() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'manual-only' ),
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
It will apply it to more places. Again though, you'll have to test it and be sure this isn't disrupting any theme/plugin functions.
Here is a solid article for very basic plugins [[LINK href="http://premium.wpmudev.org/blog/how-to-create-your-very-first-wordpress-plugin/"]]http://premium.wpmudev.org/blog/how-to-create-your-very-first-wordpress-plugin/[[/LINK]]
Liz comments:
Hi. I'm not sure why, but it didn't work at all.
1. I created a category called "manual-only"
2. I published a product with that category checked.
3. I created a plugin and activated it. (I tried the first batch of code you posted, then the second).
The product showed up in my "Latest" section. And the category showed up in my categories list on the front of the site.
What am I doing wrong?
Here's a screenshot. The ugly photo was the one I was trying to exclude.