web-dev-qa-db-fra.com

Ajouter un rôle sur le réseau dans plusieurs sites

J'ai essayé d'ajouter de nouveaux rôles et fonctionnalités wordpress, dans une installation multisite, à l'aide du code ci-dessous. Le problème est que cela ne concerne que le site "principal" du multisite et ne se propage pas vers les sous-sites. Je n'ai vraiment rien trouvé dans la documentation qui couvre cela.

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

Ceci est mon expérience.

J'ai dû ajouter un rôle pour chaque site dans Wordpress. J'ai développé une page d'ajout dans un tableau de bord afin que l'administrateur du site puisse ajouter le rôle/les capacités définis par l'utilisateur.

Mais j’ai trouvé que $wp_roles->add_role, add_cap ne fonctionne que sur le sous-site. Alors j'ai fait quelques corrections,

J'ai créé un plugin, le super-administrateur (pas l'administrateur du site mais "l'administrateur") peut "Activer le réseau" dans le tableau de bord

xxx/wp-admin/network/plugins.php

le rôle/les capacités auto-définis ont été enregistrés dans le fichier role.ini, le plug-in peut créer deux tables nommées wp_s_role et wp_s_cap, le rôle/les capacités prédéfinis par l'utilisateur seront insérés dans la table.

$wp_roles->add_role et add_cap peuvent ensuite être insérés sur le réseau et insérer le rôle/les fonctionnalités dans tous les sous-sites.

Mais l'administrateur de sous-site doit ajouter le rôle/les capacités définis par l'utilisateur et le faire fonctionner dans tous les sous-sites. Je crée donc un déclencheur pour

    register_activation_hook(__FILE__, array($s_role, 'install'));
    register_deactivation_hook(__FILE__, array($s_role, 'uninstall'));

Ensuite, la fonction de désinstallation fonctionne, toutes les données des deux tables seront à nouveau sauvegardées dans le fichier role.ini, après quoi la fonction d’installation fonctionnera à nouveau. et tous les rôles/capacités auto-définis ont été ajoutés à tous les sous-sites.

Comme vous le voyez, j'ai créé un déclencheur afin d'ajouter le rôle auto-défini à tous les sous-sites, mais l'efficacité est très faible, le redémarrage du plug-in prend plus de 5 secondes. J'ai donc amélioré les méthodes. Cette fois, lorsque la fonction add_role est terminée, j'ai copié le rôle/les capacités du sous-site dans les autres sous-sites.

Quelques étapes:

  • Dans les sous-sites, lorsque l'administrateur ajoute le rôle, j'utilise $blog_id et $table_prefix pour obtenir le contenu d'une table de sous-site wp_2_options. (Nous avons supposé que le blog_id était 2 et que le préfixe_table était wp).

  • Je sélectionne le 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);), 
    

alors je foreach les blogs et récupère la table de sous-sites. Donc, j'insère le résultat de la sélection dans chaque table de sous-site (wp_n_options) et dans la table principale (wp_options), muhaha, suis-je assez intelligent? :)

La fonction ci-dessous explique comment supprimer les rôles définis par l'utilisateur dans tous les sous-sites. Je pense que cela vous serait utile.

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

Pour le $ site_result, j'ai une autre fonction pour récupérer toutes les informations exactes du site.

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

Je viens de terminer la fonction et cela fonctionne parfaitement. Vous pouvez utiliser s_copy_site_role_cap () pour appeler. La fonction peut copier le rôle dans d'autres rôles de sous-site après avoir ajouté le rôle. Parce que le plugin peut fonctionner sur le site principal ou le sous-site, il existe deux manières de réseau (sous-domaine, sous-chemin). J'ai donc créé une autre fonction pour obtenir le bon nom de blog actuel, afin de pouvoir obtenir le contenu des derniers rôles à partir des informations nom_blog.

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

}

Merci.

1
rainysia

Il suffit de l'ajouter en tant que plug-in 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'
    ]
);

les plugins mu sont chargés par défaut sur tous les sites du réseau.

Si vous souhaitez une solution plus robuste, vous pouvez utiliser mon WordPress Register Roles project.

0
Lucas Bustamante