Använda ett register, prenumeranter och tjänster i WordPress
TL;DR: Jag tycker att användningen av ett register, abonnenter och tjänster är mycket användbart när jag bygger backend-centrerade plugins och verktyg för WordPress. Det här inlägget går igenom hur man gör.
Efter att ha arbetat med designmönster, objektorienterad programmering och WordPress i flera år, kommer vanliga sätt att lösa problem att uppstå.
Så här fick vi objektorienterade designmönster till att börja med, så kanske det här är en WordPress-centrerad variant av det.
Även om jag har skrivit om saker som register i tidigare artiklar (och sådana som inte ens är så gamla ), är det aldrig en dålig idé att återkomma till samma ämne, särskilt när det finns något att fortsätta att lägga till i den tidigare versionen.
Ett register, abonnenter och tjänster
Allt som beskrivs nedan ska förstås inom ramen för WordPress-plugin. Det vill säga, det här är inte tänkt att läsas som ett sätt att arbeta med andra ramverk, språk, applikationer eller när du använder det med andra mönster.
Kom ihåg det när du läser detta.
Hur som helst, den allmänna idén bakom kombinationen av dessa objekttyper om följande:
- Registret hanterar alla abonnenter,
- Prenumeranterna lyssnar efter krokar inom WordPress (de som finns eller till och med anpassade krokar),
- Tjänsterna utför själva arbetet närhelst abonnenten skickar dem.
Syftet är att det finns en enda plats för att registrera de klasser som ansvarar för att skicka arbetet. Det är allt.
Detta gör det också enkelt att hålla saker åtskilda så att om du vill testa dina tjänster isolerat är det mycket enklare eftersom de inte nödvändigtvis är tätt kopplade till WordPress. Och om de är det, då kan du håna de data som måste skickas till en given funktion och sedan utvärdera resultatet.
Det här är dock inte en artikel om testning, så tillbaka till de faktiska klasserna.
Register
Per definition är syftet med ett register att hålla reda på saker och ting. När det gäller att implementera det här mönstret i WordPress är tanken att registret kan hålla reda på prenumeranter (vilket jag kommer att definiera senare i den här artikeln).
Foto av Denny Müller på Unsplash
Vidare är tanken att när tiden kommer, vilket sannolikt kommer att vara annorlunda oavsett hur ditt plugin är strukturerat, kommer alla prenumeranter att vara instanser. Till den punkten kommer du dock troligen att vilja göra det tidigt i WordPress-livscykeln.
Som sagt, här är ett exempel på hur man koder för att registrera prenumeranter:
private $subscribers = [
AssetSubscriber::class,
// ...
DeletedUserSubscriber::class,
];
Nästa, här är en funktion för att instansiera prenumeranterna.
Dessa block kan vara en del av samma funktion eller så kan de vara separata beroende på dina behov.
Prenumeranter
Som nämnts är prenumeranter vägen till:
- Lyssna efter en viss hook i WordPress
- Skicka en tjänst för att utföra det arbete som är avsett för den givna kroken.
Så anta för ett ögonblick att du vill göra något när en användare raderas. Du vill instansiera en tjänst via abonnenten närhelst denna hook inträffar.
Foto av Lee Campbell på Unsplash
Som ett exempel:
Notera att abonnenten är medveten om tjänsten (även om den inte är beroende av den eftersom den helt enkelt är en mellanhand mellan WordPress och tjänsten) och anger vilken krok på tjänsten som den instansierar.
Tjänster
Slutligen, tjänster är de objekt som gör allt det tunga arbetet i ett plugin. Det betyder att om de behöver läsa eller skriva till databasen, filsystemet, nätverket, bearbeta data etc. sker allt inom deras sammanhang.
Foto av Erik Mclean på Unsplash
De kanske är medvetna om andra klasser, kanske inte. De kan implementera ett gränssnitt eller en abstrakt klass eller inte. Det är verkligen utanför ramen för detta inlägg. Men poängen är att, med hjälp av kroken från ovan som exempel, om du vill göra något när en användare raderas så gör du det inom tjänsten.
Till exempel:
class DeletedUserService
{
public function add(string $hook)
{
add_action($hook, [$this, 'deletedUser'], 99, 1);
}
public function deletedUser(int $userId)
{
$user = get_userdata($userId);
if (false === $user) {
return;
}
// Do work with the user that's being deleted.
}
}
Och det är slutet på det. När tjänsten körs kommer kontrollen att returneras till WordPress och applikationen kommer att fortsätta köras som vanligt.
Alla tillsammans nu
Om du antar att du har en bootstrap-fil för din plugin, vilket de flesta gör eftersom det är här det erforderliga pluginet definieras, krävs en autoloader och instansiering av själva pluginet sker.