Как проверить активен ли плагин (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' ) )
, но более точно использовать проверку класса с именем плагина, как вы предложили ;-)

Это забавная игра :) Полагаю, вы говорите гипотетически, потому что, насколько мне известно, функции WC не существует. Так что речь идет о повышении осведомленности о function_exists()
. Я не добавил это в ответ, потому что автор вопроса уже упомянул это в своем вопросе. @birgire

На самом деле функция WC()
существует, я просто пытался найти более короткий способ, ссылаясь на нее ;-) Думаю, было бы точнее использовать if( function_exists( 'WC' ) && is_object( WC() ) && is_a( WC(), 'WooCommerce' ) )
;-). Играя дальше, мы также могли бы проверять константы (например, WOOCOMMERCE_VERSION
) или действия (например, did_action( 'woocommerce_loaded' )
) ;-) @ialocin

Действительно, в конечном итоге существует множество возможностей! @birgire

Да, я понял :) Так что WPSE фактически является онлайн-версией »99 способов решить ваши PHP/WordPress проблемы« - мне пришлось придумать это, чтобы сделать официальным :) @birgire

Этот ответ НЕ является надежным. Поскольку ни вопрос, ни ответ явно не указывают контекст, возможно, что WooCommerce активен, но загружается после этого кода. Например, в другом плагине, который случайно загружается раньше. Предложенная проверка класса гораздо надежнее, если дополнительно обернуть ее в хук plugins_loaded. То есть обернуть условие if в функцию check_for_woocommerce()
и зарегистрировать ее с помощью add_action('plugins_loaded', 'check_for_woocommerce');

Многие официальные плагины 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 не активен.';
}
