I have a function that displays the post count of any terms for its taxonomy anywhere i want to show it and it works great but i would like to change this up a bit to completely exclude the post count of any post that has a certain term added to it, let's call that "state". So if a post has "state" added to it, i would like the function to not include the count of that post in any terms within the taxonomy.
function get_city_count( $taxonomy = 'countries', $term = '', $args = [] )
{
if ( !$term )
return false;
if ( $term !== 'all' ) {
if ( !is_array( $term ) ) {
$term = filter_var( $term, FILTER_VALIDATE_INT );
} else {
$term = filter_var_array( $term, FILTER_VALIDATE_INT );
}
}
if ( $taxonomy !== 'countries' ) { $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
if ( !taxonomy_exists( $taxonomy ) ) return false;
}
if ( $args ) { if ( !is_array ) return false; } $defaults = [ 'posts_per_page' => 1, 'fields' => 'ids' ];
if ( $term !== 'all' ) { $defaults['tax_query'] = [ [ 'taxonomy' => $taxonomy, 'terms' => $term ] ]; }
$combined_args = wp_parse_args( $args, $defaults );
$q = new WP_Query( $combined_args );
return $q->found_posts;
}
Related
Using the answer from search multiple sku's on woocommerce admin side I adapted my code to replace $sku with the value of the custom field within my product, which is $winner.
When I search by separating product custom fields with a delimiter, it does not work. How can I edit my code so I can search products multiple by custom field?
function woo_multiple_title_search( $query_vars ) {
global $typenow;
global $wpdb;
global $pagenow;
if ( 'product' === $typenow && isset( $_GET['s'] ) && 'edit.php' === $pagenow ) {
$search_term = esc_sql( sanitize_text_field( $_GET['s'] ) );
if (strpos($search_term, '|') == false) return $query_vars;
$names = explode('|',$search_term);
$meta_query = array(
'relation' => 'OR'
);
if(is_array($winners) && $winners) {
foreach($winners as $winner) {
$meta_query[] = array(
'key' => '_winner',
'value' => $winner,
'compare' => '='
);
}
}
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => $meta_query
);
$posts = get_posts( $args );
if ( ! $posts ) return $query_vars;
foreach($posts as $post){
$query_vars['post__in'][] = $post->ID;
}
}
return $query_vars;
}
add_filter( 'request', 'woo_multiple_title_search', 20 );
We are using Advanced Custom Fields, WP All Export Pro, and WordPress with Woocommerce.
I have an ACF field created for our accountant in users area of WordPress called "traverse_customer_id". This is for her to know what customer this order is for.
I have this ACF field showing in the orders export but the data comes back blank on each export. I think it's because I'm not relating the order with the customer or user ID. I've attempted to use a code snippet from WP All Exports' support without any luck. Could anyone with knowledge help me see what I'm doing wrong?
This is what I have in the "Custom export field" area: (I think this is running the function on each line of the import.)
[sf_helper_meta_query_lookup("traverse_customer_id",{Customer User ID},"user")]
Then I have this below in the Function Editor:
function sf_helper_meta_query_lookup( $meta_key = '', $meta_value = '', $object_type = 'post', $taxonomy = '', $return_field = 'ID', $compare = '=', $custom_args = array() ) {
if ( empty( $object_type ) || empty( $meta_key ) || empty( $meta_value ) ) return;
$func = 'get_posts';
switch ( $object_type ) {
case 'user':
$func = 'get_users';
break;
case 'term':
$func = 'get_terms';
if ( $return_field == 'ID' ) {
$return_field = 'term_id';
}
break;
default:
$func = 'get_posts';
break;
}
if ( ! empty( $custom_args ) ) {
$objects = $func( $custom_args );
if ( ! empty( $objects ) ) {
return $objects[0]->$return_field;
} else {
return false;
}
}
$args = array();
$meta_query = array( array(
'key' => $meta_key,
'value' => $meta_value,
'compare' => $compare
) );
if ( $func == 'get_terms' ) {
$args = array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'meta_query' => $meta_query
);
} elseif ( $func == 'get_users' ) {
$args = array(
'meta_query' => $meta_query
);
} else {
$args = array(
'post_type' => $object_type,
'meta_query' => $meta_query
);
}
if ( $objects = $func( $args ) ) {
return $objects[0]->$return_field;
} else {
return false;
}
}
Any help would be greatly appreciated!
I've created a number of custom fields for custom taxonomy. Got no problem pulling their values inside the query. But in this case, I get them repeating as many times as I have posts in this taxonomy.
This is the code with it inside the loop
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
}
endwhile;
wp_reset_postdata();
echo $custom;
}
How do I get these to show once, outside the loop?
You can use, get_term_meta;
get_term_meta retrieves metadata for a term.
get_term_meta( $term->term_id, 'your_term_name', true )
So the following code actually worked for me
$term_slug = $tables_terms;
$taxonomies = get_taxonomies();
foreach ( $taxonomies as $tax_type_key => $taxonomy ) {
if ( $term_object = get_term_by( 'slug', $term_slug , $taxonomy ) ) {
break;
}
}
$t_id = $term_object->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
and from there on, I simply echoed each meta like this
echo $term_meta['term_1'];
Try Like that:
Store your output in a array and check when store it that value already exist or not.
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
$term_meta_array = array();
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
if(!in_array($term_meta['term_1'], $term_meta_array)) array_push($$term_meta_array, $term_meta['term_1']);
}
endwhile;
wp_reset_postdata();
echo $custom;
foreach($term_meta_array as $st){
echo $st;
}
}
I have a category with products not visible to everyone.
I already have a script in place, that removes this category from the sidebar widget, when no items in the category are visible to the user.
I created a function that puts the exclude term_id in a global variable.
Now I need something that excludes them from view in the shop.
$GLOBALS['cat_exclude'] = NULL;
function getExcludedCats( ) {
//if( ! is_admin() && (is_product_category() || is_shop())){
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$parentid = $term->term_id;
$args = array(
'hide_empty' => true,
'parent' => $parentid
);
$product_categories = get_terms( 'product_cat', $args );
$exclude = array();
foreach ( $product_categories as $category ) {
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $category->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new WC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
if ( false === $show_category ) {
$exclude[] = $category->term_id;
}
}
if ( ! empty( $exclude ) ) {
$GLOBALS['cat_exclude'] = implode( ',', $exclude );
}
//}
}
add_action('wp_head', 'getExcludedCats');
However, in the shop view itself, the category is still visible. How can I remove it there, when no items in this category are visible to the user.
I have tried:
https://gist.github.com/rynaldos/a9d357b1e3791afd9bea48833ff95994
But it removes the category ALWAYS, in both widget and shop.
Products are being displayed by group membership of the customer:
https://wordpress.org/plugins/groups/
I think I managed to create a script that made this possible:
https://gist.github.com/DarkAllMan/cffb114eb97c6f26882e54793e023587
<?php
/**
Plugin Name: WooCommerce - Hide categories where no products are visible to user
Plugin URI: https://www.randall.nl
Description: Excludes categories with no visible products from the WooCommerce category overview in shop
Version: 0.1
Author: Randall Kam
Author URI: https://www.randall.nl
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( !class_exists( 'ExcludeCats' ) ) :
class ExcludeCats {
public $version = '0.1',
$exclude = array();
protected static $_instance = null;
/**
* Main Plugin Instance
*
* Ensures only one instance of plugin is loaded or can be loaded.
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Constructor
*/
public function __construct() {
// CHECK CATEGORIES FOR VISIBLE PRODUCTS
add_action('wp_head', array( $this, 'get_excluded_cats' ), 10, 3 );
// ADD THE WIDGET SIDEBAR FILTER
add_filter( 'woocommerce_product_categories_widget_args', array( $this, 'kfg_exclude_categories_from_widget'), 10, 1 );
// ADD THE SHOP FILTER
add_filter( 'woocommerce_product_subcategories_args', array( $this, 'filter_woocommerce_product_subcategories_args'), 10, 1 );
}
// GET CATEGORIES WITH NO VISIBLE PRODUCTS AND PUT IN GLOBAL IF GLOBAL FALSE
public function get_excluded_cats( $terms, $taxonomies, $args ) {
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$args = array(
'parent' => $term_id,
'hide_empty' => false,
'hierarchical' => false,
);
$product_categories = get_terms( 'product_cat', $args );
// if a product category and on the shop page
//if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() ) {
if ( ! is_admin() && is_shop() ) {
foreach ( $product_categories as $key => $term ) {
unset($this->exclude);
if($term->taxonomy=='product_cat'){
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $term->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new WC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
}
if ( false === $show_category ) {
$this->exclude[] = $term->term_id;
}
}
}
}
public function get_parent_cats ($cat_termid, $found = array()) {
array_push ($found, $cat_termid);
$term =get_term_by( 'term_id', $cat_termid, 'product_cat');
if($term->parent > 0){
return get_parent_cats($term->parent, $found);
}
return $found;
}
// ADD FILTERS FOR CATEGORIES AND EXCLUDE EMPTY
public function filter_woocommerce_product_subcategories_args( $temp_args = array() ) {
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$temp_args = array(
'parent' => $term_id,
'menu_order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'taxonomy' => 'product_cat',
'pad_counts' => 1,
'include' => NULl,
'exclude' => $this->exclude,
);
return $temp_args;
}
public function kfg_exclude_categories_from_widget( $category_list_args ) {
$current_tax = get_query_var( 'product_cat' );
$term = get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$parents = $this->get_parent_cats($term_id);
$args = array(
'hide_empty' => false,
'hierarchical' => true,
);
$product_categories = get_terms( 'product_cat', $args );
$wexclude = array();
foreach ( $product_categories as $category ) {
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $category->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new wC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
if ( false === $show_category || ( $category->parent > 0 && !in_array($category->parent,$parents) ) ) {
$wexclude[] = $category->term_id;
}
}
if ( ! empty( $wexclude ) ) {
$category_list_args['exclude'] = implode( ',', $wexclude );
unset( $category_list_args['include'] );
}
return $category_list_args;
}
} // class ExcludeCats
endif; // class_exists
/**
* Returns the main instance of the plugin class to prevent the need to use globals.
*
* #since 2.0
* #return WooCommerce_PostcodeAPInu
*/
function ExcludeCats() {
return ExcludeCats::instance();
}
ExcludeCats(); // load plugin
I want to add a filter to get_categories function.
I tried this:
function wpr_cat_filter($args) {
$args['include'] = '37';
return $args;
}
add_filter('get_categories','wpr_cat_filter');
but it doesn't seem to be working. Any ides of what is wrong?
The filter doesn't actually seems to be applied.
If you check the "get_categories" function (in wp-includes/category.php), there's no "get_categories" filter applied:
function &get_categories( $args = '' ) {
$defaults = array( 'taxonomy' => 'category' );
$args = wp_parse_args( $args, $defaults );
$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
// Back compat
if ( isset($args['type']) && 'link' == $args['type'] ) {
_deprecated_argument( __FUNCTION__, '3.0', '' );
$taxonomy = $args['taxonomy'] = 'link_category';
}
$categories = (array) get_terms( $taxonomy, $args );
foreach ( array_keys( $categories ) as $k )
_make_cat_compat( $categories[$k] );
return $categories;
}
Also, if you check the source:
wordpress$ grep -Ri "apply_filters" * | grep get_categories
wp-includes/default-widgets.php: wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
wp-includes/default-widgets.php: wp_list_categories(apply_filters('widget_categories_args', $cat_args));
wp-includes/category.php: $taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
Perhaps it is just a placeholder for a filter that you can add yourself or might be added later.
If you want that filter, change the get_category function:
function &get_categories( $args = '' ) {
$defaults = array( 'taxonomy' => 'category' );
$args = wp_parse_args( $args, $defaults );
$args = apply_filters( 'get_categories', $args );
$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
// Back compat
if ( isset($args['type']) && 'link' == $args['type'] ) {
_deprecated_argument( __FUNCTION__, '3.0', '' );
$taxonomy = $args['taxonomy'] = 'link_category';
}
$categories = (array) get_terms( $taxonomy, $args );
foreach ( array_keys( $categories ) as $k )
_make_cat_compat( $categories[$k] );
return $categories;
}
You might want to file a bug with wordpress or ask on their mailing list to find out why this filter isn't being applied!