Cómo adaptar mi plugin a Multisitio?


Tengo muchos plugins que escribí para WordPress, y ahora quiero adaptarlos a MU.
¿Cuáles son las consideraciones / mejores prácticas / flujo de trabajo / funciones / trampas que tengo que seguir / evitar / adaptar para 'actualizar' mis complementos para admitir también instalaciones Multisitio?

Por ejemplo, pero no limitado a:

  • Enqueue scripts / register
  • Archivos incluidos (php, imágenes)
  • Rutas para archivos personalizados subidas
  • $wpdb
  • Activación, desinstalación, desactivación
  • Manejo de páginas específicas de administración

En el Códice, hay a veces comentarios sobre Multisitio en la descripción de una sola función, pero no encontré ninguna página de ventanilla única que aborde este tema.

Author: brasofilo, 2012-12-20

1 answers

En cuanto a preguntar e incluir, las cosas van como normales. La ruta del plugin y la URL son las mismas.

Nunca he tratado con nada relacionado con las rutas de subida en Multisitio y supongo que normalmente WP se encarga de esto.


$wpdb

Hay un fragmento de código comúnmente utilizado para iterar a través de todos los blogs:

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 );

Puede encontrar ejemplos donde se usa restore_current_blog() en lugar de switch_to_blog( $original_blog_id ). Pero he aquí por qué switch es más confiable: restore_current_blog () vs switch_to_blog () .


$blog_id

Ejecutar alguna función o gancho de acuerdo con el ID del blog:

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

O tal vez:

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

Install-Solo Activación de red

Usando el encabezado del pluginNetwork: true (ver: Complemento de muestra) solo mostrará el plugin en la página /wp-admin/network/plugins.php. Con este encabezado en su lugar, podemos usar lo siguiente para bloquear ciertas acciones que deben suceder si el complemento es de red solo.

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 
            )
        );    
}

Desinstalar

Para la Activación (De), depende de cada plugin. Pero, para Desinstalar, este es el código que uso en el archivo 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 );
}

Páginas de administración

1) Agregar una página de administración

Para añadir un menú de administración comprobamos si is_multisite() y modificamos el hook en consecuencia:

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

2) Compruebe si hay un panel de control multisitio y modifique la URL de administración:

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

3) Solución alternativa para mostrar solo los elementos de la interfaz en el sitio principal

Sin crear un Menú de Administración de Red (action hook network_admin_menu), es posible mostrar alguna parte del plugin solo en el sitio principal.

Comencé a incluir algunas funcionalidades multisitio en mi mayor plugin e hice lo siguiente para restringir una parte de las opciones del plugin al sitio principal. Es decir, si el plugin está activado en un sitio secundario, la opción no aparecerá.

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

Mirando esto de nuevo, tal vez pueda ser simplemente: is_multisite() && is_super_admin() && is_main_site(). Tenga en cuenta que los dos últimos devuelven true en sitios individuales.

Y luego: {[42]]}

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

4) Colección de ganchos y funciones útiles.

Ganchos: 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

Funciones: 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

PD: Prefiero enlazar a las respuestas de WordPress que al Códice, ya que habrá más ejemplos de código de trabajo.


Plugin de muestra

Acabo de lanzar un plugin Multisitio, Red Desactivada pero Activa en otro lugar, e hizo un no funciona reanudó la versión anotada a continuación (ver GitHub para la versión completa de trabajo terminada). El plugin terminado es puramente funcional, no hay interfaz de configuración.

Tenga en cuenta que el encabezado del plugin tiene Network: true. Evita que el plugin se muestre en los sitios secundarios.

<?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;
    }
}

Otros recursos-libros electrónicos

No está directamente relacionado con el desarrollo de complementos, pero es esencial para la administración de múltiples sitios.
Los libros electrónicos están escritos por nada menos que dos gigantes de Multisitio: Mika Epstein (también conocido como Ipstenu) y Andrea Rennick.

 68
Author: brasofilo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 12:37:28