在多站点中跨网络添加角色

时间:2013-06-08 作者:Anthony F. Camilleri

我一直在尝试使用下面的代码在多站点安装中添加新的wordpress角色和功能。问题是,它只适用于多站点的“主”站点,而不适用于子站点。我在文档中还没有找到任何关于这方面的内容。

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

2 个回复
最合适的回答,由SO网友:rainysia 整理而成

这是我的经验。

我必须在Wordpress中为每个站点添加角色,我在dashboard中开发了一个添加页面,以便站点管理员可以添加自定义角色/功能。

但我发现$wp_roles->add_role, add_cap 仅适用于子网站。所以我做了一些修复,

我制作了一个插件,超级管理员(不是站点管理员,而是“管理员”)可以在仪表板中“网络激活”

xxx/wp管理员/网络/插件。php

自定义角色/功能保存在role.ini 文件中,插件可以创建两个名为wp_s_rolewp_s_cap, 预定义的角色/功能将插入表中。

然后$wp_roles->add_role和add_cap 可以跨网络并将角色/功能插入所有子网站。

但是子网站管理员必须添加自定义角色/功能,并使其在所有子网站中都能工作,因此我为

    register_activation_hook(__FILE__, array($s_role, \'install\'));
    register_deactivation_hook(__FILE__, array($s_role, \'uninstall\'));
然后卸载功能工作,所有两个表的数据将保存到role.ini 然后,安装功能将再次工作。并将所有自定义角色/功能添加到所有子网站中。

如您所见,我做了一个触发器,以便将自定义角色添加到所有子网站中,但有效性非常低,插件重新启动需要5秒钟以上。因此,我改进了这些方法,这次,当add\\u role功能完成时,我将子网站角色/功能复制到其他子网站中。

一些步骤:

在子网站中,当管理员添加角色时,我使用$blog_id$table_prefix 获取子网站表wp_2_options 目录(我们假设blog\\u id为2 table\\u前缀为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\\u结果,我有另一个函数来获取所有准确的站点信息。

/**
 * 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\\u copy\\u site\\u role\\u cap()调用。添加\\u角色后,该功能可以将角色复制到其他子网站角色中。由于该插件可能在主站点或子站点中工作,因此在网络中有两种方式(子域、子路径),因此我创建了另一个函数来获取正确的当前blog\\u名称,以便从blog\\u名称信息中获取最新的角色内容。

/**
 * 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];
        }
    }

}
谢谢。

SO网友:Lucas Bustamante

只需将其添加为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插件。

如果你想要一个更强大的解决方案,你可以使用我的WordPress Register Roles 项目

结束

相关推荐

Broken image multisite

我有两个wp站点(多站点),配置如下:1个#(主站点)主页:http://www.mysite。com公司上载路径:wp内容/上载文件上传Url:http://www.mysite。com/wp内容/上载2#主页:http://www.mysite。com/en/上载路径:wp内容/博客。目录/2/文件文件上传Url:http://www.mysite。com/en/文件我的htaccess具有以下功能:# BEGIN WordPress RewriteEngine On RewriteB