0

Is it possible to stop a post from publishing/updating, and instead redirect back to the post with the same data that was being submitted? I want to do this so I can show an error message, should they enter invalid information in a metabox.

Right now it just doesn't save the values of that metabox, but that isn't a very good option.

I think it may be possible by abusing the auto-save system a bit, but before I go digging around I thought I'd see if anyone else has run into this issue.

  • Probably, but it could get a little tricky. Please post your (relevant) code. – s_ha_dum Feb 3 '14 at 22:49
  • Well the system itself is multiple thousands of lines over tens of files; and I'm not sure what of that would be relevant considering I haven't come to a conclusion on how to approach the issue. I found some code using WordPress's wp_insert_post_empty_content, but it wouldn't carry content, title, etc. back on redirect. – Ben Feb 4 '14 at 0:34
  • 1
    Ok. I can probably give you a very broad solution later. – s_ha_dum Feb 4 '14 at 1:28
  • Have you tried using JS to stop the post from being submitted? – gdaniel Feb 4 '14 at 2:10
1

I had to do the exact same thing with a custom post type that would be useless and cause theme problems without metadata.

You'll have to either

A.

Check the post for metadata AFTER it has been published using the transition_post_status hook, and if the metadata isn't there, change the status to "draft" and throw an error message, prompting them with a link to go back an add it. This way involves a separate error page that can be styled at will with multiple messages for multiple post requirements. My code:

// Validation - make sure teams and team news have the required fields before publishing
    // https://wordpress.stackexchange.com/a/187999/127459
    // https://developer.wordpress.org/reference/hooks/transition_post_status/#comment-244

    // the only issue with this is that it sometimes failed to register changes unless refreshed, so errors that are subsequently fixed would still throw an error until the page is refreshed.
    add_action( 'transition_post_status', 'team_post_changed', 10, 3 );

    function team_post_changed( $new_status, $old_status, $post ) {

            // only check Teams or Team News Posts
            if ( $post->post_type === 'team' || $post->post_type === 'team-news' ) {

                // only if it is being published or saved
                if ($new_status === 'publish') {

                    $count = 0;
                    $sports = wp_get_object_terms($post->ID, 'sport');
                    $gender = wp_get_object_terms($post->ID, 'gender');
                    $meta = get_post_meta($post->ID);
                    $thisCoach = $meta['_coach_name'][0];

                    if ( $post->post_type === 'team') {$thisPostType = 'Team';
                    } else {$thisPostType = 'Team News Post';}

                    $die_message = '<em>The '.$thisPostType.' was not published because of the following errors:</em><hr>';
                    $die_title = 'Error - Missing ';

                    // Team / Team News must have Sport
                    if (!$sports[1]) {

                        $die_message .= '<br><h3>Error - Please Specify a Sport</h3>';
                        $die_message .= '<p>'.$thisPostType.'s must be assigned a Season and Sport before they can be published. If the sport for this team is not avaialable, create a new sport <a href="'.admin_url('edit-tags.php?taxonomy=sport&post_type=team').'">here</a>, under the correct season.</p>';
                        $die_title .= 'Sport';
                        $count += 1;

                    } 
                    // Teams must also have Gender
                    if ( $post->post_type === 'team') {
                        if (!$gender[0]){

                            if ($count === 1){ $die_title .= ' and ';}
                            $die_message .= '<br><h3>Error - Please Specify a Team Gender</h3>';
                            $die_message .= '<p>'.$thisPostType.'s must be assigned a Gender before they can be published.</p>';
                            $die_title .= 'Gender';
                            $count += 1;

                        }
                    }
                    if ($count > 0) {
                        // keep post from publishing
                        $post->post_status = 'draft';
                        wp_update_post($post);

                        // provide error message
                        $die_message .= '<br><hr><p><a href="' . admin_url('post.php?post=' . $post->ID . '&action=edit') . '">Go back and edit the post</a></p>';
                        wp_die($die_message, $die_title);
                    }

                }
            }
    }

or

B.

Check the post content via Ajax BEFORE it has been published (immediately when the Publish button is pressed) and alert the user on the same screen unless the post is completely valid. This method requires Javascript and Jquery. It alerts the user with a browser modal-type alert which prevents further actions on the page until you press "OK". See the original answer where I found this solution, and another like it. Here's my code that works for me:

        // Validate Teams and Team News Posts Before Publishing
    // modified from https://wordpress.stackexchange.com/a/42709/127459

    add_action('admin_head-post.php','ep_publish_admin_hook');
    add_action('admin_head-post-new.php','ep_publish_admin_hook');
    function ep_publish_admin_hook(){
        global $post;
        if ( is_admin() && ($post->post_type == 'team' || $post->post_type == 'team-news') ){
            ?>
            <script language="javascript" type="text/javascript">

                jQuery(document).ready(function() {
                    console.log('running this now');
                    jQuery('#publish').click(function() {
                        if(jQuery(this).data("valid")) {
                            return true;
                        }
                        var form_data = jQuery('#post').serializeArray();
                        var data = {
                            action: 'ep_pre_submit_validation',
                            security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
                            form_data: jQuery.param(form_data),
                        };
                        jQuery.post(ajaxurl, data, function(response) {
                            if (response.indexOf('true') > -1 || response == true) {
                                jQuery("#post").data("valid", true).submit();
                            } else {
                                alert("Error: " + response);
                                jQuery("#post").data("valid", false);

                            }
                            //hide loading icon, return Publish button to normal
                            jQuery('#ajax-loading').hide();
                            jQuery('#publish').removeClass('button-primary-disabled');
                            jQuery('#save-post').removeClass('button-disabled');
                        });
                        return false;
                    });
                });
            </script>
            <?php
        }
    }

    add_action('wp_ajax_ep_pre_submit_validation', 'ep_pre_submit_validation');
    function ep_pre_submit_validation() {
        //simple Security check (checks for post-type team or team-news, etc, via scripts above in ep_publish_admin_hook)
        check_ajax_referer( 'pre_publish_validation', 'security' );

        //convert the string of data received to an array
        //from https://wordpress.stackexchange.com/a/26536/10406
        parse_str( $_POST['form_data'], $vars );
        // _e(print_r($vars));

        //check that are actually trying to publish a post
        if ( $vars['post_status'] == 'publish' || 
            (isset( $vars['original_publish'] ) && 
            in_array( $vars['original_publish'], array('Publish', 'Schedule', 'Update') ) ) ) {

            // Check that post title is set
            if (!isset($vars['post_title'])) {
                // _e(print_r($vars)); // uncomment to see what is included in this array
                _e('Please provide a post title.');
                die();
            }
            // Check that gender is set
            if (!isset($vars['gender'])) {
                // _e(print_r($vars)); // uncomment to see what is included in this array
                _e('Please specify a gender.');
                die();
            }

        }

        //everything ok, allow submission
        echo 'true';
        die();
    }

Note: I got both solutions working for me, except that solution 'A', in my implementation, required a browser reload after changes were made, to update the error message (for example, if you go back and fix all errors, the publish buttom still triggers the error page, but when you reload the page, it publishes the post). So then I found solution B, and am customizing it for my needs, with multiple validations on multiple post types.

  • I never thought I'd see an answer for this question! I really like option B, it sucks it requires JS, but such is the life of a Wordpress developer – Ben Oct 6 '17 at 18:56

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.