Как отключить плагин, активированный в сети, только для одного сайта?
Я нахожусь в процессе настройки (потенциально) большой мультисайтовой сети и хочу максимально упростить процесс добавления и настройки сайтов при необходимости. Сейчас я на этапе работы с плагинами.
В мультисайтовой сети WordPress я знаю несколько различных способов активации плагинов:
- Разместить плагин в
/plugins
, активировать его на каждом сайте индивидуально - Разместить плагин в
/plugins
, использовать 'network activate' для активации на всех сайтах - Разместить плагин в
/mu-plugins
, автоматически активируется на каждом сайте
Сейчас я экспериментирую с настройками и хочу активировать Akismet на всех сайтах кроме одного или двух. Я думал, что смогу активировать плагин в сети, а затем отключить его на отдельном сайте, но это оказалось невозможным - если я использую сетевую активацию, то есть только опция 'network deactivate' - которая отключает плагин на всех сайтах сразу.
Существует ли способ использовать удобную функциональность сетевой активации, но при этом сохранить возможность отключать плагины для отдельных сайтов?

Вы можете использовать фильтр site_option_*
.
Например, следующий код отключит Akismet на блоге с ID 2.
add_filter('site_option_active_sitewide_plugins', 'modify_sitewide_plugins');
function modify_sitewide_plugins($value) {
global $current_blog;
if( $current_blog->blog_id == 2 ) {
unset($value['akismet/akismet.php']);
}
return $value;
}

+1 за предоставление чистого решения на уровне PHP, которое решает поставленную проблему без необходимости устанавливать дополнительные плагины — потому что я маниакальный чистюля и люблю Wordpress максимально чистым и без плагинов! :]

Вставил этот код в PHP-файл в mu-plugins
, и он работает как мечта!

Важно отметить, что это не будет работать в теме. Код должен выполниться раньше, поэтому mu-plugins — отличное место для него. Возможно, он заработает как плагин, но я бы рекомендовал использовать mu-plugins, если и это не сработает.

Также этот фильтр выполняется ОЧЕНЬ часто, я бы проверил, установлен ли индекс в массиве перед его удалением. После первого раза он продолжит попытки работать с массивом, в котором этого элемента уже нет. if ( isset($value['akismet/akismet.php']) ) { unset($value['akismet/akismet.php']); }

На самом деле этот метод не работает, если ваш сайт является первым сайтом (ID: 1). В таком случае он не позволит вам выполнить сетевую активацию плагина. С любым другим ID, похоже, всё работает.

Еще немного проб и ошибок. Если деактивировать на сайте с ID = 1, можно активировать их для всей сети, но в настройках сети они не будут отображаться как активированные. Однако на сайтах они должны работать. Сохранение настроек плагинов для всей сети может снова их деактивировать... Не уверен.

Похоже, это больше не работает. Плагин отображается как деактивированный в списке плагинов, но продолжает работать как обычно.

Этот плагин: http://firestats.cc/wiki/WPMUPluginCommander
обходит стандартную активацию для сети и делает это по-своему, а также позволяет отключать плагин для каждого сайта в отдельности.
Обновление: Похоже, этот плагин ломает функциональность плагина sitewide tags, поэтому будьте осторожны перед использованием на рабочей сети.

https://wordpress.org/plugins/plugin-commander/ - URL изменился. Хотя этот плагин не обновлялся уже несколько лет...

Вот что сработало для меня, чтобы отключить плагин для одной конкретной темы в мультисайтовой/мультитемевой установке. Я добавил эти несколько строк в начало файла functions.php моей темы:
/**
* Отключаем плагин fancybox для этой темы, он ломает javascript
*/
function deactivate_plugin_conditional() {
if ( is_plugin_active('fancybox-for-wordpress/fancybox.php') ) {
deactivate_plugins('fancybox-for-wordpress/fancybox.php');
}
}
add_action( 'muplugins_loaded', 'deactivate_plugin_conditional' );

Активные плагины хранятся в таблице wp_[blog_id]_options в поле 'active_plugins' и в таблице wp_[blog_id]_sitemeta в поле 'active_sitewide_plugins'. Это сериализованные поля, поэтому не редактируйте их, если не уверены в своих действиях.
Также обратите внимание на файл wp-admin\plugin.php. Можно написать плагин, который будет делать то, что вам нужно, используя объявленные там функции, такие как is_plugin_active() и activate_plugin().
Однако я предполагаю, что вы владеете PHP, что может быть не так.

Ответы от sorich87 и user33465 не сработали для меня в WordPress 4.3. Добавление этого кода в functions.php темы сработало:
function deactivate_plugin_conditional() {
$deactivated_plugin_name = 'lazy-load/lazy-load.php';
deactivate_plugins($deactivated_plugin_name, false, true);
}
add_action( 'init', 'deactivate_plugin_conditional' );

Я могу подтвердить, что ранее предложенные решения больше не работают, а решение от @gdr действительно работает.

Я могу подтвердить, что решение @sorich87 отлично работает в версии 4.4.1. Видимо, вы используете его не так, как нужно, но оно всё ещё работает. Однако, скорее всего, оно будет работать только в mu-plugins и точно не в теме. Этот вариант будет работать в темах. Но учтите, что это принудительно деактивирует плагин, в отличие от решения @sorich87, которое просто прекращает его принудительное включение на сайте, но всё ещё позволяет использовать его в обычном режиме, если нужно. Мне больше нравится последнее, но оба варианта могут быть полезны.

На самом деле, метод решения @sorich87 не работает, если ваш сайт - первый (ID: 1). В этом случае он не позволит вам активировать плагин для всей сети. С любым другим ID, похоже, всё работает.

Лучший способ управления всеми плагинами в сети Multisite — это "Plugin Commander", который можно найти здесь: http://wordpress.org/extend/plugins/plugin-commander/

Мне удалось отключить плагин, но он всё ещё отображался в панели основного сайта. Единственное решение, которое я нашёл для полного удаления его с основного сайта, — это проверить файл main.php плагина и отключить его в соответствии с этим кодом:
global $current_blog;
// Доступно только для сайта B
if( $current_blog->blog_id == 2 ) {
define( 'AB_PATH', __DIR__ );
include_once 'includes.php';
// Загрузка функционала плагина
AB_Plugin::registerHooks();
is_admin() ? new AB_Backend() : new AB_Frontend();
}
