以下のコードを使用して、マルチサイトインストールで新しいワードプレスの役割と機能を追加しようとしています。問題は、それがマルチサイトの「メイン」サイトにのみ適用され、サブサイトに伝播しないことです。私はこれをカバーしているドキュメントには何も実際にはありません。
function civicrm_wp_set_capabilities() {
global $wp_roles;
if (!isset($wp_roles)) {
$wp_roles = new WP_Roles();
}
//Minimum capabilities (Civicrm permissions) arrays
$min_capabilities = array(
'access_civimail_subscribe_unsubscribe_pages' => 1,
'access_all_custom_data' => 1,
'access_uploaded_files' => 1,
'make_online_contributions' => 1,
'profile_create' => 1,
'profile_edit' => 1,
'profile_view' => 1,
'register_for_events' => 1,
'view_event_info' => 1,
'sign_civicrm_petition' => 1,
'view_public_civimail_content' => 1,
);
// Assign the Minimum capabilities (Civicrm permissions) to all WP roles
foreach ( $wp_roles->role_names as $role => $name ) {
$roleObj = $wp_roles->get_role($role);
foreach ($min_capabilities as $capability_name => $capability_value) {
$roleObj->add_cap($capability_name);
}
}
//Add the 'anonymous_user' role with minimum capabilities.
if (!in_array('anonymous_user' , $wp_roles->roles)) {
add_role(
'anonymous_user',
'Anonymous User',
$min_capabilities
);
}
}
これが私の経験です。
私はWordpressで各サイトの役割を追加しなければなりませんでした、私はサイト管理者が自己定義された役割/機能を追加できるようにダッシュボードで追加ページを開発しました。
しかし、私は$wp_roles->add_role
を見つけました、add_cap
はサブサイトだけを働きます。だから私はいくつかの修正をしました、
私はプラグインを作りました、スーパー管理者(サイト管理者ではなく、「管理者」)がダッシュボードで「ネットワークを有効にする」ことができます
xxx/wp-admin/network/plugins.php
自己定義されたロール/機能はrole.ini
ファイルに保存され、プラグインはwp_s_role
とwp_s_cap
という名前の2つのテーブルを作成できます。事前定義されたロール/機能はテーブルに挿入されます。
それから$wp_roles->add_rol
eとadd_cap
はネットワークを越えて、すべてのサブサイトにロール/機能を挿入することができます。
しかし、サブサイト管理者は、自己定義された役割/機能を追加し、それをすべてのサブサイトで機能させる必要があります。
register_activation_hook(__FILE__, array($s_role, 'install'));
register_deactivation_hook(__FILE__, array($s_role, 'uninstall'));
その後、アンインストール機能が働き、2つのテーブルデータすべてが再びrole.ini
ファイルに保存され、その後、インストール機能が再び働きます。そしてすべての自己定義された役割/能力はすべてのサブサイトに追加されました。
お分かりのように、私は自己定義された役割をすべてのサブサイトに追加するためにトリガーを作成しましたが、効果は非常に低く、プラグインの再起動には5秒以上かかります。メソッドを改良しました。今度は、add_role関数が実行されたときに、サブサイトの役割/機能を他のサブサイトにコピーしました。
いくつかのステップ:
サブサイトでは、管理者がロールを追加するときに、$blog_id
および$table_prefix
を使用してサブサイトテーブルwp_2_options
の内容を取得します。 (blog_idを2
、table_prefixをwp
としました。).
私はoption_name=wp_2_user_roles
を選びます
result($wpdb->get_row("select `option_value` from `wp_2_options` where `option_name`='wp_2_user_roles'", ARRAY_A);),
それから私はブログをforeach
し、サブサイトテーブルを取得します。それで、選択結果を各サブサイトテーブル(wp_n_options
)とメインテーブル(wp_options
)に挿入します。 :)
以下の機能は、すべてのサブサイトから自己定義ロールを削除する方法です。私はあなたに役立つと思います。
public function reset_subsite_role_cap()
{
//select * from `wp_options` where `option_name` = 'wp_user_roles';
//select * from `wp_options` where `option_name` = 'wp_backup_user_roles';
//select * from `wp_3_options` where `option_name` = 'wp_3_user_roles';
//select * from `wp_4_options` where `option_name` = 'wp_4_user_roles';
//select * from `wp_5_options` where `option_name` = 'wp_5_user_roles';
global $wpdb;
$sql = "select * from ".$wpdb->blogs;
$multisite_info = $wpdb->get_results($sql, ARRAY_A);
$site_result = array();
if (!empty($multisite_info) && is_array($multisite_info)) {
foreach ($multisite_info as $k => $v) {
$site_result[$v['blog_id']] = trim($v['path'], '/');
}
}
global $table_prefix;
$tp_arr = explode('_', $table_prefix);
$table_arr = array();
foreach ($site_result as $blog_id => $site_name) {
if ($blog_id !== 1) {
$table_arr[$tp_arr[0].'_'.$blog_id.'_options'] = $tp_arr[0].'_'.$blog_id.'_user_roles';
} else {
$table_arr[$tp_arr[0].'_options'] = $tp_arr[0].'_user_roles';
}
}
// get the backup user roles.
$backup_roles_result = $wpdb->get_row("select `option_value` from `".$tp_arr[0]."_options` where `option_name`='wp_backup_user_roles'", ARRAY_A);
// clean the others role cap
if (isset($table_arr) && is_array($table_arr)) {
foreach ($table_arr as $table_role_cap_name => $table_role_cap_filed) {
$wpdb->update(
$table_role_cap_name,
array('option_value' => $backup_roles_result['option_value']),
array('option_name' => $table_role_cap_filed)
);
}
}
return true;
}
$ site_resultには、すべての正確なサイト情報を取得する機能があります。
/**
* Get the all site info.
*
* @param integer $id BlogID.
*
* @return array array('blog_id' => 'path', '1' => 'printsolv', '2' => 'govsolv')
*/
public function s_get_multisite_info($id = null)
{
global $wpdb;
$where = '1=1';
if (isset($id)) {
$sql = "select * from ".$wpdb->blogs." where `blog_id`="."'".$id."'";
} else {
$sql = "select * from ".$wpdb->blogs." where 1=1 ";
}
$multisite_info = $wpdb->get_results($sql, ARRAY_A);
$result = array();
if (!empty($multisite_info) && is_array($multisite_info)) {
// clean the path, > 1 means not http://site_name/theme.php but http://site_name/path_name/theme.php
if (isset($id)) {
$site_info = $wpdb->get_row("select * from ".$wpdb->site." where `id`="."'".$multisite_info[0]['site_id']."'", ARRAY_A);
} else {
$site_info = $wpdb->get_row("select * from ".$wpdb->site, ARRAY_A);
}
$site_path_status = false; // path= /
if (isset($site_info['path']) && strlen(trim($site_info['path'], '/')) > 1 ) {
// site have path./xxx/
$site_path_status = true;
}
foreach ($multisite_info as $k => $v) {
if (isset($site_info['domain']) && $site_info['domain'] == $v['domain']) {
if ($site_path_status == true) {
$result[$v['blog_id']] = trim(substr($v['path'], strlen(trim($site_info['path'], '/')) + 1), '/');
} else {
$result[$v['blog_id']] = trim($v['path'], '/');
}
}
}
}
return $result;
}
私は機能を終えたところで、それは完璧に動作します。 s_copy_site_role_cap()を使って呼び出すことができます。この関数は、add_roleを追加した後で、その役割を他のサブサイトの役割にコピーできます。プラグインはメインサイトでもサブサイトでも動作するので、ネットワークには2つの方法(サブドメイン、サブパス)があるので、正しい現在のblog_nameを取得するための別の関数を作り、blog_name情報から最新のロールコンテンツを取得できます。
/**
* Copy the subsite role/caps to all subsites and main site..
*
* @param string $subsite_name SubSite Name.
*
* @return boolean.
*/
public function s_copy_site_role_cap()
{
global $wpdb;
// Get all site info
$multisite_info = $this->s_get_multisite_info();
global $table_prefix;
$tp_arr = explode('_', $table_prefix);
// Get all site wp_x_options table. and table filed.
$table_arr = array();
foreach ($multisite_info as $blog_id => $site_name) {
if ($blog_id !== 1) {
$table_arr[$tp_arr[0].'_'.$blog_id.'_options'] = $tp_arr[0].'_'.$blog_id.'_user_roles';
} else {
$table_arr[$tp_arr[0].'_options'] = $tp_arr[0].'_user_roles';
}
}
// select the blog id by blog name.
$subsite_name = $this->s_get_dashboard_site_name();
$subsite_id = array_search($subsite_name, $multisite_info);
if ($subsite_id === false) {
return false;
}
$current_site_table_pre = $tp_arr[0].'_'.$subsite_id;
// get the current subsite roles.
$subsite_roles = $wpdb->get_row("select `option_value` from `".$current_site_table_pre."_options` where `option_name`='".$current_site_table_pre."_user_roles'", ARRAY_A);
if (isset($table_arr) && is_array($table_arr)) {
foreach ($table_arr as $table_role_cap_name => $table_role_cap_filed) {
if ($table_role_cap_name != $current_site_table_pre.'_options') {
$wpdb->update(
$table_role_cap_name,
array('option_value' => $subsite_roles['option_value']),
array('option_name' => $table_role_cap_filed)
);
}
}
}
return true;
}
/**
* Get dashboard site name.
*
* @return string. SiteName
*/
public function s_get_dashboard_site_name()
{
$dashboard_url = admin_url();
//$dashboard_url = "http://xxx/wp-admin/";
//$dashboard_url = "http://subsite_name.xxx/wp-admin/";
//$dashboard_url = "http://xxx/subsite_name/wp-admin/";
// get main site name.
$site_name = get_current_site()->domain;
$parse_url = parse_url($dashboard_url);
if (!is_subdomain_install()) {
// base path http://xxx/wp-admin/
// subsite path http://xxx/subsite_name/wp-admin/
if ($parse_url['path'] == "/wp-admin/") {
return $site_name;
} else {
$tmp_url = explode("/", trim($parse_url['path'], "/"));
return $tmp_url[0];
}
} else {
// base domain http://xxx/wp-admin/
// subsite domain http://subsite_name.xxx/wp-admin/
if ($parse_url['Host'] == $site_name) {
return $site_name;
} else {
$tmp_url = explode(".", $parse_url['Host']);
return $tmp_url[0];
}
}
}
ありがとう。
Muプラグインとして追加するだけです。
wp-content/mu-plugins/roles.php
/**
* Plugin name: Multisite user roles
*/
add_role(
'example_role',
__('Example Role'),
[
'read',
'edit_post',
'publish_post',
'delete_post'
]
);
mu-pluginsはデフォルトでネットワーク上のすべてのサイトにロードされます。
もっと堅牢なソリューションが欲しいなら、私の WordPress登録ロール プロジェクトを使うことができます。