Как отключить плагины на фронтэне?
Вопрос
Существует интересный плагин «Plugin Organizer», который позволяет выборочно отключать необходимые плагины на сайте. То есть, плагин в админке продолжает выполнять свои функции (например, отображать поля или что-то еще, что нужно только в админке), но на фронтэне он не загружается.
Существует ли способ сделать это с помощью нескольких строк кода в файле functions.php
?
Я следил за некоторыми плагинами с помощью плагина Query Monitor, который показывал, какие события вызываются во время генерации страницы, и затем отключал эти события с помощью функции remove_action()
.
Но есть плагины, отключить события которых не так просто, и их достаточно много. Поэтому я интересуюсь, возможно, есть готовое решение.
Ответ (Решение)
Это можно сделать, используя хук option_active_plugins
. Вот готовый код для этого. Я не смог найти другие хуки, подходящие для этой задачи.
disable_foldernames = array_flip( $plugins_names );
return $this;
}
/**
* Получает список отключенных плагинов (названия папок).
*/
public function get_disabled(): array {
return $this->disable_foldernames;
}
public function init(): void {
if( ! $this->get_disabled() ){
return;
}
// для мультисайта
add_filter( 'site_option_active_sitewide_plugins', [ $this, 'disable' ] );
// для обычных активированных
add_filter( 'option_active_plugins', [ $this, 'disable' ] );
}
protected function skip_deactivation(): bool {
return (
defined( 'WP_CLI' )
// админ (но не ajax)
|| ( ! defined( 'DOING_AJAX' ) && is_admin() )
// ajax запрос из админ-панели
|| ( defined( 'DOING_AJAX' ) && str_contains( $_SERVER['HTTP_REFERER'], '/wp-admin/' ) )
);
}
/**
* Функция, используемая на хуке option_active_plugins
или site_option_active_sitewide_plugins
.
*/
public function disable( array $active_plugins ): array {
if( $this->skip_deactivation() ){
return $active_plugins;
}
$is_sitewide_option = ( current_filter() === 'site_option_active_sitewide_plugins' );
/**
* Плагины для всего сайта хранятся как перевернутый массив по сравнению с обычными плагинами.
*/
if( $is_sitewide_option ){
$active = $this->remove_deactivated( array_keys( $active_plugins ) );
$active = array_flip( $active );
$active_plugins = array_intersect_key( $active_plugins, $active );
}
else {
$active = $this->remove_deactivated( $active_plugins );
$active_plugins = array_intersect( $active_plugins, $active );
}
return $active_plugins;
}
/**
* Удаляет отключенные плагины из массива.
*
* Вам нужно указать массив с названиями папок плагинов,
* которые вы хотите удалить из массива активных плагинов.
*
* @param array $plugins Массив активных плагинов.
* Пример: [ 'redis-cache/redis-cache.php', 'wp-crontrol/wp-crontrol.php' ]
*
* @return array массив активных плагинов без отключенных.
*/
protected function remove_deactivated( array $plugins ): array {
foreach( $plugins as $index => $basename ){
$folder_name = dirname( $basename );
if( isset( $this->disable_foldernames[ $folder_name ] ) ){
unset( $plugins[ $index ] );
}
}
return $plugins;
}
}
Пример использования
Теперь нам нужно использовать этот класс, указав плагины, которые мы хотим отключить:
Kama_Hard_Disable_Plugins_On_Front::instance()->set_disabled( [
'advanced-custom-fields-pro',
'wp-crontrol',
'tiny-compress-images',
] )->init();
Важно
Код необходимо вставить до загрузки плагинов. Это можно сделать, создав MU (Must-Use) плагин:
- В папке
wp-content
создайте, если ее нет, папкуmu-plugins
. - В созданной папке
mu-plugins
создайте любойphp
файл, пусть это будетdisable-plugins-on-front.php
, и скопируйте туда данный код. - Готово! Плагины, указанные в коде, не будут загружаться на фронтэне.
P.S. Я заглянул внутрь плагина Plugin Organizer — неплохой плагин. Но у него много настроек, он создает таблицы в базе данных без видимых на то причин, и, в целом, он как-то сложен в использовании...