OK, finalmente é assim que acabei fazendo isso: uma chamada Ajax para uma função PHP que faz a verificação, meio que inspirada por esta resposta e usando uma dica inteligente de uma pergunta que eu perguntei no StackOverflow . Importante, eu me certifico de que somente quando queremos publicar a verificação é feita, para que um rascunho sempre pode ser salvo sem a verificação. Isso acabou sendo a solução mais fácil para impedir a publicação do post. Pode ajudar alguém, então eu escrevi aqui.
Primeiro, adicione o Javascript necessário:
//AJAX to validate event before publishing
//adapted from https://wordpress.stackexchange.com/questions/15546/dont-publish-custom-post-type-post-if-a-meta-data-field-isnt-valid
add_action('admin_enqueue_scripts-post.php', 'ep_load_jquery_js');
add_action('admin_enqueue_scripts-post-new.php', 'ep_load_jquery_js');
function ep_load_jquery_js(){
global $post;
if ( $post->post_type == 'event' ) {
wp_enqueue_script('jquery');
}
}
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 == 'event' ){
?>
<script language="javascript" type="text/javascript">
jQuery(document).ready(function() {
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
}
}
Em seguida, a função que lida com a verificação:
add_action('wp_ajax_ep_pre_submit_validation', 'ep_pre_submit_validation');
function ep_pre_submit_validation() {
//simple Security check
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 );
//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') ) ) ) {
if ( empty( $vars['_start_date'] ) || empty( $vars['_end_date'] ) ) {
_e('Both Start and End date need to be filled');
die();
}
//make sure start < end
elseif ( $vars['_start_date'] > $vars['_end_date'] ) {
_e('Start date cannot be after End date');
die();
}
//check time is also inputted in case of a non-all-day event
elseif ( !isset($vars['_all_day'] ) ) {
if ( empty($vars['_start_time'] ) || empty( $vars['_end_time'] ) ) {
_e('Both Start time and End time need to be specified if the event is not an all-day event');
die();
}
elseif ( strtotime( $vars['_start_date']. ' ' .$vars['_start_time'] ) > strtotime( $vars['_end_date']. ' ' .$vars['_end_time'] ) ) {
_e('Start date/time cannot be after End date/time');
die();
}
}
}
//everything ok, allow submission
echo 'true';
die();
}
Esta função retorna true
se tudo estiver bem, e submete o formulário para publicar a postagem pelo canal normal. Caso contrário, a função retornará uma mensagem de erro mostrada como alert()
e o formulário não será enviado.