it-swarm.com.de

Implementieren erweiterter add_ * -Funktionswrapper

add_action() und add_filter() sind Hauptfunktionen. In einigen Szenarien fügen Sie jedoch eine weitere Funktion hinzu und haken Sie sie irgendwo ein . Die Vorgehensweise wird sperrig und unpraktisch.

Ich hatte für mich mehrere Anwendungsfälle festgelegt, die Code mit Wrappern zusätzlich zu add_*-Funktionen optimieren können. Dinge, die mit Single-Liner besser erledigt werden als jedes Mal zusätzliche Funktionen.

  1. Beliebige Filterrückgabe hinzufügen . Es gibt bereits __return_* Funktionen, aber sie sind per Definition sehr begrenzt. Warum übergeben Sie nicht einfach das, was Sie im Filter zurückgeben möchten? Speichert von unzähligen function return_stuff(){return 'stuff';}

  2. Ersetzen Sie X durch Y im Filter . Speichert von unzähligen function replace_stuff(){return str_replace();}

  3. Fügen Sie eine Aktion mit beliebigen Argumenten hinzu . Aktionen werden mit Argumenten ausgelöst, die im Hook übergeben wurden. Aber manchmal interessiert Sie das nicht und Sie möchten Ihre Funktion nur mit Ihren eigenen Argumenten an einem bestimmten Hook ausführen. Speichert von unzähligen function echo_stuff(){echo 'stuff'}; und mehr.

So...

  • Gibt es andere Anwendungsfälle, die Sie möchten und/oder in der Praxis verwenden?

  • Wie würden Sie solche Wrapper implementieren? Es gibt viele mögliche Ansätze (Abschlüsse, globale Variablen zum Speichern zusätzlicher Argumente, Übergeben von Objekten im Rückruf usw.).

PS Ich habe verschiedene Implementierungen für (1) und (3) und (wie vorgeschlagen) werden einige Zeit später Teile meines Codes veröffentlichen, damit ich den Spaß nicht verderbe. :)

Beispiel

Aktueller Weg:

add_filter('wp_feed_cache_transient_lifetime', 'change_transient_lifetime', 10);

function change_transient_lifetime($lifetime) {

    return 3600;
}

Verpackung:

add_filter_return('wp_feed_cache_transient_lifetime', 10, 3600);
5
Rarst

Ich hatte meinen Code als Advanced Hooks API Bibliothek veröffentlicht.

Einige Beispiele:

add_action_with_arguments('test', 'printf', 10, 'boo%s', '<br />');
do_action('test');
// boo

add_filter_return('test2',10,'boo');
echo apply_filters('test2','not boo') . '<br />';
// boo

add_filter_append('test3',10,' and boo');
echo apply_filters('test3','boo') . '<br />';
// boo and boo

add_filter_prepend('test4',10,'boo and ');
echo apply_filters('test4','boo') . '<br />';
// boo and boo

add_filter_replace('test5','boo','you thought...');
echo apply_filters('test5','boo');
// you thought...
5
Rarst

Für einfache Fälle wie schnelle einzeilige Rückgaben sollte man bedenken, dass es möglich ist, eine anonyme Funktion direkt in den Aufruf zum Hinzufügen eines Filters einzubinden, z.

add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);});

add_action('some_action_hook', function(){echo '....';});
6
wyrfel

Vielleicht möchten Sie sich mit Magic Class-Methoden und Überladungen in PHP befassen, bei denen der Funktionsname als Parameter übergeben wird. Dann können Sie Entscheidungen auf der Grundlage des Funktionsnamens wie return__some_string treffen. Ich bringe einen beispielhaften und nicht getesteten Code an:

class magiCall {
    public static function __callStatic ( string $name , array $arguments ) {
        // your code here, $name is the function name called.
    }
}

add_filter('hookname', 'magiCall::return__the_string');

Ich denke, dieses Beispiel zeigt ziemlich genau die Idee.

Dies ist PHP 5.3.x. Sie können dieses PHP 5.2 mithilfe der __call magic-Methode kompatibel machen. Wenn Sie eine statische öffentliche Funktion haben, um den Rückruf zurückzugeben, können Sie dies möglicherweise vergleichbar vereinfacht zu schreiben. Siehe den Link zum PHP-Handbuch oben.

5
hakre

Ad anonyme oder Lambda-Funktionen) In jedem Fall würde ich diese vermeiden, da Sie den Namen nicht kennen oder eine ziemlich kryptische Ausgabe erhalten, wenn Sie eine überprüfen später einhängen. Debuggen wäre ein Schmerz.

Ad your A) Der Ansatz sieht gut aus und bietet eine ziemlich einfache API (+1).

Ad @hakre A) Ich verwende im Kern meines Frameworks fast dieselbe Funktion [1] - erweitert um "set_" & eine Ausnahme - zum Setzen und Holen Sie sich Variablen on the fly. Auf diese Weise muss ich diese Klasse nur um eine untergeordnete Klasse erweitern, die wie eine "Nur Variablen" -Schnittstelle aussieht (die, die verfügbar sein sollen). Es ist ein netter und organisierter Ansatz, bei dem nur Dinge in den Dateien aufbewahrt werden, die einer einzelnen Aufgabe dienen. Mit so etwas können Sie vielleicht vermeiden, bestimmte Funktionen für jeden einzelnen Takes wie "_replace" usw. zu schreiben.

[1] Code - Ich führe ihn die ganze Zeit aus, damit du ihn "getestet - und funktioniert" nennen kannst

/**
 * Magic getter/setter method
 * Guesses for a class variable & calls/fills it or throws an exception.
 * Note: Already defined methods override this method.
 * 
 * Original @author Miles Keaton <[email protected]> 
 * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440}
 * The function was extended to also allow 'set' tasks/calls and throws an exception.
 * 
 * @param (string) $name | Name of the property
 * @param unknown_type $args | arguments the function can take
 */
function __call( $name, $args )
{
    $_get = false;

    // See if we're calling a getter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'get_' )
    {
        $_get = true;
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'get' )
    {
        $_get = true;
        $varname = substr( $val, 3 );
    }

    // See if we're calling a setter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'set_' )
    {
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'set' )
    {
        $varname = substr( $val, 3 );
    }

    if ( ! isset( $varname ) )
        return new Exception( sprintf( __( "The method %1$s doesn't exist" ), "<em>{$val}</em>" ) );

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
        if ( strtolower( $class_var ) == strtolower( $varname ) )
        {
            // GET
            if ( $_get )
            {
                return $this->{$class_var};
            }
            // SET
            else 
            {
                return $this->{$class_var} = $x[0];
            }
        }
    }

    return false;
}
0
kaiser

Für einfache Rückgabewerte benötigen Sie nicht viele zusätzliche Funktionen. Da ist die handliche current_filter() . Sie können das innerhalb Ihrer eigenen Funktionen verwenden.

Beispiel

<?php # -*- coding: utf-8 -*-
/*
Plugin Name: Filter System From Mail
Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name.
Version:     1.1
Author:      Thomas Scholz
Author URI:  http://toscho.de
License:     GPL
*/

if ( ! function_exists( 'filter_system_from_mail' ) )
{
    /**
     * First admin's e-mail address or blog name depending on current filter.
     *
     * @return string
     */
    function filter_system_from_mail()
    {
        return get_option( 'wp_mail_from' == current_filter()
            ? 'admin_email' : 'blogname' );
    }

    add_filter( 'wp_mail_from',      'filter_system_from_mail' );
    add_filter( 'wp_mail_from_name', 'filter_system_from_mail' );
}

Oder ... habe ich deine Frage falsch verstanden?

0
fuxia