Почему бы не зарегистрировать шорткоды, если панель инструментов is_admin?

10

Я заметил, что некоторые плагины, такие как Contact-form-7 , Nextgen-gallery , возможно, другие, имеют интересную анти-функцию - не регистрировать свои шорткоды, когда is_admin()это правда.

Проблема в том, что если вы хотите сгенерировать какой-то динамический контент (который может иметь шорткод) из ajax и использовать «правильный» способ wp, admin-ajax.php, то невозможно, чтобы WP_ADMIN был истинным. Смотрите первые строки admin-ajax.php:

define( 'DOING_AJAX', true );
if ( ! defined( 'WP_ADMIN' ) ) {
    define( 'WP_ADMIN', true );
}

Теперь, кажется, есть расширения PHP, которые позволят вам отменить определенную константу (хакерскую), или может быть способ возиться с недокументированной системой WP_Screen и $GLOBALS['current_screen']заставить is_admin()функцию возвращать false ?? Наиболее полезный обходной путь, кажется, отправляет на страницу или корень сайта.

Часто ли плагины регистрируют свои шорткоды, когда is_admin()ложно? Если так, я не мог найти никакой документации или причины для этого кроме того, что это может быть преждевременной оптимизацией.

NoBugs
источник

Ответы:

6

Я наблюдал ту же проблему с контактной формой-7 некоторое время назад.

Но обратите внимание, что регистрация шорткодов на основе is_adminосуществляется с помощью did_it_wrong ( см. Ответ gmazzap )

Есть две причины, которые на первый взгляд кажутся законными (и почему они ошибаются):

  1. (Маловероятно) Автор плагина попытался оптимизировать скрипт, чтобы регистрировать шорткоды только тогда, когда они необходимы. В этом случае автор не учел, что шорткод может использоваться в запросах Ajax.

    Неправильно, потому что : эта оптимизация не дает никакого прироста производительности. Он просто добавляет значение в глобальный массив «зарегистрированных коротких кодов».

  2. (Это наиболее вероятный вариант) Автор плагина намеренно отключил поддержку шорткода в Ajax-запросах. С Contact-Form-7 это возможно, потому что формы могут быть установлены на «Отправить через Ajax». Однако для этой функции требуется форма для загрузки дополнительных файлов javascript, которые не загружаются, когда шорткод анализируется с помощью Ajax, а javascript добавляется с помощью enqueue_scripts().

    Автор решил отключить поддержку Ajax, чтобы предотвратить появление отчетов об ошибках, таких как «Не используйте это: форма отображается, но нажатие кнопки« Отправить »не работает. Полная трата времени!»

    Таким образом, пользователь либо увидит гарантированно работающую форму, либо вообще не увидит ее.

    Неправильно, потому что : проверка на is_adminплохую практику здесь. Условие должно проверить, определена ли константа и DOING_AJAXявляется ли она истинной.

Хотя большинство плагинов не используют такого рода условия, те, у кого есть такое ограничение, возможно, имеют его из-за проблем в прошлом.

Когда шорткод просто выполняет какой-либо вывод на страницу, нет никаких причин добавлять какие-либо административные условия. Однако, когда шорткод также ставит в очередь файлы js или css, тогда имеет смысл ограничить использование запросов не-admin / non-ajax.

Philipp
источник
2
Незарегистрированный шорткод практически не влияет на производительность. Регистрация просто добавляет переменную в массив. Что может быть медленным, так это выполнять шорткод, а не регистрировать его. Так что, если это оптимизация производительности, это провал. Если автор плагина хочет отключить шорткод для ajax, проверка is_adminвыполняется с помощью do_it_wrong, в WP есть гораздо лучшие способы проверки запросов на ajax. Наконец, если плагин ставит в очередь js / css, если он делает это хорошо (используя 'wp_enqueue_scripts'действие), это не повлияет на страницы администратора, потому что эта ловушка не запускается на страницах администратора.
gmazzap
@gmazzap Спасибо за отзыв, я полностью согласен! Я обновил свой ответ и добавил ваш вклад, чтобы было ясно, что это плохая практика.
Филипп
Я не думаю, что # 2 вероятно, так как enqueue_scripts не должен влиять на the_contentвызовы и вызовы admin-ajax.
NoBugs
3

На самом деле, нет причин не регистрировать шорткоды на админа.

Если автор плагина хочет отключить форму плагина Ajax, он должен сделать

if (defined('DOING_AJAX') && DOING_AJAX)

вместо проверки это админ.

Обратите внимание, что в будущем возможно, что Shortcake будет встроен в ядро, потому что это «Feature Plugin».

Если это произойдет, шорткод, не определенный в admin, не будет работать с ним. Это дает вам еще одно подтверждение того, что нет причин не регистрировать шорткоды для администратора: даже разработчики ядра работают над вещами, которые требуют шорткоды, доступные для администратора.

Тем не менее, у вас есть возможности:

  1. свяжитесь с автором плагинов и посмотрите, смогут ли они исправить это поведение
  2. попытаться найти решение самостоятельно

Что касается # 2, на самом деле существуют библиотеки, которые могут заставить is_adminбыть правдой. Они хакерские, и я бы никогда не использовал их в производстве.

Примером является Пэчворк .

Используя его, вы можете переопределить любую пользовательскую функцию PHP.

В плагине MU вы можете сделать (полностью НЕПРОВЕРЕНО):

add_action('muplugins_loaded', function() {
  if ( defined('DOING_AJAX') && DOING_AJAX ) {
     require 'path/to/Patchwork.php';
     Patchwork\replace("is_admin", function() {
        return FALSE;
     });
  }
});

Это сделает is_admin()возврат ложным при запросах ajax.

Однако, как уже было сказано, это довольно хакерский и повлияет на поведение других плагинов (и ядра) с непредсказуемым эффектом.

Еще одна вещь, которую вы можете сделать, это зарегистрировать обработчик шорткода плагина на запросы администратора.

Например, если код плагина:

if (! is_admin()) {
  add_shortcode( 'shortcode' , 'plugin_shortcode_handler' );
}

тогда вы можете написать другой плагин, который делает:

if (is_admin()) {
  add_shortcode( 'shortcode' , 'plugin_shortcode_handler' );
}

Таким образом, шорткод будет добавлен в обоих случаях.

Это может или не может работать в одиночку в зависимости от другого кода плагина, но нет общего ответа на это.

Gmazzap
источник
Вы также можете add_shortcode('shortcode', array('their-class', 'their-function') )или подобное.
NoBugs
@nobugs конечно :)
gmazzap
Или лучший «обходной путь», просто отправьте сообщение в корень сайта или на страницу, что по иронии судьбы делает NextGen.
NoBugs