Skip Navigation

[Resolved] Calculated field works in CRED form, not in backend

This thread is resolved. Here is a description of the problem and solution.

Problem:

There is a custom field, wpcf-full-name, which is not shown on the CRED forms but is calculated from 4 other fields. I do this calculation using "save_post" action hook.

The problem comes when I use the backend form to update the data. In this case it seems to grab the OLD values for the fields used in calculating wpcf-full-name rather than the NEW values.

Solution:

In case it is a compatibility problem, please deactivate other plugins, and switch to wordpress default theme 2017, and test again, you can also test it in a fresh wordpress installation.

See details here:

https://toolset.com/forums/topic/calculated-field-works-in-cred-form-not-in-backend/#post-1142002

Relevant Documentation:

This support ticket is created 6 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Hong_Kong (GMT+08:00)

This topic contains 5 replies, has 3 voices.

Last updated by helenmaryC 6 years ago.

Assisted by: Luo Yang.

Author
Posts
#1140554

I am sure I am missing something basic, but this is driving me nuts.

I have a custom post type, dogs which has front end CRED forms to allow users to add and edit dogs.

There is a custom field, wpcf-full-name, which is not shown on the CRED forms but is calculated from 4 other fields. I do this calculation using the following code:

function crfcrc_save_dog_data( $post_id, $post, $update  ) {

    if ( isset( $_POST['wpcf-pre-titles'] ) ) {
        $preTitles = sanitize_text_field( $_POST['wpcf-pre-titles'] );
    } else {
        $preTitles = get_post_meta($post_id, 'wpcf-pre-titles', true);
    }
    if ( isset( $_POST['wpcf-registered-name'] ) ) {
        $registeredName = sanitize_text_field( $_POST['wpcf-registered-name'] );
    } else {
        $registeredName = get_post_meta($post_id, 'wpcf-registered-name', true);
    }
    if ( isset( $_POST['wpcf-post-titles'] ) ) {
        $postTitles = sanitize_text_field( $_POST['wpcf-post-titles'] );
    } else {
        $postTitles = get_post_meta($post_id, 'wpcf-post-titles', true);
    }
    if ( isset( $_POST['wpcf-call-name'] ) ) {
        $callName = sanitize_text_field( $_POST['wpcf-call-name'] );
    } else {
        $callName = get_post_meta($post_id, 'wpcf-call-name', true);
    }

    $fullName = crfcrc_registered_name($preTitles, $registeredName, $postTitles, $callName);

    update_post_meta($post_id, 'wpcf-full-name', $fullName);

    if ($registeredName > '') {
        $args = array('ID' => $post_id,
            'post_title' => $registeredName
        );
    } else {
        $args = array('ID' => $post_id,
            'post_title' => $callName
        );
    }

    remove_action( 'save_post_dog', 'crfcrc_save_dog_data', 10, 3 );
        wp_update_post($args);
    add_action('save_post_dog', 'crfcrc_save_dog_data', 10, 3 );

}
add_action('save_post_dog', 'crfcrc_save_dog_data', 10, 3 );

When I enter data using the CRED forms, this works just as expected. The problem comes when I use the backend form to update the data. In this case it seems to grab the OLD values for the fields used in calculating wpcf-full-name rather than the NEW values.

My guess is that Types is using this hook as well, and that setting a higher priority might fix the problem, but I have no clue what value to use. Am I on the right track or is some other issue involved?

Thanks for your help!

#1141052

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Hello. Thank you for contacting the Toolset support.

Yes - you are right actually the general save_post action must be used instead of save_post_{custom-post-slug} action with a priority of at least 30 when used in conjunction with post types registered with Types, or inconsistencies in the updated data may be experienced.

Please check the following important Doc:
=> https://toolset.com/documentation/customizing-sites-using-php/updating-types-fields-using-php/

#1141280

I think I am making progress, but it still isn't entirely working. The code is now as follows:

function crfcrc_save_special_data( $post_id, $post, $update  ) {
    if ( 'dog' == $post->post_type  ) {
            if ( isset( $_POST['wpcf-pre-titles'] ) ) {
                $preTitles = sanitize_text_field( $_POST['wpcf-pre-titles'] );
            } else {
                $preTitles = get_post_meta($post_id, 'wpcf-pre-titles', true);
            }
            if ( isset( $_POST['wpcf-registered-name'] ) ) {
                $registeredName = sanitize_text_field( $_POST['wpcf-registered-name'] );
            } else {
                $registeredName = get_post_meta($post_id, 'wpcf-registered-name', true);
            }
            if ( isset( $_POST['wpcf-post-titles'] ) ) {
                $postTitles = sanitize_text_field( $_POST['wpcf-post-titles'] );
            } else {
                $postTitles = get_post_meta($post_id, 'wpcf-post-titles', true);
            }
            if ( isset( $_POST['wpcf-call-name'] ) ) {
                $callName = sanitize_text_field( $_POST['wpcf-call-name'] );
            } else {
                $callName = get_post_meta($post_id, 'wpcf-call-name', true);
            }

        $fullName = crfcrc_registered_name($preTitles, $registeredName, $postTitles, $callName);

        update_post_meta($post_id, 'wpcf-full-name', $fullName);

        if ($registeredName > '') {
            $args = array('ID' => $post_id,
                'post_title' => $registeredName
            );
        } else {
            $args = array('ID' => $post_id,
                'post_title' => $callName
            );
        }

        remove_action('save_post', 'crfcrc_save_special_data', 30, 3 );
            wp_update_post($args);
        add_action('save_post', 'crfcrc_save_special_data', 30, 3 );

    } elseif ( 'rosette-title' == $post->post_type  ) {
        if ( !$update ){
            $postTitle = 'Rosette Title ' . $post_id;
            $slug = 'rt' . $post_id;

            $args = array('ID' => $post_id,
                        'post_title' => $postTitle,
                        'post_name' => $slug
                    );

            remove_action('save_post', 'crfcrc_save_special_data', 30, 3 );
                wp_update_post($args);
            add_action('save_post', 'crfcrc_save_special_data', 30, 3 );
        }
    }
}
add_action('save_post', 'crfcrc_save_special_data', 30, 3 );

This still works on the front end with the CRED form, updating both wpcf-full-name and the post title. On the back end, the title gets updated (which tells me the function is firing and picking up the new data) but wpcf-full-name doesn't change. I have a feeling that this may be because wpcf-full-name is on the back end form so the old value is getting saved over the calculated value AFTER my code above runs.

One other data point, I first tried using just

$preTitles = get_post_meta($post_id, 'wpcf-pre-titles', true);

rather than the individual if statements to load the values that feed into fullName, but that failed on the front end as well. That made me think I am still not quite running this at the right time.

#1141284

I tried one more thing and now it is working on the back end, too.

What I did was set a condition for wpcf-full-name in Types so that it will only display If wpcf-call-name == XXXYYYZZZ (which it never will be!). That took it off of the back end form and now wpcf-full-name is updating.

I can live with this, it just seems odd. And I'm still wondering why the custom fields don't appear to be saving BEFORE this code runs.

#1142002

Hi,

Minesh is on vacation, I will take care of this thread.

I have tried your custom codes(but simplify) in my localhost with a fresh wordpress installation. It works fine, here are detail steps:
1) Create a custom post type "dog"

2) Create two custom single line fields
- pre-titles
- full-name

3) add below codes into theme file functions.php:

function crfcrc_save_special_data( $post_id, $post, $update  ) {
    if ( 'dog' == $post->post_type  ) {
		$preTitles = get_post_meta($post_id, 'wpcf-pre-titles', true);
		$fullName = $preTitles;
        update_post_meta($post_id, 'wpcf-full-name', $fullName);
        remove_action('save_post', 'crfcrc_save_special_data', 30, 3 );
    }
}
add_action('save_post', 'crfcrc_save_special_data', 30, 3 );

4) In wordpress admin side, create a dog post, and input value into field "pre-titles", update this post, I can see it works fine, the "full-name" field does change according to field value of "pre-titles".

There isn't similar problem as you mentioned above:
the custom fields don't appear to be saving BEFORE this code runs

I suggest you try these:
1) In case it is a compatibility problem, please deactivate other plugins, and switch to wordpress default theme 2017, and test again, you can also test it in a fresh wordpress installation.
2) Debug your PHP codes line by line manually.

#1144465

It is going to be awhile before I get a chance to do additional trouble-shooting on this, given that it is working. I'll let you know if I have any more questions. Thanks!