hide all protected products in shop page WooCommerce - woocommerce

I'm trying to hide all password protected products in woocommerce (shop) main page.
add_filter( 'woocommerce_get_price_html', 'hide_protected_product_price', 10, 2 );
function hide_protected_product_price( $price, $product ) {
if ( ! empty( $product->get_post_password() ) && ! is_single() ) {
return '';
}
return $price;
}
This code only hides the price.
Can someone help me to modify this function so that nothing is displayed at all?
Many thanks
Totally hide the view

Related

Add a custom "Buy now" button on WooCommerce single product page which clears the cart, add a product and redirect to checkout

I'm using this simple code to add a 'buy now' button on a single product page.
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
function add_content_after_addtocart() {
// get the current post/product ID
$current_product_id = get_the_ID();
// get the product based on the ID
$product = wc_get_product( $current_product_id );
// get the "Checkout Page" URL
$checkout_url = WC()->cart->get_checkout_url();
// run only on simple products
if( $product->is_type( 'simple' ) ) {
echo 'Buy Now';
}
}
This code effectively redirects to the checkout page and add the product to the cart, but I want to add two little features to it:
After clicking on the button, I want it to clear the cart before taking the action.
After adding the product to the cart, I want it to redirect users to '/checkout' page. Right now it sends users on 'checkout/?add-to-cart=3122', which means that any refresh on the checkout page adds 1 product on the cart automatically.
Any advice?
Instead of using the add-to-cart param in your url, which will cause the product to be added (but also perform other actions in WooCommerce), you can use a custom url for your button and the template_redirect action hook
That way you get rid of the built-in functionality in WooCommerce and you can perform your own custom actions based on the GET parameters
So you get:
// Add new/extra button
function action_woocommerce_after_add_to_cart_button() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Run only on simple products
if ( $product->is_type( 'simple' ) ) {
// Get product ID
$product_id = $product->get_id();
// Get permalink
$permalink = $product->get_permalink();
// Output url
echo ''. __ ( 'Buy Now', 'woocommerce' ) . '';
}
}
}
add_action( 'woocommerce_after_add_to_cart_button', 'action_woocommerce_after_add_to_cart_button', 10 );
// Redirect
function action_template_redirect() {
// Determines whether the current request is for an administrative interface page
if ( is_admin() ) return;
// Returns true when viewing a single product
if ( ! is_product() ) return;
// Get params
if ( isset( $_GET['product_id'] ) && isset( $_GET['redirect_checkout'] ) ) {
// Get param 1
$product_id = $_GET['product_id'];
// Get param 2
$boolean = $_GET['redirect_checkout'];
// WC Cart
if ( WC()->cart ) {
// 1. Empty cart
WC()->cart->empty_cart();
// 2. Add to cart
WC()->cart->add_to_cart( $product_id );
// 3. Redirect
// When true
if ( $boolean ) {
// Gets the url to the checkout page
$checkout_url = wc_get_checkout_url();
// Performs a safe (local) redirect
wp_safe_redirect( $checkout_url );
exit;
}
}
}
}
add_action( 'template_redirect', 'action_template_redirect' );
Here is code for clear cart before add item
add_filter( 'woocommerce_add_to_cart_validation', 'ji_remove_cart_item_before_add_to_cart', 20, 3 );
function ji_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
if( ! WC()->cart->is_empty() )
WC()->cart->empty_cart();
return $passed;}
After adding the product to the cart, I want it to redirect users to '/checkout' page. Right now it sends users on 'checkout/?add-to-cart=3122', which means that any refresh on the checkout page adds 1 product on the cart automatically.
add_filter( 'woocommerce_add_to_cart_redirect', 'ji_redirect_checkout_after_add_to_cart' );
function ji_redirect_checkout_after_add_to_cart() {
return wc_get_checkout_url();
}

Remove product title when product is "out of stock" on WooCommerce shop and archives pages

I am running an art gallery website using WooCommerce and the owner does not want to show the product name/title if the product has been sold/out of stock.
I have got this far with putting together a function, but it doesn't work. I wondered if anyone could give me any tips?
// Hides title on Sold products
add_filter( 'woocommerce_shop_loop_item_title', 'remove_name', 10, 2 );
function remove_name ( $product ) {
if ( ! $product->is_in_stock()) {
$title = '';
}
return $title;
}
Your code contains some errors and mistakes:
woocommerce_shop_loop_item_title is NOT an filter but an action hook
No arguments are passed to this hook , while your code says there would be 2
$product is undefined, use global $product;
Note: I've added a line with debug information, it can be removed
So you get:
function action_woocommerce_shop_loop_item_title() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Should be removed but may be useful towards debugging
echo '<p style="color: red; font-size: 20px;">DEBUG information: ' . $product->get_stock_status() . '</p>';
// NOT in stock
if ( ! $product->is_in_stock() ) {
// Removes a function from a specified action hook.
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
}
}
}
add_action( 'woocommerce_shop_loop_item_title', 'action_woocommerce_shop_loop_item_title', 9 );
Please try to use this hook to remove product title. Use this inside the condition to check if product is in stock:
remove_action( 'woocommerce_shop_loop_item_title','woocommerce_template_loop_product_title', 10 );
This does what you want but still allows access to the product page.
add_action( 'woocommerce_shop_loop_item_title', function() {
global $product;
if ( ! $product->is_in_stock()) {
remove_action( 'woocommerce_shop_loop_item_title','woocommerce_template_loop_product_title', 10 );
}
}, 5 );
add_action( 'woocommerce_single_product_summary', function() {
global $product;
if ( ! $product->is_in_stock()) {
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_title', 5);
}
}, 1);

Woocommerce - hide product price when out of stock (not in admin)

I'm trying to remove product prices from woocommerce out of stock products.
I've used this so far (in the functions.php) :
add_filter( 'woocommerce_get_price_html', 'remove_price_ofs', 10, 2 );
function remove_price_ofs( $price, $product ) {
if ( ! $product->is_in_stock()) {$price = '';}
return $price;
}
The problem is that it's also hiding the price in the orders admin list. How can I avoid that ?
Thanks !
Just check for it.
add_filter( 'woocommerce_get_price_html', 'remove_price_ofs', 10, 2 );
function remove_price_ofs( $price, $product ) {
if ( ! $product->is_in_stock() && (is_product() || is_product_category() || is_shop() ) ) {$price = '';}
return $price;
}
OPTION 2
To run only on frontend.
add_filter( 'woocommerce_get_price_html', 'remove_price_ofs', 10, 2 );
function remove_price_ofs( $price, $product ) {
if ( ! $product->is_in_stock() && ! is_admin() ) {$price = '';}
return $price;
}
We just check if its a product page and if it is then only we change the price. You might want to do this for archive pages as well.
List of conditional tags you can use.
https://docs.woocommerce.com/document/conditional-tags/

Woo Shop Page Code using on different page

I have a home page and shop page. I don't want to set my home page to shop page.
Home page is full of custom content and widgets, and right before this content I would like to have list of products with same pagination as on shop page.
This means I could not use shortcodes to display products as default shortcodes do not support pagination.
Have gone through all the docs and tried possible ways. But it always breaks something.
Any advice will appreciated.
Thx.
P.S. While you reading this I'm still trying to find solution, so I might post something soon :)
Finally found awesome solution right here.
I'm using shortcode [product_category per_page="4" category="category-slug"]
To make pagination alive, you need to activate this pagination.
Here is the exact code snippet that need to be pasted into the theme's functions.php:
if ( defined('WC_VERSION') ) {
// ---------------------- WooCommerce active -------------------
/**
* Set Pagination for shortcodes custom loop on single-pages.
* #uses $woocommerce_loop;
*/
add_action( 'pre_get_posts', 'kli_wc_pre_get_posts_query' );
function kli_wc_pre_get_posts_query( $query ) {
global $woocommerce_loop;
// Get paged from main query only
// ! frontpage missing the post_type
if ( is_main_query() && ( $query->query['post_type'] == 'product' ) || ! isset( $query->query['post_type'] ) ){
if ( isset($query->query['paged']) ){
$woocommerce_loop['paged'] = $query->query['paged'];
}
}
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
$query->is_paged = true;
$query->query['paged'] = $woocommerce_loop['paged'];
$query->query_vars['paged'] = $woocommerce_loop['paged'];
}
/** Prepare Pagination data for shortcodes on pages
* #uses $woocommerce_loop;
*/
add_action( 'loop_end', 'kli_query_loop_end' );
function kli_query_loop_end( $query ) {
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
return;
}
// Cache data for pagination
global $woocommerce_loop;
$woocommerce_loop['pagination']['paged'] = $woocommerce_loop['paged'];
$woocommerce_loop['pagination']['found_posts'] = $query->found_posts;
$woocommerce_loop['pagination']['max_num_pages'] = $query->max_num_pages;
$woocommerce_loop['pagination']['post_count'] = $query->post_count;
$woocommerce_loop['pagination']['current_post'] = $query->current_post;
}
/**
* Pagination for shortcodes on single-pages
* #uses $woocommerce_loop;
*/
add_action( 'woocommerce_after_template_part', 'kli_wc_shortcode_pagination' );
function kli_wc_shortcode_pagination( $template_name ) {
if ( ! ( $template_name === 'loop/loop-end.php' && is_page() ) ){
return;
}
global $wp_query, $woocommerce_loop;
if ( ! isset( $woocommerce_loop['pagination'] ) ){
return;
}
$wp_query->query_vars['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->query['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->max_num_pages = $woocommerce_loop['pagination']['max_num_pages'];
$wp_query->found_posts = $woocommerce_loop['pagination']['found_posts'];
$wp_query->post_count = $woocommerce_loop['pagination']['post_count'];
$wp_query->current_post = $woocommerce_loop['pagination']['current_post'];
// Custom pagination function or default woocommerce_pagination()
kli_woocommerce_pagination();
}
/**
* Custom pagination for WooCommerce instead the default woocommerce_pagination()
* #uses plugin Prime Strategy Page Navi, but added is_singular() on #line16
*/
remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination', 10);
add_action( 'woocommerce_after_shop_loop', 'kli_woocommerce_pagination', 10);
function kli_woocommerce_pagination() {
woocommerce_pagination();
}
}// END WOOCOMMERCE
Nice way to go for this try. The next thing is to make pagination ajax based without page reloading...

WooCommerce inquiry if no price available

I'm helping a good friend setting up a WooCommerce shop. Since the shop is going to be bigger and the products are pretty variable and customizable we are not able to provide/configure all prizes from the beginning.
However we would like all products to be in the shop and ad an inquiry lead form in case no price is available.
Since I never programmed with WooCommerce I was wondering that is the right hook to implement such an functionality?
Had the exact same issue and couldn't find a plugin or a solution anywhere so I figured a workaround myself:
You need to edit file
/wp-content/themes/your-theme-name/woocommerce/single-product/add-to-cart/simple.php
(if it's not there just copy it from woocommerce plugin
/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php)
and on line 14 where it says
if ( ! $product->is_purchasable() ) return;
you need to comment it out and write something like
if ( ! $product->is_purchasable() ) {
// put your code here
return;
}
and in the //put your code here line you can enter for example a shortcode for a form or a more complicated solution would be to put code for a button that when clicked will open up a popup form.
Still working on that ;)
Maybe too late, but I have had same issue currently.
Here is there code, Woocommerce uses to check if a product can be purchased:
https://github.com/woocommerce/woocommerce/blob/master/includes/abstracts/abstract-wc-product.php#L1404
Notice about: && '' !== $this->get_price()
/**
* Returns false if the product cannot be bought.
*
* #return bool
*/
public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', $this->exists() && ( 'publish' === $this->get_status() || current_user_can( 'edit_post', $this->get_id() ) ) && '' !== $this->get_price(), $this );
}
So you need to write a filter like this to override default:
add_filter( 'woocommerce_is_purchasable', function ( $is_purchasable, $product ) {
return $product->exists() && ( 'publish' === $product->get_status() || current_user_can( 'edit_post', $product->get_id() ) );
}, 10, 2 );
Try the following code snippet. You just have to put it in your functions.php. You don't need a plugin or to overwrite WooCommerce files in your child theme.
// Inquiry link if no price available
function add_inquiry_link_instead_price( $price, $product ) {
if ( '' === $product->get_price() || 0 == $product->get_price() ) :
return ''.__( 'Jetzt anfragen' ).'';
endif;
}
add_filter( 'woocommerce_get_price_html', 'add_inquiry_link_instead_price', 100, 2 );

Resources