0

I'm working on a project where we'll be creating two different custom post types: Machines and Enquiries. The Machines posts will be created by admin, and will simply be a list of items that are for sale (although this isn't an e-commerce site). Enquiries, however, will be created by users via a form displayed on the front-end. When a user submits an enquiry, they must select whether they want to buy or sell - if they are buying they must then also specify a machine.

The client has expressed that they would like to be able to see which machine the enquiry relates to in both the Enquiries admin columns, and in the Enquiries edit pages. This would obviously be non-editable, but it could be the Machine post title, SKU, or a link to either the Machine edit page or front-end - or any combination thereof.


So my question is:

When creating and saving an Enquiry post type, is there a way to query the Machines post types (i.e. the Machine submitted with the user's enquiry) and, with that Machines's row data, add a field to the Enquiry post that can then be displayed on the enquiry edit page, or admin columns?

2

Add a field to your form that allows selection of a machine. You can use get_posts to generate a select element:

$args = [
    'posts_per_page' => -1,
    'post_type' => 'machine'
];
$machines = get_posts( $args );
if( ! empty( $machines ) ){
    echo '<select name="_machine_id">';
    foreach( $machines as $machine ){
        echo '<option value="' . $machine->ID . '" >' . get_the_title( $machine ) . '</option>';
    }
    echo '</select>';
}

Save that value in post meta for the enquiry post under the key _machine_id.

To add a Machine column to the enquiry post type list screen, use the manage_$post_type_posts_columns filter:

function wpd_enquiry_posts_columns( $columns ) {
    $columns['machine'] = 'Machine';
    return $columns;
}
add_filter( 'manage_enquiry_posts_columns', 'wpd_enquiry_posts_columns' );

Next, use the manage_$post_type_posts_custom_column action to output a value in that column for each post:

function wpd_enquiry_column( $column, $post_id ) {
    if ( 'machine' === $column ) {
        // get the machine ID saved in meta
        $machine_id = get_post_meta( $post_id, '_machine_id', true );
        if( $machine_id ){
            // get the machine post
            $machine = get_post( $machine_id );
            if( is_object( $machine ) ){
                echo get_the_title( $machine );
            }
        } else {
            echo 'none';
        }
    }
}
add_action( 'manage_enquiry_posts_custom_column', 'wpd_enquiry_column', 10, 2 );

For the individual enquiry post edit screens, you can add a meta box to display the machine. Here we add a meta box:

function wpd_machine_meta_box() {
    add_meta_box( 'machine-id', 'Machine', 'wpd_display_machine_meta_box', 'enquiry' );
}
add_action( 'add_meta_boxes', 'wpd_machine_meta_box' );

And then the display function for the meta box:

function wpd_display_machine_meta_box( $post ) {
    $machine_id = get_post_meta( $post->ID, '_machine_id', true );
    if( $machine_id ){
        $machine = get_post( $machine_id );
        if( is_object( $machine ) ){
            echo get_the_title( $machine );
        }
    } else {
        echo 'none';
    }
}

Here we have just a simple display of a static value, you can also generate a form field in your meta box, like the first function above, and hook post_save to allow the admin to update the value.

  • Thank you so much - this is an enormous help, and more than enough for me to expand on the techniques you've explained. Many many thanks again. – verism Sep 3 '18 at 10:51
1

I think your answer lies with adding metadata on the Machine post type that links back to the Enquiry post. Your form on the Enquiries page would have a select field with all the machines available for purchase. The value of each option in the select control would be the ID of the Machine post.

When the user submits the form, save the Enquiery Post ID as meta key/value for the Machine post. I'll use the string machine_enquiry as the meta key.

add_post_meta($machine_post_id, 'machine_enquiry', $enquiry_post_id);

This will give you an array of enquiries for each machine in the Machine post as it seems you may have multiple enquiries for each machine.

You might also get some benefit from putting the Machine post ID in the meta for the Enquiry post. This will work as long as you don't allow enquiries for multiple machines.

update_post_meta($enquiry_post_id, 'machine_enquiry', $machine_post_id);
  • You make a good point about adding metadata to both post types - I hadn't considered that. However there is still the problem of how to show the metadata in the places I need to. – verism Sep 1 '18 at 17:52
  • @Milo has your comprehensive response which expands on my conceptual answer. Nice work there. – jdp Sep 2 '18 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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