Nu vă repetați: automatizarea sarcinilor repetitive cu WP-CLI
Publicat: 2022-03-11Te-ai trezit vreodată să intri în zona de administrare WordPress pentru a actualiza teme, pluginuri și nucleul WP? Desigur că ai. Ați fost întrebat: „Puteți crea/actualiza/șterge toți utilizatorii din acest fișier CSV?” Sunt sigur că și tu te-ai lovit de asta. Ați încercat să migrați un site și v-ați dori să existe un plugin sau un instrument terță parte la care să puteți apela pentru a face treaba? Știu că am!
Există un instrument foarte puternic disponibil pentru a vă ajuta cu aceste sarcini și multe altele. Înainte de a vă spune despre asta, aș vrea să pun la punct o anecdotă rapidă.
Problema: Într-un proiect recent, au existat mai multe sarcini programatice pe care trebuia să le repet în mod regulat. O sarcină în special a implicat actualizarea permisiunilor la nivel de utilizator pe baza dovezilor de achiziție sau abonament la nivel de membru. Dacă compania nu a putut găsi o plată de la utilizator pentru un anumit nivel de membru, dorea ca nivelul de membru să fie eliminat de la utilizator. De ce a fost nevoie de asta? Poate că un membru a oprit un abonament, dar un eveniment nu s-a declanșat, așa că membrul are încă acces chiar dacă nu plătește pentru asta (da!). Sau poate cineva a fost la o ofertă de probă, dar acea ofertă a expirat și clientul are încă un abonament (de asemenea, da!).
Soluția: În loc să intru în panoul de administrare și să șterg manual sute (poate mii) de abonamente, am optat să apelez la unul dintre instrumentele mele preferate WordPress, WP-CLI, care a rezolvat problema în câteva apăsări de taste.
În această postare, vreau să vă prezint WP-CLI (presupunând că nu sunteți deja prieteni apropiați), să vă ghidez printr-o comandă personalizată simplă pe care am scris-o pentru această situație particulară și să vă ofer câteva idei și resurse pentru utilizarea WP-CLI în propria ta dezvoltare.
Ce este WP-CLI?
Dacă nu ai auzit niciodată de WP-CLI până acum, nu ești singur. Proiectul, deși vechi de câțiva ani, părea să zboare sub radarul WordPress pentru o vreme. Iată o scurtă descriere a ceea ce este și face WP-CLI de pe site-ul oficial:
WP-CLI este un set de instrumente de linie de comandă pentru gestionarea instalărilor WordPress. Puteți actualiza pluginuri, puteți configura instalări pe mai multe site-uri și multe altele, fără a utiliza un browser web.
Următoarele comenzi vă arată puterea WP-CLI din cutie:
-
wp plugin update --allactualizează toate pluginurile actualizabile. -
wp db exportexportă un dump SQL al bazei de date. -
wp media regenerateregenerează miniaturile pentru atașamente (de exemplu, după ce modificați dimensiunea temei). -
wp checksum coreverifică dacă fișierele de bază WordPress nu au fost modificate. -
wp search-replacecaută și înlocuiește șiruri în baza de date.
Dacă explorați mai multe comenzi aici, veți vedea că există o mulțime de comenzi disponibile pentru sarcini repetitive pe care fiecare dezvoltator WordPress sau întreținător de site le face zilnic sau săptămânal. Aceste comenzi mi-au economisit nenumărate ore de indicare, clic și așteptare pentru reîncărcarea paginilor pe parcursul anului.
esti convins? Ești gata să începi? Grozav!
Va trebui să aveți WP-CLI instalat cu WordPress (sau global pe mașina dvs. locală). Dacă nu ați instalat încă WP-CLI în mediul dvs. de dezvoltare local, instrucțiunile de instalare pot fi găsite pe site-ul web aici. Dacă utilizați Variying Vagrant Vagrants (VVV2), WP-CLI este inclus. Mulți furnizori de găzduire au, de asemenea, WP-CLI inclus pe platforma lor. Voi presupune că ați instalat acest lucru cu succes de acum înainte.
Utilizarea WP-CLI pentru a rezolva problema
Pentru a rezolva problema sarcinilor repetitive, trebuie să punem la dispoziție o comandă WP-CLI personalizată pentru instalarea noastră WordPress. Una dintre cele mai ușoare modalități de a adăuga funcționalitate oricărui site este crearea unui plugin. Vom folosi un plugin în acest caz din trei motive principale:
- Vom putea dezactiva comanda personalizată dacă nu avem nevoie de ea
- Ne putem extinde cu ușurință comenzile și subcomenzile, păstrând lucrurile modulare.
- Putem menține funcționalitatea pe teme și chiar și în alte instalări WordPress.
Crearea pluginului
Pentru a crea un plugin, trebuie să adăugăm un director în directorul nostru /plugins din directorul nostru wp-content . Putem numi acest director toptal-wpcli . Apoi creați două fișiere în acel director:
-
index.php, care ar trebui să aibă o singură linie de cod:<?php // Silence is golden -
plugin.php, care este locul unde va merge codul nostru (Puteți denumi acest fișier cum doriți.)
Deschideți fișierul plugin.php și adăugați următorul cod:
<?php /** * Plugin Name: TOPTAL WP-CLI Commands * Version: 0.1 * Plugin URI: https://n8finch.com/ * Description: Some rando wp-cli commands to make life easier... * Author: Nate Finch * Author URI: https://n8finch.com/ * Text Domain: toptal-wpcli * Domain Path: /languages/ * License: GPL v3 */ /** * NOTE: THIS PLUGIN FILE WILL NOT WORK IN PRODUCTION AS IS AND IS ONLY FOR DEMONSTRATION PURPOSES! * You can of course take the code and repurpose it:-). */ if ( !defined( 'WP_CLI' ) && WP_CLI ) { //Then we don't want to load the plugin return; }Există două părți în aceste prime câteva rânduri.
În primul rând, avem antetul pluginului. Aceste informații sunt introduse în pagina de administrare a pluginurilor WordPress și ne permite să ne înregistrăm pluginul și să-l activăm. Este necesar doar numele pluginului, dar ar trebui să includem restul pentru oricine ar dori să folosească acest cod (precum și viitorul nostru!).
În al doilea rând, vrem să verificăm dacă WP-CLI este definit. Adică, verificăm dacă constanta WP-CLI este prezentă. Dacă nu este, vrem să eliberăm pe cauțiune și să nu rulăm pluginul. Dacă este prezent, este clar să rulăm restul codului nostru.
Între aceste două secțiuni, am adăugat o notă că acest cod nu trebuie folosit „ca atare” în producție, deoarece unele dintre funcții sunt substituenți pentru funcții reale. Dacă schimbați aceste funcții de substituent în funcții reale, active, nu ezitați să ștergeți această notă.
Adăugarea comenzii personalizate
În continuare, dorim să includem următorul cod:
class TOPTAL_WP_CLI_COMMANDS extends WP_CLI_Command { function remove_user() { echo "\n\n hello world \n\n"; } } WP_CLI::add_command( 'toptal', 'TOPTAL_WP_CLI_COMMANDS' );Acest bloc de cod face două lucruri pentru noi:
- Acesta definește clasa
TOPTAL_WP_CLI_COMMANDS, în care putem trece argumente. - Acesta atribuie comanda
toptalclasei, astfel încât să o putem rula din linia de comandă.
Acum, dacă executăm wp toptal remove_user , vedem:
$ wp toptal hello hello world Aceasta înseamnă că comanda noastră toptal este înregistrată și subcomanda remove_user funcționează.
Configurarea variabilelor
Deoarece procesăm în bloc eliminarea utilizatorilor, dorim să setăm următoarele variabile:
// Keep a tally of warnings and loops $total_warnings = 0; $total_users_removed = 0; // If it's a dry run, add this to the end of the success message $dry_suffix = ''; // Keep a list of emails for users we may want to double check $emails_not_existing = array(); $emails_without_level = array(); // Get the args $dry_run = $assoc_args['dry-run']; $level = $assoc_args['level']; $emails = explode( ',', $assoc_args['email'] );Intenția fiecăreia dintre variabile este următoarea:
-
total_warnings: Vom evidenția un avertisment dacă e-mailul nu există sau dacă e-mailul nu este asociat cu nivelul de membru pe care îl eliminăm. -
$total_users_removed: Vrem să numărăm numărul de utilizatori eliminați în acest proces (vezi avertismentul de mai jos). -
$dry_suffix: Dacă aceasta este o operațiune uscată, dorim să adăugăm o formulare la notificarea finală de succes. -
$emails_not_existing: Stochează o listă de e-mailuri care nu există. -
$emails_without_level: Stochează o listă de e-mailuri care nu au nivelul specificat. -
$dry_run: O valoare booleană care stochează dacă scriptul face o rulare uscată (adevărat) sau nu (fals). -
$level: un număr întreg care reprezintă nivelul de verificat și, eventual, de eliminat. -
$email: o serie de e-mailuri de verificat față de nivelul dat. Vom parcurge această matrice
Cu variabilele noastre setate, suntem gata să rulăm efectiv funcția. În mod adevărat WordPress, vom rula o buclă.
Scrierea funcției în sine
Începem prin a crea o buclă foreach pentru a parcurge toate e-mailurile din matricea noastră $emails :
// Loop through emails foreach ( $emails as $email ) { // code coming soon } // end foreachApoi, adăugăm o verificare condiționată:
// Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } } // end foreach Această verificare asigură că avem un utilizator înregistrat cu e-mailul pe care îl verificăm. Utilizează funcția email_exists() pentru a verifica dacă există un utilizator cu acel e-mail. Dacă nu găsește un utilizator cu acel e-mail, lansează un avertisment, astfel încât să știm pe ecranul terminalului nostru că e-mailul nu a fost găsit:
$ wp toptal remove_user [email protected] --dry-run Warning: The user [email protected] does not seem to exist. E-mailul este apoi stocat în $emails_not_existing pentru a fi afișat mai târziu. Apoi creștem avertismentul total cu unul și continuăm prin buclă până la următorul e-mail.
Dacă e-mailul există, vom folosi variabilele $user_id și $level pentru a verifica dacă utilizatorul are acces la nivel. Stocăm valoarea booleană rezultată în variabila $has_level :

// Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); } // end foreach La fel ca majoritatea funcțiilor din acest exemplu, această function_to_check_membership_level() este fabricată, dar majoritatea pluginurilor de membru ar trebui să aibă funcții de ajutor pentru a vă obține aceste informații.
Acum, vom trece la acțiunea principală: eliminarea nivelului de la utilizator. Vom folosi o structură if/else , care arată astfel:
foreach ( $emails as $email ) { // Previous code here... // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); if ( $has_level ) { if ( !$dry_run ) { // Deactivate membership level. This is a made up function, but you could write one or your membership plugin probably has one. function_to_deactivate_membership_level( $level, $user_id, 'inactive' ); } WP_CLI::success( "Membership canceled for {$email}, Level {$level} removed" . PHP_EOL ); $total_users_removed++; } else { WP_CLI::warning( "The user {$email} does not have Level = {$level} membership." ); array_push( $emails_without_level, $email ); $total_warnings++; } // We could echo something here to show that things are processing... } // end foreach Dacă valoarea lui $has_level este „adevărat”, adică utilizatorul are acces la nivelul de membru, dorim să rulăm o funcție pentru a elimina acel nivel. În acest exemplu, vom folosi function_to_deactivate_membership_level() pentru a efectua această acțiune.
Cu toate acestea, înainte de a elimina de fapt nivelul de la utilizator, dorim să includem acea funcție într-o verificare condiționată pentru a vedea dacă aceasta este de fapt o dry-run . Dacă este, nu vrem să eliminăm nimic, doar raportăm că am făcut. Dacă nu este o dry-run , vom continua și vom elimina nivelul de la utilizator, vom înregistra mesajul nostru de succes la terminal și vom continua să trecem prin e-mailuri.
Dacă, pe de altă parte, valoarea lui $has_level este „falsey”, adică utilizatorul nu are acces la nivelul de membru, dorim să înregistrăm un avertisment pe terminal, să trimitem e-mailul în matricea $emails_without_level și să continuăm parcurgând e-mailurile.
Terminare și raportare
Odată ce bucla s-a terminat, dorim să ne logăm rezultatele în consolă. Dacă aceasta a fost o funcționare uscată, vrem să înregistrăm un mesaj suplimentar pe consolă:
if ( $dry_run ) { $dry_suffix = 'BUT, nothing really changed because this was a dry run:-).'; } Acest $dry-suffix va fi adăugat la avertismentele și notificările de succes pe care le vom înregistra în continuare.
La final, vrem să ne înregistrăm rezultatele ca mesaj de succes și avertismentele noastre ca mesaje de avertizare. O vom face astfel:
WP_CLI::success( "{$total_users_removed} User/s been removed, with {$total_warnings} warnings. {$dry_suffix}" ); if ( $total_warnings ) { $emails_not_existing = implode(',', $emails_not_existing); $emails_without_level = implode(',', $emails_without_level); WP_CLI::warning( "These are the emails to double check and make sure things are on the up and up:" . PHP_EOL . "Non-existent emails: " . $emails_not_existing . PHP_EOL . "Emails without the associated level: " . $emails_without_level . PHP_EOL ); } Rețineți că folosim metodele de ajutor WP_CLI::success și WP_CLI::warning . Acestea sunt furnizate de WP-CLI pentru înregistrarea informațiilor în consolă. Puteți înregistra cu ușurință șiruri, ceea ce facem aici, inclusiv variabilele noastre $total_users_removed , $total_warnings și $dry_suffix .
În cele din urmă, dacă am acumulat avertismente pe parcursul rulării scriptului, dorim să tipărim acele informații pe consolă. După ce rulăm o verificare condiționată, convertim variabilele matricei $emails_not_existing și $emails_without_level în variabile șir. Facem acest lucru pentru a le putea tipări pe consolă folosind metoda WP_CLI::warning helper.
Adăugarea unei descriere
Știm cu toții că comentariile sunt utile pentru ceilalți și pentru viitorul nostru, revenind la codul nostru săptămâni, luni sau chiar ani mai târziu. WP-CLI oferă o interfață de descrieri scurte (shortdesc) și descrieri lungi (longdesc) care ne permite să adnotăm comanda noastră. Vom pune în partea de sus a comenzii noastre, după ce clasa TOPTAL_WP_CLI_COMMANDS este definită:
/** * Remove a membership level from a user * * ## OPTIONS * --level=<number> * : Membership level to check for and remove * * --email=<email> * : Email of user to check against * * [--dry-run] * : Run the entire search/replace operation and show report, but don't save changes to the database. * * ## EXAMPLES * * wp toptal remove_user --level=5 [email protected],[email protected], [email protected] --dry-run * * @when after_wp_load */ În longdesc, definim ce ne așteptăm să primească comanda noastră personalizată. Sintaxa pentru shortdesc și longdesc este Markdown Extra. În secțiunea ## OPTIONS , definim argumentele pe care ne așteptăm să le primim. Dacă este necesar un argument, îl încapsulăm în < > , iar dacă este opțional, îl încapsulăm în [ ] .
Aceste opțiuni sunt validate atunci când comanda este executată; de exemplu, dacă omitem parametrul de e-mail necesar, obținem următoarea eroare:
$ wp toptal remove_user --level=5 --dry-run Error: Parameter errors: missing --email parameter (Email of user to check against) Secțiunea ## EXAMPLES include un exemplu despre cum ar putea arăta comanda când este apelată.
Comanda noastră personalizată este acum completă. Puteti vedea esenta finala aici.
O avertizare și loc de îmbunătățire
Este important să revizuim munca pe care am făcut-o aici pentru a vedea cum ar putea fi îmbunătățit, extins și refactorizat codul. Există multe zone de îmbunătățire pentru acest script. Iată câteva observații despre îmbunătățirile care ar putea fi aduse.
Ocazional, am descoperit că acest script nu va elimina toți utilizatorii pe care îi consemnează ca „eliminați”. Acest lucru se datorează cel mai probabil faptului că scriptul rulează mai repede decât se pot executa interogările. Experiența dvs. poate varia, în funcție de mediul și configurația în care este rulat scriptul. Metoda rapidă pentru a evita acest lucru este să rulați în mod repetat cu aceleași intrări; în cele din urmă, va fi zero și va raporta că niciun utilizator nu a fost eliminat.
Scriptul ar putea fi îmbunătățit pentru a aștepta și valida faptul că un utilizator a fost eliminat înainte de a înregistra utilizatorul ca fiind eliminat efectiv. Acest lucru ar încetini execuția scriptului, dar ar fi mai precis și ar trebui să-l rulați o singură dată.
În mod similar, dacă au fost găsite erori de acest fel, scriptul ar putea arunca erori pentru a alerta că un nivel nu a fost eliminat de la un utilizator.
Un alt domeniu de îmbunătățire a scriptului este acela de a permite eliminarea mai multor niveluri simultan dintr-o singură adresă de e-mail. Scriptul ar putea detecta automat dacă există unul sau mai multe niveluri și unul sau mai multe e-mailuri de eliminat. Mi s-au dat fișiere CSV după nivel, așa că trebuia să rulez doar un nivel la un moment dat.
De asemenea, am putea refactoriza o parte din cod pentru a folosi operatori ternari în loc de verificările condiționale mai detaliate pe care le avem în prezent. Am optat pentru a face acest lucru mai ușor de citit de dragul demonstrației, dar nu ezitați să vă alcătuiți codul.
În pasul final, în loc să tipărim e-mailuri pe consolă în pasul final, le-am putea exporta automat într-un fișier CSV sau text simplu.
În cele din urmă, nu există verificări pentru a ne asigura că primim un număr întreg pentru variabila $level sau o listă de e-mailuri separate prin virgulă sau e-mail în variabila $emails . În prezent, dacă cineva ar include șiruri de caractere în loc de numere întregi sau nume de utilizator în loc de e-mailuri, scriptul nu ar funcționa (și nu ar produce erori). Ar putea fi adăugate verificări pentru numere întregi și e-mailuri.
Idei pentru automatizare suplimentară și citire suplimentară
După cum puteți vedea, chiar și în acest caz de utilizare specific, WP-CLI este destul de flexibil și suficient de puternic pentru a vă ajuta să vă desfășurați munca rapid și eficient. S-ar putea să vă întrebați: „Cum pot începe să implementez WP-CLI în fluxul meu de dezvoltare zilnic și săptămânal?”
Există mai multe moduri în care puteți utiliza WP-CLI. Iată câteva dintre preferatele mele:
- Actualizați temele, pluginurile și nucleul WP fără a fi nevoie să accesați panoul de administrare.
- Exportați baze de date pentru backup sau efectuați un dump rapid SQL dacă vreau să testez o interogare SQL.
- Migrați site-urile WordPress.
- Instalați noi site-uri WordPress cu date fictive sau setări personalizate de suite de pluginuri.
- Rulați sume de verificare pe fișierele de bază pentru a vă asigura că nu au fost compromise. (De fapt, există un proiect în curs de extindere la teme și pluginuri în depozitul WP.)
- Scrieți propriul script pentru a verifica, actualiza și întreține gazdele site-ului (despre care am scris aici).
Posibilitățile cu WP-CLI sunt aproape nelimitate. Iată câteva resurse pentru a te ajuta să mergi mai departe:
- Site-ul principal WP-CLI: http://wp-cli.org
- Comenzi WP-CLI: https://developer.wordpress.org/cli/commands/
- Blog oficial WP-CLI: https://make.wordpress.org/cli/
- Manual WP-CLI: https://make.wordpress.org/cli/handbook/
- În WooCommerce? Verificați WC-CLI: https://github.com/woocommerce/woocommerce/wiki/WC-CLI-Overview#woocommerce-commands
- Interviu podcast cu Daniel Bachhuber, menținătorul proiectului: https://howibuilt.it/episode-28-daniel-bachhuber-wp-cli/
