web-dev-qa-db-ja.com

プラグインオプションフィールドセットをループする方法

問題/背景

現在、クライアント用のプラグインを作成しています。これを使用すると、ダッシュボード内の(サイトに表示されている)所定のGoogle Mapポリゴンをマークおよび変更できます。

私は、ユーザーに多角形を重要なものとしてマークさせ、カスタムカラー、不透明度、そして情報ウィンドウのテキストを設定させたいのです。問題は、これらのフィールドセットが180のようなポリゴンすべてに存在する必要があることです。 WP settings APIを使用してフィールドを作成および保存できますが、各特定のフィールドをカバーするために500を超えるコールバックを作成するのはばかげているでしょう。それで過去数日間、私はフィールドを特定の回数設定して可変数を追加しながらループしようとしてきました。

現在のコード

これは、(クラスに格納されている)1セットのポリゴンの現在のオプションフィールド登録です。

<?php
public function page_init() {
    //[. . . ]
    add_settings_section(
        'rangers_txs',
        'Texas Senate District Options',
        array($this, 'print_txs_info'),
        'rangers_txs_option'
    );
    register_setting(
        'rangers_txs',
        'rangers_txs_option',
        array($this, 'ranger_txs_sanitize')
    );

    $i=1;
    while($i <= 31) {
        add_settings_field(
            'rangers_txs_checkbox_'.$i, //id
            'Is District '.$i.' important?', //Title
            array( $this, 'rangers_txs_check_callback_'.$i), //callback
            'rangers_txs_option', //page
            'rangers_txs', //section
            array('field' => 'txs_checkbox')
        );
        add_settings_field(
            'rangers_txs_colorpicker_'.$i, //id
            'District Color', //Title
            array( $this, 'rangers_txs_color_callback_'.$i ), //callback
            'rangers_txs_option', //page
            'rangers_txs', //section
            array('field' => 'txs_colorpicker')
        );
        add_settings_field(
            'rangers_txs_opacity_'.$i, //id
            'How important is it?', //Title
            array( $this, 'rangers_txs_opacity_callback_'.$i ), //callback
            //array($this, 'rangers_txs_input_array'),
            //'rangers_txs_opacity_callback_'.$i, //callback
            'rangers_txs_option', //page
            'rangers_txs', //section
            array('field' => 'txs_opacity')
        );
        add_settings_field(
            'rangers_txs_info_'.$i, //id
            'District Information', //Title
            array( $this, 'rangers_txs_info_callback_'.$i ), //callback
            'rangers_txs_option', //page
            'rangers_txs', //section
            array('field' => 'txs_info')
        );

        $i++;
    }

}
?>

そして、これが私がテストして正しく動作したコールバックのセットです。

<?php
public function colorpicker_init() {
    echo '<script type="text/javascript">
            jQuery(document).ready(function($) {
              $(".tr-color-picker").wpColorPicker();
            });
          </script>';
}
public function rangers_txs_check_callback_1() {
    printf(
        '<input type="checkbox" id="rangers_txs_checkbox_1" name="rangers_txs_option[rangers_txs_checkbox_1]" %1$s />
        <label for="rangers_txs_option[rangers_txs_checkbox_1]">Yep, it\'s important.', 
        checked( isset($this->txsoptions['rangers_txs_checkbox_1']), true, false)
    );
}
public function rangers_txs_color_callback_1() {
    $this->colorpicker_init();

    $color = $this->txsoptions['rangers_txs_colorpicker_1'] != '' ? sanitize_text_field($this->txsoptions['rangers_txs_colorpicker_1']) : '#0A64A4';
    printf(
        '<input type="text" name="rangers_txs_option[%1$s]" id="%1$s" class="tr-color-picker" data-default-color="#0A64A4" value="'.$color.'" />',
        'rangers_txs_colorpicker_1'
    );
}
public function rangers_txs_opacity_callback_1() {
    print '<p><em>On a scale of 1-10 (determines opacity of district, default: 5).</em></p>';
    printf(
        '<input type="text" id="rangers_txs_opacity_1" name="rangers_txs_option[rangers_txs_opacity_1]" value="%s" />', 
        isset( $this->txsoptions['rangers_txs_opacity_1'] ) ? esc_attr( $this->txsoptions['rangers_txs_opacity_1']) : '' 
    );
}
public function rangers_txs_info_callback_1() {
    isset($this->txsoptions['rangers_txs_info_1']) ? $content = $this->txsoptions['rangers_txs_info_1'] : $content = '';

    echo '<textarea id="rangers_txs_info_1" name="rangers_txs_option[rangers_txs_info_1]" rows="6" cols="50">'.$content.'</textarea>';
}
?>

質問

ご覧のとおり、チェックボックス、カラーピッカー、不透明度入力、およびテキスト領域があります。ポリゴンごとにセット全体をループしたいです。 1回のコールバックでフィールドを実行しようとしましたが、同じオプションをすべてまとめてまとめました(31個のチェックボックスと31個のカラーピッカーなど)。私はまた、クラスの外側でコールバックを設定し、関数セットの周りでwhileをループしようとしましたが、呼び出しの前や関数を呼び出すときに追加したように、関数名に$i変数を使用するとエラーが返されます。

フィールドセットのループ結果を達成するのに役立つ可能性のある提案があれば非常に感謝します。

4
penguin429

私はちょっとした仕事の後にそれを考え出しました。

最初に、私は単一のコールバックを使用することになりました:上記の同じadd_settings_field登録を使用するarray($this, 'txs_loop_callbacks')。それから、フィールド登録の最後の引数を変更して、それぞれをその特定のフィールドに固有のものにしました:array('field' => 'txs_opacity_'.$i)

次に、ループコールバックで、各フィールドのHTMLを変数として定義された無名関数に格納しました。そのようです:

$txs_checkbox = function($num) {
    $is_checked = checked( isset($this->txsoptions['rangers_txs_checkbox_'.$num]), true, false);
    printf(
       '<input type="checkbox" class="is-important-'.$num.'" id="rangers_txs_checkbox_'.$i.'" name="rangers_txs_option[rangers_txs_checkbox_'.$num.']" %1$s />
        <label for="rangers_txs_option[rangers_txs_checkbox_'.$num.']">District '.$num.' is important</label><br /><br />', 
        $is_checked
    );
};

このタイプの変数を各フィールドタイプ(つまり、$txs_checkbox$txs_colorpicker、およびon)に対して定義しました。

その後、ループ内で無名関数を呼び出し、1セットにつき1種類のフィールドのみを表示するようにしました。

$n=1;
while($n <= 31) {
    switch($args['field']):
        case('txs_checkbox_'.$n):
            $txs_checkbox($n);
            break;

        case('txs_colorpicker_'.$n):
            $txs_colorpicker($n);
            break;

        case('txs_opacity_'.$n):
            $txs_opacity($n);
            break;

        case('txs_info_'.$n):
            $txs_info($n);
            break;
    endswitch;

    $n++;
}

これらの要素をすべて組み合わせることで、フィールドセットを繰り返した結果を得ることができました。

1
penguin429