web-dev-qa-db-fra.com

Comment annuler l'action/le filtre de Wordpress lors de l'utilisation OOP avec rappel anonyme

La plupart des plugins wordpress que j'ai trouvés sont functions based, par exemple, le plugin akismet officiel

function akismet_init() {
    global $wpcom_api_key, $akismet_api_Host, $akismet_api_port;


    // ...
}
add_action('init', 'akismet_init');

Cette approche pose quelques problèmes:

  • vous ne pouvez pas partager l'état entre les fonctions, vous devez donc utiliser des variables globales
  • difficile de faire des tests unitaires, c'est-à-dire aucun moyen de se moquer

Ma tentative initiale consiste à envelopper dans un objet, par exemple. dans le akismet.php

class Akismet {

    protected static $akismet_api_Host;
    protected static $akismet_api_port;

    public function __construct()
    {
        add_action('init', array($this, 'init'));
    }

    public function init()
    {
       // Do my init here
    }
}

$GLOBALS['Akismet'] = new Akismet();

Cependant, cette approche pose encore quelques problèmes

  • Je dois mettre la plupart de mes méthodes en public pour être appelable (ce qui est mauvais)
  • Vous ne pouvez pas transmettre de variable à rappel sans utiliser le rappel anonyme (et si vous utilisez le rappel anonyme, vous ne pouvez pas les supprimer à l'aide de remove_action/remove_filter).

par exemple.

public function __construct()
{
    $foo = 'bar';
    add_action('init', function() use ($foo) {
      echo $foo; // You can pass variable by using callback but you cannot this action later!
    });
}

Alors, comment avoir la souplesse nécessaire pour passer variable dans l’action/le filtre de Wordpress et tout en conservant la souplesse nécessaire pour les annuler ultérieurement?

1
Yoga

Une façon pourrait être d'utiliser des classes et des objets. C'est plus efficace compte tenu de la réutilisabilité, du travail collectif et plus encore. Je ne pense pas qu'il soit mauvais d'utiliser des variables globales si vous savez ce que vous faites.

Je vous recommande donc d'utiliser OOP (programmation orientée objet), en particulier avec l'héritage et le polymorphisme.

1
JMau

Alors, comment avoir la souplesse nécessaire pour passer variable dans l’action/le filtre de Wordpress et tout en conservant la souplesse nécessaire pour les annuler ultérieurement?

Vous pourriez affecter la fonction à l'une des propriétés de la classe:

public function __construct()
{
    $foo = 'bar';

    $this->init_func = function() use ( $foo ) {
        echo $foo;
    };

    add_action( 'init', $this->init_func );
}

Ensuite, vous pouvez faire ceci:

remove_action( 'init', $this->init_func );

Mais s'il vous plaît ne faites pas cela.

Je pense que cela ferait des tests un cauchemar. De plus, vous êtes dans une classe, où vous pouvez affecter la valeur que vous souhaitez utiliser dans la fonction à une propriété:

public function __construct()
{
    $this->foo = 'bar';

    add_action( 'init', array( $this, 'init' ) );
}

public function init()
{
    echo $this->foo;
}

C'est un peu ce que les classes sont pour. :-)


Vous semblez avoir peur d'avoir des méthodes de classe publiques. Pourquoi? Vous voulez que WordPress puisse invoquer le code de votre classe, il doit donc avoir une API publique qui le permettra. Les classes PHP fournissent des méthodes public, vous pouvez donc aussi bien les utiliser que d'essayer de réinventer la roue. :-)

1
J.D.