skip to Main Content

I have custom field data on my WooCommerce orders which I manually add once the order has been completed. How can I delete a line from the custom field including the carriage return and line feed?

My custom field called "SERIAL_NUM" looks like this:

644765050200
644765032001
644765020502
644765070103
644765010044

Here is my current implementation of the code:

$orders = wc_get_orders(array(
    'customer' => $current_owner_id,
    'limit' => -1,
));

foreach ($orders as $order)
{
    $order_id_sender = $order->get_id();

    $serial_numbers = get_post_meta($order_id_sender, 'SERIAL_NUM');
    $new_meta_value = str_replace($serial_number_transfer, '', $serial_numbers);

    // Update the post meta with the new value
    update_post_meta($order_id_sender, 'SERIAL_NUM', $new_meta_value);
}

However, when I run this code, if serial 644765032001 matches via the $serial_number_transfer variable, the list in the custom field ends up looking like this (with an empty line):

644765050200

644765020502
644765070103
644765010044

Instead, I want it to look like this:

644765050200
644765020502
644765070103
644765010044

How can this be done?

2

Answers


  1. Chosen as BEST ANSWER

    SOLUTION

    foreach ($orders as $order)
    {
        $order_id_sender = $order->get_id();
        $serial_numbers = get_post_meta($order_id_sender, 'SERIAL_NUM');
    
        // while updating the post meta with the new value, search for multiple occurrences of "rn" and replace it with "rn"
        update_post_meta($order_id_sender, 'SERIAL_NUM', preg_replace("/[r?n]+/", "rn", str_replace($serial_number_transfer, '', $serial_numbers[0])));
    }
    

  2. Important pro tip: WordPress’s postmeta, usermeta, and option values can contain arbitrary data structures, not just strings.

    Your meta_value contains a data structure — a list of text strings. You are representing that list as a single text string. The point is, it’s a list.

    So, handle it that way. Explode it to an array, change it, then implode it back to a string before you store it. Like this:

    /* Get the meta value */
    $serial_num_string = get_post_meta( $order_id_sender, 'SERIAL_NUM' );
    /* Clean out consecutive newlines, returns, etc. */
    $serial_num_string = preg_replace( "/[rn]+/", "n", $serial_num_string );
    /* Make an array of the lines in the string. */
    $serial_nums = explode ("n", $serial_num_string );
    
    /* Now you can operate on that array, and you don't have to use regex
     * code (which is good to avoid if you can) to mess with the string. */
    
    /* array_diff($a, $b) is usesful. It removes items in $b from $a */
    $serial_nums = array_diff( $serial_nums, array( $serial_number_transfer ) );
    
    /* Store the updated array back in the postmeta. */
    update_post_meta($order_id_sender, 'SERIAL_NUM', implode( "n", $serial_nums ) );
    

    You can make any changes you need to make to the $serial_numbers array when you have it in hand. Then, implode() it back to a string and save it.

    At the beginning I mentioned WordPress can store (almost) any data structure into postmeta.

    If you handled your SERIAL_NUM postmeta values that way, you would store the array of strings directly. Your code would look like this. No exploding or imploding or cleaning up extraneous newlines or any of that jazz. Your code. Shorter is better.

    $serial_nums = get_post_meta( $order_id_sender, 'SERIAL_NUM' );
    $serial_nums = array_diff( $serial_nums, array( $serial_number_transfer ) );
    update_post_meta( $order_id_sender, 'SERIAL_NUM', $serial_nums );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search