Risoluzione problema salvataggio metabox in WordPress

8 lug 2016, 15:41:07
Visualizzazioni: 15.5K
Voti: 1



Ho due metabox ("prezzi" e "date") nella pagina di modifica del mio custom post type ("kvkoolitus"). Come pensavo correttamente, WordPress salva i valori solo dal primo metabox renderizzato. Ogni metabox ha il codice nel proprio file. Se includo solo 1 metabox - funziona, se includo entrambi - WordPress salva i valori solo dal primo metabox renderizzato.
Cosa mi sono perso?

Prima funzione di creazione metabox:

function kvkoolitus_prices_metabox() {
    add_meta_box( 
        'kvkoolitus_prices_metabox', 
        __( 'Prezzo del Corso', 'kvkoolitus'), 
        'kvkoolitus_prices_metabox_callback', 
        'kvkoolitus', 
        'normal', 
        'default'
    );
}
add_action( 'add_meta_boxes_kvkoolitus', 'kvkoolitus_prices_metabox' );

Seconda funzione di creazione metabox:

function kvkoolitus_dates_metabox() {
    add_meta_box( 
        'kvkoolitus_dates_metabox', 
        __( 'Orario del Corso', 'kvkoolitus'), 
        'kvkoolitus_dates_metabox_callback', 
        'kvkoolitus', 
        'normal', 
        'default'
    ); 
}
add_action( 'add_meta_boxes_kvkoolitus', 'kvkoolitus_dates_metabox' );

Prima funzione callback metabox:

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('Data di inizio', '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('Data di fine', '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('Durata', 'kvkoolitus' ); ?></label><br/> 
  <input type="text" class="widefat" name="kvkoolitus_duration" value="<?php echo esc_attr( $duration ); ?>" />
  </p>

</form>

<?php }

Seconda funzione callback metabox:

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('Prezzo', '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('IVA inclusa', 'kvkoolitus' ); ?></label><br/> 
  </p>          

</form>

<?php }

Prima funzione di salvataggio metabox:

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');

Seconda funzione di salvataggio metabox:

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
Tutte le risposte alla domanda 1
1

Innanzitutto, non hai bisogno dei tag <form>; i meta box vengono già visualizzati all'interno del modulo di modifica dell'articolo.

In secondo luogo, se una checkbox non è selezionata non viene inviata, quindi isset( $_POST['checkbox_name'] ) restituisce false e il campo personalizzato che memorizza il valore della checkbox non viene aggiornato correttamente.

Ho testato questo codice con il tipo di articolo standard e funziona, dovrebbe funzionare anche se lo usi con il tuo tipo di articolo personalizzato:

function kvkoolitus_prices_metabox() {
    add_meta_box( 
        'kvkoolitus_prices_metabox', 
        __( 'Prezzo del corso', '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', 
        __( 'Orario del corso', '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('Data di inizio', '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('Data di fine', '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('Durata', '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('Prezzo', '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('IVA inclusa', '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 lug 2016 19:33:41
Commenti

Grazie cybmeta! Niente da aggiungere, rimuovere completamente il tag form risolve il problema del salvataggio. Ho anche usato questo metodo per le checkbox in alcuni progetti e ha funzionato, ma ora vedo la logica nelle tue parole. Grazie ancora.

anton anton
8 lug 2016 22:42:26