Как отключить плагины на фронт-энде?
Вопрос: Есть интересный плагин "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 - неплохой вроде плаг. Но там чет много настроек, таблицы в БД создает зачем-то, в общем, навороченный он какой-то...