it-swarm.com.de

hooks & Filter und Variablen

Ich habe das Codex-Seiten-Beispiel für Action-Hooks aktualisiert, während ich herumgespielt habe, um einige wiederverwendbare Funktionen auszuführen (ursprünglich für einige Q hier bei @WA). Aber dann stieß ich auf ein Problem, das ich vorher nicht kannte: Nachdem ich mich in eine Funktion zum Ändern der Ausgabe einer Variablen eingebunden habe, kann ich nicht mehr entscheiden, ob ich die Ausgabe wiedergeben oder zurückgeben möchte.

Das Problem: Ich kann Variablen, die ich an einen do_action-Hook übergebe, mit einer Rückruffunktion ändern. Alles, was ich mit der Variablen ändere/hinzufüge, ist nur innerhalb der Rückruffunktion verfügbar, nicht jedoch nach dem Aufruf von do_action innerhalb der ursprünglichen Funktion.

FÜR IHR VERGNÜGEN: Ich habe es zu einem funktionierenden Beispiel überarbeitet, sodass Sie es einfach in eine functions.php-Datei kopieren/einfügen und das Problem mühelos anzeigen/testen können.

Beispiel:

Datenfunktion behandeln

Dies ist der handle_data_fn. Etwas mehr als dokumentiert, da dies als Leitfaden für das Parsen und Zusammenführen von Standardwerten mit anderen Argumenten dienen sollte.
Sie können das Problem am Ende der Funktion direkt nach dem Aufruf von do_action () sehen.

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

Rückruffunktionen

Diese werden verwendet, um a) das anfängliche Array zu erstellen und b) die Ausgabe zu modifizieren.

/**
 * 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 );

Vielen Dank für jede Info und Hilfe zu diesem Problem.

2
kaiser

Wenn Sie die Daten zurückgeben möchten, verwenden Sie am besten apply_filters () und weisen Sie den Rückruf an, immer Folgendes zurückzugeben:

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

if ( $args['echo'] )
  echo $output;
else
  return $output;

Eine weniger elegante Lösung wäre die Verwendung von Ausgabepufferung .

3
scribu