Як передати змінну для зворотного виклику add_settings_section ()?


16

Я намагаюся максимально автоматизувати функцію API API для кожного параметра в плагіні. Прокручування масиву параметрів, а також виведення add_settings_section()і add_settings_field()досить просте:

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

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

Завдяки цьому add_settings_field()я можу легко записати загальний зворотний виклик, передавши $hookзмінну в зворотний виклик, як п'ятий параметр у виклику функції:

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 
}

Однак виявляється, що add_settings_section()не має аналогічного $argsпараметра; таким чином, я не можу використовувати один і той же метод для передачі $sectionзмінної до зворотного дзвінка.

Отже, моє запитання: чи є спосіб передати змінну add_settings_section()зворотному виклику чи іншим способом створення зворотного дзвінка, аналогічного тому, що я роблю add_settings_field()?

Редагувати:

@Bainternet прибив це! Ось мій робочий код:

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

1
Просто сторонне позначення: Чому ви не extract( $args, EXTR_SKIP );на початку oenology_hooks_setting_callback(), щоб не потрібно зберігати кожну частину масиву в нову $var? Потім вони будуть доступні $'name_inside_the_array, наприклад, '$ title , $ tab' тощо.
кайзер

... тому що я насправді не так розумний з PHP? :) Спробую; Спасибі!
Чіп Беннетт

Можливо, ви хочете ознайомитись із цим суттю , яке показує кілька прикладів "можливо найкращої практики" щодо того, як додавати фільтри та гачки, аналізувати аргументи та мати справу з введенням рядка запиту. Він трохи старий, і я, швидше за все, перероблю його, коли у мене з’явиться час, але їм варто подивитися. :)
кайзер

Це насправді лише плагін, який додає інтерфейс для гачків, які я додав до Eenology. Мені досить комфортно, як я насправді додав гачки до Теми. Зараз я просто намагаюся запропонувати зручний спосіб викрити їх кінцевим користувачам.
Чіп Беннетт

Я не зрозумів тебе. Я просто хотів показати вам це на випадок, якщо це може вам допомогти (коли завгодно). Я розглядаю цей код як щось іронічне - просто подивіться, скільки зусиль доводиться отримувати кожен і все для всіх в wordpress способі ...
kaiser

Відповіді:


18

якщо більш детально подивитися функцію do_settings_sections, то рядок 1164, де виконується функція зворотного виклику:

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

ви бачите, що масив розділу $ передається функції зворотного виклику, тому ви можете ідентифікувати зворотний виклик за допомогою $section['id']

сподіваюся, що це зробити з тих пір.

Оновлення

ось приклад, якщо ваш зворотний виклик add_settings_section для всіх розділів був названий, oenology_hooks_section_callbackви можете визначити його так:

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

і, маючи на увазі, я маю на увазі робити все, що ви хочете зробити із зворотним викликом цього розділу.


Хм ... це виглядає перспективно. Як визначити $section['id']?
Чіп Беннетт

@Chip Bennett idбуде першим аргументом, який ти add_settings_section()
передаєш

@Chip Bennett Я додав приклад, щоб спробувати і пояснити краще.
Bainternet

@Bainternet: Дивовижно! У мене є сценарій варіантів і зіткнувся з тією ж проблемою, що і у чіпа Беннета. Зараз це працює як шарм. Спасибі.
Ань Тран

Гаразд, так, нарешті, натиснув на вихідні; дозвольте спробувати код, який я маю на увазі, і я звіту про це.
Чіп Беннетт

4

Я знаю, що це давнє питання, але я закину два центи, на випадок, якщо хтось інший прийде; простішим способом це було б зробити написання вашої власної модифікації add_settings_section()функції, яка додала б лише параметр args для зворотного виклику в кінці його.

Це виглядатиме так (або щось подібне)

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

Тепер ви просто використаєте це замість нативної функції wordpress та отримаєте доступ до аргументів зворотного виклику через клавішу 'callbackargs'масиву звичайним способом, як це

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

Що ми могли б використати для переходу до якоїсь іншої функції:

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

Або аргументи зворотного виклику можуть бути самим масивом, який ми використовуємо:

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

Це все можливо, тому що все add_settings_section()це - додати нового члена масиву до $wp_settings_sectionsглобальної змінної, цей новий член масиву міг би бути самим масивом, що містить будь-яку кількість ключів з різними іменами, які можуть бути використані будь-якою функцією, яка знала, що вони там є. Коли do_settings_sectionsдзвонитьcall_user_func_array це проходить У $sectionsпараметр , як вказано Bainternet, це означає , що весь масив ми додали $wp_settings_sectionsв my_add_settings_section()просівають в наш зворотний виклик, тобто у нас є доступ до кожного нового члена масиву ми додамо до нього , таким якcallbackargs дозволяючи нашу функція , щоб мати повний уникнути зворотного дзвінка.

Хоча я впевнений, що це може бути очевидним, я думав, що просто поясню це на випадок, коли хтось, хто заплутається, загляне.


1

Ви також завжди можете використовувати більш загальний підхід, не шукаючи конкретної реалізації функції (тобто, не перевіряючи, чи add_settings_section передає щось неявно). Цей загальний підхід використовує закриття PHP.

Як його використовувати: у кожному місці, де ви передаєте ім'я функції, замість неї передайте анонімну функцію, з використанням у ній.

Приклад:

замість

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

function callback_name() {
    do_something();
}

Ви можете використовувати:

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 );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.