kaiser
  • 0
Гуру

Крюки, фильтры и переменные

  • 0

Я обновлял пример страницы кодекса для хуков действий, играя, чтобы сделать некоторые повторно используемые функции (первоначально для некоторого Q здесь @WA). Но затем я столкнулся с проблемой, о которой раньше не знал: после подключения к функции для изменения вывода переменной я больше не могу решить, хочу ли я повторить вывод или просто вернуть его.

Проблема: я могу изменять переменные, которые я передаю в do_action хук с помощью функции обратного вызова. Все, что я изменяю/добавляю с помощью переменной, доступно только внутри функции обратного вызова, но не после do_action вызова внутри исходной функции.

ДЛЯ ВАШЕГО УДОВОЛЬСТВИЯ: Я переделал его в рабочий пример, так что вы можете просто скопировать/вставить его в какой -нибудь functions.php файл и увидеть/протестировать проблему без каких-либо усилий.

Пример:

Функция обработки данных

Это handle_data_fn. Немного задокументировано, так как должно служить руководством о том, как анализировать и объединять default с другими аргументами.

Вы можете увидеть проблему в конце функции сразу после вызова do_action().

/**
 * The "global" data handle function
 * 
 * This function can serve a lot of different purposes.
 * Incl. merging db values from an options entry with input arguments.
 * 
 * Throws a fully translateable Error if no database option name was specified.
 * Tells you from which file the Error was triggered and in which line you should search it.
 * Also tells you the "hook_data_handle_$args['UID']" name of the action hook where the Error occured. 
 * 
 * Uses of external function calls in order of their appearance inside the function:
 * @uses:   isset()         - @link: http://php.net/manual/en/function.isset.php
 * @uses:   wp_die()        - @link: http://codex.wordpress.org/Function_Reference/wp_die
 * @uses:   printf()        - @link: http://php.net/manual/en/function.printf.php
 * @uses:   _e()            - @link: http://codex.wordpress.org/Function_Reference/_e (i18n function)
 * @uses:   apply_filters() - @link: http://codex.wordpress.org/Function_Reference/apply_filters
 * @uses:   wp_parse_args() - @link: http://codex.wordpress.org/Function_Reference/wp_parse_args
 * @uses:   extract()       - @link: http://php.net/manual/en/function.extract.php
 * @uses:   get_option()    - @link: http://codex.wordpress.org/Function_Reference/get_option
 * @uses:   do_action()     - @link: http://codex.wordpress.org/Function_Reference/do_action
 * @uses:   return          - @link: http://php.net/manual/en/function.return.php
 * 
 * @param:  (array) mixed $args | array of arguments - `$args['UID']` is always a must have
 * @param:  $database           | true if you want to get and modify some db-option - `$args['name']` then is a must have
 * @param:  $output             | result from the function - @internal: should not get set
 */
    function handle_data_fn( $args = array() )
    {
        // abort if we ain't got some unique identifier as argument
        if ( !isset( $args['UID']) )
            return;

        // Trigger Error if an option should get retrieved from the database, 
        // but no option name was specified
        if ( !isset( $args['name'] ) )
            wp_die( 
                printf(
                    _e(
                        'You have to specify the "name" of a db-entry as argument inside a handle_data_fn at for the action hook: %1$s.'."\n".
                        'Error triggered inside: file name %2$s (line number %3$s)'
                     )
                    ,'some_textdomain'
                 )
                ,'hook_data_handle_'.$args['UID'].'`'
                ,__FILE__
                ,__LINE__
            );


        // setup default arguments
        $defaults = ( 
            array(
                 'UID'      => null     // DB/css: #id | used to identify the data inside your database - $name[$ID] - can be used as css #id too
                ,'name'     => null     // name of DB field, should be a constant when fn get's triggered - just here for completeness, not needed
                ,'args'     => array(   // $arguments the function can handle - put default arguments in here as array data
                    // 'classes'    => null     // css: .class - example
                 )
                ,'output'   => ''
                ,'echo'     => false    // if you want to echo the output or just save it in a var for later modifying
            ) 
        );
        // filter defaults
        $defaults = apply_filters( 'filter_defaults_'.$args['UID'], $defaults ); 

        // merge defaults with input arguments
        $args = wp_parse_args( $args, $defaults );
        extract( $args, EXTR_SKIP );

        // in case you want to call the global function again, 
        // but for some reason need to modify the merged result of defaults & arguments
        $args = apply_filters( 'filter_args_'.$args['UID'], $args );

        // retrieve the database option
        if ( isset( $args['name'] ) )
            $options = get_option( $args['name'] );


        # >>> start building $output

            // if true, echo the $output
            if ( isset( $args['echo'] ) )
            {
                if ( $args['echo'] === true )
                {
                    // do stuff here - your argument is the initial array
                    do_action( 'hook_data_handle_'.$args['UID'], $args, $options );

                    // Test output inside handle_fn: 
                    echo '<pre>From inside handle_fn: ';
                        print_r($args);
                    echo '</pre>';

                    return;
                }

            }

            // else just return the $output
            // HOW CAN I NOT ECHO THE DATA HERE. 
            // STORING THE do_action return VALUE DOESN'T WORK.
            // NEITHER DOES JUST returnING IT INSIDE THE CALLBACK FN 'modify_args_fn' BELOW
            do_action( 'hook_data_handle_'.$args['UID'], $args, $options );
            return;

        # <<< end building $output
    }

Функции обратного вызова

Они используются для а) построения исходного массива и б) изменения вывода.

/**
 * EXAMPLE for how to add initial data to the handle_data_fn function.
 * 
 * @param (array) mixed $args
 */
    function build_args_fn ( $args ) {
        // build initial array
        $args = array(
             'UID'      => 'whatever_UID'
            ,'name'     => 'some_options_name'
            ,'args'     => array(
                'class' => 'example-wrap'
             )
            ,'echo'     => true
        );

        handle_data_fn( $args );
    }
    // 'some_hook' is some hook in a template file where the output should get echoed.
    add_action( 'some_hook', 'build_args_fn', 0, 1 );

/**
 * EXAMPLE for how to add content and modify the options from the DB inside a handle_data_fn function.
 * 
 * @param (array) mixed $args
 * @param (array) mixed $options    | db-options retrieved inside the oxo_parse function
 */
    function modify_args_fn ( $args, $options )
    {
        $args['output'] .= '<div class="container">';
        $args['output'] .= '<div class="'.$args['args']['class'].'">';
        $args['output'] .= $options;
        $args['output'] .= '</div>';
        $args['output'] .= '</div>';

        // Test output inside callback fn
        echo '<pre>From inside callback: ';
            print_r($args);
        echo '</pre>';

        // HERE'S THE PROBLEM. I CAN'T SIMPLE return IT, BECAUSE IT WOULDN'T BE AVAILABLE INSIDE MY 'data_handle_fn'.
        # return $args['output'];
        // I HAVE TO PRINT IT TO GET SOME OUTPUT. THE $args['output'] IS NOT AVAILABLE INSIDE THE 'handle_data_fn' AFTER THE do_action CALL.
        return print $args['output'];
    }
    // Name of the hook comes from 'UID' argument in 'build_args_fn' combined with 'hook_data_handle_'
    add_action ( 'hook_data_handle_whatever_UID', 'modify_args_fn', 10, 2 );

Спасибо за любую информацию и помощь по этому вопросу.

Share
  1. Действия предназначены не для изменения данных, они представляют собой моменты времени для получения дополнительных результатов, фильтры предназначены для изменения данных до того, как с ними произойдет что-то конкретное. Если хук хочет, чтобы данные были изменены, это обычно фильтр, если хуки хотят, чтобы дополнительный вывод происходил в определенном месте, это действие… обычно

    • 0
  2. Если вы хотите вернуть данные, лучшим решением является использование apply_filters() и указание обратному вызову всегда возвращать:

    $output = apply_filters( 'hook_data_handle_'.$args['UID'], $args, $options );
    
    if ( $args['echo'] )
      echo $output;
    else
      return $output;
    

    Менее элегантным решением было бы использование буферизации вывода.

    • 0

Оставить ответ

You must login to add an answer.