I got a function where i collect the data and then explode, this function is inside of a while, of wordpress
global $woocommerce;
global $wpdb;
$args = array( 'post_type' => 'product', 'stock' => 1, 'posts_per_page' => -1);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
foreach($product as $sku){
$sku = $product->get_sku();
$sku_s = explode('-', $sku);
$camp = $sku_s[0];
$itm_n = $sku_s[1];
}
<h6><span class="a1"><?php echo $camp;?></span>-<span class="a2"><?php echo $itm_n;?></span></h6>
MY output
is like this
<h6><span class="a1">581</span>-<span class="a2">20</span></h6>
<h6><span class="a1">581</span>-<span class="a2">50</span></h6>
<h6><span class="a1">581</span>-<span class="a2">1</span></h6>
<h6><span class="a1">581</span>-<span class="a2">6</span></h6>
<h6><span class="a1">581</span>-<span class="a2">9</span></h6>
581-20
581-1
581-9 .... so on..
But i need to sort the numbers for oder, for example
581-1
581-6
581-9....and so on...
Thanks for you help.
Create a comparison function for your skus i.e.
function myComparison(a,b) {
a.id<b.id;
}
then use that in a standard array sort
$skus.sort(myComparison);
Cannot see exactly how your objects are laid out but I hope this helps lead you top the right answer.
First off, this foreach loop doesn't make much sense. Why would you be iterating over $sku to immediately overwrite it with $product->get_sku()?
//what you wrote
foreach($product as $sku){
$sku = $product->get_sku();
$sku_s = explode('-', $sku);
$camp = $sku_s[0];
$itm_n = $sku_s[1];
}
//did you mean this?
foreach($products as $product){
$sku = $product->get_sku();
$sku_s = explode('-', $sku);
$camp = $sku_s[0];
$itm_n = $sku_s[1];
}
Assuming that you can identify which variable is extracted in each iteration (and that it resembles the corrected loop above) you can try one of two things.
(1) Have you tried passing the orderby to the WP_Query that you are running?
http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
(2) You need to re-index your results so that your order is based on natural sort order of your SKUs.
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
//create a new array to hold by SKU
$sortProducts = array();
foreach($products as $product){
$sortProducts[$product->get_sku()] = $product;
}
endwhile;
//sort natural order
ksort($sortProducts, SORT_NATURAL);
//notice that this is a different foreach loop here
foreach($sortProducts as $sku => $product){
$sku = $product->get_sku();
$sku_s = explode('-', $sku);
$camp = $sku_s[0];
$itm_n = $sku_s[1];
echo "<h6><span class=\"a1\">$camp</span>-<span class=\"a2\">$itm_n</span></h6>";
}
EXAMPLE OUTPUT IMAGE
Related
I have a working wordpress loop which displays all posts of a certain meta_query value. The only issue is that the values are repeated. For example, if I have two posts with the value "Blue" then both posts appear in the loop, which makes "Blue" appear twice.
What I would like is for "Blue" to appear once, and underneath it, a list of all post titles with that value.
Here's my current query:
<?php
$the_query = new WP_Query(array(
'post_type' => 'post',
'post_status' => 'publish',
'meta_key' => 'colors',
));
while ( $the_query->have_posts() ) : $the_query->the_post();
$colors = get_field('colors');
if( $colors ): foreach( $colors as $color ):
endforeach;
endif;
echo' <div><h2>'.$color.'</h2><div>'.get_the_title( $post_id ).'</div></div>';
endwhile; wp_reset_postdata();?>
I tried using an array for the titles, but it just returned "Array"
$titles = get_the_title();
$title_names = array();
foreach ($titles as $title){
$title_names[] = get_the_title($id);}
echo $title_names
I'm thinking I need another if statement somewhere with an array? Or maybe I'm approaching this from the wrong direction.
You would want to try something like this:
$results = [];
while ( $the_query->have_posts() ) {
$the_query->the_post();
$colors = get_field('colors');
if( !empty($colors) ) {
foreach( $colors as $color ) {
$results [$color][]['title'] = get_the_title();
$results [$color][]['link'] = get_attachment_link();
}
}
}
foreach ($results as $color => $posts) {
echo "<div><h2>{$color}<h2>";
foreach($posts as $post) {
echo "<div>{$post['title']}</div>";
}
echo '</div>';
}
I'm trying to extract item meta value from Woocommerce's orders by using:
$data = wc_get_order_item_meta( $item, '_tmcartepo_data', true );
However, I can't find a way to get order_item_id as the first parameter (using get_items)
global $woocommerce, $post, $wpdb;
$order = new WC_Order($post->ID);
$items = $order->get_items();
foreach ( $items as $item ) {
$item_id = $item['order_item_id']; //???
$data = wc_get_order_item_meta( $item_id, '_tmcartepo_data', true );
$a = $data[0]['value'];
$b = $data[1]['value'];
echo $a;
echo $b;
}
And I mean this order item_id (1 and 2)
Order_item_id in database - Image
How can I don that?
Thanks.
2018 Update:
Clarifying the answer with 2 possible cases
Added compatibility for woocommerce 3+
So There can be 2 cases:
1) Get product meta data (not set in order item meta data):
You will need to get the product ID in the foreach loop for a WC_Order and to get some metadata for this product you wil use get_post_meta() function ( but NOT wc_get_order_item_meta() ).
So here is your code:
global $post;
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach ( $order->get_items() => $item ) {
// Compatibility for woocommerce 3+
$product_id = version_compare( WC_VERSION, '3.0', '<' ) ? $item['product_id'] : $item->get_product_id();
// Here you get your data
$custom_field = get_post_meta( $product_id, '_tmcartepo_data', true);
// To test data output (uncomment the line below)
// print_r($custom_field);
// If it is an array of values
if( is_array( $custom_field ) ){
echo implode( '<br>', $custom_field ); // one value displayed by line
}
// just one value (a string)
else {
echo $custom_field;
}
}
2) Get order item meta data (custom field value):
global $post;
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach ( $order->get_items() as $item_id => $item ) {
// Here you get your data
$custom_field = wc_get_order_item_meta( $item_id, '_tmcartepo_data', true );
// To test data output (uncomment the line below)
// print_r($custom_field);
// If it is an array of values
if( is_array( $custom_field ) ){
echo implode( '<br>', $custom_field ); // one value displayed by line
}
// just one value (a string)
else {
echo $custom_field;
}
}
If the custom field data is an array, you can access the data in a foreach loop:
// Iterating in an array of keys/values
foreach( $custom_field as $key => $value ){
echo '<p>key: '.$key.' | value: '.$value.'</p>';
}
All code is tested and works.
Reference related to data in orders:
How to get WooCommerce order details (also for woocommerce 3)
Get Order items and WC_Order_Item_Product in Woocommerce 3
When doing the foreach on $order->get_items(), their key is actually the orderline ID. So:
foreach ( $order->get_items() as $key => $item ) {
$data = wc_get_order_item_meta( $key, '_tmcartepo_data' );
...
}
Late to the party, but being working with the same point with TM Extra Product Options plugin, I think this is what answers your question:
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach( $items as $item ){
$data = unserialize($item['item_meta']['_tmcartepo_data'][0]);
$a = $data[0]['value'];
$b = $data[1]['value'];
echo $a;
echo $b;
}
Tested and works in my case.
Use this <pre><?php print_r($items); ?></pre> to check all the contents of the $items array/object.
foreach ( $order->get_items() as $key => $item ) {
$data = wc_get_order_item_meta( $key, '_tmcartepo_data' );
...
This solution was worth to me, change "_tmcartepo_data" for your meta_key.
A simple way to get order items from database;
/**
* #param $order_id
*
* #return array|null|object
*/
function get_order_items( $order_id ) {
global $wpdb, $table_prefix;
$items = $wpdb->get_results( "SELECT * FROM `{$table_prefix}woocommerce_order_items` WHERE `order_id` = {$order_id}" );
$item_name = array();
foreach ( $items as $item ) {
$item_name[] = $item->order_item_name;
}
return $item_name;
}
I am want to get the category of the items in the cart at the checkout in WooCommerce. I want to extract it and then place it in a field in my custom checkout.
I'm using WooCommerce MultiStep Checkout Wizard premium plugin and a specific hook:
add_action('woocommerce_multistep_checkout_before_order_info', 'destinationStep');
I'm a little lost and can't find much documentation for what I need to use to get it.
I'm trying to just get items to appear but I just get an empty array.
$order = new WC_Order( $order_id );
$items = $order->get_items();
var_dump($items);
You could try first with your approach "new WC_Order( $order_id );", this way:
function destinationStep( $order_id )
global $woocommerce;
$order = new WC_Order( $order_id );
$items = $order->get_items();
// echo var_dump($items);
//----
foreach ($items as $key => $item) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$terms = get_the_terms( $product_id, 'product_cat' );
// echo var_dump($terms);
foreach ( $terms as $term ) {
// Categories by slug
$product_cat_slug= $term->slug;
}
}
add_action('woocommerce_multistep_checkout_before_order_info', 'destinationStep', 10, 1);
If it still doesn't work try with "new WC_Order($post->ID)" approach:
function destinationStep()
global $woocommerce, $post;
$order = new WC_Order($post->ID);
$items = $order->get_items();
// echo var_dump($items);
//----
foreach ($items as $key => $item) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$terms = get_the_terms( $product_id, 'product_cat' );
// echo var_dump($terms);
foreach ( $terms as $term ) {
// Categories by slug
$product_cat_slug= $term->slug;
}
}
add_action('woocommerce_multistep_checkout_before_order_info', 'destinationStep');
Update - After some thought:
You can't get the order Id for `'post_type' => 'shop_order', because it doesn't exist yet. This order ID is generated when customer submit the order, but not before on checkout page.
So in this case, it's normal to get an empty array.
I want to get all the product data in the WooCommerce (product sku, name, price, stock count, availability and etc.) Can I do that using wp-query?
This way you can get all products via wp_query :
global $wpdb;
$all_product_data = $wpdb->get_results("SELECT ID,post_title,post_content,post_author,post_date_gmt FROM `" . $wpdb->prefix . "posts` where post_type='product' and post_status = 'publish'");
And if you want further product data then it will be like this :
$product = wc_get_product($product_id);
$product->product_type;
get_post_meta($prodyct_id, '_regular_price');
$product->get_available_variations();
Thanks for all reply.I have resolve that like billows
$full_product_list = array();
$loop = new WP_Query(array('post_type' => array('product', 'product_variation'), 'posts_per_page' => -1));
while ($loop->have_posts()) : $loop->the_post();
$theid = get_the_ID();
$product = new WC_Product($theid);
if (get_post_type() == 'product_variation') {
// ****************** end error checking *****************
} else {
$sku = get_post_meta($theid, '_sku', true);
$selling_price = get_post_meta($theid, '_sale_price', true);
$regular_price = get_post_meta($theid, '_regular_price', true);
$description=get_the_content();
$thetitle = get_the_title();
}
// add product to array but don't add the parent of product variations
if (!empty($sku))
$full_product_list[] = array("PartyID" => (int) $party_id,"Description"=> $description,
"ExternalNumber" => $theid, "ProductName" => $thetitle, "sku" => $sku,
"RegularPrice" => $regular_price, "SellingPrice" => $selling_price,
"ExternalProductCategoryId" => $cat_id, "ExternalProductCategoryName" => $cat_name);
endwhile;
When your building out your query set the post type to be product
$query->set('post_type', 'product');
And that will only search through woocommerce products.
Also if you are creating a theme, you can take any file from the /wp-content/plugins/woocommerce/templates/ directory and put it inside of /wp-content/themes/<yourTheme>/woocommerce to override any woocommerce page.
you can write this code in page that you want to display all product information
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 10
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
echo '<br />' . woocommerce_get_product_thumbnail().' '.get_the_title().'';
global $product;
//echo $product;
echo $product->get_id();
echo $product->get_name();
echo $product->get_sale_price();
echo $product->get_regular_price();
echo $product->get_sku();
echo $product->get_low_stock_amount();
echo $product->get_review_count();
echo $product->get_short_description();
$ratting = $product->get_rating_counts();
for($i = 0 ; $i < count($ratting); $i++) {
echo $ratting[i];
}
endwhile;
wp_reset_query();
?>
This is an old question; the answers using WP_Query() are obsolete since 2018.
See my answer here.
I use woocommerce on wordpress. This is my code
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = $values['data']->post;
echo $_product->ID.',';
}
?>
And this is the result of teh code:
1297,1694,1297,3911,4999,
How can I get just last id '4999' ?
Storing the ids in an array and using the end() function would be a solution:
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
$ids = array();
foreach($items as $item => $values) {
$_product = $values['data']->post;
$ids[] = $_product->ID;
}
echo 'Last item = ' . end($ids);
?>
You can do it even simpler that what Akhilesh proposed - instead of iterating through $items array go to the last item there:
end($items)['data']->post->ID;
I am not sure, but probably you would need PHP 5.3+ for that.