Return term_id's recursively - php

I have this code:
public function get_taxonomy_hierarchy( $taxonomy, $parent = 0 )
{
$taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
$terms = get_terms( $taxonomy, [ 'parent' => $parent ] );
$children = [];
foreach ( $terms as $term ) {
$term->url = get_term_link( $term->term_id);
$term->children = $this->get_taxonomy_hierarchy( $taxonomy, $term->term_id );
$children[ ] = $term->id;
}
return $children;
}
My problem is that this function only returns direct descendants id's and ignores others. What am I missing here?

It looks to me like you need to push the term_ids to the children array, rather than just declaring $children[ ] = $term->id;
public function get_taxonomy_hierarchy( $taxonomy, $parent = 0 )
{
$taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
$terms = get_terms( $taxonomy, [ 'parent' => $parent ] );
$children = [];
foreach ( $terms as $term ) {
$term->url = get_term_link( $term->term_id);
$term->children = $this->get_taxonomy_hierarchy( $taxonomy, $term->term_id );
array_push($children, $term->term_id);
}
return $children;
}
Also, shouldn't it be $term->term_id; in line 9 of your code?

Related

Principal Post Wordpress Category Shortcode Returning “Array”

I have created some simple shortcodes in the past to get post title and thumbnail image and everything was fine. But now I am struggling to get the primary category of posts and portfolios on Wordpress.
I have included in my functions.php file the next function from this site:
function get_primary_taxonomy_term( $post = 0, $taxonomy = 'category' ) {
if ( ! $post ) {
$post = get_the_ID();
}
$terms = get_the_terms( $post, $taxonomy );
$primary_term = array();
if ( $terms ) {
$term_display = '';
$term_slug = '';
$term_link = '';
if ( class_exists( 'WPSEO_Primary_Term' ) ) {
$wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $post );
$wpseo_primary_term = $wpseo_primary_term->get_primary_term();
$term = get_term( $wpseo_primary_term );
if ( is_wp_error( $term ) ) {
$term_display = $terms[0]->name;
$term_slug = $terms[0]->slug;
$term_link = get_term_link( $terms[0]->term_id );
} else {
$term_display = $term->name;
$term_slug = $term->slug;
$term_link = get_term_link( $term->term_id );
}
} else {
$term_display = $terms[0]->name;
$term_slug = $terms[0]->slug;
$term_link = get_term_link( $terms[0]->term_id );
}
$primary_term['url'] = $term_link;
$primary_term['slug'] = $term_slug;
$primary_term['title'] = $term_display;
}
return $primary_term;
}
Later I have created a shortcode to get the primary category term from that function:
add_shortcode( 'show_category1', 'get_primary_taxonomy_term' );
Using the shortcode [show_category1] I just get the word 'Array' and not the category term.
enter image description here
Thanks in advance for any feedback.
In your function $primary_term is defined as an array, and the result is obviously an array that contains 'url', 'slug' and 'title' strings. Perhaps try to return something like this:
function get_primary_taxonomy_term( $post = 0, $taxonomy = 'category' ) {
if ( ! $post ) {
$post = get_the_ID();
}
$terms = get_the_terms( $post, $taxonomy );
if ( $terms ) {
$term_display = '';
$term_slug = '';
$term_link = '';
if ( class_exists( 'WPSEO_Primary_Term' ) ) {
$wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $post );
$wpseo_primary_term = $wpseo_primary_term->get_primary_term();
$term = get_term( $wpseo_primary_term );
if ( is_wp_error( $term ) ) {
$term_display = $terms[0]->name;
$term_slug = $terms[0]->slug;
$term_link = get_term_link( $terms[0]->term_id );
} else {
$term_display = $term->name;
$term_slug = $term->slug;
$term_link = get_term_link( $term->term_id );
}
} else {
$term_display = $terms[0]->name;
$term_slug = $terms[0]->slug;
$term_link = get_term_link( $terms[0]->term_id );
}
}
$primary_term= '' . esc_attr($term_display) . '';
return $primary_term;
}

Object doesnt have the same properties inside a function PHP

I've never worked with PHP before. I have the code below, which works fine.
$taxonomy = 'person';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
$separator = '';
if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {
$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />', $separator, $terms ) ), $separator );
echo $terms;
}
I tried to put this in a function so I can pass it an argument and call it.
function get_custom_tax($taxonomy) {
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
$separator = '';
if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {
$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />', $separator, $terms ) ), $separator );
echo $terms;
}
}
$taxonomy = 'person';
get_custom_tax($taxonomy);
But for some reason this doesn't work... Stack tells me im trying to get the property ID of a non-object (I guess for $post->ID)
Whats going on here?
Looks like it was a score issue.
Changing my function to pass $post outside the function did the trick
function get_custom_tax($taxonomy, $post) {
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
$separator = '';
if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {
$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />', $separator, $terms ) ), $separator );
echo $terms;
}
}
$taxonomy = 'person';
get_custom_tax($taxonomy, $post);
Your function is missing post object.. you can declare as global or pass as a params
function get_custom_tax($taxonomy) {
global $post;
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
$separator = '';
if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {
$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />', $separator, $terms ) ), $separator );
echo $terms;
}
}
$taxonomy = 'person';
get_custom_tax($taxonomy);

How to exclude a term from a taxonomy post count function

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

Invalid Argument Error

Im getting an error at the following URL:
http://www.greenmonkeypublicrelations.com/citypads/apartments/the-ivinghoe-2-bedroom-1-bathroom-apartment/
The purpose here is to identify if the post has children, if it has children, to list the terms of those children and echo the permalink to the post as the href and echo the term title as the text to show. Also if the post is a child, then to get the parent post and list the same to show the links on both levels.
Heres my code:
<?php
if( has_children() ){
$postid = get_the_ID();
$args = array(
'post_parent' => $postid,
'post_type' => 'any',
'numberposts' => -1,
'post_status' => 'any'
);
$children_array = get_children( $args, OBJECT );
foreach ($children_array as $child) {
$terms = get_the_terms( $child->ID, 'Apartment_type' );
foreach ($terms as $term) {
echo '' . $term->name . '<br/>';
}
}
} elseif (!has_children()) {
if ( wp_get_post_parent_id( get_the_id() ) ){
$postid = wp_get_post_parent_id( get_the_id() );
$args = array(
'post_parent' => $postid,
'post_type' => 'any',
'numberposts' => -1,
'post_status' => 'any'
);
$children_array = get_children( $args, OBJECT );
foreach ($children_array as $child) {
$terms = get_the_terms( $child->ID, 'Apartment_type' );
foreach ($terms as $term) {
echo '' . $term->name . '<br/>';
}
}
}
} elseif( ( !has_children() ) && (!get_post_ancestors( $post->ID ))) {
echo 'on its own';
} ?>
The problem is that you expect $children_array or $terms are always arrays. foreach expects an array, so if the $children_array or $terms have the value (i.e.) false you'll get this error.
Can you try this:
<?php
if( has_children() ){
$postid = get_the_ID();
$args = array(
'post_parent' => $postid,
'post_type' => 'any',
'numberposts' => -1,
'post_status' => 'any'
);
$children_array = get_children( $args, OBJECT );
if( is_array( $children_array ) ) {
foreach ($children_array as $child) {
$terms = get_the_terms( $child->ID, 'Apartment_type' );
if( is_array( $terms ) ) {
foreach ($terms as $term) {
echo '' . $term->name . '<br/>';
}
}
}
}
} elseif (!has_children()) {
if ( wp_get_post_parent_id( get_the_id() ) ){
$postid = wp_get_post_parent_id( get_the_id() );
$args = array(
'post_parent' => $postid,
'post_type' => 'any',
'numberposts' => -1,
'post_status' => 'any'
);
$children_array = get_children( $args, OBJECT );
if( is_array( $children_array ) ) {
foreach ($children_array as $child) {
$terms = get_the_terms( $child->ID, 'Apartment_type' );
if( is_array( $terms ) ) {
foreach ($terms as $term) {
echo '' . $term->name . '<br/>';
}
}
}
}
}
} elseif( ( !has_children() ) && (!get_post_ancestors( $post->ID ))) {
echo 'on its own';
} ?>

Filter categories in wordpress

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!

Categories