Skip to main content
Commonmark migration
Source Link

###When save_post runs, it has already saved the post on the database.

When save_post runs, it has already saved the post on the database.

###When save_post runs, it has already saved the post on the database.

When save_post runs, it has already saved the post on the database.

wrong parathesis; reworded a comment because edits must be at least 6 chars...
Source Link
<?php

/**
*   Performs custom validation on custom post type "Site"
*/
function custom_post_site_save($post_id, $post_data) {
    # If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'site') {
        # In this example, we will denyraise an error for post titles with less than 5 characters
        if (strlen($post_data['post_title']) < 5)) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );
<?php

/**
*   Performs custom validation on custom post type "Site"
*/
function custom_post_site_save($post_id, $post_data) {
    # If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'site') {
        # In this example, we will deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );
<?php

/**
*   Performs custom validation on custom post type "Site"
*/
function custom_post_site_save($post_id, $post_data) {
    # If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'site') {
        # In this example, we will raise an error for post titles with less than 5 characters
        if (strlen($post_data['post_title']) < 5) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );
Source Link
Lucas Bustamante
  • 2.3k
  • 1
  • 28
  • 43

###When save_post runs, it has already saved the post on the database.

If you are using ACF, it has built-in validation.

However, if you need to validate things outside of ACF, such as post_title, things get a little more complicated.

Looking into WordPress core code, more specifically at the wp-includes/post.php's update_post() function, there is no built-in way to intercept a request before it is saved on the database.

However, we can hook pre_post_update and use header() and get_post_edit_link() to prevent the post from being saved.

<?php

/**
*   Performs custom validation on custom post type "Site"
*/
function custom_post_site_save($post_id, $post_data) {
    # If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'site') {
        # In this example, we will deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );