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

4

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 classes B et C:

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

Lors de l'affichage des éléments de $b , avec

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

Lors de l'affichage des éléments d'instance $c pour lesquels je n'ai pas ajouté de 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é , car 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, puis rechercher $this ? Ou existe-t-il une autre (meilleure) approche?

    
posée uruk 27.10.2014 - 12:25

1 réponse

5

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

Considérez également que vous devriez préférer la composition à l'héritage , et si votre structure d'application actuelle est déjà construite sur l'héritage, vous ne pouvez pas ou ne voulez pas le changer, vous devriez au moins éviter 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 de remplacer les résultats dans tous les cas, ce à quoi un filtre est destiné.

    
réponse donnée gmazzap 27.10.2014 - 14:28

Lire d'autres questions sur les étiquettes