web-dev-qa-db-fra.com

L'API de paramètres s'efface elle-même?

J'ai créé deux formulaires à l'aide de l'API de configuration. Lorsque j'en sauvegarde l'un, l'autre est effacé, et inversement.

Voici le code complet afin que vous puissiez le coller dans votre fichier functions.php et voir par vous-même:

// Register settings
function registerSettings() {

register_setting('XX_theme_settings', 'XX_theme_settings' );

add_settings_section('theme_options', 'Theme Options', 'theme_options_generate', 'page1' ); 
add_settings_field( 'XX_Option1', 'Option 1', 'text_input', 'page1', 'theme_options', 'XX_Option1' );
add_settings_field( 'XX_Option2', 'Option 2', 'text_input', 'page1', 'theme_options', 'XX_Option2' ); 
add_settings_field( 'XX_Option3', 'Option 3', 'textarea', 'page1', 'theme_options', 'XX_Option3');  
add_settings_field( 'XX_Option4', 'Option 4', 'textarea', 'page1', 'theme_options', 'XX_Option4');  

add_settings_section('theme_options2', 'Theme Options2', 'theme_options_generate2', 'page2' ); 
add_settings_field( 'XX_Option5', 'Option 5', 'text_input', 'page2', 'theme_options2', 'XX_Option5' );
add_settings_field( 'XX_Option6', 'Option 6', 'text_input', 'page2', 'theme_options2', 'XX_Option6' ); 
add_settings_field( 'XX_Option7', 'Option 7', 'textarea', 'page2', 'theme_options2', 'XX_Option7');  
add_settings_field( 'XX_Option8', 'Option 8', 'textarea', 'page2', 'theme_options2', 'XX_Option8');     

};

add_action('admin_init', 'registerSettings');

//Generate section 1    
function theme_options_generate() {
     echo 'This is a Settings Section 1';
 }
//Generate section 2
function theme_options_generate2() {
     echo 'This is a Settings Section 2';
 }

//Generate text input callback    
function text_input($args) {
    $options = get_option('XX_theme_settings');
    echo "<input id=". $args ." name='XX_theme_settings[". $args ."]' size='40' type='text' value='{$options[$args]}' />";   
 }

//Generate textarea callback    
 function textarea($args) {
    $options = get_option('XX_theme_settings');
    echo "<textarea id=". $args ." name='XX_theme_settings[". $args ."]' rows='7' cols='50' type='textarea'>{$options[$args]}</textarea>";
 }

//Add admin pages
function registerMenus() {

add_menu_page('Theme Options', 'Theme Options', 'edit_theme_options', 'theme_menu_slug', 'theme_options_page'); 
add_menu_page('Theme Options2', 'Theme Options2', 'edit_theme_options', 'theme_menu_slug2', 'theme_options_page2'); 

};

add_action('admin_menu', 'RegisterMenus'); 

//Generate Page1 form
function theme_options_page() { ?>
   <form action="options.php" method="post">
   <?php settings_fields('XX_theme_settings'); do_settings_sections('page1'); ?>
   <p class="submit">  <input name="Submit" type="submit" class="button-primary" value="<?php _e('Save Changes'); ?>" /></p> 
   </form>

   <pre><?php echo var_dump(get_option('XX_theme_settings')); ?></pre>

<?php }

//Generate Page2 form
function theme_options_page2() { ?> 
   <form action="options.php" method="post">
   <?php settings_fields('XX_theme_settings'); do_settings_sections('page2'); ?>
   <p class="submit">  <input name="Submit" type="submit" class="button-primary" value="<?php _e('Save Changes'); ?>" /></p> 
   </form>

   <pre><?php echo var_dump(get_option('XX_theme_settings')); ?></pre>

<?php } ?>

Je sais que je ne valide pas (encore) les données, mais je suppose que cela devrait simplement fonctionner (et ne pas afficher l'ensemble du tableau à chaque fois) hors de la boîte, non? Qu'est ce qui ne s'est pas bien passé?

1
Wordpressor

La raison en est que si vous êtes à la page 1, les données qui sont enregistrées pour être enregistrées sont un tableau du formulaire:

XX_theme_settings=array('XX_Option1' =>'input1','XX_Option2'=>'input2',...)

et ne contient aucune donnée de la page 2.

En effet, l'entrée de la page 2 n'est pas publiée avec elle (puisqu'elle n'était pas dans le même <form> - ce n'est pas sur la page). Ainsi, lorsque le tableau XX_theme_settings est enregistré dans la base de données, il ne contient aucune donnée de la page 2.

De même, enregistrer sur la page 2 signifie qu'aucune donnée de la page 1 ne se trouve dans le tableau. Etant donné que ce tableau remplace le tableau complet dans la base de données (c’est-à-dire qu’elles ne sont pas fusionnées), vous perdez toutes les données de la page 1.

Remarque: un seul 'formulaire' est envoyé (et donc reçu) - vous devez donc vous assurer que toutes vos sections sont contenues dans un seul formulaire. (Ils peuvent semblent être des formulaires différents et avoir un bouton d'envoi après chaque section - mais chaque bouton d'envoi enregistrera tous les paramètres) .

Le fait de placer les champs dans un <form> résoudra le problème. Si vous insistez pour les avoir dans des pages séparées, une solution simple à cela serait d'avoir un enregistrement différent dans la base de données pour chaque page.

Sinon, dans votre rappel de validation du tableau XX_theme_settings, vous pouvez fusionner ce tableau avec le tableau existant dans la base de données, de sorte que toute donnée "manquante" soit ajoutée avec sa valeur actuelle dans la base de données. (Voir array_merge )

Note : si une case à cocher est décochée, elle n'envoie rien et sera donc considérée comme "manquante". Cela rend la deuxième option un peu délicate (c’est-à-dire que les données sont manquantes car elles n’ont pas été publiées (page erronée) ou parce que c’est une case à cocher et qu’elles n’ont pas été cochées). Pour contourner ceci , vous devez déterminer quelle page a été envoyée. Si les données d’une case à cocher ont été manquantes, définissez sa valeur sur 0 avant à la fusion. Vous pouvez le faire en ayant des rappels de validation séparés pour chaque page (il pourrait y avoir un autre moyen/meilleur).

Comme @ ChipBennett indique dans les commentaires, il est possible de déterminer la page en attribuant un nom au bouton Envoyer qui indique la page.

4
Stephen Harris