WordPress: Hook Infos auslesen


Bei der Entwicklung eigener Themen oder Plugins mit WordPress ist es nützlich zu wissen, welche Callback-Funktionen an welchen Hooks hinzugefügt wurden. Viel wichtiger ist aber deren Priorität und der Typ, Action oder Filter. Denn mit add_action() und add_filter() sind sie als solche noch gar nicht endgültig definiert wie man weiter untern sehen wird. Diese Funktionen sind sogar vertauschbar, ohne einen Fehler zu generieren. So kann schnell eine Verwirrung entstehen, wenn der Programmierer die falsche Funktion benutzt. Man würde zum Beispiel anhand des Aufrufs einen Filter erwarten, der keiner ist.

In WordPress 4.7.0 wurde für die Verwaltung der Action- und Filter-Callbacks die neue WP_Hook-Klasse eingeführt. Die globale Variable $wp_filter ist seit dem ein eindimensionaler Array der WP_Hook-Klassenobjekte. Sowohl die Action- als auch Filter-Callbacks werden in diesen Objekten gespeichert. Vor der WordPress Version 4.7.0 war $wp_filter ein mehrdimensionaler Array der die Performance ziemlich belastet hat.

Was aber wenn man herausfinden möchte ob ein Hook-Callback ein Filter oder eine Aktion ist? Oder mit welcher Priorität sie ausgeführt werden? Aktionen werden beim Hinzufügen genauso behandelt wie die Filter. Man könnte einen Filter mit add_action() hinzufügen wie auch umgekehrt eine Aktion mit add_filter() und es würde keine Rolle spielen. Sie landen alle gleicherweise in dem $wp_filter-Array. Ohne Rücksicht auf den Typ. Die add_action()-Funktion ist nur ein Alias für add_filter().

Hooks Informationen auslesen



Wie schon in dem Beitrag „WordPress: Hook Infos auslesen“ zuvor erwähnt, können Aktionen und Filter gleichermaßen, unabhängig von ihrer Verwendung mit add_action() oder add_filter() zum Hook hinzugefügt bzw. mit remove_action() oder remove_filter() entfernt werden (siehe Beitrag!).

Und hier liegt das Problem. Wenn man bei der Programmierung aus Versehen diese beiden Funktionen vertauscht (z.B. eine Action mit add_filter() einbindet), wird es keinen Fehler geben und alles funktioniert. Nur applay_filter() liefert in diesem Fall gar nichts aus dieser Funktion. Irgendwann möchte man aber eine neue Filter-Callback-Funktion an den Hook anhängen, ohne zu wissen das es sich eigentlich um eine Action handelt, die mit do_action() keine erwartete Modifizierung liefert. Eine Methode dies zu Überprüfen gibt es im WordPress vom Hause aus nicht. Der einzige Weg ist zu Überprüfen ob ein Hook etwas zurückgibt oder nicht. Denn das macht eben den Unterschied zwischen Actions und Filters. Die Filter geben den modifizierten, ersten Parameter zurück, die Aktionen gar nichts.

Die folgende Funktion listet als Text die Callback-Funktionsnamen mit Priorität und Parameteranzahl, die an einem bestimmten Hook angehangen wurden. Der Funktion wird der Hook-Tag-Name übergeben und optional die Typen-Überprüfungsmethode gesetzt (Standard: in $wp_actions-Array suchen) .

function utils_get_hook_info( $hook = '', $use_wp_actions = true ) {
    global $wp_filter, $wp_actions;
    if( empty( $hook ) || !isset( $wp_filter[$hook] ) ) return "<pre>HOOKS: '$hook' hook not found!</pre>";

    $ret = "<pre>HOOKS:\n";
    $ret .= "[hook name]: $hook\n";

    /* check if action or filter */
    if ($use_wp_actions){
        $type = "Filter";
        $amount = 0;
        foreach($wp_actions as $action => $actions ){
            if ($hook == $action){
                $type = "Action";
                $amount = $actions; //the amount of times action was triggered
                break;
            }
        }
        $ret .= "[hook type]: $type\n";
        if ($type == "Action"){
            $ret .= "[trigger amount]: $amount\n";
        }
    } else {
        if (!empty(apply_filters_ref_array( $hook, array_fill ( 0 , 20 , NULL ) ))){
            $ret .= "[hook type]: Filter\n";
        } else {
            $ret .= "[hook type]: Action\n";
        }
    }

    /* get priority */
    foreach( $wp_filter[$hook] as $hook_callback => $hook_callbacks){
        $ret .= "\t[priority]: " . strval($hook_callback) . "\n";
        $ret .= "\t\t" . str_repeat ( "-" , 50 ) . "\n";

        /* get callback information */
        foreach( $hook_callbacks as $function => $callback_functions ){

            $ret .= "\t\t[callback id]: $function\n";

            if ( is_array($callback_functions['function']) ){
                $ret .= "\t\t[callback name]:\n";
            } else {
                $ret .= "\t\t[callback name]: " . $callback_functions['function'] . "\n";
            }
            $ret .= "\t\t[accepted args]: " . strval($callback_functions['accepted_args']) . "\n";
            $ret .= "\t\t" . str_repeat ( "-" , 50 ) . "\n";
        }
    }
    $ret .= "</pre>";

    return $ret;

}

Wenn der Funktionsparameter $use_wp_actions gesetzt ist (standard) wird  der Hook-Tag in den Zeilen 12 bis 18 in dem $wp_actions-Array gesucht. Diese Methode ist unsicher, da der Tag erst nach dem ersten Hook-Aufruf mit der do_action()-Funktion existiert.

Ist der Parameter $use_wp_actions=false, wird in der Zeile 24 apply_filter_ref_array() ausgeführt. Da die Anzahl der möglichen Parameter des Callbacks nicht bekannt ist, wird ein Array aus 20 NULL-Werten übergeben. Überflüssige Parameter werden ja von dem Hook ignoriert. Gibt der apply_filter()-Aufruf etwas zurück, handelt es sich um einen Filter, sonst Action.

Ausgabe-Beispiel:

HOOKS:
[hook name]: wp_enqueue_scripts
[hook type]: Action
[trigger amount]: 1
	[priority]: 10
		--------------------------------------------------
		[callback id]: seos_magazine_child_enqueue_styles
		[callback name]: seos_magazine_child_enqueue_styles
		[accepted args]: 1
		--------------------------------------------------
		[callback id]: seos_magazine_scripts
		[callback name]: seos_magazine_scripts
		[accepted args]: 1
		--------------------------------------------------
	[priority]: 1000
		--------------------------------------------------
		[callback id]: wp_localize_jquery_ui_datepicker
		[callback name]: wp_localize_jquery_ui_datepicker
		[accepted args]: 1
		--------------------------------------------------
				
HOOKS:
[hook name]: wp_review_get_box_template
[hook type]: Filter
	[priority]: 15
		--------------------------------------------------
		[callback id]: smc_wp_review_select_box_template
		[callback name]: smc_wp_review_select_box_template
		[accepted args]: 2
		--------------------------------------------------




 

War diese Seite für dich informativ? Hat sie dir gefallen und geholfen?

Dann unterstütze die Weiterentwicklung mit einer kleinen Spende!

Die Spenden werden für die Lizenzen sowie neue Hard- und Software verwendet, die für weitere Projekte auf dieser Webseite eingesetzt werden.