Wie kann man ein Plugin in einem wp-Theme erforderlich machen, ohne PHP-bedingte Anweisungen zu verwenden, wenn eine einzelne Funktion von diesem Plugin aufgerufen wird?


9

Für eines meiner Wordpress-Designs sind einige Plugins von Drittanbietern erforderlich, um ordnungsgemäß ausgeführt zu werden.

Meistens habe ich Funktionen von Plugins von Drittanbietern mit bedingten Anweisungen wie aufgerufen

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

Angenommen, ich muss ausgiebig ein Plugin für viele Dateien meines Themas verwenden ... Ich möchte die Verwendung vieler IF-Bedingungen vermeiden ... gibt es eine geeignete Möglichkeit, die Installation eines bestimmten Plugins in WP zu verlangen oder sie sogar besser zu installieren Wenn sie fehlen, bevor das Thema aktiviert wird?

Vielen Dank

Antworten:


7

is_plugin_active()ist ziemlich zerbrechlich: Es wird unterbrochen, wenn entweder der Autor des Plugins die Hauptdatei umbenennt oder wenn der Benutzer das Verzeichnis oder die Hauptdatei des Plugins umbenennt. Es ist besser zu überprüfen, ob eine bestimmte öffentliche Funktion vorhanden ist.

Um dies nicht jedes Mal überprüfen zu müssen, wenn Sie einige Funktionen des Plugins benötigen, können Sie im Admin-Bereich eine Meldung anzeigen:

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>';
}

Eine andere Alternative ist die Verwendung von http://tgmpluginactivation.com/


Wenn der Plugin-Autor einen Funktionsnamen ändert, mit dem Sie Fragen stellen function_exists, erhält ein normaler Benutzer einfach die Meldung, dass er das Plugin, auf das sich ein anderes Plugin stützt, nicht installiert hat. Das Problem ist, dass der Benutzer tatsächlich wird hat das Plugin installiert und dann einfach fragen , warum es doens't Arbeit . Oh, und ich werde dich dafür nicht herabstimmen.
Kaiser

Wenn Sie sich für Stimmen interessieren, sollten Sie das Q selbst positiv bewerten, da es gut ist.
Kaiser

Wenn der Plugin-Autor den Funktionsnamen ändert, erhält er Beschwerden von viel mehr Benutzern, als wenn er den Dateinamen ändern würde.
Scribu

Und ich habe Ihre Antwort abgelehnt, weil sie die Frage nicht angesprochen hat, IMO. Oder möchten Sie lieber, dass ich verdeckt abstimme, ohne eine Erklärung anzubieten?
Scribu

Ich habe nur über die Ablehnung gesprochen, nicht über den Kommentar. Der Kommentar selbst ist in Ordnung, da dieses Thema diskutiert werden muss. Ich werde eine weitere Antwort hinzufügen, da meine Gedanken dahinter die Länge des Kommentars überschreiten. Bitte bearbeiten Sie einfach die Antwort, damit wir die Diskussionsergebnisse in den Überarbeitungen behalten können, damit alle folgen können. Vielen Dank.
Kaiser

1

Dies würde zwar nicht verhindern, dass das Thema beschädigt wird, wenn das Plugin deaktiviert ist, aber ich würde mir diesen Artikel über das Plugin "Anzeigen eines Administratorhinweises für erforderliche Themen" ansehen. Ich war noch nie mit der Idee vertraut, dass ein Thema die Installation eines Plugins erzwingt , und daher scheint dies die nächstbeste Option zu sein.

Noch ein kurzer Gedanke: Ich habe das noch nie versucht, aber ich frage mich, ob Sie eine clevere Möglichkeit finden könnten, mehrere Haken in einer einzigen Bedingung unterzubringen. Vielleicht könnten Sie alle bedingten Funktionen in einer anderen Datei trennen und sie nur bei if( function_exists( 'plugin_function' ) )Rückgabe benötigen true(mit dem Verständnis, dass dies eine unvollständige Prüfung ist.


0

Wenn Sie nur eine Plugin-Seite benötigen, dann gibt es is_plugin_active(). Wenn Sie es außerhalb benötigen, kopieren Sie die Kernfunktion besser in Ihr Thema und fügen Sie sie dann wieder ein:

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 );
}
}

Die Bedingung vermeidet Fehler bei der doppelten Definition der Funktion.


Das beantwortet die Frage nicht wirklich. Es ersetzt lediglich if(function_exist('plugin_function'))durchif(is_plugin_active('plugin-file.php'))
scribu

0

Hinweis: Diese Antwort dient nur dazu, die Diskussion zwischen @scribu und @kaiser zu vereinfachen. Mods: Bitte nicht löschen. Benutzer / Leser: Bitte stimmen Sie nicht ab. Wenn Sie der Diskussion folgen möchten, sehen Sie sich das Revisions- / Bearbeitungsprotokoll an. Wenn Sie an der Diskussion teilnehmen möchten, bearbeiten Sie die Antwort. Wenn die Diskussion ein Ergebnis hat, wird es als solches markiert. Danke.


Szenarien

Es gibt auch verschiedene Szenarien mit unterschiedlicher Gewichtung, bei denen möglicherweise eine Plugin-Abhängigkeit besteht. (Die Beispiele sind nur fiktiv). Das Wort "(übergeordnetes) Plugin" kann aus übergeordneter Sicht mit "Theme" ausgetauscht werden.

  1. (schwer) Ein untergeordnetes Plugin, das nur die Funktionalität erweitert oder die Anzeige (und ähnliches) eines vorhandenen Plugins ändert und daher ohne das übergeordnete Plugin nicht existieren kann. Beispiel: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (normal) Ein Plugin mit erweiterter Funktionalität, wenn ein untergeordnetes Plugin aktiviert wird. Beispiel: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (soft) Ein Plugin, das nur eine Funktion hinzufügt. Beispiel: DisneyWonderlandTheme »MickeysSocialLinks

Im Folgenden versuche ich zu skizzieren, was passiert, wenn Sie das "andere" Plugin aktualisieren und die Prüfung nicht mehr funktioniert.

  • Ad 1) Das Plugin könnte ohne BuddyPress nicht existieren. »Stuff ist komplett kaputt.
  • Anzeige 2) Das Plugin konnte nicht die Option bieten, von Karussell zu SlideDeck zu wechseln. »Zeigt verkabelt an (ich gehe davon aus, dass Stile zu SlideDeck geändert wurden).
  • Anzeige 3) MickeysSocialLinks verschwinden.

Prüfen

Es gibt drei Möglichkeiten, um zu prüfen, ob ein Plugin aktiv ist:

  • A. Existiert der Ordner?
  • B. Existiert die Hauptdatei - Option 'active_plugins'-?
  • C. Existiert eine bestimmte Funktion?

Wenn ich jetzt mein Internal Link Checker Plugin als Beispiel nehme , das keine öffentliche API bietet und nicht erweitert werden soll, sehe ich keinen Grund (als Autor), die Benennung interner Funktionen nicht nach Bedarf oder nur nach Belieben zu ändern . Wenn also jemand versuchen würde, dieses Plugin zu huckepack zu nehmen, würde das Zeug beim Update einfach kaputt gehen (abhängig von der Funktionalität und der engen Bündelung). Gleiches gilt für Dateinamen. Ich hätte keinen wirklichen Grund (abgesehen davon, dass das Plugin beim Update deaktiviert würde), den Dateinamen nicht zu ändern. Das einzige, was mich davon abhalten würde, den Ordnernamen zu ändern, ist, dass die Aktualisierungsprüfung und Benachrichtigung für den Dateinamen ausgeführt wird - sofern sie im offiziellen Repo gehostet wird.

Ich würde also sagen, vom schwächsten (leicht zu ändernden) zum härtesten (viel spricht gegen das Ändern) Teil eines (übergeordneten) Plugins wäre:

Funktionsordner »Hauptdateiname»


Als ich sagte, dass eine Funktionsprüfung weniger fragil ist als die Verwendung, nahm is_plugin_active()ich an, dass die fragliche Funktion eine ist, die der Plugin-Autor ausdrücklich empfiehlt. Das ultimative Beispiel hierfür wäre das wp_pagenavi()Template-Tag, das vom WP-PageNavi-Plugin angeboten wird.

Die Schwierigkeit beim Definieren von Abhängigkeiten besteht darin, dass es keine Standardmethode gibt, um Plugins ohne Dateinamen eindeutig zu identifizieren.

Weitere Gedanken zu diesem Thema:

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


Ich denke, wir können es bisher in drei Punkten zusammenfassen:

  • Wir haben über etwas andere Themen gesprochen
  • Wir sind uns einig, dass es keinen kugelsicheren Weg gibt, um das zu umgehen, was ich mir vorgestellt habe
  • Nach Ihrem Verständnis der Frage haben Sie einen gültigen Weg angeboten

Die (bisher) klügste Art, an die ich denken kann, die ich bereits in einigen (viel zu weniger) Plugins gesehen habe:

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

Ohne zu viel darüber nachzudenken, aber ich denke, Sie könnten Ihren Hinweis in eine Überprüfung des Filters "Alle" einbinden und im aktuellen Filter überprüfen , ob er ausgelöst wurde, als Sie am shutdownHaken waren ...?


Die Verwendung von Hooks eignet sich gut für "normale" und "schwache" Abhängigkeiten. Der einzige Nachteil ist, dass Sie noch verwenden müssten function_exists()oder is_plugin_active()wenn Sie aufhören möchten, wenn die Abhängigkeit nicht erfüllt ist. Die Verwendung des "All" -Filters dafür wäre IMO zu teuer.

@scibu Dies war auf "Ihr" Thema ausgerichtet. (Ich habe schon aufgehört, über meine zu reden). :) :)

Wenn Sie also eine Abhängigkeit benötigen - und Sie haben einen netten Autor -, könnte er stattdessen einen Hook als Ersatz für ein Template-Tag anbieten. Weil sich das Plugin nur einhaken würde, wenn der Hook vorhanden wäre, oder einfach nichts tun würde. Und auf der anderen Seite hätten Sie keinen Fehler, wenn die Plugins nicht vorhanden wären.

Hier ist der schwierige Teil (oder eher ein Q): Um eine Administratorbenachrichtigung zu schreiben, um den Benutzer über die Abhängigkeit "Sie müssen» DisneyWonderLinks «installieren" zu informieren, können Sie die überprüfen array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Ich bin mir nicht sicher, ob dies funktionieren würde, aber afaik sollte das Array auf beiden Seiten (public / admin) zugänglich sein.


Das würde nicht funktionieren. Nur weil ein Rückruf für einen Hook registriert ist, bedeutet dies nicht, dass der Hook erwartungsgemäß ausgelöst wird. Das einzige, was irgendwie funktionieren würde, ist die Verwendung des "Shutdown" -Hakens, den Sie zuvor erwähnt haben:

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

Dies wird natürlich ganz unten nach dem </html>Tag im Front-End gedruckt (da dort normalerweise Vorlagen-Tags verwendet werden), was nicht sehr nützlich ist.

Sie könnten versuchen, die Nachricht in wp_options zu speichern und sie dann im Admin-Bereich anzuzeigen, aber das würde eine ganz neue Dose Würmer öffnen: Ungültigmachung, Caching-Plugins usw.


Für die Aufzeichnung ist dies eine eher unorthodoxe Art, die Funktionalität der Site zu nutzen. Es erinnert mich an c2.com/cgi/wiki
scribu

Ja ist es. Aber ich hatte keine Ahnung, wie wir die Diskussion fortsetzen könnten, ohne sie vor späteren Lesern zu verbergen.
Kaiser

Ich würde nicht realisieren, dass das Posten der Frage eine ziemliche Diskussion ausgelöst hätte :) Aber es ist in der Tat interessant und ich danke Ihnen beiden für Ihre Mühe und Zeit, Ratschläge zu geben und eine nachdenkliche Debatte zu führen. Ich denke, der Rat von scribu (einer der vielen), die TGM-Aktivierungsklasse zu verwenden, könnte eine Lösung für meine Antwort bieten, zumindest aus rein praktischer Sicht. Ich werde mich damit befassen. Ich behalte jedoch die gesamte Diskussion im Auge, da auch andere vorgeschlagene Methoden in bestimmten Szenarien sinnvoll sind und es für mich sehr interessant ist, sie zu lesen, danke!
Unfulvio
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.