Как проверить активен ли плагин (WooCommerce)?
Я пытаюсь изменить шапку и подвал моих страниц WooCommerce. У меня есть условие if, которое должно работать для страниц магазина и корзины WooCommerce, но оно не работает. Если я изменяю PHP после оператора if, ничего не меняется. Но если я изменяю PHP в операторе else, это работает:
Это не работает:
<?php if (function_exists('woocommerce')): ?>
<?php if (is_cart() || is_shop()): ?>
<?php get_template_part('inc/CHANGE'); ?>
<?php endif ?>
<?php else: ?>
<?php get_template_part('inc/page-header'); ?>
<?php endif ?>
Это работает:
<?php if (function_exists('woocommerce')): ?>
<?php if (is_cart() || is_shop()): ?>
<?php get_template_part('inc/page-header'); ?>
<?php endif ?>
<?php else: ?>
<?php get_template_part('inc/CHANGE'); ?>
<?php endif ?>
Я думаю, что функция WooCommerce может быть неправильно определена, потому что это тоже работает:
<?php if (is_cart() || is_shop()): ?>
<?php get_template_part('inc/header-shop'); ?>
<?php else: ?>
<?php get_template_part('inc/page-header'); ?>
<?php endif ?>
Ваша правка натолкнула меня на эту идею, действительно, нет функции под названием "woocommerce", но есть класс »WooCommerce«. Важно учитывать, что проверка должна выполняться достаточно поздно, чтобы плагины успели инициализироваться, иначе — очевидно — класс не будет существовать, и проверка вернет false. Поэтому ваша проверка должна выглядеть так:
if ( class_exists( 'WooCommerce' ) ) {
// какой-то код
} else {
// другой код
}
На странице документации WooCommerce »Создание плагина для WooCommerce« я нашел следующее:
/**
* Проверяет, активен ли WooCommerce
**/
if (
in_array(
'woocommerce/woocommerce.php',
apply_filters( 'active_plugins', get_option( 'active_plugins' ) )
)
) {
// Ваш код плагина здесь
}
Лично я считаю, что это не так надежно, как проверка наличия класса. По очевидным причинам: что, если имя папки/файла отличается, но плагин должен работать корректно. Кроме того, если вы делаете так, то есть API-функция, которую можно использовать, логично названная is_plugin_active(). Но поскольку она обычно доступна только на страницах админки, вам нужно сделать её доступной, подключив файл wp-admin/includes/plugin.php, где находится эта функция. Используя её, проверка будет выглядеть так:
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
// какой-то код
} else {
// другой код
}
Это может быть забавной "вечеринкой" игр, поиск других способов ;-) Позвольте мне присоединиться с if( function_exists( 'WC' ) ), но более точно использовать проверку класса с именем плагина, как вы предложили ;-)
birgire
Это забавная игра :) Полагаю, вы говорите гипотетически, потому что, насколько мне известно, функции WC не существует. Так что речь идет о повышении осведомленности о function_exists(). Я не добавил это в ответ, потому что автор вопроса уже упомянул это в своем вопросе. @birgire
Nicolai Grossherr
На самом деле функция WC() существует, я просто пытался найти более короткий способ, ссылаясь на нее ;-) Думаю, было бы точнее использовать if( function_exists( 'WC' ) && is_object( WC() ) && is_a( WC(), 'WooCommerce' ) ) ;-). Играя дальше, мы также могли бы проверять константы (например, WOOCOMMERCE_VERSION) или действия (например, did_action( 'woocommerce_loaded' )) ;-) @ialocin
birgire
Действительно, в конечном итоге существует множество возможностей! @birgire
Nicolai Grossherr
Да, я понял :) Так что WPSE фактически является онлайн-версией »99 способов решить ваши PHP/WordPress проблемы« - мне пришлось придумать это, чтобы сделать официальным :) @birgire
Nicolai Grossherr
Этот ответ НЕ является надежным. Поскольку ни вопрос, ни ответ явно не указывают контекст, возможно, что WooCommerce активен, но загружается после этого кода. Например, в другом плагине, который случайно загружается раньше. Предложенная проверка класса гораздо надежнее, если дополнительно обернуть ее в хук plugins_loaded. То есть обернуть условие if в функцию check_for_woocommerce() и зарегистрировать ее с помощью add_action('plugins_loaded', 'check_for_woocommerce');
kontur
Многие официальные плагины WooCommerce решают эту проблему, проверяя константу WC_VERSION, которую WooCommerce определяет после загрузки всех плагинов. Упрощённый код:
add_action('plugins_loaded', 'check_for_woocommerce');
function check_for_woocommerce() {
if (!defined('WC_VERSION')) {
// WooCommerce не установлен :(
} else {
var_dump("Установлен WooCommerce версии", WC_VERSION);
}
}
Дополнительным преимуществом является возможность использовать функцию PHP version_compare() для проверки, установлена ли достаточно новая версия WooCommerce (если ваш код требует определённых возможностей), так как константа WC_VERSION подходит для этого.
Для улучшения предложенных решений мы используем следующий код:
$all_plugins = apply_filters('active_plugins', get_option('active_plugins'));
if (stripos(implode($all_plugins), 'woocommerce.php')) {
// Здесь разместите код вашего плагина
}
Это предотвращает две проблемы:
- Установка WooCommerce в нестандартном каталоге — в этом случае
if ( in_array( 'woocommerce/woocommerce.php', apply_filters(...не сработает. - Вызов этой проверки до загрузки WooCommerce — в этом случае
if ( class_exists( 'WooCommerce' ) ) { .. }не сработает.
Я нашел эту полезную информацию в документации для разработчиков WooCommerce.
Вы можете просто вызвать функцию is_woocommerce_active() в файле вашего плагина.
Пример
if ( ! is_woocommerce_active() )
{
add_action( 'admin_notices', 'WC_Subscriptions::woocommerce_inactive_notice' );
return;
}
is_woocommerce_active определяется следующим образом согласно документации WooCommerce
/**
* Проверяет, активирован ли WooCommerce
*/
if ( ! function_exists( 'is_woocommerce_activated' ) ) {
function is_woocommerce_activated() {
if ( class_exists( 'woocommerce' ) ) { return true; } else { return false; }
}
}
Решение, которое я использую в 2021 году:
add_action( 'admin_init', 'my_plugin_check_if_woocommerce_installed' );
function my_plugin_check_if_woocommerce_installed() {
// Если WooCommerce НЕ установлен, деактивируем плагин
if ( is_admin() && current_user_can( 'activate_plugins') && !is_plugin_active( 'woocommerce/woocommerce.php') ) {
// Показываем уведомление об ошибке с возможностью закрыть
add_action( 'admin_notices', 'my_plugin_woocommerce_check_notice' );
// Деактивируем текущий плагин
deactivate_plugins( plugin_basename( __FILE__) );
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
}
// Если WooCommerce установлен, активируем плагин и выполняем дальнейшие действия
elseif ( is_admin() && is_plugin_active( 'woocommerce/woocommerce.php') ) {
// Выполняем дальнейшие действия здесь
}
}
// Показываем уведомление об ошибке, если WooCommerce отсутствует
function my_plugin_woocommerce_check_notice() {
?>
<div class="alert alert-danger notice is-dismissible">
<p>Извините, но для работы этого плагина требуется WooCommerce.
Пожалуйста, убедитесь, что WooCommerce установлен и активирован.
</p>
</div>
<?php
}
Код выполняется на хуке 'admin_init', а не на 'register_activation_hook', потому что ему необходимо, чтобы WooCommerce был загружен и успешно обнаружен. Если WooCommerce НЕ обнаружен, код выполняет следующее:
a) Показывает администратору уведомление об ошибке с возможностью закрыть, сообщая об отсутствии WooCommerce. Это более аккуратный подход по сравнению с использованием 'wp_die'.
b) Автоматически деактивирует ваш пользовательский плагин.
Если WooCommerce обнаружен, вы можете продолжить добавлять пункты меню и выполнять другие необходимые действия.
ВАЖНЫЕ ЗАМЕЧАНИЯ:
Приведенное решение работает в предположении, что основное имя плагина WooCommerce и его главный файл остаются "woocommerce". Если это изменится в будущем, проверки перестанут работать. Поэтому для корректной работы кода в таком случае потребуется обновить имя директории WooCommerce и имя главного файла в условиях
ifиelseif.Обратите внимание, что если и WooCommerce, и ваш плагин успешно установлены и работают, то при деактивации WooCommerce по любой причине ваш плагин также будет автоматически деактивирован.
Это для поддержки мультисайтов.
$is_active = in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) );
if ( is_multisite() ) {
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
include_once ABSPATH . 'wp-admin/includes/plugin.php';
}
if ( function_exists( 'is_plugin_active_for_network' ) ) {
$is_active = is_plugin_active_for_network( 'woocommerce/woocommerce.php' ) || $is_active;
}
}
if ( $is_active ) {
}
Вы можете обернуть ваш плагин в проверку, установлен и активен ли WooCommerce или нет:
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) {
echo 'WooCommerce активен.';
} else {
echo 'WooCommerce не активен.';
}