Pengaya di direktori yang tertaut?

20

Ketika saya mengembangkan plugin saya mengujinya di beberapa versi WordPress dengan menghubungkan direktori plugin saya di direktori yang berbeda wp-content. Ini bagus karena saya hanya perlu mengedit file satu kali, tetapi merusak konstruksi penting untuk menghasilkan referensi ke sumber daya di plugin saya: __FILE__merujuk ke lokasi plugin fisik, bukan yang ada di wp-content. Bagaimana saya mengatasi ini?

Struktur direktori saya terlihat seperti ini:

  • /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 sebagai symlink ke plugin di atas
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer sebagai symlink ke plugin di atas
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer sebagai symlink ke plugin di atas

Jika saya ingin membuat file Javascript, saya harus menggunakan plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), tetapi menggunakan di __FILE__sini tidak akan berfungsi, karena jalur file yang sebenarnya adalah /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, tidak /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, sehingga WordPress tidak dapat menghapus bagian pertama dan menghasilkan URL relatif terhadap instalasi WordPress.

Jan Fabry
sumber

Jawaban:

6

Masalahnya sebagian dapat diatasi dengan pengait plugin yang harus digunakan ke plugins_urlfilter.

Itu tidak akan menangani semua kasus lain di mana plugin_basename()digunakan, seperti register_activation_hook()dan co.

Info lebih lanjut: http://core.trac.wordpress.org/ticket/16953

scribu
sumber
Saya percaya menggunakan WP_PLUGIN_URLtidak dianjurkan karena administrator harus diizinkan untuk mengubah nama direktori plugin khusus ini, tetapi apakah ada alasan lain untuk menghindarinya? Dan memang, tiket Anda akan menjadi solusi sederhana.
Jan Fabry
Di sisi lain. WP_PLUGIN_URL hanya berisi URL yang menunjuk langsung ke direktori 'plugins'. Lihat jawaban yang diperbarui.
scribu
@scribu: Tapi bagaimana jika plugin saya hidup /external/folder/banana-plugin/tetapi admin menautkan ke direktori itu /httpd-root/wp-content/plugins/apple-plugin/? Maka itu akan mencoba untuk pergi /wp-content/plugins/banana-plugin/, bukan? Dan saya yakin admin harus bebas memilih masing-masing nama direktori plugin?
Jan Fabry
Saya tidak akan berdebat dengan Anda tentang itu lagi, karena saya menemukan solusinya: filter 'plugins_url'. Jawaban diperbarui lagi.
scribu
FWIW solusi ini bisa rentan kesalahan dan tergantung pada plugin devs hanya menggunakan plugins_url () setelah semua plugin dimuat, jika tidak Anda tidak dapat mendaftarkan filter sebelum fungsi dipanggil. plugin Akismet dan banyak lainnya memiliki masalah itu.
jerclarke
3

Saat ini saya menggunakan trik untuk mendapatkan lokasi file relatif-WordPress: wp_get_active_and_valid_plugins()mengembalikan path file, dan wp_settings.phploop atas mereka dan termasuk file . Jadi $pluginvariabel global akan merujuk ke plugin Anda saat ini (tentu saja hanya ketika plugin dimuat, jadi saya menyimpannya dalam variabel global yang diawali):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Karena plugin juga dapat dimuat sebagai plugin yang harus digunakan atau jaringan dan loop ini menggunakan nama variabel lain , kode lengkapnya terlihat seperti ini:

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

Fallback masih __FILE__, jadi jika seseorang mengubah nama variabel loop di masa depan kode saya harus tetap bekerja untuk 99% dari semua instalasi, hanya pengaturan pengembangan saya akan gagal dan saya dapat merilis versi baru dengan mudah.

Jan Fabry
sumber
Solusi hebat @Jan. Saya menerapkan sesuatu yang serupa dengan memanggil fungsi dan perulangan karena saya lupa variabel-variabel itu dapat diakses global. Berkat posting Anda di sini, saya sadar saya bisa membuatnya lebih sederhana. BTW, saya juga menguji false === strpos( __FILE__, WP_CONTENT_DIR )sebelum menjalankan pernyataan if Anda karena saya berasumsi jika plugin ada di WP_CONTENT_DIRdalamnya tidak terhubung; Saya berharap itu logika yang valid.
MikeSchinkel
0

Komentar dalam bug 46260 menyarankan untuk digunakan $_SERVER["SCRIPT_FILENAME"]sebagai ganti __FILE__. Apakah ini berhasil?

fuxia
sumber
1
Tidak, ini tidak mengubah file yang disertakan. Jadi jika index.phptermasuk library.php, $_SERVER['SCRIPT_FILENAME']di library.phpkehendak masih index.php. Tapi terima kasih untuk referensi bug, saya akan mengikutinya dengan cermat!
Jan Fabry
0

$_SERVER["SCRIPT_FILENAME"]berfungsi jika Anda menggunakannya dengan benar. Anda hanya perlu menggunakannya untuk menetapkan jalur dasar, dan kemudian memasukkan file Anda menggunakan jalur relatif ke jalur dasar itu.

Sesuatu seperti:

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

Catatan, ini lebih berguna ketika Anda belum memiliki akses ke wp-blog-header.php (yaitu dalam memproses permintaan formulir berbasis ajax)

Chad Furman
sumber