###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' );