As @t-f pointed out in his comment to question, you have an error on checking current user capability: 'delete_published_posts'. $post_author_id
simply doesn’t exist.
After that, for your scope probably is a better hookin the filter wp_insert_post_data
instead of the action save_post
: because this one run when the post was already saved / updated, so if something is wrong you have to change and update again.
Hooking wp_insert_post_data
filter, you can change the data that are being updated before update is ran, so this will improve performance.
add_filter('wp_insert_post_data', 'prevent_post_change', 20, 2);
function prevent_post_change( $data, $postarr ) {
if ( ! isset($postarr['ID']) || ! $postarr['ID'] || current_user_can('delete_published_posts') )
return $data;
$old = get_post($postarr['ID']); // old post
// prevent changing date
$data['post_date'] = $old->post_date
$data['post_date_gmt'] = $old->post_date_gmt
// prevent sent to trash
if ( $data['post_status'] == 'trash' ) $data['post_status'] = $old->post_status;
return $data;
}