advancedforms / advanced-forms

WordPress plugin to create forms using Advanced Custom Fields
75 stars 14 forks source link

Assign form to CPT #5

Closed misiman closed 7 years ago

misiman commented 7 years ago

Hi and thanks for a great plugin.

Quick question (I think): How can I assign a form (bound to a field group) to a specific Custom Post Type? I'm sure I must be missing something obvious.

All the best.

fabianlindfors commented 7 years ago

Hi!

I'm not quite sure I understand your issue. Are you aiming to create a post of a CPT and add the field values to it?

misiman commented 7 years ago

In essence, yes.

I have a CPT registered in PHP called Events with which I would like front-end users to create events using this (conceptual) logic:

Events (CPT name) > wp_posts.post_type Event Title > wp_posts.post_title Event Decription > wp_posts.post_content Custom Fields > post_meta (handled by ACF)

What I cannot figure out is how to use Advanced Forms to set a new post to type "Events" and edited/updated Events to retrieve and map the form values as per the logic above.

I know this is possible with acf_form code, but I would prefer (if possible) to use your form builder instead.

Many thanks

fabianlindfors commented 7 years ago

Advanced Forms should be perfect for your use case!

I have been planning on introducing this functionality but haven't come around to it yet. Fortunately it should be pretty simple to implement with a little bit of code.

Start by processing a form submission using the af/form/submission hook (documentation. Here you can create your post and then update its title, description etc. using the form values. If you want to map all custom fields you could do something like this:

// Transfer all fields to the entry
foreach ( $fields as $field ) {

    update_field( $field['key'], $field['_input'], $post_id );

}

I'm actually using this code for the entries functionality: Full code

If you want to be able to edit an existing post I would pre-fill the form fields using the values argument (documentation) and pass the post ID as a hidden field.

Hope this helped!

misiman commented 7 years ago

Thanks for your reply.

I have a working version of the Events form (in PHP) using acf_form utilising some custom code to validate and create the post entries. Although I would like to port the form into AF, I cannot easily see how to set Advanced Forms to create or edit a post in a Custom Post Type called Events - from your answer above it seems that maybe I'm missing something really basic?

Could you help with an example of how to achieve this, even if just in pseudo code.

Cheers

fabianlindfors commented 7 years ago

Here's an example I put together!

I started by creating a new form with all the default values. I then created a new ACF field group and assigned it to both my custom post type (Event) and to the form I just created. The field group contained four fields: post_title, post_content, meta_field_1, and meta_field_2. The idea is to map post_title and post_content to the events title and content.

To display my form I used the following shortcode: [advanced_form form="form_58cae66d88d0c" event="1"]. Notice the event argument which we'll be making use of very soon. With this argument I'm passing the post ID of the event I want to edit.

Now to the coding part. You can put this code wherever you like (e.g. functions.php) but I put it in a small plugin. My code consists of two simple functions and hooks. The first one pre-fills our form with the events current values and looks like this:

/**
 * Pre-fill form values
 */
function prefill_form_from_post( $args, $form ) {

    // Get event ID from shortcode arguments
    if ( isset( $args['event'] ) ) {
        $event = get_post( $args['event'] );

        if ( $event ) {
            // Pre-fill fields values
            $args['values']['post_title'] = $event->post_title;
            $args['values']['post_content'] = $event->post_content;
            $args['values']['meta_field_1'] = get_field( 'meta_field_1', $event->ID );
            $args['values']['meta_field_2'] = get_field( 'meta_field_2', $event->ID );
        }
    }

    return $args;
}
add_filter( 'af/form/args/key=form_58cae66d88d0c', 'prefill_form_from_post', 10, 2 );

It picks up the event I specified in my shortcode ($args['event']) and then pre-fills the fields with values from the event.

The second function and hook saves the field values to our event after the form has been submitted. It looks like this:

/**
 * Update post with new values after form submission
 */
function edit_post_from_form( $form, $fields, $args ) {

    // Get event from form arguments (same as last function)
    if ( isset( $args['event'] ) ) {
        $event = get_post( $args['event'] );

        if ( $event ) {
            // Update post title and content with form values
            $post_data = array(
                'ID' => $event->ID,
                'post_title' => af_get_field( 'post_title', $fields ),
                'post_content' => af_get_field( 'post_content', $fields ),
            );
            wp_update_post( $post_data );

            // Update custom fields values with submitted data
            update_field( 'meta_field_1', af_get_field( 'meta_field_1', $fields ), $event->ID );
            update_field( 'meta_field_2', af_get_field( 'meta_field_2', $fields ), $event->ID );
        }
    }

}
add_action( 'af/form/submission/key=form_58cae66d88d0c', 'edit_post_from_form', 10, 3 );

This works similar to the first function by finding our event through the form arguments and then saving the submitted values back to the event.

Make sure you pull the latest code from Github before using my example as I pushed a tiny bug fix. Did this help you out? :) I put my plugin code up as a gist if you'd like to check it out directly: https://gist.github.com/Fabianlindfors/b94541c647b7fc71bb78ba780af05545

misiman commented 7 years ago

Sorry for the delay and thanks for your help here.

I see a new version has been uploaded to wp.org so will test it out with your CPT instructions soon.

fabianlindfors commented 7 years ago

I hope it works!

I recently added a guide to the documentation which might help you out as well: Setting up a form which creates posts

fabianlindfors commented 7 years ago

Hello again @misiman!

Were you able to get this working with my example code?

misiman commented 7 years ago

Hi Fabian,

I haven't had a chance to test CPT posting yet - it's near on my to-do list after completing some structural DB changes.

However, I have been keeping track of your releases, and the latest one seems like a significant improvement - ACF has needed something like this for years. When I get going on the front-end, I'm sure I'll have some questions so will come back to you then.

Please close this ticket if you want to clean out old issues.

Thanks

fabianlindfors commented 7 years ago

I'm glad you liked the 1.1 release, it's a feature I have wanted to implement from the beginning and finally got around to. I also just released a smaller update with a new helper function which should be very useful for you.

The new function is af_save_field_to_post( $field_key_or_name, $post_id ); and it can be used to save a submitted field directly to a post without needing to use ACFs update_field. You simply pass the field name or key you want to save and the post to save it on. I updated the previous gist with this new helper: https://gist.github.com/Fabianlindfors/b94541c647b7fc71bb78ba780af05545

I'll close this issue for now. Feel free to re-open it if you run into any more issues. :)

asitemade4u commented 7 years ago

Hi Fabian, I am sorry, but the new addition does not seem to work when CREATING posts. Here is my code:

// NOTE: FORM: All Purpose Contact Form = PER [form_58f0e719f312a]

function aaf_submit_per() 
{

  // Set up a form using the values for post title and content
$post_data = array(
    'post_type' => 'client',
    'post_status' => 'pending',
    'post_title' => af_get_field('f_per_perso_per_name_first') . ' ' . af_get_field('f_per_perso_per_name_last'),
    'comment_status'    =>    'closed',
    'ping_status'        =>    'closed',
);    

$post_id = wp_insert_post($post_data);

// Create post with the added values
af_save_field_to_post('f_per_email_com_email_work', $post_id);
af_save_field_to_post('f_per_phone_com_phone_cell', $post_id);
af_save_field_to_post('f_per_comments_ctc_comments', $post_id);
af_save_field_to_post('f_per_perso_per_name_first', $post_id);
af_save_field_to_post('f_per_perso_per_name_last', $post_id);
af_save_field_to_post('f_per_perso_per_title', $post_id);
  }
add_action('af/form/submission/key=form_58f0e719f312a', 'aaf_submit_per', 10);

The post is created as Pending but absolutely nothing is transferred from the form. What did I do wrong?

asitemade4u commented 7 years ago

Just for the record, I am using CLONE fields and I am PREFIXING them using the name of the clone -- hence the very long names:

f_per_email_com_email_work = <name of the clone = f_per_email> + <name of the field = com_email_work>
asitemade4u commented 7 years ago

Did some further testing. The issue is definitely with the CLONE ACF fields. Here is what I did:

  1. create a test ACF group field, allocate it to both the form and the CPT
  2. Input value in the form in both CLONED fields and this TEST field
  3. Only the value input in the TEST field is transferred to the post when using af_save_field_to_post
asitemade4u commented 7 years ago

Did yet another further testing session and I confirm what I wrote before:

asitemade4u commented 7 years ago

Another hypothesis was that you only transferred to the Post fields belonging to an ACTIVE ACF group field. As recommended by ACF in the documentation, one should define groups used as clones as INACTIVE, so that there is no interaction nor display of the purely reusable building block. I tested it and it is NOT the case. My conclusion is that the Advanced Forms plugin does not take into account the CLONE field type yet.

asitemade4u commented 7 years ago

Hi Fabian,

Just opened a new defect, sorry...

Stephen Sinclair http://asitemade4u.com/?utm_source=stephen_email&amp;utm_medium=email&amp;utm_content=logolink&amp;utm_campaign=current_stephens_email email: stephen@aSiteMade4U.com mailto:stephen@aSiteMade4U.com web: aSiteMade4U.com http://asitemade4u.com/?utm_source=stephen_email&amp;utm_medium=email&amp;utm_content=logolink&amp;utm_campaign=current_stephens_email cell: (914) 334-2929

On 04/16/2017 06:42 AM, Fabian Lindfors wrote:

I'm glad you liked the 1.1 release, it's a feature I have wanted to implement from the beginning and finally got around to. I also just released a smaller update with a new helper function which should be very useful for you.

The new function is |af_save_field_to_post( $field_key_or_name, $post_id );| and it can be used to save a submitted field directly to a post without needing to use ACFs |update_field|. You simply pass the field name or key you want to save and the post to save it on. I updated the previous gist with this new helper: https://gist.github.com/Fabianlindfors/b94541c647b7fc71bb78ba780af05545

I'll close this issue for now. Feel free to re-open it if you run into any more issues. :)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/advancedforms/advanced-forms/issues/5#issuecomment-294345223, or mute the thread https://github.com/notifications/unsubscribe-auth/AK7eCg7Ov1PV6inozfP35_fYFsTG0cKLks5rwfCwgaJpZM4MO1tj.

fabianlindfors commented 7 years ago

Hi!

Thanks for your detailed troubleshooting. I'll close this issue and we'll continue the discussion in the more appropriate one. :)