Those transition post hooks run after the post is saved. You will have to interrupt the process earlier. I would hook to wp_insert_post_data
.
function minWord($data){
if (current_user_can('contributor')) {
$num = 150; //set this to the minimum number of words
if (str_word_count($data['post_content']) < $num) {
$data['post_status'] = 'draft';
}
}
return $data;
}
add_action('wp_insert_post_data','minWord');
Seems to work when I test it. Following your code, this only effects the “Contributor” role. It does not interrupt status changes for other roles.