web-dev-qa-db-fra.com

Comment faire une boucle Plugin Option Field Field?

Problème/Contexte

Actuellement, je crée un plugin pour un client qui leur permettra de marquer et de modifier des polygones Google Map prédéterminés (affichés sur le site) dans le tableau de bord.

Je souhaite laisser l’utilisateur marquer un polygone comme étant important, définir une couleur, une opacité et un texte de fenêtre d’information personnalisés, ce que j’ai pu faire jusqu’à présent. Le problème est que ces ensembles de champs doivent exister pour tous les polygones de 180 ans. Avec l'API de paramètres WP, je peux créer et enregistrer des champs, mais il serait ridicule de créer plus de 500 rappels pour couvrir chaque champ spécifique. Ainsi, depuis quelques jours, j'essaie de parcourir le champ défini un nombre spécifique de fois en ajoutant un nombre variable.

Code actuel

Voici l'enregistrement actuel du champ d'option pour un ensemble de polygones (stockés dans une classe):

<?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++;
    }

}
?>

Et voici une série de callbacks que j'ai testés et qui fonctionnent correctement:

<?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>';
}
?>

Question

Comme vous pouvez le constater, j'ai une case à cocher, un sélecteur de couleur, une entrée d'opacité et une zone de texte. Je veux que l'ensemble soit bouclé pour chaque polygone. J'ai essayé d'exécuter les champs dans un seul rappel, mais il regroupait simplement toutes les mêmes options (c'est-à-dire, 31 cases à cocher, 31 sélecteurs de couleurs, etc.). J'ai également essayé de définir les rappels en dehors de la classe et de boucler une while autour du jeu de fonctions, mais l'utilisation de la variable $i dans le nom de la fonction renvoyait des erreurs, de même que l'ajouter avant d'appeler et d'appeler les fonctions.

J'apprécierais grandement toutes les suggestions qui pourraient m'aider à atteindre le résultat de la mise en boucle des ensembles de champs.

4
penguin429

Je l'ai compris après un peu de travail.

Pour commencer, j'ai fini par utiliser un seul rappel: array($this, 'txs_loop_callbacks') en utilisant le même enregistrement add_settings_field ci-dessus. Ensuite, j'ai modifié l'argument final dans le champ resgistration, en rendant chacun unique à ce champ spécifique: array('field' => 'txs_opacity_'.$i).

Ensuite, dans le rappel de boucle, j'ai stocké le code HTML de chaque champ dans une fonction anonyme définie en tant que variable. Ainsi:

$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
    );
};

J'ai défini ce type de variable pour chaque type de champ (c'est-à-dire, $txs_checkbox, $txs_colorpicker et on).

Après cela, j'ai appelé les fonctions anonymes dans une boucle avec une coche pour afficher un seul type de champ par jeu.

$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++;
}

Avec tous ces éléments, j'ai pu obtenir le résultat de la répétition d'ensembles de champs.

1
penguin429