1

I am having a real difficulty in trying to filter some data that is going out into an e-mail after the customer places an order. The issue is that every line item is showing the shipping information (pickup location) even though it is the same as the final pickup location at the end of the order.

I have been able to look at the item_meta data which is given, but I am unsure of how to filter it to essentially remove the array portion which has the "Pickup Location' meta key and then still print the rest. Here is the area of the email-order-items.php file where the data is being generated (it is not custom...this is standard for WooCommerce):

if ( ! empty( $item_meta->meta ) ) {

                echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>';
            }

Here is what I am able to see by simply doing:

foreach ($item_meta as $value) {
   print_r($value);
}

Result:

Cookie → Cookie (One-Time)Array ( [_qty] => Array ( [0] => 1 ) [_tax_class] => Array ( [0] => ) [_product_id] => Array ( [0] => 5807 ) [_variation_id] => Array ( [0] => 0 ) [_line_subtotal] => Array ( [0] => 2.5 ) [_line_total] => Array ( [0] => 0 ) [_line_subtotal_tax] => Array ( [0] => 0.15 ) [_line_tax] => Array ( [0] => 0 ) [_line_tax_data] => Array ( [0] => a:2:{s:5:"total";a:1:{i:1;s:1:"0";}s:8:"subtotal";a:1:{i:1;s:4:"0.15";}} ) [_shipping_item_id] => Array ( [0] => 28795 ) [Pickup Location] => Array ( [0] => PICKUP ADDRESS HERE, City, State, Zip ) ) WC_Product_Simple Object ( [id] => 5807 [post] => WP_Post Object ( [ID] => 5807 [post_author] => 596 [post_date] => 2016-07-23 17:55:10 [post_date_gmt] => 2016-07-23 21:55:10 [post_content] => [post_title] => Power Protein Cookie (One-Time) [post_excerpt] => [post_status] => publish [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => power-protein-cookie-one-time [to_ping] => [pinged] => [post_modified] => 2016-07-23 19:39:18 [post_modified_gmt] => 2016-07-23 23:39:18 [post_content_filtered] => [post_parent] => 5806 [menu_order] => 1 [post_type] => product [post_mime_type] => [comment_count] => 0 [filter] => raw ) [product_type] => simple [shipping_class:protected] => [shipping_class_id:protected] => 0 ) ]

How can I iterate through the item_meta data, unset (I think is the way to do it) the Pickup Location data and then still display the rest?

UPDATE: I went in and tried the following code:

if(is_array($item_meta->meta))
{
    foreach($item_meta->meta as $key => $value)
    {
        echo $key . '<br />' . $value;
    }
}

That gave me the following:

Cookie → Cookie (One-Time)_qty Array_tax_class Array_product_id Array_variation_id Array_line_subtotal Array_line_total Array_line_subtotal_tax Array_line_tax Array_line_tax_data Array_shipping_item_id ArrayPickup Location Array

I feel like I am fairly close but not understanding the structure of what is inside of item_meta very well...any help would be appreciated.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

1 Answers1

0

@update 3 - Manipulating a php object (untested):

This is my last try:

// Cloning the base object:
$custom_meta = clone $item_meta;

// OR
// $custom_meta = new stdClass();
// $custom_meta = $item_meta;

// saving the custom array in a temporary variable
$length = sizeof($custom_meta->meta) - 1;
$meta_temp = array_slice( $custom_meta->meta, 0, $length );

// Removing the property (array) from the object
unset($custom_meta->meta);

// Recreating the same property and setting the changed array Key/Values to it
$custom_meta->meta = $meta_temp;

// Displaying your custom object (for test)
echo print_r($custom_meta);

// Using it
$custom_meta->display();

Based on this thread: Is it possible to delete an object's property in PHP?


@update 2 - Alternatives:

1) Instead using unset() function use array_pop() function (as we have to remove the last item in the array):

$item_meta_meta_arr = array_pop( $item_meta->meta );

// you will use now $item_meta_meta_arr
print_r( $item_meta_meta_arr );

2) Instead using unset() function use array_slice() function (as we have to remove the last item in the array):

$length = sizeof($item_meta->meta) - 1;
$item_meta_meta_arr = array_slice( $item_meta->meta, 0, $length );

// you will use now $item_meta_meta_arr
print_r( $item_meta_meta_arr );

But you will not use $item_meta->meta as $item_meta is an object and it's not possible to remove the data from $item_meta->meta directly


@Update (related to the author comments)

Removing a key / value in an array, where the key is Pickup Location.

First we check that it's the right key / value we want to remove

echo $item_meta->meta['Pickup Location'] // should display right "Pickup Location" value.

Once you get the right value, you can use unset() php function. But first we are going to pass our array (keys/values) to a new array. This is the process:

// Copying the data to a new array.
$item_meta_meta_arr = $item_meta->meta;
unset($item_meta_meta_arr['Pickup Location']);

// Checking that it has correctly be unset from the array:
foreach($item_meta_meta_arr as $key => $value)
{
    echo 'Key: '. $key . ' / Value: '  . $value . '<br />';
}

References: - Removing key => value pairs from an array, but its not removing them


original answer

To iterate through multiple arrays / objects you could use this (to see what you get for testing):

if(!is_string($item_meta->meta) )
{
    foreach($item_meta->meta as $key1 => $value1)
    {
        if (is_string($value1)) echo $key1 . $value1 . ' (level 1 - string)<br />';
        elseif ( is_array($value1) || is_object($value1) )
        {
            echo $key1 . ' (level 1 - array)<br />';
            foreach($value1 as $key2 => $value2) {
            {
                if (is_string($value2)) echo $key2 . $value2 . ' (level 2 - string)<br />';
                elseif ( is_array($value2) || is_object($value2) )
                {
                    echo $key2 . ' (level 2 - array)<br />';
                    foreach($value2 as $key3 => $value3) {
                    {
                        if (is_string($value3)) echo $key3 . $value3 . ' (level 3 - string)<br />';
                    }
                } 
            } 
        } 
    }
}

To see the structured data instead using print_r() function, you can use var_dump() function:

echo var_dump( $item_meta );

// Or

foreach ($item_meta as $value)
     echo var_dump( $value );

// Or

foreach ($item_meta->meta as $value)
     echo var_dump( $value );
Community
  • 1
  • 1
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • I utilized your first block of code (with some changes...some minor errors). I am able to isolate the piece that I want to get rid of...it is trapped here: if (is_string($value2)) echo $key2 . $value2 . ' (level 2)
    '; The question is now how do I actually remove it from the item_meta container appropriately? I've tried to set $value2 (which is what I want gone) to blank but it doesn't do anything. What would be the 'proper' way to eliminate that from the item_meta object?
    – user2018888 Aug 16 '16 at 22:02
  • Essentially, I want everything else in the item_meta object...the data is very dynamic, so I can't say which static fields I actually want because it could change for each part...they are variations. For example, one order may contain a meta key that has 'Vegetable' in it, but the next may not have vegetables and just need carbs, so it would have the meta key of 'Carbs.' I can isolate the data down to this: Pickup Location (level 1) 0Fitness Center, 14111 Fitness Drive, Detroit, MI 48000 (level 2) I am looking to remove the data from level where level 1 is Pickup Location. – user2018888 Aug 16 '16 at 23:00
  • I just don't know how to remove that specific piece of data from item_meta...is there even a way for me to do that? I suppose I could iterate through the values myself, but it would be much easier to just eliminate a single piece of data from every item_meta object. – user2018888 Aug 16 '16 at 23:03
  • Your examples are exactly what I ended up doing even before I read...here is what I noticed...If I examine the item_meta-> object first, I see there is a 'Pickup Location' key with a value that is of type 'array' in there. I can then create a second array as you stated, store the item_meta->meta object there, unset the 'Pickup Location' key, see that it is gone, and yet when it prints out using item_meta->display, it's still there. I'm really puzzled: – user2018888 Aug 17 '16 at 02:44
  • yes, I probably can in just a bit. I just tested your other options...array_pop is not working. It does nothing. However, if I set the new array we create to be a copy of the original item_meta->meta object, then I can actually see that after i unset() on the copy, the 'Pickup Location' element is gone. The issue is that I can't actually use item_meta_meta_arr->display in the next section...I get an error which prevents me. Perhaps I can try emptying item_meta->meta and then setting it to be a copy of our new array where unset() worked? How do I contact you? – user2018888 Aug 17 '16 at 03:14
  • ok I will reach out to you soon. The code you just posted is also working...there is no issue with getting the last array item out of the new copy. The problem is that item_meta still needs to be used in item_meta->display() and I can't utilize the new array we created. – user2018888 Aug 17 '16 at 03:25
  • Understand what you are saying, unfortunately, I want to use the display() function as it is currently displaying everything the way we desire...however, I cannot obviously call item_meta_meta_arr->display()...that is kind of the hang up right now. I know there is a proper way of doing this in WooCommerce, I'm just not well-versed enough to know how and I feel like I am circumventing the proper way. – user2018888 Aug 17 '16 at 03:35