Comment passer une variable à un rappel add_settings_section ()?

16

J'essaie d'automatiser, autant que possible, la fonction Paramètres de l'API appelle pour chaque paramètre dans un plugin. En boucle à travers le tableau d'options, et en sortie add_settings_section()et add_settings_field()est assez simple:

add_settings_section():

$oenology_hooks_tabs = oenology_hooks_get_settings_page_tabs();
foreach ( $oenology_hooks_tabs as $tab ) {
    $tabname = $tab['name'];
    $tabtitle = $tab['title'];
    $tabsections = $tab['sections'];
    foreach ( $tabsections as $section ) {
        $sectionname = $section['name'];
        $sectiontitle = $section['title'];
        $sectiondescription = $section['description'];
        // Add settings section
        add_settings_section(
            'oenology_hooks_' . $sectionname . '_section',
            $sectiontitle,
            'oenology_hooks_' . $sectionname . '_text',
            'oenology_hooks_' . $tabname . '_tab'
        );
    }
}

Et `add_settings_field ():

global $oenology_hooks;
$oenology_hooks = oenology_hooks_get_hooks();

foreach ( $oenology_hooks as $hook ) {
    $hookname = $hook['name'];
    $hooktitle = $hook['title'];
    $hooktab = $hook['tab'];
    $hooksection = $hook['section'];
    add_settings_field(
        'oenology_hooks_' . $hookname,
        $hooktitle,
        'oenology_hooks_setting_callback',
        'oenology_hooks_' . $hooktab . '_tab',
        'oenology_hooks_' . $hooksection . '_section',
        $hook
    );
}

Avec add_settings_field(), je peux facilement écrire un rappel générique, en passant la $hookvariable au rappel, comme cinquième paramètre de l'appel de fonction:

function oenology_hooks_setting_callback( $hook ) {
    $oenology_hooks_options = get_option( 'plugin_oenology_hooks_settings' ); 
    $hookname = $hook['name'];
    $hooktitle = $hook['title'];
    $hookdescription = $hook['description'];
    $hooktype = $hook['type'];
    $hooktab = $hook['tab'];
    $hooksection = $hook['section'];
    $inputvalue = $hookname . '_hide';
    $inputname = 'plugin_oenology_hooks_settings[' . $inputvalue . ']';
    $textareaname = 'plugin_oenology_hooks_settings[' . $hookname . ']';
    $textareavalue = $oenology_hooks_options[$hookname];
    if ( 'Filter' == $hooktype ) {
        ?>
        <input type="checkbox" name="<?php echo $inputname; ?>" value="<?php echo $inputvalue;?>" <?php checked( true == $oenology_hooks_options[$inputvalue]  ); ?> />
        <span>Hide <?php echo $hooktitle; ?> content?</span><br />
        <?php
    }
    ?>
    <span class="description"><?php echo $hooktype; ?> Hook: <?php echo $hookdescription; ?></span><br />
    <textarea name="<?php echo $textareaname; ?>" cols="80" rows="3" ><?php 
        echo esc_textarea( $textareavalue ); 
    ?></textarea>
    <?php 
}

Cependant, il semble qu'il add_settings_section()n'y ait pas de $argsparamètre analogue ; ainsi, je ne peux pas utiliser la même méthode pour passer la $sectionvariable au rappel.

Ainsi, ma question: existe-t-il un moyen de passer une variable au add_settings_section()rappel, ou une autre façon de créer un rappel analogue à ce que je fais add_settings_field()?

ÉDITER:

@Bainternet a réussi! Voici mon code de travail:

/**
 * Callback for add_settings_section()
 * 
 * Generic callback to output the section text
 * for each Plugin settings section. 
 * 
 * @param   array   $section_passed Array passed from add_settings_section()
 */
function oenology_hooks_sections_callback( $section_passed ) {
    global $oenology_hooks_tabs;
    $oenology_hooks_tabs = oenology_hooks_get_settings_page_tabs();
    foreach ( $oenology_hooks_tabs as $tab ) {
        $tabname = $tab['name'];
        $tabsections = $tab['sections'];
        foreach ( $tabsections as $section ) {
            $sectionname = $section['name'];
            $sectiondescription = $section['description'];
            $section_callback_id = 'oenology_hooks_' . $sectionname . '_section';
            if ( $section_callback_id == $section_passed['id'] ) {
                ?>
                <p><?php echo $sectiondescription; ?></p>
                <?php
            }
        }
    }
}
Chip Bennett
la source
1
Juste une petite note: pourquoi ne le faites-vous pas extract( $args, EXTR_SKIP );au début de oenology_hooks_setting_callback(), afin que vous n'ayez pas à enregistrer chaque partie du tableau dans un nouveau $var? Celles-ci seront alors disponibles avec $'name_inside_the_array, par ex. '$ title , $ tab`, etc.
kaiser
... parce que je ne suis pas vraiment intelligent avec PHP? :) Je vais essayer ça; Merci!
Chip Bennett
Peut-être que vous voulez jeter un coup d'œil à ce Gist , qui montre un exemple de "meilleure pratique peut-être" sur la façon d'ajouter des filtres et des crochets, d'analyser des arguments et de traiter l'entrée de chaîne de requête. C'est un peu vieux et je vais probablement le retravailler quand j'aurai le temps, mais imo ça vaut le coup d'oeil. :)
kaiser
Il s'agit en fait d'un plugin qui ajoute une interface utilisateur pour les hooks que j'ai ajoutés à Oenology. Je suis assez à l'aise avec la façon dont j'ai ajouté les crochets au thème. Maintenant, j'essaie simplement de fournir un moyen pratique de les exposer aux utilisateurs finaux.
Chip Bennett
Je ne vous ai pas mal compris. Je voulais juste vous montrer cela au cas où cela pourrait vous être utile (chaque fois). Je vois ce code comme quelque chose d'ironique - jetez un coup d'œil à quel point il est difficile d'obtenir chacun et tout pour tout le monde sous la forme de wordpress ...
kaiser

Réponses:

18

si vous regardez la fonction do_settings_sections plus spécifiquement la ligne 1164 où la fonction de rappel est exécutée:

call_user_func($section['callback'], $section);

vous pouvez voir que le tableau $ section est passé à la fonction de rappel, vous pouvez donc identifier le rappel par le $section['id']

j'espère que cela fait depuis.

Mise à jour

voici un exemple, si votre rappel add_settings_section pour toutes les sections a été nommé, oenology_hooks_section_callbackvous pouvez l'identifier comme ceci:

function oenology_hooks_section_callback($section_passed){
    if ($section_passed['id'] == 'whatever_section_id'){
        //do stuff
    }
    if ($section_passed['id'] == 'whatever_section_id_number2'){
        //do other stuff
    }
 }

et par faire des choses, je veux dire faire tout ce que vous voulez faire avec ce rappel de section.

Bainternet
la source
Hmm ... ça a l'air prometteur. Comment puis-je déterminer $section['id']?
Chip Bennett
@Chip Bennett idsera le premier argument add_settings_section()
auquel
@Chip Bennett J'ai ajouté un exemple pour essayer de mieux expliquer.
Bainternet
@Bainternet: Génial! J'ai un script d'option et j'ai rencontré le même problème que Chip Bennett. Maintenant, cela fonctionne comme un charme. Merci.
Anh Tran
D'accord, donc il a finalement cliqué au cours du week-end; laissez-moi essayer le code que j'ai en tête, et je ferai rapport.
Chip Bennett
4

Je sais que c'est une vieille question mais je mettrai mes deux cents dedans, juste au cas où quelqu'un d'autre viendrait; une façon plus simple de le faire serait d'écrire votre propre modification de la add_settings_section()fonction, qui n'ajouterait à la fin qu'un paramètre d'argument de rappel.

Cela ressemblerait à ceci (ou quelque chose comme ça)

function my_add_settings_section($id, $title, $callback, $page, $callbackargs) {

global $wp_settings_sections;

if ( !isset($wp_settings_sections) ) 
{
    $wp_settings_sections = array();
}

if ( !isset($wp_settings_sections[$page]) )
{
    $wp_settings_sections[$page] = array();
}

if ( !isset($wp_settings_sections[$page][$id]) )
{
    $wp_settings_sections[$page][$id] = array();
}

$wp_settings_sections[$page][$id] = array( 'id' => $id, 'title' => $title, 'callback' => $callback, 'callbackargs' => $callbackargs, 'page' => 'page' );
}

Maintenant, vous utiliserez simplement ceci au lieu de la fonction native wordpress et accéderez à vos arguments de rappel via la 'callbackargs'clé du tableau de la manière habituelle, comme ceci

function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   $section_passed['callbackargs']
}

Que nous pourrions utiliser pour passer à une autre fonction:

 function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   $args = $section_passed['callbackargs'];
   some_other_function( $args );
}

Ou les arguments de rappel peuvent être eux-mêmes un tableau que nous utilisons:

function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   if ( $section_passed['callbackargs']['stuff'] !== 'things' ) 
   {
       echo 'stuff is not things!";
   }
}

Tout cela est possible car tout ce add_settings_section()qui se passe est d'ajouter un nouveau membre de tableau à la $wp_settings_sectionsvariable globale, ce nouveau membre de tableau pourrait être un tableau lui-même contenant un nombre quelconque de clés avec des noms différents, qui pourraient être utilisés, par n'importe quelle fonction qui savait qu'ils étaient là. Lorsque do_settings_sectionsappelle la call_user_func_arraypasse un $sectionsparamater comme Bainternet a noté, cela signifie que l'ensemble du réseau , nous avons ajouté à $wp_settings_sectionsen my_add_settings_section()est passé dans notre rappel, ce qui signifie que nous avons accès à tous les nouveaux membres du tableau nous ajoutons comme le callbackargspermet notre fonction d'avoir une pleine rappel à part entière.

Même si je suis sûr que cela pourrait être évident, j'ai pensé que je pourrais simplement l'expliquer au cas où quelqu'un qui serait confus le verrait.

Cikica
la source
1

Vous pouvez également toujours utiliser une approche plus générale, sans chercher l'implémentation de fonction particulière (c'est-à-dire sans vérifier si add_settings_section passe quoi que ce soit implicitement). Cette approche générale utilise la fermeture PHP.

Comment l'utiliser: dans chaque endroit où vous passez un nom de fonction, au lieu de cela, passez une fonction anonyme, avec utilisation en elle.

Exemple:

au lieu de

foreach ( $ar as $name => value ) {
    add_settings_section(
        $section,
        'something',
        'something-else',
        'callback_name'
    );
}

function callback_name() {
    do_something();
}

vous pouvez utiliser:

foreach ( $ar as $name => value ) {
    add_settings_section(
        $section,
        'something',
        'something-else',
        function () use ( $name, $value ) {
            callback_name( $name, $value )
        }
    );
}

function callback_name( $name, $value ) {
    do_something( $name, $value );
}
Olga Farber
la source