web-dev-qa-db-ja.com

設定APIは自分自身を消去しますか?

Settings APIを使用して作成した2つのフォームがあり、一方を保存するともう一方が消去されます。

これがコード全体ですので、それをfunctions.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
Wordpressor

その理由は、あなたが1ページにいる場合、保存されるように転記されるデータは次の形式の配列であるということです。

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

2ページ目のデータは含まれていません。

これは、2ページ目からの入力が一緒に投稿されていないためです(同じ<form>内にないため、ページ上には表示されません)。したがって、XX_theme_settings配列がデータベースに保存されるとき、2ページ目からのデータは含まれません。

同様に、2ページ目に保存すると、1ページ目のデータが配列内にないことを意味します。この配列はデータベース内の配列全体を置き換えるので(つまりマージされないため)、1ページ目のデータはすべて失われます。

注:1つの 'form'だけが送信されます(そして受信されます)。したがって、すべてのセクションを1つのフォーム内に含めるようにしてください。(これらは異なる形式で表示され、各セクションの後に送信ボタンがあります - しかし各送信ボタンはすべての設定を保存します)

1つの<form>内にフィールドを配置すると問題が解決します。それらを別々のページに置くことを主張するならば、これに対する1つの簡単な解決策は各ページのためにデータベースに異なるレコードを持つことでしょう。

あるいは、XX_theme_settings配列の検証コールバックで、その配列をデータベース内の既存の配列とマージして、不足しているデータがデータベース内の現在の値で追加されるようにすることもできます。 ( array_merge を参照)

Note:チェックボックスがチェックされていないと、何も送信されないので、 'missing'と見なされます。これは2番目のオプションを少し扱いに​​くくします(つまり、投稿されなかった(間違ったページ)、またはチェックボックスがオンになっていてチェックされていなかったため、データが失われます)。ラウンドthisするには、どのページのデータが送信されたかを判断する必要があります。また、そのページのチェックボックスからのデータが欠けている場合は、マージの値を0 priorに設定します。ページごとに別々の検証コールバックを持つことでこれを行うことができます(他の方法やもっと良い方法があるかもしれません)。

コメントに@ChipBennettが示すように、ページを決定するには、送信ボタンにページを示す名前を付けることで実現できます。

4
Stephen Harris