Can't remove an object from a multi dimensional array - php

The function wp_get_post_terms returns an object
$terms = wp_get_post_terms( get_the_ID(), 'category', $args );
I need to remove one of these objects based on it's values:
$current_id = get_queried_object_id();
foreach( $terms as $key => $value ){
if( in_array($current_id, $value[$key]) ){
unset($terms[$key]);
}
}
But I'm stuck in this error:
Uncaught Error: Cannot use object of type WP_Term as array

You may want to save valid terms into a second array:
$terms = wp_get_post_terms( get_the_ID(), 'category', $args );
$validTerms = [];
$current_id = get_queried_object_id();
foreach( $terms as $key => $value ){
if( $value->term_id != $current_id) {
$validTerms[$key] = $value;
}
}
Edit
The error is stemming from the if statement, as Julien Lachal has explained.
As such, here is the same answer as above unsetting the offending term:
$terms = wp_get_post_terms( get_the_ID(), 'category', $args );
$current_id = get_queried_object_id();
foreach( $terms as $key => $value ){
if( $value->term_id == $current_id) {
unset($terms[$key]);
break; //Found our guilty term, no need to continue the `foreach`.
}
}

I think your error lies here :
if( in_array($current_id, $value[$key]) ){
because $value is a WP_Term, but you're trying to access it using the $key (which is linked to the index of $terms not $value.

Related

Remove Category from List in Wordpress

I have looked all over for a fix for this but I can't find one that works.
I have this code:
<?php
$terms = get_the_terms( $post->ID, 'dining' );
if ( $terms && ! is_wp_error( $terms ) ) :
$dining = array();
foreach ( $terms as $term ) {
$dining[] = $term->name;
}
$dining = implode(", ", $dining );
?>
<div><b>Open For:</b> <?php echo $dining; ?> </div>
I have a custom post type with it's own custom categories. I want to remove one category from the displayed list. It currently displays like this:
Open For: Category 1, Category 2, Category 3, Category 4
I want to remove Category 2 from this list. How do I do that? I have searched all over but none of the results seem to work in this scenario.
Just don't push it into the $dining array, like this:
$dining = array();
foreach ( $terms as $term ) {
if(!$term->name == 'Category 2'){
$dining[] = $term->name;
}
}
You can try this way:
$list_ignore_categories = array( 'Category 2', 'Else Category' );
foreach ( $terms as $term ) {
if ( in_array( $term->name , $list_ignore_categories ) ) {
continue;
}
$dining[] = $term->name;
}

Search for two values in array

I have an array $categories and I would like to check if either 'computers' or 'laptops' are in the array.
I can do
$terms = wp_get_post_terms($post_id, 'product_cat');
foreach ($terms as $term) {
$categories[] = $term->slug;
}
if (in_array( 'computers', $categories)) {
//run a lot of code
}
if (in_array('laptops', $categories)) {
//run a lot of code
}
but is there a way to combine with an OR so I don't have to write out the code twice?
something like
if ((in_array( 'computers', $categories)) OR (in_array('computers-he', $categories))) {
//run a lot of code
}
I tried it but it doesn't work I get.
PHP Warning: in_array() expects parameter 2 to be array, null
1. Define
$categories = array();
before-
$terms = wp_get_post_terms( $post_id, 'product_cat' );
2. Use || like this:-
if(in_array('computers',$categories) || in_array('laptops',$categories)) {
//run a lot of code
}
Now full code will be:-
$categories= array();
$terms = wp_get_post_terms( $post_id, 'product_cat' );
foreach($terms as $term) {
$categories[] = $term->slug;
}
if(in_array('computers',$categories) || in_array('laptops',$categories)) {
//run a lot of code
}
a different approach:
$terms = wp_get_post_terms($post_id, 'product_cat');
foreach ($terms as $term)
{
if(in_array($term->slug, ['computers', 'laptops']))
{
//run a lot of code
break; //run the code once
}
}
I usually do this:
if (array_intersect($categories, ['computers', 'laptops'])) {
//run a lot of code
}
If one or both terms are in $categories, it returns the array with those terms, if none are in it, it returns an empty array which is falsy.
From you question, I guess you need to run code if there is at least one term of particular category. In such case you can use array_reduce and take advantage of short-circuit evaluation:
$criteria = [
'computers' => true,
'laptops' => true
];
$test = function ($carry, $term) use ($criteria) {
return $carry || isset($criteria[$term->slug]);
};
if (array_reduce($terms, $test, false)) {
echo 'Run a lot of code.';
}
Here is working demo.

How to display taxonomy parent for selected taxonomy

I want to show on the site the parent of the selected taxonomy. For that I have the above code but the problem with this is that it is showing all the selected taxonomy in a list with now structure.
global $post;
$features = get_the_terms( $post->ID, 'property-feature' );
if ( !empty( $features ) && is_array( $features ) && !is_wp_error( $features ) ) {
?>
<div class="property-features">
<?php
global $inspiry_options;
$property_features_title = $inspiry_options[ 'inspiry_property_features_title' ];
if( !empty( $property_features_title ) ) {
?><h4 class="fancy-title"><?php echo esc_html( $property_features_title ); ?></h4><?php
}
?>
<ul class="property-features-list clearfix">
<?php
foreach( $parent_term as $single_feature ) {
echo '<li>'. $single_feature->name . '</li>';
}
?>
</ul>
</div>
<?php
}
Example:
Parent: option 1, option 2
Parent 2 : option 3, option 4
If I select option 2 and option 3 I want to see
Parent: option 2
Parent 2 : option 3
Updare 2
global $post;
$features = get_the_terms( $post->ID, 'property-feature' );
$featuresss = get_the_terms( $post->ID, 'property-feature' );
// determine the topmost parent of a term
function get_term_top_most_parent($term_id, $taxonomy){
// start from the current term
$parent = get_term_by( 'id', $term_id, $taxonomy);
// climb up the hierarchy until we reach a term with parent = '0'
while ($parent->parent != '0'){
$term_id = $parent->parent;
$parent = get_term_by( 'id', $term_id, $taxonomy);
}
return $parent;
}
// so once you have this function you can just loop over the results returned by wp_get_object_terms
function hey_top_parents($taxonomy, $results = 1) {
// get terms for current post
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
$y = get_the_terms($terms->term_id, $taxonomy);
// set vars
$top_parent_terms = array();
foreach ( $terms as $term ) {
//get top level parent
$top_parent = get_term_top_most_parent( $term->term_id, $taxonomy );
//check if you have it in your array to only add it once
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// build output (the HTML is up to you)
foreach( $top_parent_terms as $single_feature ) {
echo '<li>'. $single_feature->name . '</li>';
foreach( $terms as $single ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
}
//return $top_parent_terms;
}
I managed to display the top parent for the selected taxonomy but now the problem is that I need now to display in the top parent anly the selected taxonomy from that parent
global $post;
$taxonomy = "property-feature";
// determine the topmost parent of a term
function get_term_top_most_parent($term_id, $taxonomy){
// start from the current term
$parent = get_term_by( 'id', $term_id, $taxonomy);
// climb up the hierarchy until we reach a term with parent = '0'
while ($parent->parent != '0'){
$term_id = $parent->parent;
$parent = get_term_by( 'id', $term_id, $taxonomy);
}
return $parent;
}
// so once you have this function you can just loop over the results returned by wp_get_object_terms
function hey_top_parents($taxonomy, $results = 1) {
// get terms for current post
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
// set vars
$top_parent_terms = array();
foreach ( $terms as $term ) {
//get top level parent
$top_parent = get_term_top_most_parent( $term->term_id, $taxonomy );
//check if you have it in your array to only add it once
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// build output (the HTML is up to you)
foreach( $top_parent_terms as $single_feature )
{
echo '<li>'. $single_feature->name . '</li>';
foreach( $terms as $single ) {
if( $single_feature->term_id == $single->parent ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
}
}
//return $top_parent_terms;
}
CHANGES:
1) Moved taxonomy name to variable (used in echo's).
$taxonomy = "property-feature";
2) Added if condition to the code responsible for displaying sub terms.
if( $single_feature->term_id == $single->parent ) {
echo '<ul><li>'. $single->name . '</li></ul>';
}
REMOVED (not used lines of codes):
1)
$features = get_the_terms( $post->ID, 'property-feature' );
$featuresss = get_the_terms( $post->ID, 'property-feature' );
2)
$y = get_the_terms($terms->term_id, $taxonomy);
CONSIDER:
1) Removing $results variable from:
function hey_top_parents($taxonomy, $results = 1) {
it is not used anywhere or maybe should be to determine if results should be returned or displayed by the function.

Excluding terms (category names) by ID for current post

I found this function to display the terms attached to a post but i can't manage to find a way to exclude specific ID's of some category terms i don't want to display in the list.
Could someone give me a clue were to start? I looked up all the functions used in this function but can't seem to find arguments to exclude id's.
Thanks in advance!
// get taxonomies terms links
function custom_taxonomies_terms_links() {
global $post, $post_id;
// get post by post id
$post = &get_post($post->ID);
// get post type by post
$post_type = $post->post_type;
// get post type taxonomies
$taxonomies = get_object_taxonomies($post_type);
$out = "<ul>";
foreach ($taxonomies as $taxonomy) {
// get the terms related to post
$terms = get_the_terms( $post->ID, $taxonomy );
if ( !empty( $terms ) ) {
foreach ( $terms as $term )
$out .= '<li>'.$term->name.'</li> ';
}
}
$out .= "</ul>";
return $out;
}
Add another conditional if statement within your second foreach() to check whether or not the $term should be ignored. For example:
// An array of IDs to ignore/exclude
$excluded_ids = array( 1, 2, 3, 4);
foreach ( $terms as $term ) {
// Only proceed if the term_id is NOT in the $excluded_ids array
if ( !in_array( $term->term_id, $excluded_ids ) ) {
$out .= '<li>'.$term->name.'</li> ';
}
}

Count published custom posts in Wordpress

I have the following piece of code in a WordPress site which has custom posts.
This appears in a functions.php file.
It was a purchased template and I need to count the just the PUBLISHED custom posts and i added this in the code below :
'.'('.$option->count.')'.'
It is working just fine at the moment, but it's counting trash as well.
Please could somebody help me, thank you very much.
function dox_get_list_terms( $taxonomy = 'category', $term_id, $number, $orderby = 'name', $order = 'ASC', $hide = '0' ) {
$terms = array();
$terms = explode(',', $term_id);
$count = count( $terms );
$output = '';
foreach( $terms as $term ) {
if ($term >= 0) {
$options = get_terms( $taxonomy, 'number='.$number.'child_of='.$term.'&parent='.$term.'&hide_empty='.$hide.'&hierarchical=1&depth=1&orderby='.$orderby.'&order='.$order );
if (! is_wp_error($options) ) {
foreach ($options as $option) {
$output .= '<li>
<a href="'.get_term_link($option->slug, $taxonomy).'">
'.$option->name.'
</a>
'.'('.$option->count.')'.'
</li>';
}
}
}
}
return $output;
}
If you set hide_empty=1 in get_terms() function, Then you`ll only get terms who are assigned to any published post or custom posts.
Terms with 0 count will be ignored.

Categories