Settings API erases itself?

时间:2012-02-10 作者:Wordpressor

我有两个使用设置API创建的表单,当我保存其中一个表单时,另一个表单会被删除,反之亦然。

这是完整的代码,您可以将其粘贴到函数中。php文件并亲自查看:

// 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 } ?>
我知道我还没有验证数据,但我想它应该是现成的(而不是每次都使用整个阵列),对吗?出了什么问题?

1 个回复
最合适的回答,由SO网友:Stephen Harris 整理而成

原因是,如果您位于第1页,则发布要保存的数据是以下表单的数组:

XX_theme_settings=array(\'XX_Option1\' =>\'input1\',\'XX_Option2\'=>\'input2\',...)
并且不包含第2页的数据。

这是因为第2页的输入没有随它一起发布(因为它不在同一页中<form> - 它不在页面上)。因此,当XX_theme_settings 数组保存到数据库中,它不包含第2页的任何数据。

同样,保存在第2页意味着数组中没有来自第1页的数据,并且由于此数组替换了数据库中的完整数组(即,它们未合并),因此会丢失第1页中的所有数据。

Note: only one \'form\' is ever sent, (and so recieved) - so you should ensure you have all your sections within one form. (它们可以是不同的表单,并且在每个部分后都有一个提交按钮,但每个提交按钮都会保存所有设置)

Putting the fields inside one <form> will solve the issue. 如果坚持将它们放在单独的页面中,一个简单的解决方案是在数据库中为每个页面创建不同的记录。

或者,在XX_theme_settings 数组,则可以将该数组与数据库中的现有数组合并,以便将任何“缺少”的数据与其在数据库中的当前值一起添加。(参见array_merge)

Note: 如果复选框未选中,则不会发送任何内容,因此将被视为“丢失”。这使得第二个选项有点棘手(即数据丢失是因为它没有发布(错误的页面)还是因为它是一个复选框而没有选中)。要解决此问题,您需要确定发送了哪个页面的数据,如果该页面上的复选框中的数据丢失,请将其值设置为0prior 合并。您可以通过对每个页面进行单独的验证回调来做到这一点(可能有另一种/更好的方法)。

@ChipBennett 注释中的状态,可以通过给提交按钮一个指示页面的名称来确定页面。

结束

相关推荐

Help with forms and nonces

我正在尝试创建一个用于(面向公众的)表单的nonce。下面是我的代码:function my_form() { if (isset($_POST[\'submit\'])) { $name = $_POST[\'name\']; $description = $_POST[\'description\']; $output_form = false; if (wp_verify_nonce($_P