Getting all the product attributes and their terms in WooCommerce - php

I have researched this all day but cant seem to get a straight answer how can I get the set product attributes along with the configured terms for each?
This is what I have now
//get the terms
$attribute_taxonomies = wc_get_attribute_taxonomies();
$taxonomy_terms = array();
if ( $attribute_taxonomies ) {
foreach ($attribute_taxonomies as $tax) {
//dont know what to add here
}
}
var_dump($taxonomy_terms);

Here below you will get a list of all product attributes and their respective term names:
echo '<ul>';
// Loop through WooCommerce registered product attributes
foreach( wc_get_attribute_taxonomies() as $values ) {
// Get the array of term names for each product attribute
$term_names = get_terms( array('taxonomy' => 'pa_' . $values->attribute_name, 'fields' => 'names' ) );
echo '<li><strong>' . $values->attribute_label . '</strong>: ' . implode(', ', $term_names);
}
echo '</ul>';
If you prefer to get an array of the WP_terms objects, you will use:
// Get the array of the WP_Terms Object for the each product attribute
$terms = get_terms( array('taxonomy' => 'pa_' . $values->attribute_name );
That will allow use a foreach loop to get what you want from each term…

First check the wc_get_attribute_taxonomies() function with var_dump().

Related

How to Get a List of All Post Types Which Have Published Posts / Exclude Some Post Types in WordPress using get_post_types() function?

Use of get_post_types() Function
I want to list all the post types on my website tutsinsider on the search page, if the search query has no posts to show, display the list of post types that have published posts. Or even if I want to exclude some of the post types according to need. I want to use the get_post_types() function. Below is my code and an example
Post Types
Post Types
No of Published Posts
one
10
two
12
three
0
four
2
five
15
The post type three has no published posts, and post type four has 2 published posts. I want to exclude these from the list.
But, when I try to list using get_post_types, it lists all the posts.
I am using the below code.
<?php
$args = array(
'public' => true,
'_builtin' => false,
);
$output = 'names'; // 'names' or 'objects' (default: 'names')
$operator = 'and'; // 'and' or 'or' (default: 'and')
$post_types = get_post_types( $args, $output, $operator );
if ( ! empty ( $post_types ) ) { // If there are any custom public post types.
echo '<ul>';
foreach ( $post_types as $post_type ) {
echo '<li>' . $post_type . '</li>';
}
echo '<ul>';
}
?>
Solved
Hi,
After searching a lot and applying different techniques, I came up with this solution. I used the below code and got all the categories that have post status = published.
Since I have similar names of custom post types and categories, therefore, the below function came in handy for me.
Function : get_categories($args)
<?php
$categories = get_categories( array(
'orderby' => 'name',
'parent' => 0
) );
$category_list = array();
foreach ( $categories as $category ) {
$category_list[] = '' . esc_html( $category->name ) . ' ';
}
echo implode( ', ', $category_list );
?>
Further, when I acquired the list of all the categories, I excluded the ones which have less number of posts or which I wanted not to list.
I used the if() statement within foreach-loop and truncated those unwanted categories from the list.
Complete Code
<?php
$categories = get_categories( array(
'orderby' => 'name'
'parent' => 0
) );
$category_list = array();
foreach($categories as $category){
if($category->name != 'unwanted-1' && $category->name != 'unwanted-2) :
$category_list[] = '' . esc_html( $category->name ) . ' ';
}
echo implode( ', ', $category_list );
endif;
}
Source

Display a dynamic WooCommerce siblings and direct children category list

Trying to create function that displays the siblings and the first level children of the current product category. So not the children of the siblings or the children of the children.
The categories can go 4 levels deep, I need the list to change what it is displaying depending on the current page.
Example:
Category 1
Category 2
Category 3 <-- Current product category
Category 3-1
Category 3-2
Category 3-3
Category 3-4
Category 4
Category 5
I found a few posts where displaying the siblings is explained, or the first level children. But I am trying to combine both, without success:
Get a list of siblings term ids from current product category in WooCommerce
Display current category first then child categories in WooCommerce
Any thought? Anything that would point me in the right direction would help.
After a lot of trial and error, I finally figured it out:
function wc_cat_menu() {
$queried_object = get_queried_object();
$taxonomy = 'product_cat';
$sibling_terms = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'parent' => $queried_object->parent
) );
echo '<ul>';
foreach( $sibling_terms as $sibling ) {
if ( $sibling->parent > 0 ) {
$sibling_id = $sibling->term_id;
$siblingChildren = get_terms( $taxonomy, array(
'parent' => $sibling_id,
'hide_empty' => false
) );
echo '<li>' . $sibling->name . '<span> (' . $sibling->count . ')</span>';
if( $siblingChildren ) {
echo '<ul>';
foreach ( $siblingChildren as $child ) {
echo '<li>' . $child->name . '<span> (' . $child->count . ')</span></li>';
}
echo '</ul>';
}
echo '</li>';
}
}
echo '</ul>';
}
Learned a lot during the process! There is probably a much efficient way to achieve this, any suggestions are welcome.

WooCommerce get_the_terms category and subcategory order

I'm building a woocommerce website and what I'm trying to do is to get subcategories names with and relative links, over the product title.
So i call this action to retrieve the category to display the category before the title:
add_action('woocommerce_single_product_summary' , 'cat_type_before_title', 3);
function cat_type_before_title() {
global $post;
$terms = get_the_terms( get_the_ID(), 'product_cat' );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term->term_id );
<!-- this line below is to test the order of all the categories assigned -->
echo '<h2>'. $term->name . '</h2>';
}
//echo '<h2>'. $terms[2]->name . '</h2>';
}
The problem I'm having is that the output of the categories it's not always in the order that i would expect.
I have this categories structure:
CAT_A
- CAT_B
-- CAT_C
CAT_D
- CAT_E
-- CAT_F
..and so..
For some reason the output with $term->name in the foreach loop for some of the categories it's not in the expected order and i have somenthing like :
CAT_C
CAT_A
CAT_B
so, for example, if want retrieve the category name i want to print with $terms[1]->name i will expect CAT_B but instead i have CAT_A.
What i'm missing?
Any help?
Thank you! :)
You can use wp_get_post_terms() insted of get_the_terms() to get terms in that function you can use third parms to pass orderby. check code below.
add_action('woocommerce_single_product_summary' , 'cat_type_before_title', 3);
function cat_type_before_title() {
global $post;
$terms = wp_get_post_terms( get_the_ID(), 'product_cat', array( 'orderby' => 'parent' ) );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term->term_id );
echo '<h2>'. $term->name . '</h2>';
}
//echo '<h2>'. $terms[2]->name . '</h2>';
}

Display ACF Taxonomy in order of Multi Select order

Using ACF, I have a Taxonomy field with Multi Select and Stylized UI.
I usually have 2 or 3 tax items selected.
I can arrange them using drag and drop. It's wonderful.
On the front end, the array does not reflect the tax order/sorting that I put in place.
Pretty easy code. What am I doing wrong?
<?php
$values = get_the_terms( $post->ID, 'languages' );
if ( $values ) {
echo '<tr class="item"><td>';
foreach ( $values as $value ) {
echo $value->name . '<br/>';
}
echo '</td></tr>';
}
?>
Figured it out.
Because the field saved the correct sorting in the admin field, I knew the order data was saved somewhere. I looked in the database at the post's terms and the associated data. The order was saved there. Instead of using get_the_terms for the loop, I used get_post_meta. That gave me an array with the term IDs in the correct order. Then I got the term name using that ID within a foreach loop. This gave me the taxonomy names in the order from the styled multi-select field.
<?php
$values = get_the_terms( $post->ID, 'languages' );
if ( $values ) {
echo '<tr class="item"><td>';
$values = get_post_meta( $post->ID, 'languages' );
foreach ( $values as $value ) {
foreach ( $value as $item ) {
$term = get_term( $item )->name;
echo $term .'<br/>';
}
}
echo '</td></tr>';
}
?>

Create associated array out of taxonomy terms

I'm trying to get associated array out of taxonomy slug and taxonomy name. I have this
foreach (get_terms('taxonomy') as $tax_term) {
$taxonomy_slug = $tax_term->slug;
$taxonomy_name = $tax_term->name;
}
The issue is, that these are just strings glued together, I don't know how to separate them :\ When I print_r them out I get:
term1term2term3term4...
What I need is a way to separate those, and then create array that will look like this:
Array(
['term_1'] => Term 1
['term_2'] => Term 2
...
)
Is this possible?
As per your inputs in comments I have tried to find out the solution. Hope this will helps you.
$terms = array();
foreach (get_terms('taxonomy') as $tax_term) {
$taxonomy_slug = $tax_term->slug;
$taxonomy_name = $tax_term->name;
$exploded = explode($taxonomy_name,$taxonomy_slug);
foreach ($exploded as $termValue) {
if (!empty($termValue)) {
$terms[$taxonomy_name."_".$termValue] = ucfirst($taxonomy_name)." ".$termValue;
}
}
}
echo "<pre>"; print_r($terms);

Categories