php error using wordpress function get_terms - php

I'm setting a variable in my site this way:
$args = array('parent' => 2818,'hide_empty' => false);
$best_of_cat_child_terms = get_terms( $args ); -> (functions.php:26)
$best_of_cat = $best_of_cat_child_terms;
The problem is that I'm also getting this php error:
Warning:
Invalid argument supplied for foreach()
Location:
wp-includes/class-wp-term-query.php:373
Call Stack:
WP_Term_Query->get_terms()
wp-includes/class-wp-term-query.php:287
WP_Term_Query->query()
wp-includes/taxonomy.php:1217
get_terms()
wp-content/themes/theme-child/functions.php:26 (-> functions.php line 26 marked above)
Am I setting this the right way?

You can check for the error with is_wp_error(),
$terms = get_terms( array(
'taxonomy'=> 'category',
'parent' => 2818,
'hide_empty' => 0)
);
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li>' . $term->name . '</li>';
}
echo '</ul>';
}
else{
$error_string = $terms->get_error_message();
echo '<div id="message" class="error"><p>' . $error_string .'</p></div>';
}
About the error you told in comment, it's look like you don't run with a WordPress version under 4.5 ?
Prior to 4.5.0, the first parameter of get_terms() was a taxonomy or list of taxonomies:
$terms = get_terms( 'post_tag', array(
'hide_empty' => false,
) );
Since 4.5.0, taxonomies should be passed via the ‘taxonomy’ argument in the $args array:
$terms = get_terms( array(
'taxonomy' => 'post_tag',
'hide_empty' => false,
) );
About get_terms()
In your case, remove taxonomy from $args and
$terms = get_terms('category', $args);

Provide the taxonomy arg:
$args = array(
'taxonomy' => 'your_taxonomy',
'parent' => 2818,
'hide_empty' => false
);

Related

Hi How to get child terms from a specific term and exclude some specific terms

I am struggling to add 'exclude' to exclude some terms for the below code.
I cannot find the correct way to write such an array. Can anyone help me? Thanks
<?php
$terms = get_terms( 'product_cat', 'parent=175' );
$count = count($terms);
if ( $count > 0 ){
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li>'. $term->name . '</li>';
}
echo '</ul>';
}
?>
your usage of get_terms is incorrect.
it takes an array of arguments like so:
$terms = get_terms( array(
'taxonomy' => 'product_cat',
'parent' => $parent_id,
'exclude' => array( $ids, $to, $exclude )
) );

Get custom taxonomy's custom meta from outside the loop

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;
}
}

How to search for a string in a category name?

I use the search result and I GET
$s = $_GET['s'];
Which gives: "mario"
Now there is a category named Mario Bianchi under a main category called Persone
When I GET $s I need to get all posts within that category, I tried the following but I get nothing
$terms = get_terms( 'category', array(
'name__like' => $s,
'hide_empty' => true // Optional
) );
if ( count($terms) > 0 ){
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li>' . esc_html( $term->name ) . '</li>';
}
echo '</ul>';
}
Yet I need the actual post attached, not the category itself
get_terms does just that, it get the terms for your query. What you'll want is WP_Query with a tax_query. You've already got the categories you want to return the posts for, so it shouldn't be too difficult
$terms = get_terms( array(
'taxonomy' => 'category',
'name__like' => $s,
'hide_empty' => true // Optional
) );
$term_ids = array();
if ( ! empty( $terms ) ) {
foreach( $terms as $term ) {
$term_ids[] = $term->term_id;
}
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'terms' => $term_ids,
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
echo '<ul>';
while ( $query->have_posts() ) {
$query->the_post();
echo '<li>' . esc_html( get_the_title() ) . '</li>';
}
echo '</ul>';
}
wp_reset_postdata();
}

Returning custom taxonomy in slug order

I have a loop to pull in custom taxonomy terms that I'd like to order by slug, but when I add in the 'orderby' command my loop is broken and returns nothing. No doubt I'm using incorrect syntax, but I can't see where for the life of me!
<?php
$loop = new WP_Query(
array(
'post_type' => 'camp',
'orderby' => 'name',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => 'types',
'field' => 'slug',
'terms' => $term->slug,
),
)
)
);
if ($loop->have_posts()) :
while ($loop->have_posts()) : $loop->the_post();
$terms = get_lowest_taxonomy_terms(get_the_terms( get_the_ID(), array(
'taxonomy' => 'destinations',
'orderby' => 'slug',
'order' => 'ASC'
)) );
?>
Any help would be very much appreciated :)
Added additional function:
The get_lowest_taxonomy_terms is running as follows:
get_lowest_taxonomy_terms( $terms ) {
// if terms is not array or its empty don't proceed
if ( ! is_array( $terms ) || empty( $terms ) ) {
return false;
}
$filter = function($terms) use (&$filter) {
$return_terms = array();
$term_ids = array();
foreach ($terms as $t){
if( $t->parent == 0 ) {
$term_ids[] = $t->term_id;
}
}
foreach ( $terms as $t ) {
if( $t->parent == false || !in_array($t->parent,$term_ids) ) {
//remove this term
}
else{
$return_terms[] = $t;
}
}
if( count($return_terms) ){
return $filter($return_terms);
}
else {
return $terms;
}
};
return $filter($terms);
}
Desired Output
The loop should query the taxonomy type 'destination', where that destination has the additional taxonomy of 'type'.
Screen grab of the current output:
The results are ordered into 3 cols by CSS, but as you can see, not sorting alphabetically.
get_the_terms doesn't take an array as second parameter.
get_the_terms( int|object $post, string $taxonomy )
Parameters:
$post (int|object) (Required) Post ID or object.
$taxonomy (string) (Required) Taxonomy name.
More details of get_the_terms
By default, get_the_terms doesn't have any sorting option. But, you can use usort to sort the returned array.
So, your last part of the code should be:
$terms = get_lowest_taxonomy_terms(get_the_terms( get_the_ID(), 'destinations' ));
This is a quick example of how you can sort it using usort:
$terms = get_the_terms( get_the_ID(), 'destinations' );
usort($terms,"so980_sort_terms_alphabetically");
function so980_sort_terms_alphabetically($a,$b) {
return $a['slug'] > $b['slug'];//using 'slug' as sorting order
}
so980_sort_terms_alphabetically function should be in your theme's functions.php file.
So finally, your last part will become:
$terms = get_the_terms( get_the_ID(), 'destinations' );
usort($terms,"so980_sort_terms_alphabetically");
$terms = get_lowest_taxonomy_terms($terms);
Update
I have just tested it, and it is returning a fatal error, as I have made a mistake. Error message: Fatal error: Cannot use object of type WP_Term as array.
get_the_terms returns an object. So, using $a['slug'] was causing the error.
Here, so980_sort_terms_alphabetically should be implemented in following way:
function so980_sort_terms_alphabetically($a,$b) {
return $a->slug > $b->slug;//using 'slug' as sorting order
}
**This is tested, and working.
Update 2
Since your output codes are not available in your question, I will assume that you are printing inside the loop. Instead of doing that, we will save returned terms in another array, and sort it outside the loop, so that we can get all of the terms at once.
Here is a quick example of how you can do it:
if ($loop->have_posts()) :
while ($loop->have_posts()) : $loop->the_post();
$pre_terms = get_lowest_taxonomy_terms(get_the_terms(get_the_ID(), 'product_tag'));
if ( $pre_terms ) {
foreach ( $pre_terms as $pre_term ) {
$terms[] = $pre_term;
}
}
endwhile;
endif;
usort($terms,"so980_sort_terms_alphabetically");
//a quick test to see if it's working or not
foreach ( $terms as $term ) {
echo $term->slug;
echo '<br/>';
}

WooCommerce subcategories(categories of categories) - A tale of php, stupidly limited functions and frustration

The title should give you a pretty good idea about my misadventures. I am working on a project that's made in wordpress and uses WooCommerce, and after a lot of brainstorming and thought about possible compromise, i have reached the point where i am pretty much certain i have to get into the php code to solve the problem conveniently.
The problem is that i have the following website:
As you may have noticed, there is a mash of all the product categories, and what i need to do is split them into 2 main categories: food and drink. I turned what woocommerce can do by its built in functions and i just can't get it to work so i figured i'd have to write my own function. Now if any of you knows that i can actually do it with what i have i'd be happy if somebody told me. If not what i need is to create a function which can actually select all the categories belonging to a parent category or something the likes.
public function product_categories( $atts ) {
global $woocommerce_loop;
extract( shortcode_atts( array (
'number' => null,
'orderby' => 'name',
'order' => 'ASC',
'columns' => '4',
'hide_empty' => 1,
'parent' => ''
), $atts ) );
if ( isset( $atts[ 'ids' ] ) ) {
$ids = explode( ',', $atts[ 'ids' ] );
$ids = array_map( 'trim', $ids );
} else {
$ids = array();
}
$hide_empty = ( $hide_empty == true || $hide_empty == 1 ) ? 1 : 0;
// get terms and workaround WP bug with parents/pad counts
$args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
'include' => $ids,
'pad_counts' => true,
'child_of' => $parent
);
$product_categories = get_terms( 'product_cat', $args );
if ( $parent !== "" )
$product_categories = wp_list_filter( $product_categories, array( 'parent' => $parent ) );
if ( $number )
$product_categories = array_slice( $product_categories, 0, $number );
$woocommerce_loop['columns'] = $columns;
ob_start();
// Reset loop/columns globals when starting a new loop
$woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
if ( $product_categories ) {
woocommerce_product_loop_start();
foreach ( $product_categories as $category ) {
woocommerce_get_template( 'content-product_cat.php', array(
'category' => $category
) );
}
woocommerce_product_loop_end();
}
woocommerce_reset_loop();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
This i identified as the menacing WooCommerce function that does not behave. Help. Please help me :(
What about using WooCommerce's built-in [product_categories] shortcode? You could pass categories you want through the id="" attribute.

Categories