Cea mai mare parte a dezvoltării de pluginuri WordPress urmează același traseu. Cineva are nevoie de un formular de rezervare, de un importator de flux sau de un câmp în plus la finalizarea comenzii, un dezvoltator îl scrie, funcționează, toată lumea merge mai departe. Doi ani mai târziu, site-ul este blocat pe o versiune veche de WordPress, pentru că nimeni nu are încredere că pluginul acela va supraviețui unei actualizări, iar cel care l-a scris a plecat demult.
Cauza este rareori faptul că nucleul s-ar mișca prea repede. WordPress este prudent când vine vorba să strice lucruri, iar destule pluginuri bine scrise acum cinci ani rulează nemodificate pe WordPress 7.1. Pluginurile se strică din cauza deciziilor luate în prima săptămână: funcționalitate pusă în temă, fișiere din nucleu modificate în loc să fie folosite hook-uri, date salvate în orice structură era mai la îndemână și nimeni care să testeze vreodată pe o versiune candidat.
Ce face ca un plugin WordPress personalizat să supraviețuiască actualizărilor de nucleu? Patru lucruri. Codul stă într-un plugin, nu în temă. Extinde WordPress prin acțiuni și filtre, în loc să modifice fișierele nucleului. Păstrează fiecare set de date în structura care se potrivește formei acelor date. Și cineva îl testează pe fiecare versiune candidat înainte ca acea versiune să fie lansată.
De ce dezvoltarea de pluginuri WordPress aparține unui plugin, nu temei
Casa implicită a codului personalizat este fișierul functions.php al temei, pentru că este deja acolo și deja rulează. Este și fișierul care dispare la următoarea reproiectare.
O temă înseamnă prezentare. Schimbați tema și tot ce făcea tema veche se oprește. Tipurile de conținut personalizate nu mai sunt înregistrate, așa că materialul rămâne în baza de date fără ecran de administrare și fără permalink. Codurile scurte apar ca text brut în mijlocul paginii. Fragmentul de analiză, marcajul schema și apelul nocturn către CRM dispar, iar nimic nu semnalează vreo eroare.
Regula este suficient de simplă încât să încapă într-un caiet de sarcini. Tot ce trebuie să rămână valabil după o reproiectare aparține unui plugin: tipuri de conținut și taxonomii personalizate, integrări cu orice element extern, coduri scurte și blocuri, reguli de business, sarcini programate și orice scrie în baza de date. Temei îi rămân șabloanele, stilurile și părțile de șablon.
Nota de plată vine târziu. La următoarea reproiectare fie plătiți din nou ca să reconstruiți ce exista deja, fie copiați mai departe vechiul functions.php. Pe un site cu ani de fragmente adunate, asta înseamnă câteva mii de lire de muncă evitabilă și este motivul pentru care o ofertă de reproiectare se întoarce la dublul a ceea ce se aștepta clientul. O temă copil este tot o temă.
Modelul de extindere și singura regulă care contează
WordPress este construit ca să fie schimbat din exterior. Mecanismul îl reprezintă hook-urile, iar documentația hook-urilor le descrie ca punctele predefinite în care o bucată de cod poate interacționa cu alta sau o poate modifica. O acțiune se declanșează într-un moment definit și vă lasă să faceți ceva: să trimiteți o notificare după publicarea unui articol sau să înregistrați un tip de conținut. Un filtru vă predă o valoare, se așteaptă să o schimbați sau să o lăsați în pace și se așteaptă să i-o dați înapoi.
Regula care decurge de aici este absolută. Dacă modificați un fișier din wp-admin, din wp-includes sau din directorul altui plugin, ați pierdut deja. Acele modificări sunt șterse de următoarea actualizare, fără avertisment, fără eroare și de regulă fără să fie descoperite până când un client raportează că ceva a încetat să funcționeze. Întrebați direct un dezvoltator acest lucru înainte să îl angajați.
Când hook-ul de care aveți nevoie nu există, împachetați comportamentul în loc să îl înlocuiți, urcați la un hook mai larg, faceți un fork al pluginului terț sub control de versiune, cu divergența documentată, sau cereți hook-ul în amonte, așa cum au apărut cele mai multe dintre ele.
Denumiri, prefixe și un spațiu de nume foarte aglomerat
În WordPress, PHP rulează într-un singur spațiu de nume global, împărțit cu nucleul, cu tema activă și cu orice alt plugin activ. Două pluginuri care declară amândouă o funcție get_settings() nu se înțeleg politicos: al doilea este o eroare fatală, iar site-ul rămâne alb.
Prefixele sunt mai lungi decât credeți
Pagina cu bune practici pentru pluginuri din manual cere un prefix unic pentru tot ce este accesibil global, cel puțin patru caractere și de preferat cinci, evitând cuvintele englezești obișnuite și fără să folosească vreodată wp_, _ sau WordPress însuși. Cu zeci de mii de pluginuri în circulație, trei litere luate din inițialele clientului sunt o aruncare de monedă.
Spații de nume și încărcare automată
Practica modernă rezolvă jumătate din problemă. Declarați un spațiu de nume PHP, puneți o clasă într-un fișier și lăsați un autoloader PSR-4 să le găsească, astfel încât să nu existe instrucțiuni require scrise de mână și nicio șansă ca numele unei clase să intre în coliziune cu al altui plugin. În plus, face codul testabil, pentru că acele clase cu dependențe în constructor pot fi instanțiate fără ca WordPress să fie încărcat.
Încărcarea automată nu rezolvă situația în care două pluginuri livrează versiuni diferite ale aceleiași biblioteci. Câștigă cel care se încarcă primul. Prefixați spațiile de nume ale dependențelor la momentul construirii, pentru orice se distribuie.
Șirurile pe care spațiile de nume nu le pot ajuta
Un spațiu de nume acoperă simbolurile PHP. Multe dintre lucrurile pe care le înregistrează un plugin nu sunt însă simboluri PHP, ci șiruri într-un registru comun, iar acelea au nevoie în continuare de vechea convenție a prefixului: nume de hook-uri, chei de opțiuni și de tranzienți, chei de metadate ale articolelor, nume de tipuri de conținut și de taxonomii, etichete de coduri scurte, nume de evenimente cron, spații de nume REST și nume de tabele proprii. Ele trăiesc într-un spațiu plat în care ultima înregistrare câștigă sau în care două pluginuri împart în tăcere aceeași stare.
Două limite merită știute înainte să dați vreun nume. Cheia unui tip de conținut nu poate depăși 20 de caractere, iar cheia unei taxonomii 32, ambele cu litere mici alfanumerice, cu cratime și liniuțe de subliniere. Un prefix de cinci caractere lasă 15 caractere pentru numele unui tip de conținut, adică mai puțin spațiu decât pare.
Alegerea locului în care stau datele
Aceasta este decizia cu cea mai lungă coadă. Dacă o greșiți, pluginul merge foarte bine la lansare, devine mai lent lună de lună pe măsură ce datele cresc, iar până când observă cineva, remedierea este o migrare, nu o modificare.
Opțiuni și tranzienți
Opțiunile sunt pentru setări valabile pe tot site-ul: o mână de chei, valori mici, citite la majoritatea cererilor. Capcana este încărcarea automată, pentru că fiecare opțiune încărcată automat este adusă la fiecare cerere în parte, inclusiv la apelurile admin-ajax și REST, indiferent dacă o folosește cineva sau nu.
WordPress 6.6 a schimbat mecanica, așa cum arată articolul de pe blogul Make WordPress Core despre dezactivarea încărcării automate pentru opțiunile mari. Valoarea stocată este acum on, off sau auto, iar o opțiune mai mare de 150.000 de octeți nu mai este încărcată automat în mod implicit, pragul fiind ajustabil prin filtrul wp_max_autoloaded_option_size. Tratați asta ca pe un plafon, nu ca pe o țintă. Tranzienții sunt opțiuni cu termen de expirare și sunt casa potrivită pentru orice este adus din altă parte.
Metadatele articolelor nu sunt un depozit cheie-valoare
Metadatele articolelor sunt pentru atributele unui singur articol: un subtitlu, un preț, o referință de furnizor. Nu sunt un depozit cheie-valoare de uz general, iar motivul se vede în definiția tabelei. Tabela wp_postmeta are patru coloane și trei chei. Sunt indexate doar post_id și primele 191 de caractere din meta_key. Coloana meta_value este un longtext fără niciun index pe ea.
O interogare care filtrează după o valoare de metadate nu poate deci folosi un index. Fiecare clauză dintr-o interogare de metadate adaugă încă o îmbinare, iar pe un site cu 50.000 de articole care poartă câte 20 de rânduri de metadate fiecare, tabela ajunge la un milion de rânduri. Trei clauze înseamnă trei îmbinări pe un milion de rânduri la fiecare încărcare de pagină. Este unul dintre cele mai frecvente motive pentru care un site rapid în primul an devine inutilizabil în al treilea și apare tot timpul în lucrul pe performanța WooCommerce.
Tipuri de conținut și taxonomii personalizate
Un tip de conținut personalizat este potrivit atunci când lucrul respectiv este conținut. Are nevoie de ecranul lui de listare, de permalinkuri, de revizii și de un flux editorial și are sens ca pagină pe care cineva ar putea să o viziteze. O taxonomie personalizată este potrivită atunci când aveți nevoie de un vocabular comun care grupează acele lucruri și merită pagini de arhivă proprii.
Amândouă vin cu mecanică gratuită: ecrane de administrare, capabilități, căutare, editorul de blocuri și API-ul REST. Setați show_in_rest pe true, altfel editorul de blocuri nu va ști să lucreze cu tipul respectiv, și înregistrați-le pe amândouă pe hook-ul init, niciodată înainte de el.
Când chiar aveți nevoie de o tabelă proprie
O tabelă proprie este potrivită atunci când datele nu sunt conținut: înregistrări de volum mare, doar adăugate, cum ar fi jurnale de evenimente, cozi de import, istoric de prețuri sau piste de audit, ori orice veți filtra și sorta după un câmp care nu este o coloană a articolului. Peste câteva sute de mii de rânduri interogate după propriile câmpuri, o tabelă cu indexurile potrivite bate metadatele articolelor cu ordine de mărime și rămâne previzibilă pe măsură ce crește.
Prețul este că tot ce ține de ea vă aparține: crearea tabelei și migrările versionate, curățenia din uninstall.php, propriile ecrane de administrare, endpointuri REST și memorare în cache. De aceea răspunsul onest pentru majoritatea pluginurilor rămâne un tip de conținut personalizat.
Securitatea înseamnă patru obiceiuri, iar trei dintre ele sunt sărite
Manualul de securitate WordPress enunță principiul fără ocolișuri: nu aveți încredere în datele introduse de utilizatori, în API-urile terțe și nici în datele care stau deja în baza voastră de date. Patru obiceiuri duc aproape tot riscul, iar în pluginurile pe care le audităm sunt sărite într-o ordine constantă. Întâi verificările de capabilități, apoi nonce-urile, al treilea escaparea la ieșire. Interogările pregătite vin la urmă, pentru că una lipsă se prinde la revizuire.
Verificările de capabilități
Orice handler care schimbă ceva trebuie să întrebe dacă acest utilizator are voie, adică current_user_can() cu capabilitatea exactă, verificată în interiorul handlerului, nu doar în jurul butonului care îl apelează.
is_admin() nu este o verificare de permisiuni. Ea raportează pe ce parte a site-ului se află cererea și întoarce true pentru orice abonat autentificat care atinge un endpoint admin-ajax. O acțiune admin_post_ sau wp_ajax_ fără verificare de capabilități este accesibilă oricărui utilizator înregistrat, ceea ce într-un magazin înseamnă orice client care a comandat vreodată. Lista noastră de securizare a WordPress acoperă controalele la nivel de site din jurul acestui subiect.
Nonce-urile
Un nonce protejează un formular sau un URL împotriva unei cereri pe care utilizatorul nu a intenționat să o facă. Folosiți wp_nonce_field() în formular și check_admin_referer() în handler, sau check_ajax_referer() pentru AJAX. În ciuda numelui, nu sunt de unică folosință: sunt sume de control valabile pentru o fereastră de timp, o zi în mod implicit, printr-o schemă cu două tacte care așază durata reală de viață între douăsprezece și douăzeci și patru de ore.
Documentația nonce-urilor spune explicit că nu trebuie să vă bazați niciodată pe ele pentru autentificare, autorizare sau control al accesului. Un nonce stabilește că cererea a venit din formularul vostru. Nu spune nimic despre dreptul acelei persoane de a face acel lucru.
Curățați la intrare, escapați la ieșire
Validați acolo unde puteți, pentru că validarea este precisă: un cod poștal fie se potrivește cu tiparul, fie nu. Curățați acolo unde nu puteți valida, cu sanitize_text_field(), sanitize_email(), sanitize_key(), absint() sau wp_kses_post(), în funcție de câmp.
Apoi escapați în punctul de ieșire, de fiecare dată, cu esc_html(), esc_attr(), esc_url() sau wp_kses_post(). Documentația despre escapare cere să faceți asta cât mai târziu posibil, ca cel care revizuiește să vadă escaparea și ieșirea pe același rând. Escaparea este sărită mai des decât orice altceva, pentru că nimic nu pare în neregulă atunci când o sari. Pagina se randează perfect până când cineva pune o etichetă de script într-un câmp.
Interogările pregătite
Orice interogare scrisă de voi trece prin $wpdb->prepare(), care primește %d pentru numere întregi, %f pentru numere zecimale, %s pentru șiruri și %i pentru identificatori precum numele de tabele și de coloane. Substituenții rămân fără ghilimele, un semn de procent literal se scrie de două ori, iar un caracter generic pentru LIKE se transmite în argumentul de substituție, nu se scrie în interogare. Concatenarea unei variabile în SQL nu este o dispută de stil, este chiar vulnerabilitatea.
API-ul REST și editorul de blocuri
Un plugin scris anul acesta ar trebui să își expună datele prin API-ul REST și setările prin editor, nu printr-o pagină de opțiuni făcută de mână.
Rutele se înregistrează cu register_rest_route() pe hook-ul rest_api_init. Începând cu WordPress 5.5, argumentul permission_callback este obligatoriu, iar omiterea lui declanșează un mesaj _doing_it_wrong() care numește ruta. Un endpoint cu adevărat public folosește __return_true, și tocmai acesta este rostul proiectării: a face o rută publică devine o linie de cod deliberată, nu o omisiune. Documentația endpointurilor personalizate acoperă și schema argumentelor, locul în care stau funcțiile de curățare și de validare, astfel încât datele proaste să nu ajungă niciodată la handlerul vostru.
Setările se înregistrează cu register_setting() și cu show_in_rest pe true. Asta le pune pe endpointul de setări al nucleului, așa că editorul de blocuri sau un script extern le poate citi și scrie printr-o interfață care se ocupă deja de autentificare, permisiuni și validare. Elimină o pagină de opțiuni, nonce-ul ei, handlerul ei de formular și erorile care locuiau în ele.
Blocurile se înregistrează dintr-un fișier block.json, metoda canonică recomandată începând cu WordPress 5.8. Documentația metadatelor de bloc arată câștigul: resursele declarate acolo se încarcă doar pe paginile în care apare blocul, nu pe tot site-ul pentru că un plugin este activ.
Disciplina performanței în interiorul unui plugin
Patru lucruri explică cea mai mare parte a încetinelii provocate de pluginuri pe care o găsim în audituri, iar toate patru sunt ieftin de evitat și scump de corectat ulterior. Primul îl reprezintă opțiunile încărcate automat, pentru că ele costă ceva la fiecare cerere, pentru totdeauna.
Al doilea îl reprezintă cererile la distanță necache-uite în timpul încărcării unei pagini. Un wp_remote_get() către API-ul unui furnizor, fără cache, înseamnă că fiecare vizitator așteaptă acel furnizor. Când furnizorul este lent, site-ul vostru este lent, iar când el este căzut, site-ul vostru atârnă până expiră timpul de așteptare. Puneți răspunsul în cache într-un tranzient, stabiliți un timp de așteptare explicit și hotărâți din vreme ce afișează pagina atunci când apelul eșuează.
Al treilea îl reprezintă interogările din interiorul unei bucle. Apelarea get_post_meta() pentru fiecare dintre 200 de rânduri înseamnă 200 de drumuri dus-întors, dacă memoria cache a metadatelor nu a fost pregătită dinainte, iar WP_Query o pregătește în locul vostru dacă o lăsați. Remedierea constă de obicei în a înceta să dezactivați ceva, lucru valabil pentru majoritatea constatărilor dintr-un audit Core Web Vitals.
Al patrulea îl reprezintă munca făcută în interiorul cererii cuiva. WP-Cron nu este cron de sistem: se declanșează la încărcarea unei pagini, deci o sarcină programată rulează în cererea unui vizitator, iar pe un site liniștit sarcina de la ora două nu pornește până când nu trece cineva pe la cinci. Definiți DISABLE_WP_CRON, porniți wp-cron.php dintr-un planificator de sistem adevărat și țineți sarcinile scurte și idempotente.
Supraviețuirea actualizărilor de nucleu: partea pe care nimeni nu o bugetează
Nucleul șterge rareori ceva de tot. Funcțiile sunt marcate ca depreciate, continuă să funcționeze și emit un mesaj, motiv pentru care rularea mediului de test cu WP_DEBUG activat este cel mai ieftin sistem de avertizare timpurie disponibil. Un mesaj de depreciere este o invitație cu dată la care să reparați ceva cât timp este încă ieftin.
Procesul care previne surprizele costă aproximativ o oră pe trimestru. Urmăriți blogul de dezvoltare al nucleului, ca să știți când există o versiune beta și apoi una candidat. Citiți Field Guide, publicat în faza versiunii candidat, care enumeră noutățile adresate dezvoltatorilor și schimbările incompatibile ale acelei versiuni. Apoi puneți versiunea candidat pe o copie de test și rulați un test de fum scris pe funcțiile reale ale pluginului.
Sprijinul pentru versiuni contează la fel de mult ca și codul. WordPress cere PHP 7.4 ca prag absolut și recomandă 8.3 sau mai nou, împreună cu MariaDB 10.11 sau MySQL 8.0. Declarați Requires PHP și Requires at least în antetul pluginului în mod onest, apoi testați pe cea mai joasă versiune pe care ați declarat-o, nu pe ce rulează pe laptopul dezvoltatorului.
Versionați-vă pluginul semantic și vorbiți serios. Un patch repară ceva, o versiune minoră adaugă comportament fără să strice nimic, iar una majoră are voie să strice, cu condiția să spună ce a stricat. Clienții cu actualizări automate se bazează pe promisiunea aceasta.
Distribuție, licențiere și cum ajung actualizările pe site
WordPress este publicat sub licența GPL versiunea 2 sau ulterioară, iar pagina de licență de pe wordpress.org expune poziția proiectului, potrivit căreia pluginurile și temele sunt lucrări derivate care moștenesc licența, recunoscând totodată o zonă gri juridică privind ce anume se consideră derivat.
Codul sursă îl primiți întotdeauna și puteți angaja pe oricine altcineva să îl modifice. Ce nu face GPL este să vă oblige să îl publicați, așa că un plugin construit pentru o firmă poate rămâne privat. Nici nu îl împiedică pe dezvoltator să vândă aceeași muncă altcuiva. Dacă exclusivitatea contează, aceea este o clauză de contract, nu una de licență.
Dacă pluginul intră în directorul public, trebuie să respecte regulile directorului de pluginuri, optsprezece la număr. Prima cere licențiere compatibilă cu GPL pentru tot ce se află în pachet, inclusiv imaginile. Altele exclud trialware-ul, adică funcționalitatea blocată în spatele unei plăți sau al unui upgrade, interzic codul ofuscat, opresc urmărirea utilizatorilor fără consimțământ și nu permit legături sau mențiuni adăugate pe site-ul public fără acord.
Dacă rămâne privat, actualizările devin problema voastră. Setați antetul Update URI, care există tocmai ca un plugin privat să nu fie suprascris de unul cu nume asemănător din director, și serviți actualizările de la endpointul vostru. Lăsarea acestui lucru la final este felul în care un client ajunge să actualizeze prin FTP.
Cât costă un plugin WordPress personalizat
Intervalele de mai jos sunt prețuri de agenție britanică în lire, pentru muncă livrată la standardul descris aici: cu teste, documentație și o persoană nominalizată drept responsabilă după lansare. Un dezvoltator WordPress și PHP capabil facturează aproximativ 400 până la 600 de lire pe zi, așa că acestea sunt afirmații despre perimetru, nu despre tarif.
Un plugin utilitar mic costă între 1.500 și 3.000 de lire. O singură sarcină, câteva hook-uri, poate un comutator în setări: gestionarea redirecționărilor, un câmp în plus pe o comandă, un export nocturn către un furnizor.
O integrare de dimensiune medie costă între 3.000 și 15.000 de lire. Un API terț cu autentificare, reîncercări și tratarea erorilor, un tip de conținut personalizat, ecrane de administrare și procesare în fundal. Este dimensiunea comandată cel mai des și subestimată cel mai des, pentru că integrarea înseamnă o săptămână, iar tratarea eșecurilor înseamnă două săptămâni.
Un plugin de produs consistent costă între 20.000 și 75.000 de lire și peste. Tabele proprii, interfețe în editorul de blocuri, infrastructură de licențiere și de actualizare, suport pentru multisite și o povară de asistență care începe chiar în ziua lansării.
A plăti la capătul de jos nu este automat greșit. Este greșit atunci când prețul a venit dintr-un perimetru care a exclus în tăcere livrabilele de mai jos. Ghidul nostru despre tarifele dezvoltatorilor WordPress și întrebările potrivite arată cum se citește o ofertă, iar pagina noastră de dezvoltare WordPress explică felul în care stabilim perimetrul acestei munci.
Ce ar trebui să conțină livrabilul
Cereți toate acestea în scris înainte să înceapă lucrul, pentru că fiecare este ieftin de inclus și scump de adăugat ulterior. Codul sursă, într-un depozit care vă aparține, cu istoricul intact, nu o arhivă trimisă pe email în ultima zi. Teste unitare pentru regulile de business și un test de integrare pentru tot ce scrie în baza de date sau apelează un serviciu extern, pentru că tocmai asta face codul sigur de schimbat peste doi ani de către cineva care nu a fost acolo.
Un fișier readme care spune ce face pluginul, de ce se agață, ce stochează și unde, ce servicii externe apelează și ce se întâmplă când fiecare dintre acestea cade. Două pagini sunt suficiente, iar absența lui este motivul pentru care pluginurile ajung înlocuite, nu întreținute. Un uninstall.php care șterge opțiuni, tabele, evenimente cron și metadate. Și o înțelegere de asistență nominalizată, care acoperă testarea pe fiecare versiune de nucleu și repararea a ceea ce descoperă acea testare.
Cum îl construim
Mecanik construiește pluginuri la toate cele trei dimensiuni de mai sus și preia pluginuri scrise de altcineva, adesea colaborarea mai utilă. Paginile noastre de dezvoltator WordPress și de dezvoltare software explică felul în care stabilim perimetrul și livrăm. Dacă aveți deja un plugin de care nimeni nu vrea să se atingă, un audit după practicile de mai sus durează aproximativ o zi și vă spune dacă poate fi reparat sau trebuie înlocuit.
Întrebări frecvente
Funcționalitatea personalizată trebuie pusă într-un plugin sau în temă? Într-un plugin, dacă nu este pur vizuală. Tema este schimbată la următoarea reproiectare și tot ce făcea ea se oprește: tipurile de conținut personalizate își pierd ecranele de administrare, codurile scurte apar ca text brut, iar integrările încetează să ruleze în tăcere. Tot ce trebuie să rămână valabil după o reproiectare aparține unui plugin.
Cât costă un plugin WordPress personalizat în Regatul Unit? Un plugin utilitar mic costă de obicei între 1.500 și 3.000 de lire, o integrare de dimensiune medie cu un API terț și ecrane de administrare costă între 3.000 și 15.000 de lire, iar un plugin de produs consistent, cu tabele proprii și infrastructură de actualizare, costă între 20.000 și 75.000 de lire sau mai mult. Dezvoltatorii capabili de această muncă facturează aproximativ 400 până la 600 de lire pe zi.
Este vreodată acceptabil să modifici nucleul WordPress sau fișierele altui plugin? Nu. Acele modificări sunt șterse de următoarea actualizare, fără eroare și de regulă fără să fie descoperite până când ceva încetează să funcționeze. Folosiți în schimb acțiuni și filtre. Dacă hook-ul de care aveți nevoie nu există, împachetați comportamentul, faceți un fork al pluginului sub control de versiune sau cereți hook-ul în amonte.
Îmi aparține un plugin pentru care am plătit pe cineva să îl construiască? Vă aparține copia voastră și ceea ce spune contractul. GPL vă dă codul sursă, dreptul de a-l modifica și dreptul de a angaja pe oricine altcineva să îl întrețină și nu vă obligă să îl publicați, așa că un plugin construit pentru o firmă poate rămâne privat. Nu îl împiedică pe dezvoltator să revândă aceeași muncă, deci treceți exclusivitatea în contract dacă ea contează.
Cum se împiedică stricarea unui plugin atunci când WordPress se actualizează? Testați-l pe fiecare versiune candidat, pe o copie de test, înainte ca acea versiune să fie lansată, rulați mediul de test cu WP_DEBUG activat, ca mesajele de depreciere să apară din timp, și declarați în antet versiunile de PHP și de WordPress pe care pluginul le susține. WordPress cere PHP 7.4 ca prag și recomandă 8.3 sau mai nou.
Comentarii