wake-up-neo.net

Hinzufügen einer Rolle im Netzwerk für mehrere Standorte

Ich habe versucht, mithilfe des folgenden Codes neue WordPress-Rollen und -Funktionen in einer Installation mit mehreren Standorten hinzuzufügen. Das Problem ist, dass es nur für die Hauptwebsite der Multisite gilt und nicht für die Unterwebsites. Ich habe in der Dokumentation, die das behandelt, nicht wirklich etwas gefunden.

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

Das ist meine Erfahrung.

Ich musste für jede Site in Wordpress eine Rolle hinzufügen. Ich entwickelte eine Seite zum Hinzufügen im Dashboard, damit der Site-Administrator die selbst definierten Rollen/Funktionen hinzufügen kann.

Aber ich fand den $wp_roles->add_role, add_cap funktioniert nur auf der Unterwebsite. Also habe ich etwas korrigiert,

Ich habe ein Plugin erstellt, mit dem der Superadministrator (nicht der Site-Administrator, sondern der "Administrator") im Dashboard "Netzwerk aktivieren" kann

xxx/wp-admin/network/plugins.php

die selbstdefinierten Rollen/Funktionen wurden in der Datei role.ini gespeichert. Das Plugin kann zwei Tabellen mit den Namen wp_s_role und wp_s_cap erstellen. Die vordefinierten Rollen/Funktionen werden in die Tabelle eingefügt.

Dann können der $wp_roles->add_role und der add_cap netzwerkweit die Rolle/Funktionen für alle Unterwebsites einfügen.

Der Administrator der Unterwebsite muss jedoch die selbstdefinierten Rollen/Funktionen hinzufügen und sicherstellen, dass sie auf allen Unterwebsites funktionieren. Daher erstelle ich einen Auslöser für

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

Dann funktioniert die Deinstallationsfunktion, alle zwei Tabellendaten werden wieder in der Datei role.ini gespeichert, danach funktioniert die Installationsfunktion wieder. Alle selbst definierten Rollen/Funktionen wurden allen Unterwebsites hinzugefügt.

Wie Sie sehen, habe ich einen Trigger erstellt, um die selbstdefinierte Rolle in alle Unterwebsites einzufügen, aber die Effektivität ist sehr gering. Der Neustart des Plugins dauert länger als 5 Sekunden. Deshalb habe ich die Methoden verbessert. Dieses Mal, wenn die Funktion add_role ausgeführt wurde, habe ich die Unterwebsiterolle/-fähigkeiten in die anderen Unterwebsites kopiert.

Einige Schritte:

  • Wenn der Administrator auf Unterwebsites die Rolle hinzufügt, verwende ich $blog_id und $table_prefix, um den Inhalt einer Unterwebsitetabelle wp_2_options abzurufen. (Wir haben angenommen, die blog_id ist 2 und das table_prefix ist wp).

  • Ich wähle den 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);), 
    

dann foreach ich die blogs und bekomme die subsite tabelle. Also füge ich das Auswahlergebnis in jede Unterwebsitetabelle (wp_n_options) und die Haupttabelle (wp_options) ein, haha, bin ich schlau genug? :)

Mit der folgenden Funktion können Sie die selbst definierten Rollen in allen Unterwebsites entfernen. Ich denke, es wäre hilfreich für dich.

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

Für das $ site_result habe ich eine andere Funktion, um alle genauen Site-Informationen abzurufen.

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

Ich habe gerade die Funktion beendet und es funktioniert einwandfrei. Sie können s_copy_site_role_cap () zum Aufrufen verwenden. Die Funktion kann die Rolle nach add_role in andere Rollen der Unterwebsite kopieren. Da das Plugin möglicherweise auf der Haupt- oder Unterwebsite funktioniert, gibt es im Netzwerk zwei Möglichkeiten (Unterdomäne, Unterpfad). Daher habe ich eine andere Funktion erstellt, um den richtigen aktuellen Blognamen zu ermitteln, damit ich die neuesten Rolleninhalte aus den Blognamen-Informationen abrufen kann.

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

}

Vielen Dank.

1
rainysia

Füge es einfach als Mu-Plugin hinzu:

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 werden standardmäßig auf allen Sites im Netzwerk geladen.

Wenn Sie eine robustere Lösung wünschen, können Sie mein WordPress Register Roles project verwenden.

0