Wtyczki w dowiązanych katalogach?

20

Kiedy tworzę wtyczki, testuję je na wielu wersjach WordPressa poprzez symlinkowanie mojego katalogu wtyczek w różnych wp-contentkatalogach. Jest to świetne, ponieważ muszę edytować pliki tylko raz, ale łamie ważną konstrukcję, aby generować odwołania do zasobów w mojej wtyczce: __FILE__odnosi się do fizycznej lokalizacji wtyczki, a nie tej w wp-content. Jak mam to rozwiązać?

Moja struktura katalogów wygląda następująco:

  • /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 jako dowiązanie symboliczne do powyższej wtyczki
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer jako dowiązanie symboliczne do powyższej wtyczki
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer jako dowiązanie symboliczne do powyższej wtyczki

Jeśli chcę enqueue plik JavaScript, powinno się używać plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), ale przy użyciu __FILE__tutaj nie będzie działać, ponieważ rzeczywista ścieżka do pliku będzie /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, nie /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, tak nie może pozbawić WordPress pierwszą część na zewnątrz i wygenerować URL w stosunku do instalacji WordPressa.

Jan Fabry
źródło

Odpowiedzi:

6

Problem można częściowo rozwiązać za pomocą wtyczki, której należy użyć, podłączonej do plugins_url filtra.

Nie obsługuje wszystkich innych przypadków, w których plugin_basename()jest używany, takich jakregister_activation_hook() i co.

Więcej informacji: http://core.trac.wordpress.org/ticket/16953

scribu
źródło
Uważam, że używanie WP_PLUGIN_URLnie jest zalecane, ponieważ administratorzy powinni mieć możliwość zmiany nazwy katalogu tej konkretnej wtyczki, ale czy jest też inny powód, aby tego unikać? I rzeczywiście, twój bilet byłby prostym rozwiązaniem.
Jan Fabry,
Przeciwnie. WP_PLUGIN_URL zawiera tylko adres URL prowadzący bezpośrednio do katalogu „wtyczek”. Zobacz zaktualizowaną odpowiedź.
scribu,
@scribu: A co, jeśli moje wtyczki będą dostępne, /external/folder/banana-plugin/ale administrator odsyła do tego katalogu jako /httpd-root/wp-content/plugins/apple-plugin/? Potem spróbuje się udać /wp-content/plugins/banana-plugin/, nie? I wierzę, że administrator powinien mieć swobodę wyboru nazw poszczególnych katalogów wtyczek?
Jan Fabry,
Nie będę się z tobą o to kłócić, ponieważ znalazłem rozwiązanie: filtr „plugins_url”. Zaktualizowana odpowiedź ponownie.
scribu
FWIW to rozwiązanie może być podatne na błędy i zależy od programistów wtyczek używających plugins_url () po załadowaniu wszystkich wtyczek, w przeciwnym razie nie można zarejestrować filtra przed wywołaniem funkcji. wtyczka Akismet i wiele innych ma ten problem.
jerclarke
3

Obecnie używam sztuczki, aby uzyskać lokalizację pliku zależną od WordPress: wp_get_active_and_valid_plugins()zwraca ścieżki do plików, wp_settings.phpzapętla je i dołącza pliki . Zatem $pluginzmienna globalna będzie odnosić się do twojej bieżącej wtyczki (oczywiście tylko wtedy, gdy wtyczka jest załadowana, więc zapisuję ją w zmiennej globalnej z prefiksem):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Ponieważ wtyczki można również ładować jako wtyczki do użycia lub wtyczki sieciowe, a te pętle używają innych nazw zmiennych , pełny kod wygląda następująco:

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

Powrót jest nadal możliwy __FILE__, więc jeśli ktoś zmieni nazwę zmiennej pętli w przyszłości, mój kod powinien nadal działać dla 99% wszystkich instalacji, tylko moja konfiguracja programowania zakończy się niepowodzeniem i mogę z łatwością wydać nową wersję.

Jan Fabry
źródło
Świetne rozwiązanie @ Jan. Zaimplementowałem coś podobnego, wywołując funkcje i zapętlając, ponieważ zapomniałem, że te zmienne były dostępne jako global. Dzięki postowi tutaj zrozumiałem, że mogę to znacznie uprościć. BTW, testuję również false === strpos( __FILE__, WP_CONTENT_DIR )przed uruchomieniem instrukcji if, ponieważ zakładam, że wtyczka jest w WP_CONTENT_DIRniej, nie jest dowiązaniem symbolicznym; Mam nadzieję, że to poprawna logika.
MikeSchinkel,
0

Komentarz w błędzie 46260 sugeruje użycie $_SERVER["SCRIPT_FILENAME"]zamiast __FILE__. czy to działa?

fuxia
źródło
1
Nie, to nie zmienia się w dołączonych plikach. Więc jeśli index.phpzawiera library.php, $_SERVER['SCRIPT_FILENAME']w library.phpnadal będzie index.php. Ale dzięki za odniesienie do błędu, będę go dokładnie śledził!
Jan Fabry,
0

$_SERVER["SCRIPT_FILENAME"]działa, jeśli używasz go poprawnie. Wystarczy użyć go, aby ustawić ścieżkę bazową, a następnie dołączyć pliki, używając ścieżki względem tej ścieżki bazowej.

Coś jak:

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

Uwaga: jest to bardziej przydatne, gdy nie masz jeszcze dostępu do wp-blog-header.php (tj. Podczas przetwarzania żądania formularza opartego na ajax)

Chad Furman
źródło