function flt_wp_dropdown_users($wp_output) { // just filter Post Author dropdown if (!strpos($wp_output, "name='post_author_override'")) { return $wp_output; } // this is meant to filter the post author selection if (!is_admin()) { return $wp_output; } // if (even after our blogcap tinkering) the author list is already locked due to insufficient blog-wide caps, don't mess if (!($pos = strpos($wp_output, '<option'))) { return $wp_output; } if (!strpos($wp_output, '<option', $pos + 1)) { return $wp_output; } global $wpdb, $scoper; $last_query = $wpdb->last_query; if (!($object_type = cr_find_post_type())) { return $wp_output; } if (!($post_type_obj = get_post_type_object($object_type))) { return $wp_output; } global $current_user; $is_ngg_edit = strpos($_SERVER['REQUEST_URI'], 'nggallery-manage-gallery'); if (!$is_ngg_edit) { $src_name = 'post'; $object_id = scoper_get_object_id('post', $object_type); // only modify the default authors list if current user has Editor role for the current post/page $have_cap = cr_user_can($post_type_obj->cap->edit_others_posts, $object_id, 0, array('require_full_object_role' => true)); } else { $src_name = 'ngg_gallery'; $object_id = $_REQUEST['gid']; $have_cap = !empty($current_user->allcaps[$post_type_obj->cap->edit_others_posts]); // $post_type_obj defaults to 'post' type on NGG Manage Gallery page } //if ( ! $have_cap ) // return $wp_output; $orderpos = strpos($last_query, 'ORDER BY'); $orderby = $orderpos ? substr($last_query, $orderpos) : ''; if (!strpos($orderby, 'display_name')) { // sanity check in case the last_query buffer gets messed up $orderby = ''; } $id_in = $id_not_in = $show_option_all = $show_option_none = ''; $pos = strpos($last_query, 'AND ID IN('); if ($pos) { $pos_close = strpos($last_query, ')', $pos); if ($pos_close) { $id_in = substr($last_query, $pos, $pos_close - $pos + 1); } } $pos = strpos($last_query, 'AND ID NOT IN('); if ($pos) { $pos_close = strpos($last_query, ')', $pos); if ($pos_close) { $id_not_in = substr($last_query, $pos, $pos_close - $pos + 1); } } $search = "<option value='0'>"; $pos = strpos($wp_output, $search . __awp('Any')); if ($pos) { $pos_close = strpos($wp_output, '</option>', $pos); if ($pos_close) { $show_option_all = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = "<option value='-1'>"; $pos = strpos($wp_output, $search . __awp('None')); if ($pos) { $pos_close = strpos($wp_output, '</option>', $pos); if ($pos_close) { $show_option_none = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = "<select name='"; $pos = strpos($wp_output, $search); if (false !== $pos) { $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $name = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = " id='"; $multi = !strpos($wp_output, $search); // beginning with WP 2.7, some users dropdowns lack id attribute $search = " class='"; $pos = strpos($wp_output, $search); if ($pos) { $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $class = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = " selected='selected'"; $pos = strpos($wp_output, $search); if ($pos) { $search = "<option value='"; $str_left = substr($wp_output, 0, $pos); $pos = strrpos($str_left, $search); //back up to previous option tag $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $selected = substr($wp_output, $pos + strlen($search), $pos_close - ($pos + strlen($search))); } } if (empty($selected)) { $selected = $current_user->ID; } // precaution prevents default-selection of non-current user // Role Scoper filter application $where = "{$id_in} {$id_not_in}"; $args = array(); $args['where'] = $where; $args['orderby'] = $orderby; if ($object_id > 0) { if ($current_author = $scoper->data_sources->get_from_db('owner', $src_name, $object_id)) { $force_user_id = $current_author; } } else { $force_user_id = $current_user->ID; } if ($have_cap) { if ($force_user_id) { $args['preserve_or_clause'] = " uro.user_id = '{$force_user_id}'"; } $users = $scoper->users_who_can($post_type_obj->cap->edit_posts, COLS_ID_DISPLAYNAME_RS, 'post', $object_id, $args); } else { $display_name = $wpdb->get_var("SELECT display_name FROM {$wpdb->users} WHERE ID = '{$force_user_id}'"); $users = array((object) array('ID' => $force_user_id, 'display_name' => $display_name)); } if (empty($users)) { // sanity check: users_who_can should always return Administrators if ($admin_roles = awp_administrator_roles()) { $users = scoper_get_results("SELECT DISTINCT ID, display_name FROM {$wpdb->users} INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.user_id = {$wpdb->users}.ID AND uro.scope = 'blog' AND uro.role_type = 'wp' AND uro.role_name IN ('" . implode("','", $admin_roles) . "')"); } else { return $wp_output; } // the user data must be messed up } $show = 'display_name'; // no way to back this out // ----------- begin wp_dropdown_users code copy (from WP 2.7) ------------- $id = $multi ? "" : "id='{$name}'"; $output = "<select name='{$name}' {$id} class='{$class}'>\n"; if ($show_option_all) { $output .= "\t<option value='0'>{$show_option_all}</option>\n"; } if ($show_option_none) { $output .= "\t<option value='-1'>{$show_option_none}</option>\n"; } foreach ((array) $users as $user) { $user->ID = (int) $user->ID; $_selected = $user->ID == $selected ? " selected='selected'" : ''; $display = !empty($user->{$show}) ? $user->{$show} : '(' . $user->user_login . ')'; $output .= "\t<option value='{$user->ID}'{$_selected}>" . esc_html($display) . "</option>\n"; } $output .= "</select>"; // ----------- end wp_dropdown_users code copy (from WP 2.7) ------------- return $output; }
function users_queryroles($reqd_caps, $src_name, $object_id = '', $args = array()) { $defaults = array('roles' => '', 'user' => '', 'querying_groups' => 0, 'use_term_roles' => 1, 'use_blog_roles' => 1, 'skip_object_roles' => false, 'ignore_strict_terms' => 0, 'object_terms' => array(), 'object_type' => '', 'objscope_roles' => '', 'any_object' => false); $args = array_merge($defaults, (array) $args); extract($args); $src = $this->scoper->data_sources->get($src_name); // ---- The following default argument generation is included to support potential direct usage of this function // (not needed for flt_users_where call ----------------- // Treat empty reqd_caps array as an error if (empty($reqd_caps)) { return array(); } $reqd_caps = (array) $reqd_caps; // Calling function may save us a little work if it has already made this call if (!$roles) { if (!($roles = $this->scoper->role_defs->qualify_roles($reqd_caps))) { return array(); } } else { $roles = (array) $roles; } // this set of reqd_caps cannot be satisfied by any role if (!$reqd_caps && !$roles) { return; } if ($object_id && !$src_name) { $object_id = 0; } // ----------------------------------------------------------------------------------- // Default to not honoring custom user caps, but support option $custom_user_blogcaps = SCOPER_CUSTOM_USER_BLOGCAPS; if (!$object_type) { if ($object_types = $this->scoper->cap_defs->object_types_from_caps($reqd_caps, $src_name)) { if (count($object_types) == 1) { $object_type = reset($object_types); } } if (!$object_type) { $object_type = cr_find_object_type($src_name, $object_id); } } // RS roles are object type-specific $roles_wp = $this->scoper->role_defs->filter($roles, array('role_type' => 'wp')); $roles_rs = $this->scoper->role_defs->filter($roles, array('role_type' => 'rs')); $this_otype_roles = $this->scoper->role_defs->get_matching('rs', $src_name, $object_type); $roles_rs = array_intersect_key($roles_rs, $this_otype_roles); $roles = array_merge($roles_rs, $roles_wp); $qualifying_roles = array(); // --------- ACCOUNT FOR OBJECT ROLES ----------- // If this set of reqd_caps can be satisfied by a scopable role, check for object role assignements if (!$skip_object_roles && ($object_id || $any_object)) { // exclude roles which have never been assigned to any object if ($object_roles = $this->scoper->qualify_object_roles($reqd_caps, $object_type, -1)) { $qualifying_roles[OBJECT_SCOPE_RS][''] = scoper_role_handles_to_names(array_keys($roles)); } } // If this inquiry is for a particular object, find out which roles must be object-assigned for it if ($object_id) { // For term and blog role clauses, exclude roles which require object assignment for that object // But don't disqualify a role if any of the roles it "contains" also qualify and are not object-scoped. // (i.e. If the required caps are satisfied by admin, editor and contributor, the actual minimum requirement // is contributor. A specification that admin and editor roles "require object assignment" does not apply // in this scenario. if (!is_array($objscope_roles)) { $objscope_roles = $this->get_objscope_roles($src_name, $object_id, '', true); } if ($objscope_roles) { $contained_roles = array(); $roles_wp = $this->scoper->role_defs->filter($roles, array('role_type' => 'wp')); foreach (array_keys($roles_wp) as $role_handle) { // If scoping with RS roles, this will also have the effect of disqualifying a WP blog role if all of the qualifying RS roles it contains are objscoped. $contained_roles[$role_handle] = $this->scoper->role_defs->get_contained_roles($role_handle, false, 'rs'); $contained_roles[$role_handle] = array_intersect_key($contained_roles[$role_handle], $roles); if (!array_diff_key($contained_roles[$role_handle], $objscope_roles)) { unset($roles[$role_handle]); } } foreach (array_keys($roles) as $role_handle) { $contained_roles[$role_handle] = $this->scoper->role_defs->get_contained_roles($role_handle, true, 'rs'); //true: include this role in return array $contained_roles[$role_handle] = array_intersect_key($contained_roles[$role_handle], $roles); if (!array_diff_key($contained_roles[$role_handle], $objscope_roles)) { unset($roles[$role_handle]); } } } } // --------- ACCOUNT FOR TERM ROLES ----------- // Consider term scope settings and role assignments // $uses_taxonomies = scoper_get_taxonomy_usage($src_name, $object_type); if ($use_term_roles && $src_name && $roles && !empty($uses_taxonomies)) { // If scoping with RS roles, strip out WP role definitions (which were included for blogrole clause) $term_roles = $this->scoper->role_defs->filter($roles, array('role_type' => 'rs')); if ($term_roles) { foreach ($uses_taxonomies as $taxonomy) { // include users with a sufficient term role assignment in any term $qualifying_roles[TERM_SCOPE_RS][$taxonomy] = scoper_role_handles_to_names(array_keys($term_roles)); } } // Honor blog-wide assignment of any non-objscope role, but only if at least one term // is not "strict" (i.e. merges blogroles into term-specific assignments). if (!$ignore_strict_terms) { $term_roles = $this->get_unrestricted_term_roles($term_roles, $uses_taxonomies, $object_id, $object_terms); // disqualify a WP blog role if all of the qualifying RS roles it contains were excluded by the strict terms filter. if ($roles_wp = $this->scoper->role_defs->filter($roles, array('role_type' => 'wp'))) { $contained_roles = array(); foreach (array_keys($roles_wp) as $role_handle) { $contained_roles[$role_handle] = $this->scoper->role_defs->get_contained_roles($role_handle, false, 'rs'); $contained_roles[$role_handle] = array_intersect_key($contained_roles[$role_handle], $roles); if (!$term_roles || !$contained_roles[$role_handle] || !array_intersect_key($contained_roles[$role_handle], $term_roles)) { unset($roles[$role_handle]); } } } $roles_current = $this->scoper->role_defs->filter($roles, array('role_type' => 'rs')); foreach (array_keys($roles_current) as $role_handle) { if (!isset($term_roles[$role_handle])) { unset($roles[$role_handle]); } } // Since this term role is restricted for all terms, prevent corresponding blog role from being added to qualifying_roles array by subsequent code } } // --------- ACCOUNT FOR BLOG ROLES ----------- // For each qualifying role, recognize blog assignment if the reqd_caps set is not associated // with a defined data source, if this source/object type does not use term roles, // or if some of the the terms are not strict. // // Note that WP blogrole assignments (if not taxonomy or object-scoped) are honored // regardless of Role Scoper role_type setting. if ($use_blog_roles) { if ($admin_roles = awp_administrator_roles()) { $roles = $roles ? array_merge($roles, $admin_roles) : $admin_roles; } if ($roles) { $role_types = array('rs', 'wp'); foreach ($role_types as $role_type) { //if ( ('rs' == $role_type) && ! RS_BLOG_ROLES ) // rs_blog_roles option has never been active in any RS release; leave commented here in case need arises // continue; $this_type_roles = $this->scoper->role_defs->filter($roles, array('role_type' => $role_type)); $qualifying_roles[BLOG_SCOPE_RS][$role_type] = scoper_role_handles_to_names(array_keys($this_type_roles)); } } if ($custom_user_blogcaps && $use_blog_roles) { // If custom user blogcaps option is enabled, this function is called separately for each reqd cap. // Custom user caps are stored as "hidden" single-cap role of type WP_CAP, sync'd to WP usermeta storage. if ($custom_user_blogcaps) { $qualifying_roles[BLOG_SCOPE_RS]['wp_cap'] = $reqd_caps; } // ...which contains one cap } } return $qualifying_roles; }