Remove item from array if value equals - php

On the Woocommerce order page, I have of items in the order, through which I want to loop and exclude a specific item by product id.
$order->get_order_number();
$items = $order->get_items();
foreach( $items as $key => $value) :
$exclude = $value->get_product_id();
if( in_array($exclude, array('3404') ) {
unset($items[$key]);
}
}
endforeach;
$new_items = array_values($items);
I thought this would loop through the original array, remove the $item whose $product_id == 3404 and then reindex.
I'm having no luck here. Any thoughts?
Solved ->
//Filter out colon cleanse duo
$items = array_filter($order->get_items(), function($item) {
return $item->get_product_id() != 3404;
});
//Randomize ids and grab one
shuffle($items);
foreach( $items as $item) :
$product_id = $item->get_product_id();
$product_name = $item->get_name();
break;
endforeach;

You should be able to do this:
$items = array_filter($order->get_items(), function($item) {
return $item->get_product_id() != 3404;
});
This iterates over $items and passes like a foreach each value to $item. If the callback of array_filter returns a true, the value will be kept else dropped.
You even can pass $order->get_items() directly in without fetching the items to an array.
Additionally if you require to exclude more than one, as asked in your comment, you can do like so:
$items = array_filter($order->get_items(), function($item) {
return !in_array($item->get_product_id(), [3404, 6890]);
});

Related

PHP | Add elements to the array and sort after loop

I'm trying to get some numeric values ​​out, recovered thanks to: wp_get_post_terms, which retrieves me the daughter taxonomies of customized taxonomies, where prices are inserted in them in numerical form.
The goal is to display prices using sort and rsort, in the order decided.
When recovering the values, however, I am wrong to add elements to the array and sort them later
code:
foreach ($qprice as $r)
{
$children = $r->term_id;
$child_terms = get_term_children($r->term_id, 'servizi_pro');
$all_terms = wp_get_post_terms($r->ID, 'servizi_pro');
foreach ( $all_terms as $term )
{
if (!in_array($term->term_id, $child_terms))
continue;
$price = $term->name;
$final_price = [$price];
}
rsort($final_price, SORT_NUMERIC);
foreach($final_price as $pr_f) {
echo '<span class="numberCircle"><span>'.str_pad($pr_f, 9).''.'€'.'</span></span>';
}
}
plus:
$final_price = [];
foreach ($qprice as $r)
{
$children = $r->term_id;
$child_terms = get_term_children($r->term_id, 'servizi_pro');
$all_terms = wp_get_post_terms($r->ID, 'servizi_pro');
foreach ( $all_terms as $term )
{
if (!in_array($term->term_id, $child_terms))
continue;
$price = $term->name;
$final_price[] = $price;
}
}
sort($final_price, SORT_NUMERIC);
foreach($final_price as $pr_f) {
echo '<span class="numberCircle"><span>'.str_pad($pr_f, 9).'€'.'</span></span>';
}
You need to initialize the $final_price array before the inner foreach loop, and push onto the array rather than replacing it each time through the loop.
foreach ($qprice as $r)
{
$children = $r->term_id;
$child_terms = get_term_children($r->term_id, 'servizi_pro');
$all_terms = wp_get_post_terms($r->ID, 'servizi_pro');
$final_price = [];
foreach ( $all_terms as $term )
{
if (!in_array($term->term_id, $child_terms))
continue;
$price = $term->name;
$final_price[] = $price;
}
rsort($final_price, SORT_NUMERIC);
foreach($final_price as $pr_f) {
echo '<span class="numberCircle"><span>'.str_pad($pr_f, 9).''.'€'.'</span></span>';
}
}

Update custom order item meta in WooCommerce

I am missing something. I have seen several articles about how to update an items meta data but I can't get any one of them to work. I need to get the item_id but I can't figure out how to do that.
$your_phone = $item->get_meta('dinner_phone'); // 1115559999
$update_phone = wdc_format_phone($your_phone); // comes back (111) 555-9999
wc_update_order_item_meta($item_id,'dinner_phone', $update_phone); //I want to update with new format
$new_phone = $item->get_meta('dinner_phone'); // doesn't work I still get 1115559999
I have tried to pull the Item_id by the following
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$item_id = $item['item_id'];
break;
}
Also tried this
foreach ($items as $key => $product ) {
$item_id = $key;
}
You will use the following from an existing WC_Order Object $order variable:
foreach ( $order->get_items() as $item-id => $item ) {
$dinner_phone = $item->get_meta('dinner_phone'); // 1115559999
if ( ! empty( $dinner_phone ) ) {
$formatted_diner_phone = wdc_format_phone( $dinner_phone ); // comes back (111) 555-9999
$item->update_meta_data('dinner_phone', $formatted_diner_phone);
$item->save(); // Save item
$new_phone = $item->get_meta('dinner_phone');
echo $new_phone; // Check that items is updated
}
$order->calculate_totals(); // Recalculate Order totals and save
}
It should work.

How to get order items ids to get some product meta data?

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;
}

Call the results from a previous Foreach

I am trying to get the results from my Foreach in another echo way later then the foreach but I am stuck, any help would be much appericated.
$items = $order->get_items();
// Output the loop
foreach ($order->get_items() as $item) {
// Getting some information
$product_qty = $item['qty'];
$product_variation_id = $item['variation_id'];
$product = new WC_Product($item['product_id']);
// SKU
$SKU = $product->get_sku();
print_r($SKU);
print_r($product_qty);
print_r(' ');
}
// this gives all 3 quantities and all 3 sku, added a space at the end for easier reading
// this only gives the 1st entry of both variables but i need all 3 of both variables
echo '<a href="https://www.domainname.someurl'.$product_quantity .$SKU . '" target=_blank>';
echo "<p>TEXT</p></a>";
I hope it is clear like this, thanks
Well, you're overwriting the value of $SKU and product_qty on each iteration, maybe try storing them in an array? Like create an array outsite the loop and use array_push(created_array, array($SKU, $product_qty)). Hope it helps.
$items = $order->get_items();
$push = array();
// Output the loop
foreach ($order->get_items() as $item) {
// Getting some information
$product_qty = $item['qty'];
$product_variation_id = $item['variation_id'];
$product = new WC_Product($item['product_id']);
// SKU
$SKU = $product->get_sku();
array_push($push, array('sku'=>$SKU, 'qty'=>$product_qty));
print_r($SKU);
print_r($product_qty);
print_r(' ');
}
// this gives all 3 quantities and all 3 sku, added a space at the end for easier reading
// this only gives the 1st entry of both variables but i need all 3 of both variables
$link = '<a href="https://www.domainname.someurl';
for ($i=0;$i<count($push);$i++){
$link .= $push[$i]['qty'];
$link .= $push[$i]['sku'];
}
$link .= '" target=_blank>';
echo $link;
Try the below code
$items = $order->get_items();
// Output the loop
$product_qty_string = '';
$sku_string = '';
foreach ($order->get_items() as $item) {
// Getting some information
$product_qty_string .= $item['qty']."-";
// SKU
$SKU = $product->get_sku();
$sku_string .=$SKU."-";
}
$product_quantity = rtrim($product_qty_string,'-');
$SKU = rtrim($sku_string,'-');
echo '<a href="https://www.domainname.someurl'.$product_quantity.''.$SKU.''" target=_blank>';
echo "<p>TEXT</p></a>";
Why don't you add your values in a array and then implode them.
$items = $order->get_items();
// Output the loop
$SKU = $product_qty = [];
foreach ($order->get_items() as $item) {
// Getting some information
$product_qty[] = $item['qty'];
$product_variation_id = $item['variation_id'];
$product = new WC_Product($item['product_id']);
// SKU
$SKU[] = $product->get_sku();
print_r($SKU);
print_r($product_qty);
print_r(' ');
}
$sku_string = implode('-', $SKU);
$product_qty_string = implode('-', $product_qty);
echo '<a href="https://www.domainname.someurl'.$product_qty_string .$sku_string . '" target=_blank>';
echo "<p>TEXT</p></a>";
You can implode your data with any separator you want, i use "-" for my example but its depending on your needs.

get last cart item id woocommerce

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.

Categories