gpt4 book ai didi

php - 如何使我的插件适应多站点?

转载 作者:IT王子 更新时间:2023-10-29 01:20:31 26 4
gpt4 key购买 nike

我有很多为 WordPress 编写的插件,现在我想将它们适配到 MU。
为了“升级”我的插件以支持多站点安装,我必须遵循/避免/适应哪些注意事项/最佳实践/工作流程/功能/陷阱

例如但不限于:

  • 排队脚本/注册
  • 包含文件(php、图片)
  • 自定义文件上传路径
  • $wpdb
  • 激活、卸载、停用
  • 管理特定页面

在Codex中,有时在单个功能描述中有关于Multisite的评论,但我没有找到任何一站式页面来解决这个问题。

最佳答案

至于入队和包含,一切正常。插件路径和 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 );

您可能会发现使用 restore_current_blog() 代替 switch_to_blog( $original_blog_id ) 的示例。但这就是 switch 更可靠的原因:restore_current_blog() vs switch_to_blog() .


$blog_id

根据博客ID执行一些函数或钩子(Hook):

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 (参见:Sample Plugin) 只会在页面 /wp 中显示插件-admin/network/plugins.php。有了这个 header ,我们可以使用以下内容来阻止某些在插件仅网络时会发生的操作。

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

卸载

对于(取消)激活,这取决于每个插件。但是,对于卸载,这是我在文件 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() 并相应地修改钩子(Hook):

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

2) 检查多站点仪表板并修改管理 URL:

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

3) 仅在主站点中显示界面元素的解决方法

如果不创建网络管理菜单(操作 Hook network_admin_menu),则可以仅在主站点中显示插件的某些部分

我开始在我的 biggest plugin 中包含一些多站点功能。并执行以下操作以将插件选项的一部分限制在主站点。意思是,如果插件在子站点中被激活,选项不会显示

$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, i.e.: Super Admin!";

4) 有用的钩子(Hook)和函数的集合。

Hook :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 Answers 而不是 Codex,因为会有更多的工作代码示例。


示例插件

我刚刚推出了一个多站点插件,Network Deactivated but Active Elsewhere ,并在下面制作了一个非工作恢复带注释的版本(有关完成的完整工作版本,请参见 GitHub)。完成的插件是纯功能性的,没有设置界面。

请注意,插件 header 具有 Network: true。它阻止插件 showing in child sites .

<?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 的两大巨头:Mika Epstein(又名 Ipstenu)和 Andrea Rennick。

关于php - 如何使我的插件适应多站点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13960514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com