У меня есть много плагинов, которые я написал для WordPress, и теперь я хочу адаптировать их к MU.
Каковы соображения / рекомендации / рабочие процессы / функции / ловушки, которые я должен соблюдать / избегать / адаптировать , чтобы «обновить» мои плагины, чтобы поддерживать также многоуровневые установки?
Например, но не ограничиваясь:
$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 ); }
Чтобы добавить меню администрирования, мы проверяем, является ли is_multisite()
и соответственно измените is_multisite()
:
$hook = is_multisite() ? 'network_' : ''; add_action( "{$hook}admin_menu", 'unique_prefix_function_callback' );
// Check for MS dashboard if( is_network_admin() ) $url = network_admin_url( 'plugins.php' ); else $url = admin_url( 'plugins.php' );
Без создания меню сетевого администратора (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!";
Крючки : 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: Мика Эпштейн (ака Ипстену) и Андреа Ренник.