Как адаптировать мой плагин к Multisite?

У меня есть много плагинов, которые я написал для WordPress, и теперь я хочу адаптировать их к MU.
Каковы соображения / рекомендации / рабочие процессы / функции / ловушки, которые я должен соблюдать / избегать / адаптировать , чтобы «обновить» мои плагины, чтобы поддерживать также многоуровневые установки?

Например, но не ограничиваясь:

  • Скрипты ввода / регистрации
  • Входящие файлы (php, images)
  • Пути для загрузки пользовательских файлов
  • $wpdb
  • Активация, деинсталляция, деактивация
  • Обработка отдельных страниц администратора

В Codex иногда упоминается о Multisite в описании одной функции, но я не нашел ни одной страницы, которая затрагивает эту тему.

Что касается enqueuing и в том числе, все идет как обычно. Путь и URL-адрес плагина совпадают.

Я никогда не рассматривал ничего, связанное с путями загрузки в Multisite, и я предполагаю, что обычно WP заботится об этом.


$wpdb

Существует часто используемый фрагмент для повторения всех блогов:

 global $wpdb; $blogs = $wpdb->get_results(" SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0' "); $original_blog_id = get_current_blog_id(); foreach ( $blogs as $blog_id ) { switch_to_blog( $blog_id->blog_id ); // do something in the blog, like: // update_option() } switch_to_blog( $original_blog_id ); 

Вы можете найти примеры, где вместо switch_to_blog( $original_blog_id ) используется switch_to_blog( $original_blog_id ) . Но вот почему switch более надежный: restore_current_blog () vs switch_to_blog () .


$blog_id

Выполните некоторую функцию или зацепите в соответствии с идентификатором блога:

 global $blog_id; if( $blog_id != 3 ) add_image_size( 'category-thumb', 300, 9999 ); //300 pixels wide (and unlimited height) 

Или, может быть:

 if( 'child.multisite.com' === $_SERVER['SERVER_NAME'] || 'domain-mapped-child.com' === $_SERVER['SERVER_NAME'] ) { // do_something(); } 

Установка – только сетевая активация

Использование заголовка плагина Network: true (см. Пример плагина ) будет отображать только плагин на странице /wp-admin/network/plugins.php . С помощью этого заголовка мы можем использовать следующее, чтобы блокировать определенные действия, которые должны произойти, если плагин является только сетью.

 function my_plugin_block_something() { $plugin = plugin_basename( __FILE__ ); if( !is_network_only_plugin( $plugin ) ) wp_die( 'Sorry, this action is meant for Network only', 'Network only', array( 'response' => 500, 'back_link' => true ) ); } 

Удалить

Для активации (De) это зависит от каждого плагина. Но, для деинсталляции, это код, который я использую в файле uninstall.php :

 <?php /** * Uninstall plugin - Single and Multisite * Source: https://wordpress.stackexchange.com/q/80350/12615 */ // Make sure that we are uninstalling if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) exit(); // Leave no trail $option_name = 'HardCodedOptionName'; if ( !is_multisite() ) { delete_option( $option_name ); } else { global $wpdb; $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ); $original_blog_id = get_current_blog_id(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); delete_option( $option_name ); } switch_to_blog( $original_blog_id ); } 

Страницы администратора

1) Добавление страницы администратора

Чтобы добавить меню администрирования, мы проверяем, является ли is_multisite() и соответственно измените is_multisite() :

 $hook = is_multisite() ? 'network_' : ''; add_action( "{$hook}admin_menu", 'unique_prefix_function_callback' ); 

2) Проверьте панель управления Multisite и измените URL-адрес администратора:

 // Check for MS dashboard if( is_network_admin() ) $url = network_admin_url( 'plugins.php' ); else $url = admin_url( 'plugins.php' ); 

3) Временное решение для отображения элементов интерфейса только на основном сайте

Без создания меню сетевого администратора (action hook network_admin_menu ) можно отобразить часть плагина только на главном сайте .

Я включил некоторые функции Multisite в свой самый большой плагин и сделал следующее, чтобы ограничить одну часть параметров плагина на основном сайте. Значение, если плагин активирован на подсайте, опция не будет отображаться .

 $this->multisite = is_multisite() ? ( is_super_admin() && is_main_site() ) // must meet this 2 conditions to be "our multisite" : false; 

Глядя на это снова, возможно, это может быть просто: is_multisite() && is_super_admin() && is_main_site() . Обратите внимание, что последние два возвращают true в отдельных сайтах.

А потом:

 if( $this->multisite ) echo "Something only for the main site, ie: Super Admin!"; 

4) Сбор полезных крючков и функций.

Крючки : network_admin_menu , wpmu_new_blog , signup_blogform , wpmu_blogs_columns , manage_sites_custom_column , manage_blogs_custom_column , wp_dashboard_setup , network_admin_notices , site_option_active_sitewide_plugins , {$hook}admin_menu

Функции : is_multisite , is_super_admin is_main_site , get_blogs_of_user , update_blog_option , is_network_admin , network_admin_url , is_network_only_plugin

PS: Я скорее связываюсь с ответами WordPress, чем с Codex, так как будет больше примеров рабочего кода.


Пример плагина

Я только что перевернул плагин Multisite, Network Deactivated, но активно в другом месте , и сделал нерабочую возобновленную аннотированную версию ниже (см. GitHub для готовой полной рабочей версии). Готовый плагин является чисто функциональным, нет интерфейса настроек.

Обратите внимание, что заголовок плагина имеет Network: true . Это предотвращает показ плагина на дочерних сайтах .

 <?php /** * Plugin Name: Network Deactivated but Active Elsewhere * Network: true */ /** * Start the plugin only if in Admin side and if site is Multisite */ if( is_admin() && is_multisite() ) { add_action( 'plugins_loaded', array ( B5F_Blog_Active_Plugins_Multisite::get_instance(), 'plugin_setup' ) ); } /** * Based on Plugin Class Demo - https://gist.github.com/toscho/3804204 */ class B5F_Blog_Active_Plugins_Multisite { protected static $instance = NULL; public $blogs = array(); public $plugin_url = ''; public $plugin_path = ''; public static function get_instance() { NULL === self::$instance and self::$instance = new self; return self::$instance; } /** * Plugin URL and Path work as normal */ public function plugin_setup() { $this->plugin_url = plugins_url( '/', __FILE__ ); $this->plugin_path = plugin_dir_path( __FILE__ ); add_action( 'load-plugins.php', array( $this, 'load_blogs' ) ); } public function __construct() {} public function load_blogs() { /** * Using "is_network" property from $current_screen global variable. * Run only in /wp-admin/network/plugins.php */ global $current_screen; if( !$current_screen->is_network ) return; /** * A couple of Multisite-only filter hooks and a regular one. */ add_action( 'network_admin_plugin_action_links', array( $this, 'list_plugins' ), 10, 4 ); add_filter( 'views_plugins-network', // 'views_{$current_screen->id}' array( $this, 'inactive_views' ), 10, 1 ); add_action( 'admin_print_scripts', array( $this, 'enqueue') ); /** * This query is quite frequent to retrieve all blog IDs. */ global $wpdb; $this->blogs = $wpdb->get_results( " SELECT blog_id, domain FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0' " ); } /** * Enqueue script and style normally. */ public function enqueue() { wp_enqueue_script( 'ndbae-js', $this->plugin_url . '/ndbae.js', array(), false, true ); wp_enqueue_style( 'ndbae-css', $this->plugin_url . '/ndbae.css' ); } /** * Check if plugin is active in any blog * Using Multisite function get_blog_option */ private function get_network_plugins_active( $plug ) { $active_in_blogs = array(); foreach( $this->blogs as $blog ) { $the_plugs = get_blog_option( $blog['blog_id'], 'active_plugins' ); foreach( $the_plugs as $value ) { if( $value == $plug ) $active_in_blogs[] = $blog['domain']; } } return $active_in_blogs; } } 

Другие ресурсы – электронные книги

Не имеет прямого отношения к разработке плагинов, но является существенным для управления Multisite.
Электронные книги написаны не менее чем двумя гигантами Multisite: Мика Эпштейн (ака Ипстену) и Андреа Ренник.

  • WordPress Multisite 101
  • WordPress Multisite 110