janfabry
  • 0
Гуру

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

  • 0

Когда я разрабатываю плагины, я тестирую их на нескольких версиях 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.

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

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

    Дополнительная информация: http://core.trac.wordpress.org/ticket/16953.

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

      • 0
    • Напротив. WP_PLUGIN_URL содержит только URL-адрес, который указывает непосредственно на каталог «плагины». Смотрите обновленный ответ.

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

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

      • 0
    • FWIW это решение может быть подвержено ошибкам и зависит от разработчиков плагинов, использующих только plugins_url() после загрузки всех плагинов, иначе вы не сможете зарегистрировать фильтр до вызова функции. плагин Akismet и многие другие имеют эту проблему.

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

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

      • 0
  2. В настоящее время я использую трюк, чтобы получить местоположение файла относительно 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% всех установок, только моя установка для разработки завершится ошибкой, и я смогу легко выпустить новую версию.

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

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

    Что-то типа:

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

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

    • 0

Оставить ответ

You must login to add an answer.