web-dev-qa-db-fra.com

Problème de mise à jour avec update_option () en combinaison avec register_setting ()

Intro

J'ai une page de paramètres qui inclut un paramètre avec une fonction de rappel plus complexe à enregistrer.

Sauvegarder les données

Pour enregistrer les données, j'utilise la fonction register_setting() avec un rappel de nettoyage personnalisé. Je l'ai implémenté exactement comme l'explique l'API de paramètres WordPress, donc cela fonctionne bien.

Supprimer les données de l'option

Pour supprimer des données de ce tableau d'options, j'utilise jQuery en combinaison avec une fonction de rappel AJAX.

Le problème

Le problème est que je ne peux pas utiliser update_option() (dans mon callback AJAX) lorsque le register_setting() est également actif. Je le sais parce que, lorsque je commente la fonction register_setting(), la fonction update_option() fonctionne soudainement, alors qu’elle supprime l’option avec le paramètre register_setting () uncommented.

Quelqu'un at-il une expérience de ce problème et sait ce que je peux faire pour utiliser les deux fonctions afin de mettre à jour l’option?

Configuration et enregistrement du réglage

function gtp_init_theme_options() { 

    $page = 'services-settings-page';

    /**
     * Services settings sections and fields
     */
    $section = 'installing_settings_section';

    // Add installation settings section
    add_settings_section( $section, _x( 'Installing', 'Measure and installing', 'gtp_translate' ), 'gtp_display_installing_settings_section', $page );

    // Add and register installation areas
    $id = 'installing_data';
    add_settings_field( $id, __( 'Installing data', 'gtp_translate' ), 'gtp_settings_installing_data_fields', $page, $section, array( 'id' => $id, 'label_for' => $id ) );
    register_setting( 'services-theme-settings', $id, 'gtp_register_installing_data_setting' ); 

}
add_action( 'admin_init', 'gtp_init_theme_options' );

Le rappel de nettoyage appelé par le register_setting ()

/**
 * Sanatizes callback for saving installation areas
 */
function gtp_register_installing_data_setting() {

    // Initialize object
    $installing     = new Installing();

    $error = false;

    // Check if country isset
    if ( ! empty( $_POST['existing_country'] ) ) {
        $country = strtolower( $_POST['existing_country'] );
    } elseif ( ! empty( $_POST['country'] ) ) {
        $country = strtolower( $_POST['country'] );
    } else {
        $error = true;  
    }

    // Check if zipcode isset
    if ( ! empty( $_POST['existing_zipcode_area'] ) ) {
        $range = $_POST['existing_zipcode_area'];
    } elseif ( ! empty( $_POST['zipcode_from'] ) && ! empty( $_POST['zipcode_to'] ) ) {
        $range = $_POST['zipcode_from'] . '-' . $_POST['zipcode_to'];
    } else {
        $error = true;  
    }

    // Check if product isset
    if ( ! empty( $_POST['existing_product'] ) ) {
        $product = strtolower( $_POST['existing_product'] );    
    } elseif ( ! empty( $_POST['product'] ) ) {
        $product = strtolower( $_POST['product'] );
    } else {
        $error = true;  
    }

    // Check if price isset
    if ( ! empty( $_POST['price'] ) ) {
        $price = str_replace( ',', '.', $_POST['price'] );
    } else {
        $error = true;  
    }

    // No errors
    if ( ! $error ) {

        // Add row to data array
        $installing->addRow( $country, $range, $product, $price );

        // Return data array
        return $installing->getData();

    }

}

fonction de rappel AJAX

/**
 * Remove installing data in admin AJAX handle
 */
function gtp_remove_installing_data() {

    // Initialize object
    $installing     = new Installing();

    // Remove product
    if ( ! empty( $_POST['country'] ) && ! empty( $_POST['zipcode_area'] ) && ! empty( $_POST['product'] ) ) {
        $installing->removeRow( $_POST['country'], $_POST['zipcode_area'], $_POST['product'] );
    } 
    // Remove zipcode area
    elseif ( ! empty( $_POST['country'] ) && ! empty( $_POST['zipcode_area'] ) ) {
        $installing->removeRow( $_POST['country'], $_POST['zipcode_area'] );
    }
    // Remove country
    elseif ( ! empty( $_POST['country'] ) ) {
        $installing->removeRow( $_POST['country'] );
    }

    // Update 
    $installing->update();

    die;        
}
add_action( 'wp_ajax_remove_installing_data', 'gtp_remove_installing_data' );
add_action( 'wp_ajax_nopriv_remove_installing_data', 'gtp_remove_installing_data' );

J'ai joint une image de l'écran de configuration pour indiquer à votre imagination le type de projet sur lequel je travaille.

 enter image description here 

1
Robbert

Notez ce qui se passe lorsque vous fournissez un rappel de désinfection dans register_setting(). Il enregistre un filtre pour assainir vos options

add_filter( "sanitize_option_{$option_name}", $sanitize_callback );

Maintenant, quand vous faites update_option(), déclenchez votre propre fonction pour empêcher la sauvegarde: D

Parce que update_option() appelle $value = sanitize_option( $option, $value );

Solution: Supprimez le rappel register_settings() avant d'appeler update_option().

function gtp_remove_installing_data() {

    //Your code 

    //Remove sanitizing for adding
    remove_filter( "sanitize_option_installing_data", 'gtp_register_installing_data_setting' );

    // Update 
    $installing->update();

    die;        
}
0
Sumit

Ceci est juste une intuition, mais il me semble que ce problème a quelque chose à voir avec l'ordre dans lequel les opérations sont appelées.

Si vous avez défini vos hooks wp_ajax_remove_installing_data et wp_ajax_nopriv_remove_installing_data dans votre plugin et que vous avez raccordé ce plugin de la manière habituelle dans WP avec le hook init, cela signifie que ce code est exécuté avant le register_setting, auquel vous raccordez le admin_init, qui est plus tard dans la file d'attente .

Maintenant, vous mettez à jour l'option directement, et non via l'API Options. Comme vous pouvez le lire au bas de la page codex sur update_option , cela signifie que le cache n’a pas été mis à jour. Donc, vous supprimez l’option, mais lorsque register_setting est appelé plus tard, il récupère la valeur du cache et la redéfinit.

La solution consisterait à vider le cache après la mise à jour de l'option, ou à connecter register_setting également dans init et à vérifier que sa priorité est supérieure à celle de votre fonction de mise à jour. Cette dernière est donc exécutée après l'appel à register_setting. Disclaimer: Je n'ai pas essayé cela.

0
cjbj