✅ WEB- och WordPress -nyheter, teman, plugins. Här delar vi tips och bästa webbplatslösningar.

Registrera WordPress Hooks med en annan klass

20

I gårdagens inlägg pratade jag om ett WordPress-plugin-konstruktörer och skälen till varför krokar inte borde finnas i konstruktören.

Även om jag nämnde ett antal sätt att hantera krokregistrering, brydde jag mig inte om att gå in på detaljer för var och en av dessa strategier. För mig är de värda en egen artikel för att ge så mycket detaljer som möjligt för hur man ställer upp något.

Till exempel, en av metoderna jag delade sa:

  • Det är möjligt att skapa en klass som upprätthåller ett register över objekt och krokar med WordPress.

Det handlar med andra ord om att registrera WordPress-hooks med hjälp av ett objektorienterat tillvägagångssätt för att minska kopplingen och öka sammanhållningen mellan komponenterna i plugin.

Men vad betyder det ens? Vilka är fördelarna med det, hur är det konfigurerat och hur används det?

Registrera WordPress Hooks

Om du läser det här är du förmodligen bekant med WordPress hook-systemet, ordningen på hur de aktiveras och hur en funktion eller klass kan registrera sina funktioner med WordPress så att de kan utföra det arbete de behöver hantera.

Och vi ser ofta klasser som gör detta på egen hand. Beroende på projekt gör jag det själv. För de som inte är bekanta ser det vanligtvis ut ungefär så här :

<?php

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

Men allt detta kan delas upp i mer sammanhållna klasser för att i slutändan ge dem klasser ännu mindre ansvar (en bra sak) och för att minska kopplingen mellan en klass eller uppsättning klasser med WordPress.

Ett exempel på en design som jag ska bryta ner i det här inlägget.

Den kontraintuitiva karaktären av detta är dock att det kommer att kräva åtminstone en annan klass. Men så här fungerar det.

Konfigurera det

För detta exempel kommer vi bara att använda en enkel klass som kommer att registrera någon typ av åtgärd med WordPress. Idén till arkitekturen fungerar ungefär så här:

  1. Det finns huvudklassen som har funktionen vi vill koppla till WordPress.
  2. Det finns en klass som ansvarar för att orkestrera kopplingen av klassens funktion till WordPress.

Lätt nog, eller hur? Men här är haken: Klassen som ansvarar för att registrera en given klass funktioner med WordPress är punkten som kräver ett designbeslut.

Låt oss först kalla klassen HookRegistry så att vi kan referera till den ordentligt. Låt oss sedan kalla klassen med funktionerna som vi vill koppla AcmeColumn helt enkelt för att representera en klass som lägger till en ny kolumn på sidans instrumentpanel i adminområdet i WordPress.

Med det på plats kommer designbeslutet ner på detta:

  1. Bör HookRegistery veta om AcmeColumn?
  2. Bör AcmeColumn känna till HookRegistry?

Jag vet att det finns andra sätt att organisera detta och det finns också strategier för hur man hanterar detta (som inversion av kontroll) och det här är ämnen som är värda att utforska, men för att hålla den här första idén så enkel som möjligt, ska jag lägga upp det för ett framtida inlägg.

Använder klassen

Med tanke på alternativen ovan kommer vi att skicka en instans av AcmeColumn till HookRegistry när klasserna instansieras under den första WordPress-pluginstartprocessen. Det här kan se ut ungefär så här :

<?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();
}

Därefter, när det är dags att låta AcmeColumn  registrera sin funktion med WordPress, ringer vi HookRegistry och instruerar det att göra det.

Först, 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;
    } 
}

Sedan 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) );
  }
}

Valfritt kan vi även föra en lista över de olika klasser och krokar som har registrerats. Detta kan eller kanske inte är användbart beroende på din implementering så jag delar bara som ett "här är något som du kanske vill göra."

Och det kan se ut så här (med en enkel associativ 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) );
  }
}

Lägg märke till att i klassen ovan accepterar den nu ett $id som en parameter. Det finns flera sätt att identifiera informationen som kommer in i ett register, det enklaste är att skapa ID själv.

Men om du vill använda något som namnet på kroken eller namnet på klassen, skulle det också fungera. Observera bara att eftersom det är en associativ array, kan den bara behålla ett enda värde per nyckel, så du kan hamna i att kasta tidigare data om du inte är försiktig.

Oavsett vilket är detta något som jag anser vara valfritt, men om det är implementerat är det viktigt att se till att du har rätt funktioner för att hämta en instans av objektet med en nyckel.

En av många

Som med allt som har med den här typen av arbete att göra, är det möjligt att omarbeta eller omorientera detta på ett sätt som fungerar annorlunda eller som passar dina behov. Syftet är inte att visa det definitiva mönstret för hur man gör något, utan ett sätt att närma sig och anpassa det (ungefär som vilket designmönster som helst).

Vidare är det menat att se till att våra klasser upprätthåller det ansvar som de skapas för samtidigt som de låter dem registrera sig själva med WordPress efter behov. Den här gången behöver klassen dock inte göra det själv.

Istället överlämnar den ansvaret till en klass som har det ensamma ansvaret för att registrera nämnda krokar. Så även om det introducerar fler klasser, ökar det sammanhållningen och minskar kopplingen.

Detta ger fördelar i underhåll, testning och övergripande design.

Inspelningskälla: tommcfarlin.com

Denna webbplats använder cookies för att förbättra din upplevelse. Vi antar att du är ok med detta, men du kan välja bort det om du vill. Jag accepterar Fler detaljer