/** * Removes a given group * * @param int $id - Identifier of the group to delete * @param boolean True if the deletion is successful **/ function deleteGroup($group_id) { global $wpdb; if (!$group_id || !UserGroups_tp::getGroup($group_id)) { return false; } do_action('delete_group_rs', $group_id); wpp_cache_flush_group('all_usergroups'); wpp_cache_flush_group('group_members'); wpp_cache_flush_group('usergroups_for_user'); wpp_cache_flush_group('usergroups_for_groups'); wpp_cache_flush_group('usergroups_for_ug'); // first delete all cache entries related to this group if ($group_members = ScoperAdminLib::get_group_members($group_id, COL_ID_RS)) { $id_in = "'" . implode("', '", $group_members) . "'"; $any_user_roles = scoper_get_var("SELECT assignment_id FROM {$wpdb->user2role2object_rs} WHERE role_type = 'rs' AND user_id IN ({$id_in}) LIMIT 1"); foreach ($group_members as $user_id) { wpp_cache_delete($user_id, 'group_membership_for_user'); } } //if ( $got_blogrole = scoper_get_var("SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE scope = 'blog' AND role_type = 'rs' AND group_id = '$group_id' LIMIT 1") ) { scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE scope = 'blog' AND role_type = 'rs' AND group_id = '{$group_id}'"); scoper_flush_roles_cache(BLOG_SCOPE_RS, ROLE_BASIS_GROUPS); if ($any_user_roles) { scoper_flush_roles_cache(BLOG_SCOPE_RS, ROLE_BASIS_USER_AND_GROUPS, $group_members); } //} //if ( $got_taxonomyrole = scoper_get_var("SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE scope = 'term' AND role_type = 'rs' AND group_id = '$group_id' LIMIT 1") ) { scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE scope = 'term' AND role_type = 'rs' AND group_id = '{$group_id}'"); scoper_flush_roles_cache(TERM_SCOPE_RS, ROLE_BASIS_GROUPS); if ($any_user_roles) { scoper_flush_roles_cache(TERM_SCOPE_RS, ROLE_BASIS_USER_AND_GROUPS, $group_members); } //} //if ( $got_objectrole = scoper_get_var("SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE scope = 'object' AND role_type = 'rs' AND group_id = '$group_id' LIMIT 1") ) { scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE scope = 'object' AND role_type = 'rs' AND group_id = '{$group_id}'"); scoper_flush_roles_cache(OBJECT_SCOPE_RS, ROLE_BASIS_GROUPS); if ($any_user_roles) { scoper_flush_roles_cache(OBJECT_SCOPE_RS, ROLE_BASIS_USER_AND_GROUPS, $group_members); } //} //if ( $got_blogrole || $got_taxonomyrole || $got_objectrole ) { scoper_flush_results_cache(ROLE_BASIS_GROUPS); if ($any_user_roles) { scoper_flush_results_cache(ROLE_BASIS_USER_AND_GROUPS, $group_members); } //} $delete = "DELETE FROM {$wpdb->groups_rs} WHERE {$wpdb->groups_id_col}='{$group_id}'"; scoper_query($delete); $delete = "DELETE FROM {$wpdb->user2group_rs} WHERE {$wpdb->user2group_gid_col}='{$group_id}'"; scoper_query($delete); return true; }
function scoper_sync_wproles($user_ids = '', $role_name_arg = '', $blog_id_arg = '') { global $wpdb, $wp_roles; if ($user_ids && !is_array($user_ids)) { $user_ids = array($user_ids); } if (empty($wp_roles->role_objects)) { return; } $wp_rolenames = array_keys($wp_roles->role_objects); $uro_table = $blog_id_arg ? $wpdb->base_prefix . $blog_id_arg . '_' . 'user2role2object_rs' : $wpdb->user2role2object_rs; $groups_table = $wpdb->groups_rs; $user2group_table = $wpdb->user2group_rs; // Delete any role entries for WP roles which were deleted or renamed while Role Scoper was deactivated // (users will be re-synched to new role name) $name_in = "'" . implode("', '", $wp_rolenames) . "'"; $qry = "DELETE FROM {$uro_table} WHERE role_type = 'wp' AND scope = 'blog' AND role_name NOT IN ({$name_in})"; scoper_query($qry); // also sync WP Role metagroups if (!empty($user_ids)) { foreach ($user_ids as $user_id) { wpp_cache_delete($user_id, 'group_membership_for_user'); } } $metagroup_ids = array(); $metagroup_names = array(); $metagroup_descripts = array(); foreach ($wp_rolenames as $role_name) { $metagroup_id = "wp_role_" . trim(substr($role_name, 0, 40)); // if the name is too long and its truncated ID already taken, just exclude it from eligible metagroups if (in_array($metagroup_id, $metagroup_ids)) { continue; } $metagroup_ids[] = $metagroup_id; $metagroup_names["wp_role_{$role_name}"] = sprintf('[WP %s]', $role_name); $metagroup_descripts["wp_role_{$role_name}"] = sprintf('All users with the WordPress %s blog role', $role_name); } // add a metagroup for anonymous users $metagroup_ids[] = "wp_anon"; $metagroup_names["wp_anon"] = '[Anonymous]'; $metagroup_descripts["wp_anon"] = 'Anonymous users (not logged in)'; // add a metagroup for pending revision e-mail notification recipients $metagroup_ids[] = "rv_pending_rev_notice_ed_nr_"; $metagroup_names["rv_pending_rev_notice_ed_nr_"] = '[Pending Revision Monitors]'; $metagroup_descripts["rv_pending_rev_notice_ed_nr_"] = 'Administrators / Publishers to notify (by default) of pending revisions'; // add a metagroup for pending revision e-mail notification recipients $metagroup_ids[] = "rv_scheduled_rev_notice_ed_nr_"; $metagroup_names["rv_scheduled_rev_notice_ed_nr_"] = '[Scheduled Revision Monitors]'; $metagroup_descripts["rv_scheduled_rev_notice_ed_nr_"] = 'Administrators / Publishers to notify when any scheduled revision is published'; $stored_metagroup_ids = array(); $qry = "SELECT {$wpdb->groups_meta_id_col}, {$wpdb->groups_id_col}, {$wpdb->groups_name_col} FROM {$groups_table} WHERE NOT ISNULL({$wpdb->groups_meta_id_col}) AND ( {$wpdb->groups_meta_id_col} != '' )"; // LIKE 'wp_%'"; if ($results = scoper_get_results($qry)) { //rs_errlog("metagroup results: " . serialize($stored_metagroup_ids)'); $delete_metagroup_ids = array(); $update_metagroup_ids = array(); foreach ($results as $row) { if (!in_array($row->{$wpdb->groups_meta_id_col}, $metagroup_ids)) { $delete_metagroup_ids[] = $row->{$wpdb->groups_id_col}; } else { $stored_metagroup_ids[] = $row->{$wpdb->groups_meta_id_col}; if ($row->{$wpdb->groups_name_col} != $metagroup_names[$row->{$wpdb->groups_meta_id_col}]) { $update_metagroup_ids[] = $row->{$wpdb->groups_meta_id_col}; } } } if ($delete_metagroup_ids) { $id_in = "'" . implode("', '", $delete_metagroup_ids) . "'"; scoper_query("DELETE FROM {$groups_table} WHERE {$wpdb->groups_id_col} IN ({$id_in})"); } if ($update_metagroup_ids) { foreach ($update_metagroup_ids as $metagroup_id) { if ($metagroup_id) { scoper_query("UPDATE {$groups_table} SET {$wpdb->groups_name_col} = '{$metagroup_names[$metagroup_id]}', {$wpdb->groups_descript_col} = '{$metagroup_descripts[$metagroup_id]}' WHERE {$wpdb->groups_meta_id_col} = '{$metagroup_id}'"); } } } } if ($insert_metagroup_ids = array_diff($metagroup_ids, $stored_metagroup_ids)) { //rs_errlog("inserting metagroup ids: " . serialize($insert_metagroup_ids)'); foreach ($insert_metagroup_ids as $metagroup_id) { scoper_query("INSERT INTO {$groups_table} ( {$wpdb->groups_meta_id_col}, {$wpdb->groups_name_col}, {$wpdb->groups_descript_col} ) VALUES ( '{$metagroup_id}', '{$metagroup_names[$metagroup_id]}', '{$metagroup_descripts[$metagroup_id]}' )"); //rs_errlog( "INSERT INTO $groups_table ( $wpdb->groups_meta_id_col, $wpdb->groups_name_col, $wpdb->groups_descript_col ) VALUES ( '$metagroup_id', '$metagroup_names[$metagroup_id]', '$metagroup_descripts[$metagroup_id]' )" ); } } if (!empty($delete_metagroup_ids) || !empty($update_metagroup_ids)) { wpp_cache_flush(); // role deletion / rename might affect other cached data or settings, so flush the whole cache } elseif (!empty($insert_group_ids)) { wpp_cache_flush_group('all_usergroups'); wpp_cache_flush_group('usergroups_for_groups'); wpp_cache_flush_group('usergroups_for_user'); wpp_cache_flush_group('usergroups_for_ug'); } // Now step through every WP usermeta record, // synchronizing the user's user2role2object_rs blog role entries with their WP role and custom caps // get each user's WP roles and caps $user_clause = $user_ids ? 'AND user_id IN (' . implode(', ', $user_ids) . ')' : ''; $qry = "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = '{$wpdb->prefix}capabilities' {$user_clause}"; if (!($usermeta = scoper_get_results($qry))) { return; } //rs_errlog("got " . count($usermeta) . " usermeta records"); $wp_rolecaps = array(); foreach ($wp_roles->role_objects as $role_name => $role) { $wp_rolecaps[$role_name] = $role->capabilities; } //rs_errlog(serialize($wp_rolecaps)); $strip_vals = array('', 0, false); $stored_assignments = array('wp' => array(), 'wp_cap' => array()); foreach (array_keys($stored_assignments) as $role_type) { $results = scoper_get_results("SELECT user_id, role_name, assignment_id FROM {$uro_table} WHERE role_type = '{$role_type}' AND user_id > 0 {$user_clause}"); foreach ($results as $key => $row) { $stored_assignments[$role_type][$row->user_id][$row->assignment_id] = $row->role_name; unset($results[$key]); } } foreach (array_keys($usermeta) as $key) { $user_id = $usermeta[$key]->user_id; $user_caps = maybe_unserialize($usermeta[$key]->meta_value); if (empty($user_caps) || !is_array($user_caps)) { continue; } //rs_errlog("user caps: " . serialize($user_caps)); $user_roles = array(); // just in case, strip out any entries with false value $user_caps = array_diff($user_caps, $strip_vals); $user_roles = array('wp' => array(), 'wp_cap' => array()); //Filter out caps that are not role names $user_roles['wp'] = array_intersect(array_keys($user_caps), $wp_rolenames); // Store any custom-assigned caps as single-cap roles // This will be invisible and only used to support the users query filter // With current implementation, the custom cap will only be honored when // users_who_can is called with a single capreq $user_roles['wp_cap'] = array_diff(array_keys($user_caps), $user_roles['wp']); // which roles are already stored in user2role2object_rs table? $stored_roles = array(); $delete_roles = array(); foreach (array_keys($user_roles) as $role_type) { //$results = scoper_get_results("SELECT role_name, assignment_id FROM $uro_table WHERE role_type = '$role_type' AND user_id = '$user_id'"); //if ( $results ) { if (isset($stored_assignments[$role_type][$user_id])) { //rs_errlog("results: " . serialize($results)); foreach ($stored_assignments[$role_type][$user_id] as $assignment_id => $role_name) { // Log stored roles, and delete any roles which user no longer has (possibly because the WP role definition was deleted). // Only Role Scoper's mirroring of WP blog roles is involved here unless Role Scoper was configured and used with a Role Type of "WP". // This also covers any WP role changes made while Role Scoper was deactivated. if (in_array($role_name, $user_roles[$role_type])) { $stored_roles[$role_type][] = $role_name; } else { $delete_roles[] = $assignment_id; } } } else { $stored_roles[$role_type] = array(); } } if ($delete_roles) { $id_in = implode(', ', $delete_roles); scoper_query("DELETE FROM {$uro_table} WHERE assignment_id IN ({$id_in})"); } //rs_errlog("user roles " . serialize($user_roles) '); //rs_errlog("stored roles " . serialize($stored_roles)'); // add any missing roles foreach (array_keys($user_roles) as $role_type) { if (!empty($stored_roles[$role_type])) { $user_roles[$role_type] = array_diff($user_roles[$role_type], $stored_roles[$role_type]); } if (!empty($user_roles[$role_type])) { foreach ($user_roles[$role_type] as $role_name) { //rs_errlog("INSERT INTO $uro_table (user_id, role_name, role_type, scope) VALUES ('$user_id', '$role_name', '$role_type', 'blog')"); scoper_query("INSERT INTO {$uro_table} (user_id, role_name, role_type, scope) VALUES ('{$user_id}', '{$role_name}', '{$role_type}', 'blog')"); } } } } // end foreach WP usermeta // disable orphaned role deletion until we can recreate and eliminate improper deletion as reported in support forum (http://agapetry.net/forum/role-scoper/permissions-reset-randomly-for-a-section-of-pages/page-1/post-3513/) // Delete any role assignments for users which no longer exist //delete_roles_orphaned_from_user(); // Delete any role assignments for WP groups which no longer exist //delete_roles_orphaned_from_group(); // Delete any role assignments for posts/pages which no longer exist //delete_roles_orphaned_from_item( OBJECT_SCOPE_RS, 'post' ); //delete_restrictions_orphaned_from_item( OBJECT_SCOPE_RS, 'post' ); // hold off on this until delete_roles_orphaned_from_item() call has a long, clear track record // Delete any role assignments for categories which no longer exist //delete_roles_orphaned_from_item( TERM_SCOPE_RS, 'category' ); //delete_restrictions_orphaned_from_item( TERM_SCOPE_RS, 'category' ); //rs_errlog("finished syncroles "'); }
function scoper_flush_roles_cache($scope, $role_bases = '', $user_ids = array(), $taxonomies = '') { $scoper_role_types = array('rs', 'wp', 'wp_cap'); if (OBJECT_SCOPE_RS == $scope) { foreach ($scoper_role_types as $role_type) { // this cache stores roles which have been applied for any user or group (currently only uses 'all' key) wpp_cache_flush_group("{$role_type}_applied_object_roles"); } } $user_ids = (array) $user_ids; if (empty($role_bases)) { $role_bases = array(); $role_bases[] = ROLE_BASIS_USER; $role_bases[] = ROLE_BASIS_GROUPS; $role_bases[] = ROLE_BASIS_USER_AND_GROUPS; } $role_bases = (array) $role_bases; foreach ($role_bases as $role_basis) { if (TERM_SCOPE_RS == $scope) { if (!$taxonomies) { global $scoper; if (!empty($scoper->taxonomies)) { $taxonomies = $scoper->taxonomies->get_all_keys(); } if (!$taxonomies) { update_option('scoper_need_cache_flush', true); // if taxonomies could not be determined, invalidate entire cache return; } } $taxonomies = (array) $taxonomies; if ($user_ids) { foreach ($scoper_role_types as $role_type) { foreach ($user_ids as $user_id) { foreach ($taxonomies as $taxonomy) { wpp_cache_delete($user_id, "{$role_type}_term-roles_{$taxonomy}_for_{$role_basis}"); } } } } else { foreach ($scoper_role_types as $role_type) { foreach ($taxonomies as $taxonomy) { wpp_cache_flush_group("{$role_type}_term-roles_{$taxonomy}_for_{$role_basis}"); } } } } else { if ($user_ids) { foreach ($scoper_role_types as $role_type) { foreach ($user_ids as $user_id) { wpp_cache_delete($user_id, "{$role_type}_{$scope}-roles_for_{$role_basis}"); } } } else { foreach ($scoper_role_types as $role_type) { wpp_cache_flush_group("{$role_type}_{$scope}-roles_for_{$role_basis}"); } } } } }