Проверить наличие хука действия перед добавлением действий к нему
Я пытаюсь добавить теги ссылок rel=next
и rel=prev
в элемент head шаблона image.php
. У меня установлен плагин Wordpress SEO, и я хочу использовать его хук действия wpseo_head
для этого.
Мне нужно проверить, существует ли хук действия wpseo_head
, прежде чем прикреплять к нему свое действие. Если хук не существует (например, когда плагин не установлен или деактивирован), я хочу использовать wp_head
вместо него.
Я пробовал функцию has_action('wpseo_head')
, но проблема в том, что если к этому хуку не прикреплены функции, она вернет false
, даже если плагин установлен и активирован.
if (has_action('wpseo_head')) {
add_action('wpseo_head', 'ad_add_link_tag_image_head');
} else {
add_action('wp_head', 'ad_add_link_tag_image_head');
}
Как правильно проверить наличие действий, которые могут не существовать в WordPress?
Спасибо.
Вы не можете проверить, будет ли вызван экшен до того, как это произойдет. Даже если к экшену уже были прикреплены колбэки, нет гарантии, что будет использован соответствующий do_action()
.
В вашем случае проверьте с помощью is_plugin_active()
:
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) )
{
// выполнить действие
}
Как упоминает @Barry Carlyon в комментариях, директория может быть переименована. Вы можете проверить, определена ли константа или класс. Но нет 100% решения: константы, функции или классы могут измениться после обновления, или другой плагин уже определяет эти константы. Особенно в этом случае: существует другой плагин WP SEO (я так и не понял, почему он использовал уже занятое название…), и вы можете получить ложное срабатывание.
Есть функция get_file_data()
. Пример псевдокода, не тестировался:
$wpseo_active = FALSE;
$plugins = get_option( 'active_plugins', array() );
foreach ( $plugins as $plugin )
{
if ( FALSE !== stripos( $plugin, 'wp-seo' )
{
$data = get_file_data( WP_PLUGIN_DIR . "$plugin" , array ( 'Author' ) );
if ( 'Joost de Valk' === $data[0] )
{
$wpseo_active = TRUE;
}
}
}
if ( $wpseo_active )
{
// выполнить действие
}
И это все еще не безопасно: названия могут быть изменены.

Лучший способ, чем попытки использовать путь к плагину, — это проверять наличие констант (или классов), которые создает wp-seo, потому что если я установлю wordpress-seo, я могу поместить его не в папку wordpress-seo. Но в этом случае wp_head всегда должен работать для подключения, так как wpseo_head должен вызывать wp_head

Я обнаружил этот ответ, который частично отвечает на вопрос,
// проверка существования фильтра "some_hook_filter"
if( array_key_exists( 'some_hook_filter' , $GLOBALS['wp_filter']) ) {
// ваш код здесь
}
Однако, как отметил оригинальный автор, это не покажет все возможные фильтры в зависимости от времени выполнения кода. Например, фильтры, добавленные темой, не будут видны во время загрузки плагина. В этот массив включены как фильтры, так и действия.
Я нашел список переменных WordPress, хранящихся в массиве $GLOBALS.

Вы не можете надежно проверить, существует ли действие.
Потому что действие существует только в момент вызова do_action или когда кто-то добавляет к нему другие действия.
Таким образом, действие существует только тогда, когда кто-то добавляет к нему другое действие или когда оно вызывается.
И даже если кто-то добавит действия, это не гарантирует, что само действие будет вызвано.
Одна из серьёзных проблем, с которой сталкиваются разработчики плагинов, — это зависимость от действия wp_head, но плохо сделанная тема может вообще не вызывать это действие!

Вам следует использовать функцию has_action
.
Функция
has_action( string $hook_name, callable|false $callback = false )
Эта функция проверяет, зарегистрировано ли какое-либо действие для хука.
Параметры
$hook_name (string) (Обязательный) Название хука действия.
$callback (callable|false) (Необязательный) Проверяемый колбэк. Значение по умолчанию: false
Дополнительная информация
Для получения дополнительной информации посетите сайт WP Code Reference: has_action
