3

I am trying to query some custom posts so that I can iterate through them, extract the title of ecah and add the titles into an array. The reason I am doing this is so that I can then create a select field in woocommerce using the array contents to generate the options (haven't done this bit yet)

Can anyone see where I'm going wrong with this snippet or provide any advice, I can't get it to work. The site goes down and I get nothing in a var_dump

add_action('woocommerce_after_order_notes', 'custom_checkout_field');

function custom_checkout_field($checkout)

{

$args = array(
    'post_type'         => 'pickup-point',
    'posts_per_page'    => -1,
    'post_status'       => 'publish'
    );

// Custom query to pull in the pickup points.
$query = new WP_Query( $args );

// Check that we have query results.
if ( $query->have_posts() ) {


    $available_locations = [];

  while ( $query->have_posts() ) {

        $query->the_post();

        array_push($available_locations, the_title());

    }
}

var_dump ($available_locations);

}

// Restore original post data.
wp_reset_postdata();

3 Answers 3

2

I see two problems with the code you've written. The first one is that the_title() echos the post title although returning the title would be more appropriate in this context. Also wp_reset_postdata() should be after the while loop inside the if statement.

But as you mentioned that you only need the post titles, you can get them directly from the post objects from the query object without setting up the loop with have_posts() and the_post(). Like so,

add_action('woocommerce_after_order_notes', 'custom_checkout_field');
function custom_checkout_field($checkout) {

  $args = array(
    'post_type'              => 'pickup-point',
    'posts_per_page'         => -1,
    'post_status'            => 'publish',
    'no_found_rows'          => true, // pagination not needed
    'update_post_meta_cache' => false, // post meta not needed
    'update_post_term_cache' => false, // taxonomy terms not needed
  );
  $query = new WP_Query( $args );

  $titles = array_map( 'get_the_title', $query->posts );
  if ( $titles ) {
    // do something with $titles    
  }

}

I added couple of extra parameters to the query $args, which make the query a bit more efficient as only post titles are needed.

1

The main problem is that you need to use get_the_title() instead of the_title() in your code, as the_title() is echoed and can't be set to a variable.

It seems that you want to make your pickup locations (custom post type) to be displayed in a dropdown (or radio buttons) field in WooCommerce checkout page.

You can also simply use get_posts() function like:

add_action('woocommerce_after_order_notes', 'custom_checkout_field');

function custom_checkout_field( $checkout ) {

    $pickup_points = (array) get_posts( array(
        'post_type'         => 'pickup-point',
        'posts_per_page'    => -1,
        'post_status'       => 'publish'
    ) );

    if ( count( $pickup_points ) > 0 ) {

        $available_locations = []; // Initializing

        // Loop though each 'pickup-point' WP_Post object
        foreach ( $pickup_points as $pickup_point ) {
            // Set current post title in the array
            $available_locations[] = $pickup_point->post_title;
        }

        // testing output
        var_dump ($available_locations);
    }
}

Or if you keep a WP_Query:

add_action('woocommerce_after_order_notes', 'custom_checkout_field');

function custom_checkout_field( $checkout ) {

    // Custom query to pull in the pickup points.
    $query = new WP_Query( array(
        'post_type'         => 'pickup-point',
        'posts_per_page'    => -1,
        'post_status'       => 'publish'
    ) );

    $available_locations = []; // Initializing

    // Check that we have query results.
    if ( $query->have_posts() ) :

    $available_locations = []; // Initializing

    while ( $query->have_posts() ) : $query->the_post();

    $available_locations[] = get_the_title(); // Set the current title in the array

    endwhile;

    // testing output
    var_dump ($available_locations);

    wp_reset_postdata();

    endif;
}

Both should work the same way.

1

There's a shorter way to get the titles of posts into an array if you use get_posts():

$posts = get_posts(
    array(
        'post_type'         => 'pickup-point',
        'posts_per_page'    => -1,
        'post_status'       => 'publish'
    )
);

$titles = array_map( 'get_the_title', $posts );

This takes advantage of the fact that you can pass a WP_Post object to get_the_title() by using array_map() to run get_the_title() on the results of get_posts(), which is an array of WP_Post objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.