Как отключить плагины на фронт-энде?
Вопрос: Есть интересный плагин "Plugin Organizer", который позволяет выборочно отключать нужные плагины на сайте. т.е. плагин в админке будет продолжать выполнять свои функции (например, отображать поля или что-то еще, что нужно только в админке), во фронтенде он загружаться не будет.
Есть ли способ обойтись парой строк кода в файле functions.php для этого?
Я посмотрел некоторые плагины через плагин Query Monitor, он выдал, какие события срабатывают при генерации страницы, а затем отключил эти события с помощью remove_action().
Но есть плагины, которые не так просто отключить, и их слишком много. Вот я и интересуюсь, может есть готовый вариант кода.
Ответ (решение):
Это можно сделать прицепившись на хук: option_active_plugins. Вот готовый код для этого. Других хуков, чтобы это сделать я не нашел...
GitHub<?php
/**
* Disables the connection of the specified plugins at the front and ajax requests.
*
* @version 2.0
* @author Kama (wp-kama.ru)
*/
class Kama_Hard_Disable_Plugins_On_Front {
/**
* To be deactivated plugins folder names.
* The names placed in array index. The array value means nothing.
*/
protected array $disable_foldernames = [];
public static function instance(): self {
static $instance;
$instance || $instance = new self();
return $instance;
}
/**
* @param array $plugins_names List of plugins you want to deactivate on front.
* Specify plugin`s folder name.
*/
public function set_disabled( array $plugins_names = [] ): self {
/**
* Allows you to filter plugins slugs (folder names) that will be disabled.
*
* @param string[] $plugins_names Array of folder names.
*/
$plugins_names = apply_filters( 'hard_disable_plugins__filter_names', $plugins_names );
$this->disable_foldernames = array_flip( $plugins_names );
return $this;
}
/**
* Gets currently disabled plugins slugs (folder names) list.
*/
public function get_disabled(): array {
return $this->disable_foldernames;
}
public function init(): void {
if( ! $this->get_disabled() ){
return;
}
// for multisite
add_filter( 'site_option_active_sitewide_plugins', [ $this, 'disable' ] );
// for regular activated
add_filter( 'option_active_plugins', [ $this, 'disable' ] );
}
protected function skip_deactivation(): bool {
return (
defined( 'WP_CLI' )
// admin (but not ajax)
|| ( ! defined( 'DOING_AJAX' ) && is_admin() )
// ajax request from admin-panel
|| ( defined( 'DOING_AJAX' ) && str_contains( $_SERVER['HTTP_REFERER'], '/wp-admin/' ) )
);
}
/**
* The function is used on the hook `option_active_plugins` or `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' );
/**
* Sitewide plugins stored as flipped array compared with regular 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;
}
/**
* Deletes the disabled plug-ins from the array.
*
* You must specify an array with the names of the folders of the plugins,
* which you want to remove from the array of active plugins.
*
* @param array $plugins Array of active plugins basenames.
* Example: [ 0 => redis-cache/redis-cache.php, 1 => wp-crontrol/wp-crontrol.php ]
*
* @return array array of active plugins without deactivated.
*/
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 плагин, т.е. делаешь так:
- В папке
wp-content, создаешь, если её там нет, папкуmu-plugins. - В созданной папке
mu-pluginsсоздаешь любой php файл, пусть будетdisable-plugins-on-front.phpи копируешь этот код в этот файл. - Готово! указанные в коде плагины не будут загружаться во фронте...
П.С. Глянул в код Plugin Organizer - неплохой вроде плаг. Но там чет много настроек, таблицы в БД создает зачем-то, в общем, навороченный...