Check if cart have active subscriptions in YITH WooCommerce Subscription Wordpress - wordpress

I am using YITH WooCommerce Subscription and I want to check if in my cart has subscription I want to disable one of my payment gateway. How could I do ?
I already try this code but this is doesn't work.
add_filter( 'woocommerce_available_payment_gateways', 'filter_gateways', 1);
function filter_gateways( $gateways ){
if (has_woocommerce_subscription('','','active')) {
unset( $gateways['pin_payments'] );
}
return $gateways;
}
function has_woocommerce_subscription($the_user_id, $the_product_id, $the_status) {
$current_user = wp_get_current_user();
if (empty($the_user_id)) {
$the_user_id = $current_user->ID;
}
if (WC_Subscriptions_Manager::user_has_subscription( $the_user_id, $the_product_id, $the_status)) {
return true;
}
}

You have 2 questions, one is active subscription that you can test via this function:
function CheckSubscriptionByEmail($email) {
// getting all the records of the user by email for the subscription
$subscriptions = get_posts( array(
'numberposts' => -1,
'post_type' => 'ywsbs_subscription', // Subscription post type
'orderby' => 'post_date', // ordered by date
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_billing_email', //additional fields being used to get the data
'value' => $email,
'compare' => '='
),
array(
'key' => '_status',
'value' => 'active', //active subscriptions
'compare' => '='
))
) );
// check if user has any active subscription
foreach ( $subscriptions as $post ) : setup_postdata( $post );
$nextdue = get_post_meta(get_the_id(), '_payment_due_date',true);
$current_date = date("Y-m-d");
$date_to_compare = date("Y-m-d",strtotime($nextdue));
if (strtotime($date_to_compare) > strtotime($current_date)) {
echo "active"; //returns active
break;
}
endforeach;
wp_reset_postdata();
}
Refernece and Explanation at:
https://makersbyte.com/check-active-subscriptions-using-yith-woocommerce/
If you want to just test all the active subcriptions then change in above function the following:
$subscriptions = get_posts( array(
'numberposts' => -1,
'post_type' => 'ywsbs_subscription', // Subscription post type
'orderby' => 'post_date', // ordered by date
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_status',
'value' => 'active', //active subscriptions
'compare' => '='
))
) );
Once you have the list of active subscription, it be fairly straight and simple to disable them if needed.
Payment Gateway, simply goto Woocommerce -> Checkout > All payment gateways are listed in it. Use it to disable.

Related

Display sale items on shop page in WooCommerce

I'm trying to figure out a direct link to display all sale items in the shop. URLs can usually filter out specific attributes and queries, so I was hopeful that this would be possible. So far, no luck.
My result turns up: no products found. But there are indeed products on sale.
I've tried the following:
add_filter( 'woocommerce_product_query_meta_query', 'filter_on_sale_products', 20, 1 );
function filter_on_sale_products( $meta_query ){
if( isset($_GET['onsale']) && $_GET['onsale'] ){
$meta_query[] = array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>'
);
}
return $meta_query;
}
This should return all sale items by URL: https://www.example.com/shop/?onsale=1
Any advice would be appreciated
Your code contains some very minor errors.
You can use the woocommerce_product_query action hook instead. This should suffice:
function action_woocommerce_product_query( $q ) {
if ( is_admin() ) return;
// Isset & NOT empty
if ( isset( $_GET['onsale'] ) ) {
// Equal to 1
if ( $_GET['onsale'] == 1 ) {
// Function that returns an array containing the IDs of the products that are on sale.
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', $product_ids_on_sale );
}
}
}
add_action( 'woocommerce_product_query', 'action_woocommerce_product_query', 10, 1 );
check this link out
$args = array(
'post_type' => 'product',
'posts_per_page' => 8,
'meta_query' => array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
$loop = new WP_Query( $args );

woocommerce - list hidden products

I am working on a project where I need to list all hidden products in a page. I have created a shortcode for that and I have used following meta query, but it's not working.
$meta_query = array(
'key' => '_visibility',
'value' => array('hidden'),
'compare' => 'IN'
);
Any idea why this is not working? Thank you in advance for your help.
$args = array(
'post_type' => 'product',
'meta_key' => '_visibility',
'meta_value' => 'hidden'
);
$query = new WP_Query($args);
Then your usual loop worked for me :)
WooCommerce 3+ visibility has been changed to a taxonomy instead of post meta and if you're using WC()->query->get_tax_query() function call for building the args, you can just remove that call from setting tax_query.
IF you don't have access to the args or how they are built and it is ran through get_tax_query you can use the filter to remove the NOT IN tax query for visibility:
add_filter( 'woocommerce_product_query_tax_query', 'smyles_show_all_products' );
// do something that calls some fn that makes product query
remove_filter( 'woocommerce_product_query_tax_query', 'smyles_show_all_products' );
function smyles_show_all_products( $tax_query ) {
foreach( (array) $tax_query as $t_index => $t_query ){
if( isset( $t_query['taxonomy'], $t_query['operator'] ) && $t_query['taxonomy'] === 'product_visibility' && $t_query['operator'] === 'NOT IN' ){
unset( $tax_query[ $t_index ] );
break;
}
}
return $tax_query;
}
Use this
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array( 'catalog', 'visible' ),
'compare' => 'IN'
)
)

How to random order a user list with get_users

I actually have a "users" page ordered by post_count.
I'm wondering if is possible to order the list randomly. I know that the get_usersfunction just allows ordering by 'ID', 'login', 'nicename', 'email', 'url', 'registered', 'display_name', 'post_count', 'include',or'meta_value'
For get_posts, if I remember well, there is a rand option to achieve this.
Here's the code of my template:
<?php
/*
Template Name: Display Contributors and Authors
*/
$args = array(
'role' => 'contributor',
'orderby' => 'post_count',
'order' => 'DESC'
);
// only return users with published posts
$args['has_published_posts'] = true;
// run the WP_Query
$contributors = get_users( $args );
?>
You can use following code to register order by rand:
add_action( 'pre_user_query', 'my_random_user_query' );
function my_random_user_query( $class ) {
if( 'rand' == $class->query_vars['orderby'] )
$class->query_orderby = str_replace( 'user_login', 'RAND()', $class->query_orderby );
return $class;
}
And then use it like this:
$args = array(
'role' => 'contributor',
'orderby' => 'rand',
'order' => 'DESC'
);
Source

How can I override BBPress function bbp_has_topics() by adding a filter for this function in Wordpress?

The "bbp_has_topics" function in "public/wp-content/plugins/bbpress/includes/topics/template.php" fetches the topics by "meta_value" in a "Descending" order. I need to override this behaviour to fetch the post by "created date" without editing this file. So is there a way to add a filter for this "bbp_has_topics". I added a filter in functions.php as below. But in the listing page the pagination links are not showing.
function mybbp_has_topics( $args = '') {
$bbp = bbpress();
// Other defaults
$default_topic_search = !empty( $_REQUEST['ts'] ) ? $_REQUEST['ts'] : false;
$default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
$default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
// The default forum query for most circumstances
$default = array(
'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
'post_parent' => $default_post_parent, // Forum ID
'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
'orderby' => 'date', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
'order' => 'DESC', // 'ASC', 'DESC'
'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
'paged' => bbp_get_paged(), // Page Number
's' => $default_topic_search, // Topic Search
'show_stickies' => $default_show_stickies, // Ignore sticky topics?
'max_num_pages' => false, // Maximum number of pages to show
);
$r = bbp_parse_args( $args, $default, 'has_topics' );
// Run the query
$bbp->topic_query = new WP_Query( $r );
return apply_filters( 'mybbp_has_topics', $bbp->topic_query->have_posts(), $bbp->topic_query );
}
From my understanding of this, you need to add your filter to the hook in bbp_has_topics.
Something like this function should be added as either in a new plugin or your theme's functions.php.
function mybbp_has_topics($have_posts, $topic_query){
//your code
$default_topic_search = !empty( $_REQUEST['ts'] ) ? $_REQUEST['ts'] : false;
$default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
$default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
// The default forum query for most circumstances
$default = array(
'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
'post_parent' => $default_post_parent, // Forum ID
'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
'orderby' => 'date', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
'order' => 'DESC', // 'ASC', 'DESC'
'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
'paged' => bbp_get_paged(), // Page Number
's' => $default_topic_search, // Topic Search
'show_stickies' => $default_show_stickies, // Ignore sticky topics?
'max_num_pages' => false, // Maximum number of pages to show
);
$r = bbp_parse_args( $args, $default, 'has_topics' );
// Run the query
$topic_query = new WP_Query( $r );
return $topic_query;}
add_filter( 'bbp_has_topics', mybbp_has_topics, 99, 2);
the parameter $topic_query contains the query that was made in bbp_has_topics.

WooCommerce: Display ONLY on-sale products in Shop

I need to create a products archive page (usually the Shop page in WooCommerce) but displays ONLY the ON SALE products. Basically it should use the same template layout as that in the archive-product.php. There will be a link in the main menu that will direct to this page. How do I go about this?
UPDATE
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'order' => 'ASC',
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I named archive-product_sale.php and made as a page template.
However, this only works for Simple products type and I need it to work for both Simple products and Variable products type.
#mirus' answer regarding the shortcode gave me the idea to check out how WooCommerce is querying only the on-sale items. Apparently WooCommerce has a wc_get_product_ids_on_sale() function that will return the IDs of the on-sale items. Then we can easily adjust the query using the post__in parameter to only return those specific items.
WooCommerce has a woocommerce_product_query hook in the class-wc-query.php class that allows for us to modify the query before it is run.... it is run on pre_get_posts which is the usual place for modifying the query. Using Woo's hook just means you let them handle the majority of the conditional logic about when this query modification should be applied.
add_action( 'woocommerce_product_query', 'so_20990199_product_query' );
function so_20990199_product_query( $q ){
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', $product_ids_on_sale );
}
I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...
$args = array(
'post_type' => 'product',
'meta_query' => array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
query_posts( $args );
The code is placed in a copy of archive-product.php which I renamed archive-product_sale.php and made as a page template.
#gmaggio using query_posts() will break your site.
Use pre_get_posts
add_filter( 'pre_get_posts', 'catalog_filters' );
function catalog_filters( $query ) {
if ( $query->is_main_query() && $query->post_type = 'product' ) {
if(isset($_GET['onsale'])) {
$meta_query = array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
); $query->set('meta_query', $meta_query);
}
if(isset($_GET['bestsellers'])) {
$meta_query = array(
array(
'key' => 'total_sales',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
);
}
}
return $query;
}
Create a new page using shortcode [sale_products per_page="12"]
List of available shortcodes and their parameters is here: http://docs.woothemes.com/document/woocommerce-shortcodes/
Solution for variable and simple products:
add_action( 'save_post_product', 'update_product_set_sale_cat_var' );
function update_product_set_sale_cat_var( $post_id ) {
$sales_ids = wc_get_product_ids_on_sale();
foreach ( $sales_ids as $sale_id ) :
if ($sale_id == $post_id) :
wp_set_object_terms($post_id, 'sale', 'product_cat', true );
else :
if ( has_term( 'sale', 'product_cat', $post_id ) ) {
wp_remove_object_terms( $post_id, 'sale', 'product_cat' );
}
endif;
endforeach;
}

Resources