it-swarm.com.de

Wie kann ich einen Filter nur zur Klasseninstanz hinzufügen?

Ich habe eine benutzerdefinierte Klasse, die ich beispielsweise in mehreren Fällen verwende, um sie zu erweitern

class A {
    public function show_things() {
        print_r( apply_filter( 'yet_another_filter', array( 'coffee', 'tea' ) ) );
    }
}

class B extends A {
    public function __construct() {
        parent::__construct();
        add_filter( 'yet_another_filter', array( $this, 'other_things' ) );
    }

    public function other_things( $things ) {
        return array( 'crisps', 'beer' );
    }
}

class C extends A {
    public function __construct() {
        parent::__construct();
        // no filter added here
    }
}

Jetzt erstelle ich Instanzen der Klassen B und C:

$b = new B;
$c = new C;

Bei der Anzeige der Dinge von $b mit

$b->show_things(); // gives crisps, beer

Wenn ich die Dinge der Instanz $c anzeige, bei denen ich keinen Filter hinzugefügt habe, erhalte ich dasselbe, da der von der Instanz $b hinzugefügte Filter 'global' ist:

$c->show_things(); // gives crisps, beer, which is logical

Aber ich möchte Kaffee und Tee bekommen , da ich den Filter nicht in Klasse C hinzugefügt habe. Muss ich die Instanz selbst hinzufügen, wenn ich den Filter hinzufüge und dann nach $this suche? Oder gibt es einen anderen (besseren) Ansatz?

4
uruk

Das Problem ist, dass die Filter in WordPress global sind. Wenn Sie irgendwo einen Filter hinzufügen, bleibt dieser überall bestehen, es sei denn, Sie entfernen ihn.

Denken Sie auch daran, dass Sie Komposition vor Vererbung bevorzugen sollten. Wenn Ihre aktuelle Anwendungsstruktur bereits auf Vererbung basiert und Sie sie nicht ändern können oder möchten, sollten Sie zumindest vermeiden, Filter für Dinge zu verwenden, die sind nicht global.

Durch die Trennung der Logik, die Daten zurückgibt, von der Logik, die sie filtert, wird alles viel einfacher:

class A {

    function get_things() {
        return array( 'coffee', 'tea' );
    }

    function show_things() {
        return apply_filter( 'yet_another_filter', $this->get_things() );
    }

}

class B extends A {

    function get_things() {
        return array( 'crisps', 'beer' );
    }

}

class C extends A {

}

Wie Sie sich vorstellen können:

$a = new A;
$b = new B;
$c = new C;

$a->show_things(); // array( 'coffee', 'tea'  )
$b->show_things(); // array( 'crisps', 'beer'  )
$c->show_things(); // array( 'coffee', 'tea'  )

Alle Ergebnisse durchlaufen den Filter "yet_another_filter", sodass der externe Code in allen Fällen die Ergebnisse überschreibt, wofür ein Filter vorgesehen ist.

5
gmazzap