У меня есть пользовательский тип сообщения, Event
который содержит начальные и конечные настраиваемые поля даты / времени (как метабоксы на экране редактирования сообщения).
Я хотел бы убедиться, что событие не может быть опубликовано (или запланировано) без заполнения дат, так как это вызовет проблемы с шаблонами, отображающими данные события (помимо того факта, что это необходимое требование!). Тем не менее, я хотел бы иметь возможность иметь черновики событий, которые не содержат действительной даты, пока они готовятся.
Я думал о подключении save_post
для проверки, но как я могу предотвратить изменение статуса?
EDIT1: это крюк, который я использую сейчас, чтобы сохранить post_meta.
// Save the Metabox Data
function ep_eventposts_save_meta( $post_id, $post ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !isset( $_POST['ep_eventposts_nonce'] ) )
return;
if ( !wp_verify_nonce( $_POST['ep_eventposts_nonce'], plugin_basename( __FILE__ ) ) )
return;
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ) )
return;
// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though
//debug
//print_r($_POST);
$metabox_ids = array( '_start', '_end' );
foreach ($metabox_ids as $key ) {
$events_meta[$key . '_date'] = $_POST[$key . '_date'];
$events_meta[$key . '_time'] = $_POST[$key . '_time'];
$events_meta[$key . '_timestamp'] = $events_meta[$key . '_date'] . ' ' . $events_meta[$key . '_time'];
}
$events_meta['_location'] = $_POST['_location'];
if (array_key_exists('_end_timestamp', $_POST))
$events_meta['_all_day'] = $_POST['_all_day'];
// Add values of $events_meta as custom fields
foreach ( $events_meta as $key => $value ) { // Cycle through the $events_meta array!
if ( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode( ',', (array)$value ); // If $value is an array, make it a CSV (unlikely)
if ( get_post_meta( $post->ID, $key, FALSE ) ) { // If the custom field already has a value
update_post_meta( $post->ID, $key, $value );
} else { // If the custom field doesn't have a value
add_post_meta( $post->ID, $key, $value );
}
if ( !$value )
delete_post_meta( $post->ID, $key ); // Delete if blank
}
}
add_action( 'save_post', 'ep_eventposts_save_meta', 1, 2 );
РЕДАКТИРОВАТЬ 2: и это то, что я пытаюсь использовать для проверки данных поста после сохранения в базе данных.
add_action( 'save_post', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $post_id, $post ) {
//check that metadata is complete when a post is published
//print_r($_POST);
if ( $_POST['post_status'] == 'publish' ) {
$custom = get_post_custom($post_id);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$post->post_status = 'draft';
wp_update_post($post);
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$post->post_status = 'draft';
wp_update_post($post);
}
else {
return;
}
}
}
Основная проблема с этим - проблема, которая была фактически описана в другом вопросе : использование wp_update_post()
в save_post
ловушке запускает бесконечный цикл.
EDIT3: я придумал способ сделать это, подключив wp_insert_post_data
вместо save_post
. Единственная проблема заключается в том, что теперь post_status
оно отменено, но теперь появляется вводящее в заблуждение сообщение «Опубликовать публикацию» (путем добавления &message=6
к перенаправленному URL-адресу), но статус установлен как Черновик.
add_filter( 'wp_insert_post_data', 'ep_eventposts_check_meta', 99, 2 );
function ep_eventposts_check_meta( $data, $postarr ) {
//check that metadata is complete when a post is published, otherwise revert to draft
if ( $data['post_type'] != 'event' ) {
return $data;
}
if ( $postarr['post_status'] == 'publish' ) {
$custom = get_post_custom($postarr['ID']);
//make sure both dates are filled
if ( !array_key_exists('_start_timestamp', $custom ) || !array_key_exists('_end_timestamp', $custom )) {
$data['post_status'] = 'draft';
}
//make sure start < end
elseif ( $custom['_start_timestamp'] > $custom['_end_timestamp'] ) {
$data['post_status'] = 'draft';
}
//everything fine!
else {
return $data;
}
}
return $data;
}