web-dev-qa-db-ja.com

設定API - チェックボックスを検証する最も簡単な方法は?

私はSettings APIを使っていますが、チェックボックスが "false"に設定されていると$ _POSTにさえならないため、チェックボックスが機能しません。それがポイントです。

Stephen HarrisとChip Bennettがそれを説明した しかし、彼らのやり方はそれほど単純ではないと私は思う(特に私にとっては、まったくPHP人ではない)。この単純なことを機能させるためだけに、すべてのフォームにいくつかのカスタムPHP関数とカスタム名の送信ボタンが本当に必要ですか。

私の設定は以下のようになります。

register_setting('XX_theme_settings', 'XX_theme_settings', 'setting_validate' );

add_settings_section('theme_options', 'Theme Options', 'theme_options_generate', 'page1' ); 
add_settings_field( 'XX_Option1', 'Option 1', 'checkbox', 'page1', 'theme_options', 'XX_Option1', $args = array('id' => 'checkbox1', 'type' => 'checkbox') );
add_settings_field( 'XX_Option2', 'Option 2', 'checkbox', 'page1', 'theme_options', 'XX_Option2', $args = array('id' => 'checkbox2', 'type' => 'checkbox') ); 

それから私はこのコールバック関数でチェックボックスを生成します:

function checkbox($args) {
    $options = get_option('XX_theme_settings');
    echo '<input type="checkbox" name="'. $args['id'] .'" value="true"'; if($options[$args['id']]==true) { echo 'checked="checked'; }; echo '/>';
    echo $args['type'];  
}

今、私が必要とするすべては良い検証コールバックです:

function setting_validate($input) {
   // Firstly it should find all fields of type == "checkbox" 
   // (I'm not sure why should I check which field was just being sent, 
   // is updating all the checkboxes from different sections a big no-no?
   // it is much easier indeed.
   // Now set the ones missing to false/0 and the rest to true/1.
   // Then merge everything like below:

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);  
   return $merged;  
}

問題は次のとおりです。 すべてのSettings Apiチェックボックスを一覧表示してから正しいものをtrueに設定する方法

私はそれがそのように見えると思います:

$options = array(
        array(
            'id' => 'checkbox1',
            'type' => 'checkbox',
            'page' => 'page1',
         ),
        array(
            'id' => 'checkbox2',
            'type' => 'checkbox',
            'page' => 'page1',
         ),
);

function setting_validate($input) {
   foreach($options as $option) {
     if($option['type'] == "checkbox") { 
        //set it to 1 if sent
     }
   }

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);  
   return $merged;  
}

ありがとう:)

Chip Bennettが正確にそれを行う方法は次のとおりです しかし、これらすべての素晴らしいコメントがあっても、正確に動作する方法を取得できません。

7
Wordpressor

問題の設定が$settingで、チェックボックスタイプの場合、次のように検証します。

<?php
$valid_input[$setting] = ( isset( $input[$setting] ) && true == $input[$setting] ? true : false );
?>

この場合、$inputは、検証コールバックに渡されるフォームデータです。ここで、$inputは配列の配列です。 。検証方法はwhitelistingとして知られており、current settings arrayは(この場合、$valid_input)として呼び出され、設定配列の各設定は、$input[$setting]の値が検証に合格した場合にのみ更新されます。

チェックボックスでは、チェックボックスがsetでない場合、設定自体は$input配列に取り込まれません。そのため、それを検証する最初のステップは$inputで設定されているかどうかを判断するです。 2番目のステップは、設定される値がtrue(または'true'、または'on'、または設定フォームでチェックボックス値を設定するもの)であることを確認することです。これらの条件が両方とも満たされる場合、true;を返します。それ以外の場合は、falseを返します。

参照:本当に簡単です。 :)

編集

これに関して:

function setting_validate($input) {
   foreach($options as $option) {
     if($option['type'] == "checkbox") { 
        //set it to 1 if sent
     }
   }

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);  
   return $merged;  
}

...それは正確にあなたがやりたいことではありません。戻り値をvalidオプションに制限します。つまり、定義した設定を明示的に返す必要があります。誰かが$inputに追加データ(悪意のあるコード)を入力できる場合、メソッドはその追加データをデータベースに直接渡すだけです

array_merge()を実行しないでください。各$valid_options[$setting]を個別に/個別に更新し、$valid_optionsのみを返します。

プロセスは次のとおりです。

  1. 現在有効なデータを定義します:

    $valid_input = get_option( 'XX_theme_settings' );
    
  2. 現在有効なデータを$inputで更新するif$inputは検証/サニタイズに合格します。
  3. 次に、更新された、現在有効なデータを返します。

フィールドが動的に生成されている場合は、ステップスルー動的に、検証コールバックで。 foreach( $options as $option )でこれは正しいです。

すべてをまとめると、次のようになります。

<?php
function setting_validate( $input ) {
    // Get current setting values
    $valid_options = get_option( 'XX_theme_options' );
    // Get option parameters array
    // Note: XX_theme_get_option_parameters() function
    // should be defined to return the array you've 
    // defined for $options
    $options = XX_theme_get_option_parameters();
    // Now step through the option parameters,
    // and validate each $input[$option]
    foreach( $options as $option ) {
         // If $option['type] is a checkbox
         if( 'checkbox' == $option['type'] ) { 
             // verify that $input[$option] is set
             // and is set with a valid value;
             // if so, set $valid_input[$option] to 1
             $valid_input[$option] = ( isset( $input[$option] && true == $input[$option] ? 1 : 0 );
         }
     }
     // Return the updated $valid_input array
     return $valid_input;
}
?>
4
Chip Bennett