How to filter custom field array through get post meta then write to CSV

I have a code snippet that I use throughout my site, it reads the product IDs from a custom field "menu_listing" and displays content (like image, title, hyperlink, etc.) in an unordered list. I use this in various places on my site (ex. https://eatgoodathome.com/order/menu).

I am trying to get that list of product names to output next to customer order info in my Export Orders to CSV plugin. Here is the code pertaining to "menu_listing".

Read More
global $post; 

// Date Range Parameters
   $today = date("Y-m-d");
   $next = date("Y-m-d", strtotime( "$today +2 weeks"));

// Query current menu based on date
   $menu_args = array(
        'post_type'=>'single_menu',
        'posts_per_page' => 1,
        'meta_query' => array( 
         array(
             'key' => "delivery_date",
             'value' =>  array( $today, $next ),
             'type'  => 'date',
             'compare' => 'BETWEEN'
             ),
         ));

// Display custom field
   $menu = new WP_Query( $menu_args );
   if ( $menu->have_posts() ) {
     while ( $menu->have_posts() ) {
                $menu->the_post();
            }

        // This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
        $current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );


     if( $current_menu ){
           foreach( $current_menu as $single_block ) {

             if( $single_block->id ) { 
                      $dishes = get_post( $single_block->id )->post_title;
     }}}}

//Output CSV cells
    $row = array( $dishes );

In the state shown above, it loops through all the all the products, and only displays the name for the last one. I tried using implode(), explode(), an additional foreach() — those all seem to be a step in the wrong direction, outputting a blank column. What am I missing?

Related posts

Leave a Reply

2 comments

  1. It looks like you’re reassigning the value of $dishes with each iteration which is why you’re only seeing the name of the last item. Try doing this instead:

    $dishes[] = get_post( $single_block->id )->post_title;
    

    This way, you’ll be creating a new index of the $dishes array every iteration instead of reassigning its value. Then you can just assign $row = $dishes.

  2. SOLUTION: The code in my question looped through the array and only gave the last item in the array. My goal was to loop through each key/value pair, convert the value (“id”) to title, and have each title populate a column for my csv. My solution involved scrapping the foreach statement, and requesting each array in the loop by its offset, then assigning it a column in the csv file.

        //Output for CSV
        $output = fopen('php://output', 'w');
    
    if ( $menu->have_posts() ) {
     while ( $menu->have_posts() ) {
                $menu->the_post();
            }
    
        // This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
        $current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );
    
    
        $dish1 =  get_post( $current_menu[0]->id )->post_title;
        $dish2 =  get_post( $current_menu[1]->id )->post_title;
        $dish3 =  get_post( $current_menu[2]->id )->post_title;
    
     // Validate for 4th array item, if exists
        if( sizeof($current_menu) === 4 ) {
        $dish4 =  get_post( $current_menu[3]->id )->post_title;
        } else {
        $dish4 =  "";
        }
    }
    
    //Output CSV cells
    $row = array( $dish1, $dish2, $dish3, $dish4 );
            fputcsv( $output, $row );