Jak zrobić wtyczkę wymaganą w kompozycji wp bez użycia instrukcji warunkowych php podczas wywoływania poszczególnych funkcji z tej wtyczki?

10

Jeden z moich motywów Wordpress wymaga poprawnego działania kilku wtyczek innych firm.

W większości przypadków wywoływałem funkcje z wtyczek firm trzecich przy użyciu instrukcji warunkowych, takich jak

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

przypuśćmy, że muszę korzystać z jednej wtyczki w wielu plikach mojego motywu ... Chciałbym uniknąć używania wielu warunków JEŻELI ... czy istnieje właściwy sposób, aby wymagać zainstalowania określonej wtyczki w WP lub nawet lepiej ją zainstalować jeśli ich brakuje przed aktywowaniem motywu?

dzięki

unfulvio
źródło

Odpowiedzi:

7

is_plugin_active()jest raczej delikatny: pęknie, gdy autor wtyczki zmieni nazwę głównego pliku lub gdy użytkownik zmieni nazwę katalogu wtyczki lub głównego pliku. Lepiej sprawdzić, czy istnieje jakaś funkcja publiczna.

Aby uniknąć konieczności sprawdzania za każdym razem, gdy potrzebujesz niektórych funkcji wtyczki, możesz wyświetlić komunikat w obszarze administracyjnym:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

Inną alternatywą jest użycie czegoś takiego jak http://tgmpluginactivation.com/

scribu
źródło
Jeśli autor wtyczki zmieni nazwę funkcji, o którą pytasz function_exists, zwykły użytkownik po prostu otrzyma wiadomość, że nie zainstalował wtyczki, na której opiera się inna wtyczka. Problem polega na tym, że użytkownik rzeczywiście będzie mieć zainstalowane wtyczki, a następnie po prostu zastanawiam się, dlaczego to doens't pracy . Och, i nie zamierzam cię za to głosować.
kaiser
Jeśli zależy ci na głosach, powinieneś głosować na samo Q, ponieważ jest dobre.
kaiser
Jeśli autor wtyczki zmieni nazwę funkcji, otrzyma skargi od znacznie większej liczby użytkowników, niż gdyby zmienił nazwę pliku.
scribu
Poparłem twoją odpowiedź, ponieważ nie zawierała odpowiedzi na pytanie, IMO. A może wolałbym głosować potajemnie, bez żadnego wyjaśnienia?
scribu
Mówiłem tylko o przeglądzie, a nie o komentarzu. Sam komentarz jest w porządku, ponieważ ten temat wymaga dyskusji. Dodam kolejną odpowiedź, ponieważ moje przemyślenia na ten temat przekroczą długość komentarzy. Po prostu edytuj odpowiedź, abyśmy mogli zachować wyniki dyskusji w wersjach, które każdy powinien śledzić. Dzięki.
kaiser
1

Chociaż nie zapobiegnie to zerwaniu motywu, gdy wtyczka jest wyłączona, przyjrzałbym się zręcznemu artykułowi na temat wtyczki „Jak wyświetlić powiadomienie administratora o wymaganych motywach” . Nigdy nie czułem się dobrze z pomysłem na motyw zmuszający do zainstalowania wtyczki, więc wydaje się, że to kolejna najlepsza opcja.

Kolejna szybka myśl: nigdy tego nie próbowałem, ale zastanawiam się, czy możesz wymyślić jakiś sprytny sposób na umieszczenie wielu haczyków w jednym warunku. Być może możesz oddzielić wszystkie funkcje warunkowe w innym pliku i wymagać go tylko w przypadku if( function_exists( 'plugin_function' ) )powrotu true(przy założeniu, że jest to niedokładna kontrola).

mrwweb
źródło
0

Jeśli potrzebujesz tylko strony wtyczki, to jest is_plugin_active(). Jeśli potrzebujesz go na zewnątrz, lepiej skopiuj / wklej podstawową funkcję do swojego motywu, a następnie użyj go ponownie:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

Warunkowe pozwala uniknąć błędów z podwójnym zdefiniowaniem funkcji.

kajzer
źródło
To tak naprawdę nie odpowiada na pytanie. To po prostu zamienia if(function_exist('plugin_function'))sięif(is_plugin_active('plugin-file.php'))
scribu
0

Uwaga: ta odpowiedź jest właśnie tutaj, aby ułatwić dyskusję między @scribu a @kaiser. Mody: Proszę nie usuwać. Użytkownicy / czytelnicy: Proszę nie głosować. Jeśli chcesz śledzić dyskusję, zajrzyj do dziennika zmian / edycji. Jeśli chcesz dołączyć do dyskusji, edytuj odpowiedź. Jeśli dyskusja przyniesie wynik, zostanie oznaczona jako taka. Dziękuję Ci.


Scenariusze

Istnieją również różne scenariusze, które różnią się wagą, w których można mieć zależność od wtyczek. (Przykłady są tylko fikcyjne). Słowo „(nadrzędny) Plugin” można zamienić na „Theme” z nadrzędnego punktu widzenia.

  1. (trudny) Wtyczka podrzędna, która jedynie rozszerza funkcjonalność lub zmienia wyświetlanie (i podobne) istniejącej wtyczki i dlatego nie może istnieć bez elementu nadrzędnego. Przykład: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (normalny) Wtyczka o rozszerzonej funkcjonalności, gdy aktywowana jest wtyczka potomna. Przykład: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (miękki) Wtyczka, która po prostu dodaje funkcję. Przykład: DisneyWonderlandTheme »MickeysSocialLinks

Poniżej próbuję naszkicować, co się stanie, gdy zaktualizujesz „inną” wtyczkę, a sprawdzenie już nie działa.

  • Ad 1) Wtyczka nie mogła istnieć bez aktywacji BuddyPress »Rzeczy są całkowicie zepsute.
  • Ad 2) Wtyczka nie mogła zaoferować opcji przełączenia z karuzeli na SlideDeck »Wyświetlacze przewodowe (zakładam, że style zostały zmodyfikowane do SlideDeck).
  • Ad 3) MickeysSocialLinks znikają.

Czek

Istnieją trzy możliwości sprawdzenia, czy chcesz wiedzieć, czy wtyczka jest aktywna:

  • A. Czy folder istnieje?
  • B. Czy plik główny - opcja 'active_plugins'- istnieje?
  • C. Czy istnieje określona funkcja?

Jeśli teraz wezmę przykład mojej wtyczki Internal Link Checker , która nie oferuje publicznego interfejsu API i nie jest przeznaczona do rozszerzenia, nie widzę powodu (jako autora), aby nie zmieniać nazewnictwa funkcji wewnętrznych na żądanie lub po prostu . Więc jeśli ktoś spróbuje zastosować piggyback na tej wtyczce, wtedy rzeczy po prostu się zepsują (w zależności od funkcjonalności i szczelności pakowania) podczas aktualizacji. To samo dotyczy nazw plików. Nie miałbym żadnego prawdziwego powodu (poza tym, że wtyczka zostałaby dezaktywowana podczas aktualizacji), aby nie zmieniać nazwy pliku. Jedyną rzeczą, która powstrzymałaby mnie przed zmianą nazwy folderu jest to, że sprawdzanie aktualizacji i powiadomienie działa z nazwą pliku - jeśli jest przechowywany w oficjalnym repozytorium.

Powiedziałbym więc, że od najsłabszej (łatwej do zmiany) do najtrudniejszej (dużo mówi się przeciwko zmianie) części (macierzystej) wtyczki byłoby:

funkcja »nazwa głównego pliku» folder


Kiedy powiedziałem, że sprawdzanie funkcji jest mniej kruche niż używanie is_plugin_active(), założyłem, że dana funkcja jest tą, którą autor wtyczki wyraźnie zachęca. Ostatecznym tego przykładem jest wp_pagenavi()tag szablonu oferowany przez wtyczkę WP-PageNavi.

Trudność w definiowaniu zależności polega na tym, że nie ma standardowego sposobu jednoznacznej identyfikacji wtyczek, które nie wymagają nazw plików.

Więcej przemyśleń na ten temat:

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


Myślę, że do tej pory możemy to podsumować w trzech punktach:

  • Rozmawialiśmy o nieco innych tematach
  • Zgadzamy się, że nie ma kuloodpornego sposobu na obejście tego, co według mnie byłoby tematem
  • Z twojego zrozumienia pytania zaoferowałeś właściwą drogę

(Jak dotąd) najmądrzejszy sposób, w jaki mogę myśleć, że widziałem już w (o wiele za mało) wtyczkach:

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

Nie zastanawiając się nad tym zbyt szczegółowo, ale myślę, że możesz podpiąć uwagę do filtra „wszystko” i sprawdzić w filtrze prądu, jeśli został on uruchomiony, gdy jesteś na shutdownhaku…?


Używanie haków działałoby dobrze w przypadku „normalnych” i „słabych” zależności. Jedyną wadą jest to, że nadal będziesz musiał skorzystać function_exists()lub is_plugin_active()jeśli chcesz przestać, jeśli zależność nie zostanie spełniona. Zastosowanie do tego filtru „wszystko” byłoby zbyt drogim IMO.

@scibu To było skierowane na „twój” temat. (Upuściłem już mówiąc o moim). :)

Zasadniczo, jeśli potrzebujesz zależności - a masz miłego autora - może zaoferować hak zamiast / jako zamiennik tagu szablonu. Ponieważ wtyczka zaczepiłaby się tylko, gdyby haczyk był obecny lub po prostu nic nie zrobił. Z drugiej strony nie byłoby błędu, gdy wtyczki nie były obecne.

Oto trudna część (lub więcej pytań): Aby napisać powiadomienie administratora, aby poinformować użytkownika o zależności „Musisz zainstalować» DisneyWonderLinks «”, możesz to sprawdzić array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Nie jestem pewien, czy to zadziała, ale afaik powinien być dostępny po obu stronach (publicznej / administracyjnej).


To by nie działało. To, że oddzwanianie jest zarejestrowane na przechwytywaniu, nie oznacza, że ​​przechwytywanie zostanie uruchomione zgodnie z oczekiwaniami. Jedyną rzeczą, która byłaby swego rodzaju pracą, jest użycie haka „zamykania”, o którym wspominałeś wcześniej:

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

Oczywiście byłoby to wydrukowane na samym dole, po </html>znaczniku, na froncie (ponieważ tam zwykle używane są znaczniki szablonów), co nie jest zbyt użyteczne.

Możesz spróbować zapisać wiadomość w wp_options, a następnie wyświetlić ją w obszarze administracyjnym, ale otworzy to zupełnie nową puszkę robaków: unieważnienie, buforowanie wtyczek itp.

kajzer
źródło
Dla przypomnienia, jest to dość niekonwencjonalny sposób korzystania z funkcjonalności strony. Przypomina mi c2.com/cgi/wiki
scribu
Tak to jest. Ale nie miałem pojęcia, jak możemy kontynuować dyskusję bez ukrywania jej przed późniejszymi czytelnikami.
kaiser
Nie zdawałbym sobie sprawy z tego, że opublikowanie pytania spowodowałoby sporą dyskusję :) Ale to naprawdę interesujące i dziękuję wam zarówno za wasz wysiłek i czas, udzielając porad i rozważnej debaty. Myślę, że rada scribu (jedna z wielu), aby skorzystać z klasy aktywacji TGM, może zaoferować rozwiązanie mojej odpowiedzi przynajmniej z praktycznego punktu widzenia, przyjrzę się jej. Nadal jednak obserwuję całą dyskusję, ponieważ inne proponowane metody mają sens w niektórych scenariuszach i są dla mnie bardzo interesujące, dzięki!
unfulvio,