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.
Related
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.
I'm working on something on wordpress + woocommerce.
I've inputed some 'filter' attributes value for some products.
So if the value of the attribute for this product includes a "Wood Grains" value, i want to echo an Woodgrains.jpg on the front end.
Therefore if the value = Texture, i want to echo Texture.jpg icon.
the code below is what i've mustered so far, but this only echoes out all the values tagged to a product, i can't figure out what to change to get the 'if' statement in it.
$terms = get_the_terms( $product->id, 'pa_filter');
foreach ( $terms as $term ) {
echo $term->name;
}
here's a screenshot of what the code above does on the front end:
http://edleuro.com/new/wp-content/themes/mystile/img/1.png
If this returns an array of terms for the said product:
$terms = get_the_terms( $product->id, 'pa_filter');
You can check if the returned result array has what you are looking for by doing this:
if (in_array("Wood Grains", $terms))
{
// has it
}
else
{
// doesn't have it
}
Update
Based in your reply to my answer, I have came up with the following:
Create a helper function like this:
function termExists($myTerm, $terms)
{
if (is_array($terms)) {
foreach ($terms as $id => $data) {
if ($data->name == $myTerm)
return true;
}
}
return false;
}
Then you use it like this:
if (termExists('Wood Grains', get_the_terms($product->id, 'pa_filter')))
{
// term exists
}
else
{
// does not exists
}
i found a better way to resolve my problem. i had this in my content-product.php woocommerce template.
<?php
$terms = get_the_terms( $product->id, 'pa_filter');
foreach($terms as $term){
if($term->name == 'Wood Grains'){
echo '<img src="icon_woodgrains.gif">';
}
}
?>
do take note that the term name is case sensitive.
foreach prints Warning: invalid argument supplied for foreach()…
This works for me "on a purely":
if ( is_product() && has_term( 'Wood Grains', 'pa_filter' )) {
echo '<img src="Texture.jpg">';
}
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.
function get_people_cats($taxonomy) {
$output = '';
$terms = get_terms($taxonomy);
$count = count($terms);
if ( $count > 0 ):
foreach ( $terms as $term ):
$output .= "'". $term->name ."'". '=>';
$output .= "'". $term->term_id."',";
endforeach;
endif;
return $output;
}
This function returns a list of custom taxonomies and which words are found if the function is called in a template. But I want to assign the the function values to a variable in functions.php, and it's returning nothing.
If your Taxonomies are actually creaetd with a plugin instead of creating them with code in your functions.php the result of get_terms will be empty untill the taxonomies have initiated, which is on plugin level initiation better yet, most probably using the 'init' hook, so you would have to hook your function after the hook and use it only in your theme template files (not in functions.php) basicly you do something like:
add_action('init', 'get_people_cats', 9999);
Then you would call it normaly: $cats = get_people_cats('person_category');
Hope this solves your issue (I know it took me around an hour to solve this when I ran into it).
If you're not getting terms back it's probably due to where the taxonomy is being registered. If it's being registered in an init hook then you're likely trying to print them out before the taxonomy has actually been registered.
You can test it with the following:
function get_people_cats( $taxonomy ) {
$output = '';
$terms = get_terms('category');
$count = count( $terms );
if ( $count > 0 ):
foreach ( $terms as $term ):
$output .= $term->name.'=>'.$term->term_id;
endforeach;
endif;
return $output;
}
function echo_cats() {
echo get_people_cats('taxonomy_name', array('hide_empty' => 0) );
}
add_action('wp_footer', 'echo_cats');
By hooking into wp_footer it's not being called until well after any plugins that might have registered the taxonomy.
// UPDATE //
Got it. To create an array just do this:
$terms = get_terms($taxonomy, array('hide_empty' => false) );
if( !is_wp_error( $terms ) ) {
foreach( $terms as $term ) {
$types[$term->term_id] = $term->name;
}
}
return $types;
}
That will give you an array of $term->id => $term->name -- you may want to reverse that depending on how you're using the array.
Try this, works fine in my functions.php file on a local site:
function get_people_cats( $taxonomy ) {
$output = '';
$terms = get_terms( $taxonomy );
$count = count( $terms );
if ( $count > 0 ):
foreach ( $terms as $term ):
$output .= $term->name.'=>'.$term->term_id;
endforeach;
endif;
return $output;
}
echo get_people_cats('category');
How would the code below (which is in a foreach loop) sometimes return something and sometimes return nothing when passed the same variables:
$term_id = 76;
$term_parent = 75;
if($term_id != 114 && $term_id != 115 && $term_parent != 83){
$term_link_content = 'something';
} else {
$term_link_content = 'nothing';
}
-- Based on responses so far, the full code is below. I'm basically after the first term that isn't equal to any of the ids listed. And I've checked the loop by outputting the $term_id and $term_parent for different posts which have the same terms so I can see that the if statement is being passed the same values but sometimes the $term_link_content variable has content and other times it's empty.
$posts = get_posts('post_type=products&product_categories=Best Sellers');
foreach($posts as $post){
$post_ID = $post->ID;
$terms = get_the_terms( $post_ID, "product_categories" );
$i = 0;
foreach($terms as $term){
$term_id = $term->term_id;
$term_parent = $term->parent;
$term_name = $term->name;
$term_slug = $term->slug;
if($term_id != 114 && $term_id != 115 && $term_parent != 83){
// only get the first
if(++$i > 1) break;
$term_text = $term_name;
$term_link = $url.'/shop/'.$term_slug;
$term_link_content = '<span class="term_text"><a class="'.$card_colour.'" href="'.$term_link.'">'.$term_text.'</a></span>';
} else { $term_link_content = ''; }
}
}
I presume you define $term_id and / or $term_parent before entering your foreach loop, and perform the rest of the code in the body of the loop.
However, when you do something like this:
foreach (getTerms() as $term) {
// perform an if-statement
}
This might change the variables you defined, eg.:
function getTerms() {
global $term_id, $term_parent;
// probably some database-connection that changes $term_id and $term_parent.
}
Correct me if I'm wrong, but I'm pretty sure Wordpress's functions work this way, so you shouldn't trust generic global variables when you're using Wordpress, when you're developing plugins or when you're using functional-oriented (instead of object-oriented) framework.