✅ WEB- und WordPress-Nachrichten, Themen, Plugins. Hier teilen wir Tipps und beste Website-Lösungen.

Registrieren von WordPress-Hooks mit einer anderen Klasse

12

Im gestrigen Beitrag habe ich über einen WordPress-Plugin-Konstruktor und die Begründung gesprochen, warum Hooks nicht im Konstruktor enthalten sein sollten.

Obwohl ich eine Reihe von Möglichkeiten erwähnt habe, mit der Hakenregistrierung umzugehen, habe ich nicht die Mühe gemacht, auf jede dieser Strategien im Detail einzugehen. Soweit es mich betrifft, verdienen sie einen eigenen Artikel, um so detailliert wie möglich zu beschreiben, wie man etwas einrichtet.

Eine der von mir geteilten Methoden lautete beispielsweise:

  • Es ist möglich, eine Klasse zu erstellen, die eine Registrierung von Objekten und den Hooks mit WordPress verwaltet.

Mit anderen Worten, es geht darum, WordPress-Hooks mit einem objektorientierten Ansatz zu registrieren, um die Kopplung zu verringern und die Kohäsion zwischen den Komponenten im Plugin zu erhöhen.

Aber was bedeutet das überhaupt? Welche Vorteile bringt es, wie ist es eingerichtet und wie wird es verwendet?

Registrierung von WordPress-Hooks

Wenn Sie dies lesen, sind Sie wahrscheinlich mit dem WordPress -Hook-System vertraut, der Reihenfolge, in der sie ausgelöst werden, und wie eine Funktion oder Klasse ihre Funktionen bei WordPress registrieren kann, damit sie alle erforderlichen Aufgaben ausführen können.

Und wir sehen oft, dass Klassen dies alleine tun. Je nach Projekt mache ich das selbst. Für diejenigen, die es nicht kennen, sieht es im Allgemeinen so aus :

<?php

add_action( 'plugins_loaded', 'acme_start' );
/**
 * Start the machine.
 * https://www.youtube.com/watch?v=ysoMOefPyRs
 */
function acme_start() {
    $plugin = new AcmeColumn();
}

Aber all dies kann in zusammenhängendere Klassen aufgeteilt werden, um ihnen letztendlich noch weniger Verantwortung zu geben (eine gute Sache) und die Kopplung zwischen einer Klasse oder einer Reihe von Klassen mit WordPress zu verringern.

Ein Beispiel für ein Design, das ich in diesem Beitrag aufschlüsseln werde.

Die widersprüchliche Natur davon ist jedoch, dass mindestens eine weitere Klasse erforderlich ist. Aber so funktioniert es.

Einrichten

Für die Zwecke dieses Beispiels verwenden wir nur eine einfache Klasse, die irgendeine Art von Aktion bei WordPress registriert. Die Idee für die Architektur funktioniert ungefähr so:

  1. Es gibt die Hauptklasse, die die Funktion hat, die wir mit WordPress verknüpfen möchten.
  2. Es gibt eine Klasse, die dafür verantwortlich ist, die Funktion der Klasse mit WordPress zu verknüpfen.

Einfach genug, oder? Aber hier ist der Haken: Die Klasse, die für die Registrierung der Funktionen einer bestimmten Klasse bei WordPress verantwortlich ist, ist der Punkt, der eine Designentscheidung erfordert.

Rufen wir zunächst die Klasse HookRegistry auf, damit wir richtig darauf verweisen können. Rufen wir als Nächstes die Klasse mit den Funktionen auf, die wir AcmeColumn haken möchten, einfach um eine Klasse darzustellen, die dem Page-Dashboard im Admin-Bereich von WordPress eine neue Spalte hinzufügt.

Damit läuft die Designentscheidung auf Folgendes hinaus:

  1. Sollte HookRegistery etwas über AcmeColumn wissen?
  2. Sollte AcmeColumn über die HookRegistry Bescheid wissen ?

Ich weiß, dass es andere Möglichkeiten gibt, dies zu organisieren, und es gibt auch Strategien, wie man damit umgeht (wie Inversion of Control) und dies sind Themen, die es wert sind, untersucht zu werden, aber um diese anfängliche Idee so einfach wie möglich zu halten, werde ich das aufstellen ein zukünftiger Beitrag.

Verwendung der Klasse

Angesichts der oben genannten Optionen übergeben wir eine Instanz von AcmeColumn an ​​die HookRegistry, wenn die Klassen während des anfänglichen Startvorgangs des WordPress-Plugins instanziiert werden. Das kann etwa so aussehen :

<?php

add_action( 'plugins_loaded', 'acme_start' );
/**
 * Start the machine.
 * https://www.youtube.com/watch?v=ysoMOefPyRs
 */
function acme_start() {

  $registry    = new HookRegistry();

  $acme_column = new AcmeColumn( $registry );
  $acme_column->start();
}

Als Nächstes rufen wir, wann immer AcmeColumn  seine Funktion bei WordPress registrieren soll, HookRegistry auf und weisen es an, dies zu tun.

Zuerst AcmeColumn :

<?php

class AcmeColumn {

    private $registry;

    public function __construct( $registry) {
        $this->registry = $registry;
    }

    public function start() {
        $registry->add_hook( 'filter', 'manage_edit-page_columns', $this, 'add_page_column' );
    }

    public function add_page_column( $page_columns) {

        $page_columns['template'] = 'Acme Column';
        return $page_columns;
    } 
}

Dann die HookRegistry :

<?php

class HookRegistry {

  public add_hook( $type, $name, $object, $method) {

    $type = strtolower( $type );
    if ('filter' !== $type || 'action' !== $type) {
      return new WP_Error( '1', 'No proper hook type defined.' );
    }
  }

  private function add_filter( $name, $object, $method) {
    add_filter( $name, array( $object, $method) );
  }

  private function add_action( $name, $object, $method) {
    add_action( $name, array( $object, $method) );
  }
}

Optional können wir auch eine Liste der verschiedenen registrierten Klassen und Hooks führen. Dies kann je nach Ihrer Implementierung nützlich sein oder auch nicht, daher teile ich es nur als „Hier ist etwas, das Sie vielleicht tun möchten“.

Und das könnte so aussehen (mit einem einfachen assoziativen Array):

<?php

class HookRegistry {

  private $registry;

  public function __construct() {
    $this->registery = array(); 
  }

  public add_hook( $id, $type, $name, $object, $method) {

    $type = strtolower( $type );
    if ('filter' !== $type || 'action' !== $type) {
      return new WP_Error( '1', 'No proper hook type defined.' );
    }

    if ('filter' === $type) {
      $this->add_filter( $name, $object, $method );
    } else {
      $this->add_action( $name, $object, $method );
    }

    $hook_info = array(
      $type,
      $name,
      $object,
      $method,
    );
    $this->registry[ $id ] = $hook_info;
  }

  private function add_filter( $name, $object, $method) {
    add_filter( $name, array( $object, $method) );
  }

  private function add_action( $name, $object, $method) {
    add_action( $name, array( $object, $method) );
  }
}

Beachten Sie, dass in der obigen Klasse jetzt eine $id als Parameter akzeptiert wird. Es gibt mehrere Möglichkeiten, wie Sie die Informationen identifizieren können, die in eine Registrierung eingehen. Am einfachsten ist es, die ID selbst zu erstellen.

Wenn Sie jedoch so etwas wie den Namen des Hooks oder den Namen der Klasse verwenden möchten, würde das auch funktionieren. Beachten Sie nur, dass es, da es sich um ein assoziatives Array handelt, nur einen einzigen Wert pro Schlüssel beibehalten kann, sodass Sie am Ende frühere Daten löschen können, wenn Sie nicht aufpassen.

Unabhängig davon betrachte ich dies als optional, aber wenn es implementiert ist, ist es wichtig sicherzustellen, dass Sie über die richtigen Funktionen verfügen, um eine Instanz des Objekts mit einem Schlüssel abzurufen.

Einer von vielen

Wie bei allem, was mit dieser Art von Arbeit zu tun hat, ist es möglich, dies so zu gestalten oder neu auszurichten, dass es anders funktioniert oder Ihren Anforderungen entspricht. Der Zweck besteht nicht darin, das endgültige Muster zu zeigen, wie etwas zu tun ist, sondern eine Möglichkeit, sich ihm zu nähern und es anzupassen (ähnlich wie bei jedem Entwurfsmuster).

Darüber hinaus soll es sicherstellen, dass unsere Klassen die Verantwortlichkeiten behalten, für die sie erstellt wurden, während sie sich bei Bedarf bei WordPress registrieren können. Diesmal muss die Klasse das aber nicht selbst machen.

Stattdessen übergibt sie die Verantwortung an eine Klasse, die die alleinige Verantwortung für die Registrierung dieser Hooks hat. Obwohl es also mehr Klassen einführt, erhöht es die Kohäsion und verringert die Kopplung.

Dies bietet Vorteile bei Wartung, Prüfung und Gesamtdesign.

Aufnahmequelle: tommcfarlin.com

Diese Website verwendet Cookies, um Ihre Erfahrung zu verbessern. Wir gehen davon aus, dass Sie damit einverstanden sind, Sie können sich jedoch abmelden, wenn Sie möchten. Annehmen Weiterlesen