Плагины в каталогах с символическими ссылками?


20

Когда я разрабатываю плагины, я тестирую их на нескольких версиях WordPress, вставляя ссылки на каталог моих плагинов в разные wp-contentкаталоги. Это замечательно, поскольку мне нужно редактировать файлы только один раз, но это нарушает важную конструкцию для генерации ссылок на ресурсы в моем плагине: __FILE__относится к физическому расположению плагина, а не к тому, в котором он находится wp-content. Как мне решить это?

Моя структура каталогов выглядит так:

  • /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 как символическая ссылка на вышеуказанный плагин
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer как символическая ссылка на вышеуказанный плагин
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer как символическая ссылка на вышеуказанный плагин

Если я хочу епдиеий файл Javascript, я должен использовать plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), но при использовании __FILE__здесь не буду работать, так как реальный путь к файлу будет /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, не /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.phpтак WordPress не может лишить первую часть и сгенерирует URL относительно установки WordPress.

Ответы:


6

Эта проблема может быть частично решена с помощью обязательного подключения плагина к plugins_urlфильтру.

Он не будет обрабатывать все другие случаи plugin_basename()использования, такие как register_activation_hook()и co.

Более подробная информация: http://core.trac.wordpress.org/ticket/16953


Я считаю, что использование WP_PLUGIN_URLне рекомендуется, потому что администраторы должны иметь возможность изменять имя каталога этого конкретного плагина, но есть ли еще одна причина, чтобы этого избежать? И действительно, ваш билет будет простым решением.
Ян Фабри

С другой стороны. WP_PLUGIN_URL содержит только URL, который указывает непосредственно на каталог 'plugins'. Смотрите обновленный ответ.
scribu

@scribu: Но что, если мои плагины живут, /external/folder/banana-plugin/но админ ссылается на этот каталог как /httpd-root/wp-content/plugins/apple-plugin/? Тогда он попытается пойти /wp-content/plugins/banana-plugin/, нет? И я считаю, что администратор должен свободно выбирать имена каталогов отдельных плагинов?
Ян Фабри

Я больше не буду с вами спорить об этом, потому что я нашел решение: фильтр 'plugins_url'. Обновленный ответ снова.
scribu

ПОЭТОМУ это решение может быть подвержено ошибкам и зависит от разработчиков плагинов, использующих plugins_url () только после загрузки всех плагинов, в противном случае вы не можете зарегистрировать фильтр до вызова функции. плагин Akismet и многие другие имеют эту проблему.
Джеркларк

3

В настоящее время я использую трюк, чтобы получить местоположение файла, относящееся к WordPress: wp_get_active_and_valid_plugins()возвращает пути к файлам, wp_settings.phpперебирает их и включает в себя файлы . Таким образом, глобальная $pluginпеременная будет ссылаться на ваш текущий плагин (конечно, только когда плагин загружен, поэтому я сохраняю его в префиксной глобальной переменной):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Поскольку плагины также могут быть загружены как обязательные или сетевые плагины, и эти циклы используют другие имена переменных , полный код выглядит следующим образом:

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

Откат остается прежним __FILE__, поэтому, если в будущем кто-то изменит имя переменной цикла, мой код все равно будет работать для 99% всех установок, произойдет сбой только моей настройки разработки, и я с легкостью смогу выпустить новую версию.


Отличное решение @Jan. Я реализовал нечто подобное, вызвав функции и циклы, потому что я забыл, что эти переменные были доступны как global. Благодаря вашему посту я понял, что могу сделать это намного проще. Кстати, я также проверяю false === strpos( __FILE__, WP_CONTENT_DIR )перед выполнением ваших операторов if, потому что я предполагаю, что если плагин находится в, WP_CONTENT_DIRон не является символической ссылкой; Я надеюсь, что это правильная логика.
MikeSchinkel

0

Комментарий в ошибке 46260 предлагает использовать $_SERVER["SCRIPT_FILENAME"]вместо __FILE__. Это работает?


1
Нет, это не изменится во включенных файлах. Так что, если index.phpвключает в себя library.php, $_SERVER['SCRIPT_FILENAME']по - library.phpпрежнему будет index.php. Но спасибо за ссылку на ошибку, буду внимательно следить за ней!
Ян Фабри

0

$_SERVER["SCRIPT_FILENAME"]работает, если вы используете это правильно. Вам просто нужно использовать его, чтобы установить базовый путь, а затем включить ваши файлы, используя путь относительно этого базового пути.

Что-то вроде:

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

Обратите внимание, это более полезно, когда у вас еще нет доступа к wp-blog-header.php (т.е. при обработке запроса формы на основе ajax)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.