web-dev-qa-db-fra.com

Comment puis-je ajouter un filtre à l'instance de classe uniquement?

J'ai une classe personnalisée que j'utilise dans plusieurs cas pour l'étendre, par exemple

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

Maintenant, je crée des instances de classe B et C:

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

Lors de l'affichage des choses de $b, avec

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

Lorsque j'affiche les éléments de l'instance $c pour lesquels je n'ai ajouté aucun filtre, j'obtiens le même résultat, car le filtre ajouté par l'instance $b est 'global':

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

Mais je voudrais obtenir le café et le thé , puisque je n’ai pas ajouté le filtre dans la classe C. Dois-je ajouter l’instance elle-même lors de l’ajout du filtre et de la recherche de $this? Ou existe-t-il une autre (meilleure) approche?

4
uruk

Le problème est que les filtres dans WordPress sont globaux; si vous ajoutez un filtre quelque part, il persiste partout, à moins que vous ne le supprimiez.

Considérez également que vous devriez préférer la composition à l’héritage , et si votre structure d’application actuelle est déjà basée sur l’héritage, et que vous ne pouvez pas ou ne voulez pas la modifier, évitez au moins d’utiliser des filtres pour les éléments qui ne sont pas globaux.

En séparant la logique qui renvoie les données de la logique qui les filtre, tout devient beaucoup plus facile:

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 {

}

Comme vous pouvez le deviner:

$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'  )

Tous les résultats passent par le filtre "yet_another_filter", ce qui permet au code externe d’écraser les résultats dans tous les cas, ce à quoi un filtre est destiné.

5
gmazzap