Home › Toolset Professional Support › [Resolved] Setting up a view that shows Woocommerce order product attributes as a column.
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | - |
- | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: Asia/Karachi (GMT+05:00)
This topic contains 13 replies, has 3 voices.
Last updated by Waqar 11 months, 1 week ago.
Assisted by: Waqar.
You helped us with this previously in this ticket:
I am now trying to duplicate this on one of our other sites to create an order report page. I can't seem to get the product attribute to work here. I have copied the custom code snippet that was supplied in this ticket, saved, and activated it on the new site.
I also copied and pasted the code that was used in the view to display the selected attributes into the view on the new site.
The only thing I changed was the attribute slug. In what was provided in the previous ticket, the attribute that gets printed is membership type with this line:
return $item['pa_membership-type'];
In the custom code on the new site, I'm trying to display all attributes selected, not just the membership type attribute. So I've changed that code as follows:
return $item['pa_color']; return $item['pa_cut']; return $item['pa_gender']; return $item['pa_site_selection']; return $item['pa_size']; return $item['pa_water_bottle_size'];
That should show any attribute selected from all six attributes we have present on this site. I'm not sure if I've done this correctly or not. But the column in view is showing as empty. I tried reducing this to only showing one attribute just in case I had the syntax wrong here, but that showed nothing as well. So I've definitely done something else wrong.
Can you assist with getting this working? I think I have it most of the way there.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi there
You will need a slightly different approach if you want to output multiple attributes.
A function can only be returned once, so stacking return statements in the way you have won't work, only the first one will ever be executed.
The code from the linked thread shows that a shortcode is registered to to return the product attribute.
A shortcode returns a string.
So if you were to use a single shortcode to return all the attributes, what should the shortcode return? A string with all the attributes separated by commas? Or something else?
But, first, the code needs to work in the same way as on the first site.
Have you inserted the same shortcode where you want the output to appear?
How have you added the code to your site? The theme functions.php, or as a code snippet in the Types settings (or some other plugin)? If via Types or another plugin, is the code snippet active?
OK, I didn't know you could only use return once. Good to know. I'm not a PHP programmer.
I have a code snippet for retrieve-order-attributes in the Toolset | Settings | Custom Code area. That is currently set as
<?php /** * New custom code snippet (replace this with snippet description). */ toolset_snippet_security_check() or die( 'Direct access is not allowed' ); // Put the code of your snippet below this comment. add_shortcode('get_ordered_product_attributes', 'get_ordered_product_attributes_func'); function get_ordered_product_attributes_func() { $order_id = do_shortcode('[wpv-post-id]'); $order = wc_get_order( $order_id ); //returns WC_Order if valid order $items = $order->get_items(); //returns an array of WC_Order_item or a child class (i.e. WC_Order_Item_Product) foreach( $items as $item ) { //returns the type (i.e. variable or simple) $type = $item->get_type(); //the product id, always, no matter what type of product $product_id = $item->get_product_id(); //a default $variation_id = false; //check if this is a variation using is_type if( $item->is_type('variable') ) { $variation_id = $item->get_variation_id(); } return $item['pa_color']; return $item['pa_cut']; return $item['pa_gender']; return $item['pa_site_selection']; return $item['pa_size']; return $item['pa_water_bottle_size']; } }
But I now know the stacked returns needs to be changed.
I have the shortcode appearing as one of the table cells in the View
<td style="text-align: center; text-transform: capitalize;">[get_ordered_product_attributes]</td>
Hi,
Thanks for writing back.
You can update your shortcode, so that it accepts the 'type' attribute, to specify which 'attribute' needs to be returned:
add_shortcode('get_ordered_product_attributes', 'get_ordered_product_attributes_func'); function get_ordered_product_attributes_func($atts) { $a = shortcode_atts( array( 'type' => '' ), $atts ); $order_id = do_shortcode('[wpv-post-id]'); $get_type = $a['type']; $order = wc_get_order( $order_id ); //returns WC_Order if valid order $items = $order->get_items(); //returns an array of WC_Order_item or a child class (i.e. WC_Order_Item_Product) foreach( $items as $item ) { //returns the type (i.e. variable or simple) $type = $item->get_type(); //the product id, always, no matter what type of product $product_id = $item->get_product_id(); //a default $variation_id = false; //check if this is a variation using is_type if( $item->is_type('variable') ) { $variation_id = $item->get_variation_id(); } return $item[$get_type]; } }
In your content, you can call each instance of the desired attribute like this:
[get_ordered_product_attributes type='pa_color'] [get_ordered_product_attributes type='pa_cut'] [get_ordered_product_attributes type='pa_gender'] [get_ordered_product_attributes type='pa_site_selection'] [get_ordered_product_attributes type='pa_size'] [get_ordered_product_attributes type='pa_water_bottle_size']
regards,
Waqar
Thanks!!! OK, that got this *substantially* closer to success. But I'm seeing two remaining problems on the page now.
1) The pa_site_selection attribute is not working. I'm not sure why this would not display anything. On all orders where this attribute should be showing something, it's blank.
2) If we have an order where multiple products are ordered, it is only displaying the attribute for one of the products.
Everything else looks like it is working as expected.
To troubleshoot this, I'll need to see exactly how the related elements are set up in the admin area.
Can you please share temporary admin login details, along with the example page, where these shortcodes are in use?
Note: Your next reply will be private and making a complete backup copy is recommended before sharing the access details.
I tried the admin access details, but it is showing the 'Invalid login details.' message.
Can you please check the username and password again?
I'm setting your next reply as private.
The admin access details worked, thank you.
1) The pa_site_selection attribute is not working. I'm not sure why this would not display anything. On all orders where this attribute should be showing something, it's blank.
- The slug of this 'Site Selection' attribute is 'site-selection' and not 'site_selection'. I've updated the same in the shortcode and it is working now.
[get_ordered_product_attributes type='pa_site-selection']
2) If we have an order where multiple products are ordered, it is only displaying the attribute for one of the products.
- I've done some tests on my website and here is the updated shortcode, that should fix this:
add_shortcode('get_ordered_product_attributes', 'get_ordered_product_attributes_func'); function get_ordered_product_attributes_func($atts) { $a = shortcode_atts( array( 'type' => '' ), $atts ); $order_id = do_shortcode('[wpv-post-id]'); $get_type = $a['type']; $order = wc_get_order( $order_id ); //returns WC_Order if valid order $items = $order->get_items(); //returns an array of WC_Order_item or a child class (i.e. WC_Order_Item_Product) $item_arr = array(); foreach( $items as $item ) { //returns the type (i.e. variable or simple) $type = $item->get_type(); //the product id, always, no matter what type of product $product_id = $item->get_product_id(); //a default $variation_id = false; //check if this is a variation using is_type if( $item->is_type('variable') ) { $variation_id = $item->get_variation_id(); } if (!empty($item[$get_type])) { $item_arr[] = $item[$get_type]; } } if(!empty($item_arr)) { return implode(', ', $item_arr); } }
Thanks for the find on the issue with using - instead of _ . I missed noticing that one.
Your revised code for showing all attributes is working with the exception of the Water Bottle Size attribute.
On the Orders for Admin page here:
hidden link
You can look at order #1869. That one has 3 shirts and 2 water bottles in the order. The attribute column is showing the 3 shirt sizes, but not the 2 water bottle sizes. I'm not sure what would cause it to ignore that specific different attribute. The other attributes all look like they are working fine.
Thanks for helping with this one.
Glad that it is working.
The slug of the 'Water Bottle Size' attribute taxonomy is 'water-bottle-size', but in your shortcode in the view 'pa_water_bottle_size' is used.
You can view the attribute taxonomy slugs at:
{yourwebsite.com}/wp-admin/edit.php?post_type=product&page=product_attributes
Perfect! Sorry for my being completely obtuse on this one. I was forgetting where I had the attributes defined in the view. I should have realized the same mistake was made.
One final thing with this page now is I'm seeing that the table columns are not sorting on each column when I click on the column headers. Feel free to split this into another ticket if need be.
I'm seeing that the Order ID and Order Date field columns are sorting correctly, but the other columns are not. Here's how the other headers are coded in the View:
<th style="text-align: center;">[wpv-heading name="_billing_first_name"]First Name[/wpv-heading]</th> <th style="text-align: center;">[wpv-heading name="_billing_last_name"]Last Name[/wpv-heading]</th> <th style="text-align: center;">[wpv-heading name="_order_total"]Order Total[/wpv-heading]</th> <th style="text-align: center;">[wpv-heading name="post-field"]Ordered products[/wpv-heading]</th> <th style="text-align: center;">[wpv-heading name="post-field"]Product attributes[/wpv-heading]</th>
Previously I had them all as name="post-field". I tried changing to _billing_first_name, _billing_last_name, and _order_total on those three, but that didn't fix it. I'm not sure what I'd use for the other two fields getting the product titles and attributes. I suppose it is possible that I can't sort on those with those being pulled from shortcodes.
New threads created by Waqar and linked to this one are listed below:
https://toolset.com/forums/topic/split-sortable-columns-for-the-view-table/
I've created a separate ticket for your question about the sortable table columns and will follow up on that shortly.
( ref: https://toolset.com/forums/topic/split-sortable-columns-for-the-view-table/ )
You're welcome to mark this ticket as resolved and start a new one, for each new question or concern.
Thanks a bunch!