Como passar a variável para o retorno de chamada add_settings_section ()?

16

Estou tentando automatizar, tanto quanto possível, a função da API de configurações para cada configuração em um plug-in. Dar laços na matriz de opções e gerar add_settings_section()e add_settings_field()é bastante simples:

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

E `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
    );
}

Com add_settings_field(), eu posso escrever facilmente um retorno de chamada genérico, passando a $hookvariável para o retorno de chamada, como o quinto parâmetro na chamada de função:

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 
}

No entanto, parece que add_settings_section()não possui um $argsparâmetro análogo ; portanto, não posso usar o mesmo método para passar a $sectionvariável para o retorno de chamada.

Portanto, minha pergunta: existe alguma maneira de passar uma variável para o add_settings_section()retorno de chamada ou alguma outra maneira de criar um retorno de chamada análogo ao que estou fazendo add_settings_field()?

EDITAR:

@Bainternet acertou em cheio! Aqui está o meu código de trabalho:

/**
 * 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
fonte
1
Apenas uma nota de rodapé: por que você não faz isso extract( $args, EXTR_SKIP );no começo oenology_hooks_setting_callback()para não salvar todas as partes da matriz em uma nova $var? Estes estarão disponíveis com $'name_inside_the_array, por ex. '$ title , $ tab`, etc.
kaiser
... porque eu não sou tão inteligente com PHP? :) Vou tentar; obrigado!
Chip Bennett
Talvez você queira dar uma olhada neste Gist , que mostra alguns exemplos de "talvez práticas recomendadas" sobre como adicionar filtros e ganchos, analisar argumentos e lidar com a entrada da string de consulta. É um pouco velho e provavelmente vou retrabalhá-lo quando tiver tempo, mas vale a pena dar uma olhada. :)
kaiser
Na verdade, é apenas um plug-in que adiciona interface do usuário para ganchos que eu adicionei à Oenology. Estou bastante confortável com a forma como adicionei os ganchos ao tema. Agora, estou apenas tentando fornecer uma maneira conveniente de expô-los aos usuários finais.
Chip Bennett
Eu não te entendi mal. Eu só queria lhe mostrar isso, caso isso possa lhe ajudar (sempre). Eu vejo este código como algo irônico - basta dar uma olhada quanto esforço é fazer com que cada um e tudo para todos no wordpress caminho ...
kaiser

Respostas:

18

se você observar a função do_settings_sections mais especificamente a linha 1164 onde a função de retorno de chamada está sendo executada:

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

você pode ver que a matriz da seção $ está sendo passada para a função de retorno de chamada, para poder identificar o retorno de chamada pelo $section['id']

espero que isso faça desde então.

Atualizar

Aqui está um exemplo, se seu retorno de chamada add_settings_section para todas as seções foi nomeado oenology_hooks_section_callback, você pode identificá-lo assim:

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
    }
 }

e por coisas, quero dizer, faça o que você quiser fazer com o retorno de chamada dessa seção.

Bainternet
fonte
Hmm ... isso parece promissor. Como eu determino $section['id']?
Chip Bennett
@Chip Bennett idserá o primeiro argumento que você passa paraadd_settings_section()
Rarst
@Chip Bennett Adicionei um exemplo para tentar explicar melhor.
Bainternet
@Bainternet: Awesome! Eu tenho um script de opção e conheci o mesmo problema que Chip Bennett. agora isso trabalha como charme. Obrigado.
Anh Tran
Ok, então finalmente clicou no fim de semana; deixe-me tentar o código que tenho em mente, e vou relatar.
Chip Bennett
4

Sei que essa é uma pergunta antiga, mas vou jogar meus dois centavos, para o caso de alguém aparecer; uma maneira mais simples de fazer isso seria escrever sua própria modificação da add_settings_section()função, que adicionaria apenas um parâmetro args de retorno de chamada no final dela.

Isso seria assim (ou algo parecido)

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

Agora você simplesmente usaria isso em vez da função nativa de wordpress e acessaria seus argumentos de retorno de chamada através da 'callbackargs'chave de matriz da maneira usual, como este

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

Que poderíamos usar para passar para outra função:

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

Ou os argumentos de retorno de chamada podem ser eles mesmos uma matriz que usamos:

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

Isso tudo é possível porque tudo o que add_settings_section()faz é adicionar um novo membro da matriz à $wp_settings_sectionsvariável global, esse novo membro da matriz poderia ser uma matriz em si contendo qualquer número de chaves com nomes diferentes, que poderiam ser usados ​​por qualquer função que soubesse que eles estavam lá. Quando do_settings_sectionschama o call_user_func_arrayque passa um $sectionsparamater como Bainternet observado, isto significa que toda a matriz que foram adicionadas para $wp_settings_sectionsdentromy_add_settings_section() é passado para o nosso retorno de chamada, o que significa que têm acesso a cada novo membro da matriz que adicionar a ele, como ocallbackargs permitir que a nossa função de ter um completo retorno de chamada emplumado.

Embora eu tenha certeza de que isso possa ser óbvio, pensei em explicar o caso de alguém que se confunda aparecer.

Cikica
fonte
0

Você também pode sempre usar uma abordagem mais geral, sem procurar a implementação da função específica (ou seja, sem verificar se add_settings_section passa algo implicitamente). Essa abordagem geral usa o fechamento do PHP.

Como usá-lo: em todos os lugares, onde você passa o nome de uma função, em vez de passar uma função anônima, com o uso .

Exemplo:

ao invés de

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

function callback_name() {
    do_something();
}

você pode usar:

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
fonte