Plugins in verknüpften Verzeichnissen?

20

Wenn ich Plugins entwickle, teste ich sie auf mehreren Versionen von WordPress, indem ich mein Plugin-Verzeichnis mit den verschiedenen wp-contentVerzeichnissen verbinde. Das ist großartig, da ich die Dateien nur einmal bearbeiten muss, aber es bricht ein wichtiges Konstrukt ab, um Verweise auf Ressourcen in meinem Plugin zu generieren: __FILE__Bezieht sich auf den physischen Speicherort des Plugins, nicht auf den in wp-content. Wie soll ich das lösen?

Meine Verzeichnisstruktur sieht folgendermaßen aus:

  • /path/to/wordpress/development/dir/
    • plugin-development/
      • monkeyman-rewrite-analyzer/
        • monkeyman-rewrite-analyzer.php
        • js/
          • monkeyman-rewrite-analyzer.js
    • versions/
      • 3.1/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer als Symlink zum obigen Plugin
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer als Symlink zum obigen Plugin
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer als Symlink zum obigen Plugin

Wenn ich die Javascript-Datei in die Warteschlange stellen möchte, sollte ich sie verwenden plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), aber die Verwendung __FILE__hier funktioniert nicht, da der tatsächliche Dateipfad /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.phpnicht /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.phpso ist, dass WordPress den ersten Teil nicht entfernen und eine URL relativ zur WordPress-Installation generieren kann.

Jan Fabry
quelle

Antworten:

6

Das Problem kann teilweise mit einem Plugin behoben werden, das in den plugins_urlFilter eingehängt werden muss.

Alle anderen Fälle, in denen plugin_basename()verwendet wird, wie z. B. register_activation_hook()und co, werden nicht behandelt .

Weitere Informationen: http://core.trac.wordpress.org/ticket/16953

scribu
quelle
Ich glaube, die Verwendung WP_PLUGIN_URLwird nicht empfohlen, da Administratoren den Namen dieses bestimmten Plugin-Verzeichnisses ändern dürfen. Gibt es jedoch auch einen anderen Grund, dies zu vermeiden? Und in der Tat wäre Ihr Ticket eine einfache Lösung.
Jan Fabry
Andererseits. WP_PLUGIN_URL enthält nur die URL, die direkt auf das 'Plugins'-Verzeichnis verweist. Siehe aktualisierte Antwort.
Scribu
@scribu: Aber was ist, wenn meine Plugins darin leben, /external/folder/banana-plugin/aber der Admin mit diesem Verzeichnis verknüpft ist /httpd-root/wp-content/plugins/apple-plugin/? Dann wird es versuchen zu gehen /wp-content/plugins/banana-plugin/, nein? Und ich glaube der Admin sollte frei sein, die einzelnen Plugin-Verzeichnisnamen zu wählen?
Jan Fabry
Darüber werde ich mich nicht mehr mit Ihnen streiten, da ich die Lösung gefunden habe: den Filter 'plugins_url'. Antwort erneut aktualisiert.
Scribu
FWIW diese Lösung kann fehleranfällig sein und hängt von Plugin-Entwicklern ab, die nur plugins_url () verwenden, nachdem alle Plugins geladen wurden. Andernfalls können Sie keinen Filter registrieren, bevor die Funktion aufgerufen wird. Das Akismet-Plugin und viele andere haben dieses Problem.
Jerclarke
3

Momentan benutze ich einen Trick, um den WordPress-relativen Dateispeicherort zu ermitteln: wp_get_active_and_valid_plugins()Gibt die Dateipfade zurück, wp_settings.phpdurchläuft sie und schließt die Dateien ein . Die globale $pluginVariable bezieht sich also auf Ihr aktuelles Plugin (natürlich nur, wenn das Plugin geladen ist, also speichere ich es in einer vorangestellten globalen Variablen):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Da Plugins auch als Must-Use- oder Netzwerk-Plugins geladen werden können und diese Loops andere Variablennamen verwenden , sieht der vollständige Code folgendermaßen aus:

$monkeyman_Rewrite_Analyzer_file = __FILE__;
if ( isset( $mu_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $mu_plugin;
}
if ( isset( $network_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $network_plugin;
}
if ( isset( $plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $plugin;
}

Der Fallback bleibt bestehen. __FILE__Wenn also jemand den Namen der Schleifenvariablen in Zukunft ändert, sollte mein Code für 99% aller Installationen noch funktionieren. Nur mein Entwicklungssetup schlägt fehl und ich kann problemlos eine neue Version veröffentlichen.

Jan Fabry
quelle
Tolle Lösung @Jan. Ich habe etwas Ähnliches implementiert, indem ich die Funktionen und Schleifen aufgerufen habe, weil ich vergessen habe, dass auf diese Variablen zugegriffen werden kann als global. Dank Ihres Beitrags hier wurde mir klar, dass ich es viel einfacher machen könnte. Übrigens teste ich auch, false === strpos( __FILE__, WP_CONTENT_DIR )bevor ich Ihre if-Anweisungen WP_CONTENT_DIRausführe, da ich davon ausgehe, dass das Plugin in dem nicht verlinkt ist. Ich hoffe, das ist eine gültige Logik.
MikeSchinkel
0

Ein Kommentar in Bug 46260 schlägt vor, $_SERVER["SCRIPT_FILENAME"]anstelle von zu verwenden __FILE__. Funktioniert das?

fuxia
quelle
1
Nein, dies ändert sich nicht in den enthaltenen Dateien. Also , wenn index.phpenthält library.php, $_SERVER['SCRIPT_FILENAME']in library.phpnoch sein index.php. Aber danke für den Hinweis auf den Fehler, ich werde ihn genau verfolgen!
Jan Fabry
0

$_SERVER["SCRIPT_FILENAME"]funktioniert, wenn Sie es richtig verwenden. Sie müssen es nur verwenden, um einen Basispfad festzulegen, und dann Ihre Dateien unter Verwendung eines Pfads relativ zu diesem Basispfad einschließen.

So etwas wie:

$plugin_dir = dirname($_SERVER["SCRIPT_FILENAME"]);
$myFile = $plugin_dir."/includes/js/myJavascriptFile.js";

Beachten Sie, dass dies nützlicher ist, wenn Sie noch keinen Zugriff auf die Datei wp-blog-header.php haben (dh wenn Sie eine Ajax-basierte Formularanforderung bearbeiten).

Chad Furman
quelle