Сохранение значений метабоксов

8 июл. 2016 г., 15:41:07
Просмотры: 15.5K
Голосов: 1



У меня есть 2 метабокса ("prices" и "dates") на странице редактирования моего пользовательского типа записи ("kvkoolitus"). Как я понял, WordPress сохраняет значения только из первого отрендеренного метабокса. Каждый метабокс хранится в своем собственном файле. Если я подключаю только 1 метабокс - он работает, если оба - WordPress сохраняет значения только из первого отрендеренного метабокса.
Что я упустил?

Функция создания первого метабокса:

function kvkoolitus_prices_metabox() {
    add_meta_box( 
        'kvkoolitus_prices_metabox', 
        __( 'Стоимость курса', 'kvkoolitus'), 
        'kvkoolitus_prices_metabox_callback', 
        'kvkoolitus', 
        'normal', 
        'default'
    );
}
add_action( 'add_meta_boxes_kvkoolitus', 'kvkoolitus_prices_metabox' );

Функция создания второго метабокса:

function kvkoolitus_dates_metabox() {
    add_meta_box( 
        'kvkoolitus_dates_metabox', 
        __( 'Время проведения курса', 'kvkoolitus'), 
        'kvkoolitus_dates_metabox_callback', 
        'kvkoolitus', 
        'normal', 
        'default'
    ); 
}
add_action( 'add_meta_boxes_kvkoolitus', 'kvkoolitus_dates_metabox' );

Callback-функция первого метабокса:

function kvkoolitus_dates_metabox_callback( $post ) { 

    wp_nonce_field( 'kvkoolitus_dates_metabox_nonce', 'kvkoolitus_dates_nonce' ); ?>

<form action="" method="post">

  <?php         
    $start_date = get_post_meta( $post->ID, 'kvkoolitus-start', true );
    $end_date   = get_post_meta( $post->ID, 'kvkoolitus-end', true );
    $duration   = get_post_meta( $post->ID, 'kvkoolitus-duration', true );
  ?>

  <p>   
    <label for="kvkoolitus_start_date"><?php _e('Дата начала', 'kvkoolitus' ); ?></label><br/>    
    <input type="text" class="widefat kvkoolitusDate" name="kvkoolitus_start_date" value="<?php echo esc_attr( $start_date ); ?>" />
  </p>

  <p>
  <label for="kvkoolitus_end_date"><?php _e('Дата окончания', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat kvkoolitusDate" name="kvkoolitus_end_date" value="<?php echo esc_attr( $end_date ); ?>" />
  </p>    

  <p>
  <label for="kvkoolitus_duration"><?php _e('Продолжительность', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat" name="kvkoolitus_duration" value="<?php echo esc_attr( $duration ); ?>" />
  </p>

</form>

<?php }

Callback-функция второго метабокса:

function kvkoolitus_prices_metabox_callback( $post ) { 

wp_nonce_field( 'kvkoolitus_prices_metabox_nonce', 'kvkoolitus_prices_nonce' ); ?>

<form action="" method="post">

  <?php         
    $price   = get_post_meta( $post->ID, 'kvkoolitus-price', true );
    $km      = get_post_meta( $post->ID, 'kvkoolitus-km', true );
  ?>  

  <p>
  <label for="kvkoolitus_price"><?php _e('Цена', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat" name="kvkoolitus_price" value="<?php echo esc_attr( $price ); ?>" />
  </p>   

  <p>
  <input type="checkbox" value="1" name="kvkoolitus_km" <?php checked( '1', $km ); ?> />
  <label for="kvkoolitus_km"><?php _e('Включая НДС', 'kvkoolitus' ); ?></label><br/> 
  </p>          

</form>

<?php }

Функция сохранения первого метабокса:

function kvkoolitus_dates_save_meta( $post_id ) {

  if( !isset( $_POST['kvkoolitus_dates_nonce'] ) || !wp_verify_nonce( $_POST['kvkoolitus_dates_nonce'],'kvkoolitus_dates_metabox_nonce') ) 
    return;

  if ( !current_user_can( 'edit_post', $post_id ))
    return;

  if ( isset($_POST['kvkoolitus_start_date']) ) {        
    update_post_meta($post_id, 'kvkoolitus-start', sanitize_text_field( $_POST['kvkoolitus_start_date']));      
  }  

  if ( isset($_POST['kvkoolitus_end_date']) ) {        
    update_post_meta($post_id, 'kvkoolitus-end', sanitize_text_field( $_POST['kvkoolitus_end_date'] ));      
  }

  if ( isset($_POST['kvkoolitus_duration']) ) {        
    update_post_meta($post_id, 'kvkoolitus-duration',  sanitize_text_field($_POST['kvkoolitus_duration']));      
  }

}
add_action('save_post', 'kvkoolitus_dates_save_meta');

Функция сохранения второго метабокса:

function kvkoolitus_prices_save_meta( $post_id ) {

  if( !isset( $_POST['kvkoolitus_prices_nonce'] ) || !wp_verify_nonce( $_POST['kvkoolitus_prices_nonce'],'kvkoolitus_prices_metabox_nonce') ) 
    return;

  if ( !current_user_can( 'edit_post', $post_id ))
    return;

  if ( isset($_POST['kvkoolitus_price']) ) {        
    update_post_meta($post_id, 'kvkoolitus-price', sanitize_text_field($_POST['kvkoolitus_price']));      
  }

  if ( isset($_POST['kvkoolitus_km']) ) {        
    update_post_meta($post_id, 'kvkoolitus-km', sanitize_text_field($_POST['kvkoolitus_km']));      
  }

}
add_action('save_post', 'kvkoolitus_prices_save_meta');
0
Все ответы на вопрос 1
1

Во-первых, вам не нужны теги <form>; метабоксы уже отображаются внутри формы редактирования записи.

Во-вторых, если чекбокс не отмечен, он не отправляется, поэтому isset( $_POST['checkbox_name'] ) возвращает false, и пользовательское поле, хранящее значение чекбокса, не обновляется корректно.

Я протестировал этот код со стандартным типом записи, и он работает, он должен работать и с вашим пользовательским типом записи:

function kvkoolitus_prices_metabox() {
    add_meta_box( 
        'kvkoolitus_prices_metabox', 
        __( 'Цена курса', 'kvkoolitus'), 
        'kvkoolitus_prices_metabox_callback', 
        'post', 
        'normal', 
        'default'
    );
}
add_action( 'add_meta_boxes', 'kvkoolitus_prices_metabox' );

function kvkoolitus_dates_metabox() {
    add_meta_box( 
        'kvkoolitus_dates_metabox', 
        __( 'Время проведения курса', 'kvkoolitus'), 
        'kvkoolitus_dates_metabox_callback', 
        'post', 
        'normal', 
        'default'
    ); 
}
add_action( 'add_meta_boxes', 'kvkoolitus_dates_metabox' );

function kvkoolitus_dates_metabox_callback( $post ) { 

    wp_nonce_field( 'kvkoolitus_dates_metabox_nonce', 'kvkoolitus_dates_nonce' ); ?>

  <?php         
    $start_date = get_post_meta( $post->ID, 'kvkoolitus-start', true );
    $end_date   = get_post_meta( $post->ID, 'kvkoolitus-end', true );
    $duration   = get_post_meta( $post->ID, 'kvkoolitus-duration', true );
  ?>

  <p>   
    <label for="kvkoolitus_start_date"><?php _e('Дата начала', 'kvkoolitus' ); ?></label><br/>    
    <input type="text" class="widefat kvkoolitusDate" name="kvkoolitus_start_date" value="<?php echo esc_attr( $start_date ); ?>" />
  </p>

  <p>
  <label for="kvkoolitus_end_date"><?php _e('Дата окончания', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat kvkoolitusDate" name="kvkoolitus_end_date" value="<?php echo esc_attr( $end_date ); ?>" />
  </p>    

  <p>
  <label for="kvkoolitus_duration"><?php _e('Продолжительность', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat" name="kvkoolitus_duration" value="<?php echo esc_attr( $duration ); ?>" />
  </p>

<?php }

function kvkoolitus_prices_metabox_callback( $post ) { 

wp_nonce_field( 'kvkoolitus_prices_metabox_nonce', 'kvkoolitus_prices_nonce' ); ?>

  <?php         
    $price   = get_post_meta( $post->ID, 'kvkoolitus-price', true );
    $km      = get_post_meta( $post->ID, 'kvkoolitus-km', true );
  ?>

  <p>
  <label for="kvkoolitus_price"><?php _e('Цена', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat" name="kvkoolitus_price" value="<?php echo esc_attr( $price ); ?>" />
  </p>   

  <p>
  <input type="checkbox" value="1" name="kvkoolitus_km" <?php checked( '1', $km ); ?> />
  <label for="kvkoolitus_km"><?php _e('Включая подоходный налог', 'kvkoolitus' ); ?></label><br/> 
  </p>  

<?php }

function kvkoolitus_dates_save_meta( $post_id ) {

  if( !isset( $_POST['kvkoolitus_dates_nonce'] ) || !wp_verify_nonce( $_POST['kvkoolitus_dates_nonce'],'kvkoolitus_dates_metabox_nonce') ) 
    return;

  if ( !current_user_can( 'edit_post', $post_id ))
    return;

  if ( isset($_POST['kvkoolitus_start_date']) ) {        
    update_post_meta($post_id, 'kvkoolitus-start', sanitize_text_field( $_POST['kvkoolitus_start_date']));      
  }  

  if ( isset($_POST['kvkoolitus_end_date']) ) {        
    update_post_meta($post_id, 'kvkoolitus-end', sanitize_text_field( $_POST['kvkoolitus_end_date'] ));      
  }

  if ( isset($_POST['kvkoolitus_duration']) ) {        
    update_post_meta($post_id, 'kvkoolitus-duration',  sanitize_text_field($_POST['kvkoolitus_duration']));      
  }

}
add_action('save_post', 'kvkoolitus_dates_save_meta');

function kvkoolitus_prices_save_meta( $post_id ) {

  if( !isset( $_POST['kvkoolitus_prices_nonce'] ) || !wp_verify_nonce( $_POST['kvkoolitus_prices_nonce'],'kvkoolitus_prices_metabox_nonce') ) 
    return;

  if ( !current_user_can( 'edit_post', $post_id ))
    return;

  if ( isset($_POST['kvkoolitus_price']) ) {        
    update_post_meta($post_id, 'kvkoolitus-price', sanitize_text_field($_POST['kvkoolitus_price']));      
  }

  if ( isset($_POST['kvkoolitus_km']) ) {        
    update_post_meta($post_id, 'kvkoolitus-km', sanitize_text_field($_POST['kvkoolitus_km']));      
  } else {
    delete_post_meta($post_id, 'kvkoolitus-km');
  }

}
add_action('save_post', 'kvkoolitus_prices_save_meta');
8 июл. 2016 г. 19:33:41
Комментарии

Спасибо, cybmeta! Нечего добавить, полное удаление тега form решает проблему сохранения. Я также использовал этот метод для чекбоксов в некоторых проектах, и он работал, но теперь вижу логику в ваших словах. Еще раз спасибо.

anton anton
8 июл. 2016 г. 22:42:26