Cum să faci un plugin obligatoriu într-o temă WordPress fără a folosi instrucțiuni condiționale PHP când apelezi o funcție individuală din acel plugin?

19 ian. 2012, 08:45:28
Vizualizări: 19.8K
Voturi: 14

Una dintre temele mele WordPress necesită câteva plugin-uri terțe pentru a funcționa corect.

De cele mai multe ori obișnuiam să apelez funcții din plugin-uri terțe folosind instrucțiuni condiționale precum

    if(function_exist('plugin_function')) {
             plugin_function() // execută ceva
    }

Să presupunem totuși că trebuie să folosesc extensiv un plugin în multe fișiere ale temei mele... Aș dori să evit folosirea multor condiții IF... există o modalitate adecvată de a face ca anumite plugin-uri specifice să fie instalate obligatoriu în WP sau și mai bine, să le instaleze dacă lipsesc înainte de activarea temei?

mulțumesc

0
Toate răspunsurile la întrebare 4
7

Funcția is_plugin_active() este destul de fragilă: se va întrerupe atunci când autorul plugin-ului redenumește fișierul principal sau când utilizatorul redenumește directorul sau fișierul principal al plugin-ului. Este mai bine să verifici dacă o anumită funcție publică există.

Pentru a evita să faci această verificare de fiecare dată când ai nevoie de o parte din funcționalitatea plugin-ului, poți afișa un mesaj în zona de administrare:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Atenție: Tema necesită Plugin X pentru a funcționa', 'my-theme' ) . '</p></div>';
}

O altă alternativă este să folosești ceva de genul http://tgmpluginactivation.com/

19 ian. 2012 13:31:01
Comentarii

Dacă autorul plugin-ului schimbă numele unei funcții pe care o verifici cu function_exists, atunci un utilizator obișnuit va primi pur și simplu mesajul că nu a instalat plugin-ul de care depinde alt plugin. Problema este că utilizatorul va avea de fapt plugin-ul instalat și se va întreba de ce nu funcționează. Ah, și nu am de gând să te downvotez pentru asta.

kaiser kaiser
19 ian. 2012 14:27:21

Dacă te interesează voturile, atunci ar trebui să upvotezi întrebarea în sine, deoarece este una bună.

kaiser kaiser
19 ian. 2012 14:32:42

Dacă autorul plugin-ului schimbă numele funcției, va primi plângeri de la mult mai mulți utilizatori decât dacă ar schimba numele fișierului.

scribu scribu
19 ian. 2012 15:47:15

Și am dat vot negativ răspunsului tău pentru că, în opinia mea, nu a abordat întrebarea. Sau ai prefera să votez negativ în mod ascuns, fără să ofer nicio explicație?

scribu scribu
19 ian. 2012 15:50:20

Vorbeam doar despre votul negativ, nu despre comentariu. Comentariul în sine este ok, deoarece acest subiect necesită discuție. Voi adăuga un alt răspuns, deoarece gândurile mele despre asta vor depăși lungimea unui comentariu. Te rog să editezi răspunsul, astfel încât să putem păstra rezultatele discuției în revizii pentru ca toată lumea să le poată urmări. Mulțumesc.

kaiser kaiser
19 ian. 2012 16:28:29

Presupun că întrebarea este dacă este adecvat să dai un vot negativ unui răspuns și apoi să postezi unul propriu. Dar asta este o discuție pentru meta.

scribu scribu
19 ian. 2012 16:51:36

Nu-mi pasă. Doar mă întrebam despre asta. Singurul lucru care mă interesează cu adevărat este părerea ta despre subiect. Vezi noul răspuns și te rog să citești comentariul de la început (și te rog să-l lași acolo pentru alții).

kaiser kaiser
19 ian. 2012 16:59:45
Arată celelalte 2 comentarii
1

Deși acest lucru nu ar preveni ruperea temei atunci când pluginul este dezactivat, aș recomanda citirea acestui articol interesant despre "Cum să afișezi o notificare de administrare pentru temele necesare" plugin. Niciodată nu m-am simțit confortabil cu ideea unei teme care forțează instalarea unui plugin, așa că aceasta pare următoarea cea mai bună variantă.

O altă idee rapidă: nu am încercat niciodată acest lucru, dar mă întreb dacă ai putea găsi o metodă inteligentă de a grupa mai multe hook-uri într-o singură condiție. Poți separa toate funcțiile condiționale într-un fișier diferit și să-l incluzi doar dacă if( function_exists( 'plugin_function' ) ) returnează true (cu înțelegerea că aceasta este o verificare imperfectă).

11 mai 2012 19:38:22
Comentarii

Linkul nu mai funcționează...

Alex Alex
21 sept. 2021 14:07:19
1

Dacă ai nevoie doar pentru o pagină de plugin, atunci există is_plugin_active(). Dacă ai nevoie în afara acesteia, este mai bine să copiezi/lipești funcția din nucleu în tema ta și apoi să o refolosești:

if ( ! is_admin() )
{
/**
 * Verifică dacă plugin-ul este activ prin verificarea listei active_plugins.
 *
 * @since 2.5.0
 *
 * @param string $plugin Calea de bază a plugin-ului din directorul plugins.
 * @return bool True, dacă se află în lista de plugin-uri active. False, dacă nu se află în listă.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

Condiția evită orice eroare legată de definirea dublă a funcției.

19 ian. 2012 09:16:48
Comentarii

Asta nu răspunde cu adevărat la întrebare. Doar înlocuiește if(function_exist('plugin_function')) cu if(is_plugin_active('plugin-file.php'))

scribu scribu
19 ian. 2012 13:32:30
3

Notă: Acest răspuns este aici doar pentru a facilita discuția între @scribu și @kaiser. Moderatori: Vă rugăm să nu ștergeți. Utilizatori/Cititori: Vă rugăm să nu votați. Dacă doriți să urmăriți discuția, consultați jurnalul de revizuire/editare. Dacă doriți să vă alăturați discuției, editați Răspunsul. Dacă discuția are un rezultat, acesta va fi marcat ca atare. Vă mulțumim.


Scenarii

Există și diferite scenarii care au greutăți diferite, unde ați putea avea o dependență de plugin. (Exemplele sunt doar fictive). Cuvântul "Plugin (părinte)" poate fi înlocuit cu "Temă" din perspectiva părintelui.

  1. (hard) Un plugin copil care doar extinde funcționalitatea sau modifică afișarea (și altele asemenea) unui plugin existent și, prin urmare, nu poate exista fără părinte. Exemplu: BuddyPress » BuddyPress-FunkyCommentDisplay
  2. (normal) Un plugin care are funcționalitate extinsă atunci când un plugin copil este activat. Exemplu: jQueryAttachmentCarousel » jQuerySlideDeck
  3. (soft) Un plugin care doar adaugă o caracteristică. Exemplu: DisneyWonderlandTheme » MickeysSocialLinks

În cele ce urmează încerc să schițez ce se întâmplă când actualizați plugin-ul "altul" și verificarea nu mai funcționează.

  • La punctul 1) Plugin-ul nu putea exista fără BuddyPress activat » Lucrurile sunt complet stricate.
  • La punctul 2) Plugin-ul nu putea oferi opțiunea de a trece de la Carousel la SlideDeck » Afișează lucruri ciudate (presupun că stilurile sunt modificate pentru SlideDeck).
  • La punctul 3) MickeysSocialLinks dispar.

Verificare

Există, în opinia mea, trei posibilități de verificare, dacă doriți să știți dacă un plugin este activ:

  • A. Există folderul?
  • B. Există fișierul principal - opțiunea 'active_plugins'?
  • C. Există o anumită funcție?

Dacă acum iau ca exemplu Plugin-ul meu de verificare a linkurilor interne, care nu oferă nicio API publică și nu este menit să fie extins, atunci nu aș vedea niciun motiv (ca autor) să nu schimb denumirea funcțiilor interne la cerere sau pur și simplu după bunul plac. Deci, dacă cineva ar încerca să se agațe de acest plugin, atunci lucrurile s-ar strica pur și simplu (în funcție de funcționalitate și strânsoarea de legătură) la actualizare. Același lucru este valabil și pentru numele fișierelor. Nu aș avea niciun motiv real (în afară de faptul că plugin-ul ar fi dezactivat la actualizare) să nu schimb numele fișierului. Singurul lucru care m-ar împiedica să schimb numele folderului este că verificarea și notificarea de actualizare se face împotriva numelui fișierului - dacă este găzduit în depozitul oficial.

Așadar, aș spune că de la partea cea mai slabă (ușor de schimbat) la cea mai dură (multe argumente împotriva schimbării) a unui plugin (părinte) ar fi:

funcție » nume fișier principal » folder


Când am spus că o verificare a funcției este mai puțin fragilă decât utilizarea is_plugin_active(), am presupus că funcția în cauză este una pe care autorul plugin-ului o încurajează în mod explicit. Exemplul suprem al acestui lucru ar fi wp_pagenavi() oferit de plugin-ul WP-PageNavi.

Dificultatea în definirea dependențelor este că nu există o modalitate standard de a identifica în mod unic plugin-urile care să nu implice nume de fișiere.

Mai multe gânduri pe această temă:

http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme


Cred că putem să rezumăm până acum în trei puncte:

  • Am vorbit despre subiecte ușor diferite
  • Suntem de acord că nu există o metodă sigură pentru a ocoli ceea ce am crezut eu că ar fi subiectul
  • Din înțelegerea dumneavoastră a întrebării, ați oferit o modalitate validă de a proceda

Cea (până acum) mai inteligentă metodă la care mă pot gândi, pe care am văzut-o deja în unele (mult prea puține) plugin-uri:

// în interiorul fișierului plugin:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// în interiorul unui template:
do_action( 'plugin_custom_hook' );

Fără să mă gândesc prea mult în detaliu la asta, dar cred că ați putea să vă conectați notificarea într-o verificare pe filtrul 'all' și să verificați în interiorul filtrului curent dacă a fost declanșat când sunteți pe hook-ul shutdown...?


Utilizarea hook-urilor ar funcționa bine pentru dependențe 'normale' și 'slabe'. Singurul dezavantaj este că tot ar trebui să utilizați function_exists() sau is_plugin_active() dacă doriți să opriți dacă dependența nu este îndeplinită. Utilizarea filtrului 'all' pentru asta ar fi prea costisitoare, în opinia mea.

@scibu Aceasta a fost direcționată către "subiectul" dumneavoastră. (Am renunțat deja să vorbesc despre al meu). :)

Deci, în principiu, dacă aveți nevoie de o dependență - și aveți un autor drăguț - atunci acesta ar putea oferi un hook în loc de/sau ca înlocuitor pentru un template tag. Pentru că plugin-ul s-ar conecta doar dacă hook-ul ar fi prezent, sau pur și simplu nu ar face nimic. Iar pe de altă parte nu ați avea o eroare, când plugin-ul nu este prezent.

Aici este partea grea (sau mai degrabă o întrebare): Pentru a scrie o notificare în admin pentru a informa utilizatorul despre dependența "Trebuie să instalați »DisneyWonderLinks«", ați putea verifica array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Nu sunt sigur dacă asta ar funcționa, dar din câte știu, array-ul ar trebui să fie accesibil pe ambele părți (public/admin).


Asta nu ar funcționa. Doar pentru că un callback este înregistrat la un hook nu înseamnă că hook-ul va fi declanșat atunci când este așteptat. Singurul lucru care ar funcționa într-un fel ar fi utilizarea hook-ului 'shutdown', pe care l-ați menționat mai înainte:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problemă.';
} );

Desigur, acest lucru ar fi afișat chiar în partea de jos, după tag-ul </html>, pe front-end (deoarece acolo sunt folosite în mod normal template tag-urile), ceea ce nu este de mare folos.

Ați putea încerca să stocați mesajul în wp_options și apoi să-l afișați în zona de admin, dar asta ar deschide o cutie nouă de viermi: invalidare, plugin-uri de caching etc.

19 ian. 2012 16:58:29
Comentarii

Pentru evidență, acesta este un mod destul de neortodox de a folosi funcționalitatea site-ului. Îmi amintește de http://c2.com/cgi/wiki

scribu scribu
19 ian. 2012 17:23:50

Da, așa este. Dar nu știam cum am putea continua discuția fără a o ascunde de cititorii ulteriori.

kaiser kaiser
19 ian. 2012 18:27:40

Nu mi-am dat seama că publicarea întrebării va genera o discuție atât de amplă :) Dar este într-adevăr interesant și vă mulțumesc amândurora pentru efort și timp acordat oferind sfaturi și oferind o dezbatere gândită. Cred că sfatul de la scribu (unul dintre cele multe) de a folosi clasa TGM Activation ar putea oferi o soluție la întrebarea mea măcar din punct de vedere practic, voi cerceta această posibilitate. Totuși, urmăresc întreaga discuție pentru că și alte metode propuse au sens în anumite scenarii și este foarte interesant pentru mine să le citesc, vă mulțumesc!

unfulvio unfulvio
20 ian. 2012 19:43:24