function get_reqd_caps() { $reqd_caps = array(); $generic_uri = in_array($GLOBALS['pagenow'], array('index.php', 'comments.php')); if (!$generic_uri && ($_post_type = cr_find_post_type('', false))) { // arg: don't return 'post' as default if detection fails $post_types = array($_post_type => get_post_type_object($_post_type)); } else { $post_types = array_diff_key(get_post_types(array('public' => true), 'object'), array('attachment' => true)); } $use_post_types = scoper_get_option('use_post_types'); $post_statuses = get_post_stati(array('internal' => null), 'object'); foreach ($post_types as $_post_type => $type_obj) { if (empty($use_post_types[$_post_type])) { continue; } foreach ($post_statuses as $status => $status_obj) { $reqd_caps[$_post_type][$status] = array($type_obj->cap->edit_others_posts); if (scoper_get_option('require_moderate_comments_cap')) { $reqd_caps[$_post_type][$status][] = 'moderate_comments'; } if ($status_obj->private) { $reqd_caps[$_post_type][$status][] = $type_obj->cap->edit_private_posts; } if ($status_obj->public || 'future' == $status) { $reqd_caps[$_post_type][$status][] = $type_obj->cap->edit_published_posts; } } } return $reqd_caps; }
function flt_dropdown_pages($orig_options_html) { if ('no_parent_filter' == scoper_get_option('lock_top_pages')) { return $orig_options_html; } if (!strpos($orig_options_html, 'parent_id') || !$orig_options_html || is_content_administrator_rs()) { return $orig_options_html; } $post_type = awp_post_type_from_uri(); // User can't associate or de-associate a page with Main page unless they have edit_pages blog-wide. // Prepend the Main Page option if appropriate (or, to avoid submission errors, if we generated no other options) if (!$GLOBALS['scoper_admin_filters']->user_can_associate_main($post_type)) { $is_new = $GLOBALS['post']->post_status == 'auto-draft'; if (!$is_new) { global $post; $object_id = !empty($post->ID) ? $post->ID : (int) $GLOBALS['scoper']->data_sources->detect('id', 'post', 0, 'post'); $stored_parent_id = !empty($post->ID) ? $post->post_parent : get_post_field('post_parent', $object_id); } if ($is_new || $stored_parent_id) { $mat = array(); preg_match('/<option[^v]* value="">[^<]*<\\/option>/', $orig_options_html, $mat); if (!empty($mat[0])) { return str_replace($mat[0], '', $orig_options_html); } } } return $orig_options_html; }
function scoper_requested_file_rule_expire() { if (scoper_get_option('file_filtering')) { if ($key = scoper_get_option('file_filtering_regen_key')) { if (!empty($_GET['key']) && $key == $_GET['key']) { // user must store their own non-null key before this will work global $wpdb; if (IS_MU_RS) { $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id"); $orig_blog_id = $GLOBALS['blog_id']; foreach ($blog_ids as $id) { switch_to_blog($id); scoper_query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_rs_file_key'"); } } else { scoper_query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_rs_file_key'"); } scoper_expire_file_rules(); if (IS_MU_RS) { _e("File attachment access keys and rewrite rules will be regenerated for each site at next access.", 'scoper'); } else { _e("File attachment access keys and rewrite rules were regenerated.", 'scoper'); } } else { _e('Invalid argument.', 'scoper'); } } else { _e('Please configure File Filtering options!', 'scoper'); } } else { _e('The function is disabled.', 'scoper'); } exit(0); }
function scoper_review_file_htaccess() { $min_date = (int) scoper_get_site_option('file_htaccess_min_date'); $last_regen = (int) scoper_get_option('file_htaccess_date'); if (!$last_regen || $min_date > $last_regen) { scoper_flush_file_rules(); } }
function user_can_admin_role_rs($role_handle, $item_id, $src_name = '', $object_type = '') { if (is_user_administrator_rs()) { return true; } global $scoper; static $require_blogwide_editor; if (!isset($require_blogwide_editor)) { $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only'); } if ('admin' == $require_blogwide_editor) { return false; } // User Admins already returned true if ('admin_content' == $require_blogwide_editor && !is_content_administrator_rs()) { return false; } static $role_ops; if (!isset($role_ops)) { $role_ops = array(); } if (!isset($role_ops[$role_handle])) { $role_ops[$role_handle] = $scoper->cap_defs->get_cap_ops(array_keys($scoper->role_defs->role_caps[$role_handle])); } // user can't view or edit role assignments unless they have all rolecaps // however, if this is a new post, allow read role to be assigned even if contributor doesn't have read_private cap blog-wide if ($item_id || $role_ops[$role_handle] != array('read' => 1)) { static $reqd_caps; if (!isset($reqd_caps)) { $reqd_caps = array(); } if (!isset($reqd_caps[$role_handle])) { $reqd_caps[$role_handle] = $scoper->role_defs->role_caps[$role_handle]; } $type_caps = $scoper->cap_defs->get_matching($src_name, $object_type); $reqd_caps[$role_handle] = array_intersect_key($reqd_caps[$role_handle], $type_caps); if (is_null($item_id)) { $item_id = 0; } if (!cr_user_can(array_keys($reqd_caps[$role_handle]), $item_id)) { return false; } // are we also applying the additional requirement (based on RS Option setting) that the user is a blog-wide editor? if ($require_blogwide_editor) { static $can_edit_blogwide; if (!isset($can_edit_blogwide)) { $can_edit_blogwide = array(); } if (!isset($can_edit_blogwide[$src_name][$object_type])) { $can_edit_blogwide[$src_name][$object_type] = user_can_edit_blogwide_rs($src_name, $object_type, array('require_others_cap' => true)); } if (!$can_edit_blogwide[$src_name][$object_type]) { return false; } } } return true; }
function otype_option_checkboxes($option_name, $caption, $tab_name, $section_name, $hint_text, $trailing_html, $args = array()) { global $scoper, $scoper_admin; $defaults = array('caption_header' => true); $args = array_merge($defaults, $args); extract($args); $return = array('in_scope' => false, 'val' => array()); if (in_array($option_name, $this->form_options[$tab_name][$section_name])) { $this->all_otype_options[] = $option_name; if (isset($this->def_otype_options[$option_name])) { if (!($return['val'] = scoper_get_option($option_name, $this->sitewide, $this->customize_defaults))) { $return['val'] = array(); } $return['val'] = array_merge($this->def_otype_options[$option_name], $return['val']); $label_property = isset($args['label_property']) ? $args['label_property'] : 'name'; $first_pass = true; foreach ($return['val'] as $src_otype => $val) { if ($caption_header && $first_pass) { printf($caption, $scoper_admin->interpret_src_otype($src_otype, $label_property)); echo '<br /><div style="margin-left: 2em">'; $first_pass = false; } $arr_src_otype = explode(':', $src_otype); if (!scoper_get_otype_option('use_object_roles', $arr_src_otype[0], $arr_src_otype[1])) { continue; } $item_label = $scoper_admin->interpret_src_otype($src_otype, $label_property); //arg: use plural display name $id = str_replace(':', '_', $option_name . '-' . $src_otype); echo "<label for='{$id}'>"; echo "<input name='{$id}' type='checkbox' id='{$id}' value='1' "; checked('1', $val); echo " /> "; if ($caption_header) { echo $item_label; } else { printf($caption, $item_label); } echo '</label><br />'; } // end foreach src_otype if ($caption_header) { echo '</div>'; } if ($hint_text && $this->display_hints) { echo "<span class='rs-subtext'>" . $hint_text . "</span>"; } if ($trailing_html) { echo $trailing_html; } } // endif default option isset $return['in_scope'] = true; } // endif in this option is controlled in this scope return $return; }
function flt_recent_comments($query) { // Due to missing get_comments hook prior to WP 3.1, this filter operates on every front-end query. // If query doesn't pertain to comments, skip out with as little overhead as possible. if (strpos($query, 'comment') && strpos($query, "ELECT") && !strpos($query, 'posts as parent') && !strpos($query, "COUNT") && strpos($query, "comment_approved")) { if (!is_attachment() && !is_content_administrator_rs()) { global $wpdb; if (strpos($query, " {$wpdb->posts} ")) { return $query; } if (awp_is_plugin_active('wp-wall')) { $options = WPWall_GetOptions(); if (strpos($query, 'comment_post_ID=' . $options['pageId'])) { return $query; } } if (strpos($query, $wpdb->comments)) { $query = str_replace(" post_status = 'publish'", " {$wpdb->posts}.post_status = 'publish'", $query); // theoretically, a slight performance enhancement if we can simplify the query to skip filtering of attachment comments if (defined('SCOPER_NO_ATTACHMENT_COMMENTS') || false !== strpos($query, 'comment_post_ID =')) { if (!strpos($query, "JOIN {$wpdb->posts}")) { $query = preg_replace("/FROM\\s*{$wpdb->comments}\\s*WHERE /", "FROM {$wpdb->comments} INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID WHERE ", $query); } $query = apply_filters('objects_request_rs', $query, 'post', '', array('skip_teaser' => true)); } else { $query = str_replace("user_id ", "{$wpdb->comments}.user_id ", $query); $query = str_replace("SELECT {$wpdb->comments}.* FROM {$wpdb->comments}", "SELECT DISTINCT {$wpdb->comments}.* FROM {$wpdb->comments}", $query); if (!strpos($query, ' DISTINCT ')) { $query = str_replace("SELECT ", "SELECT DISTINCT ", $query); } $post_types = array_diff(get_post_types(array('public' => true)), array('attachment')); $post_type_in = "'" . implode("','", $post_types) . "'"; $join = "LEFT JOIN {$wpdb->posts} as parent ON parent.ID = {$wpdb->posts}.post_parent AND parent.post_type IN ({$post_type_in}) AND {$wpdb->posts}.post_type = 'attachment'"; $use_post_types = scoper_get_option('use_post_types'); $where = array(); foreach ($post_types as $type) { if (!empty($use_post_types[$type])) { $where_post = apply_filters('objects_where_rs', '', 'post', $type, array('skip_teaser' => true)); } else { $where_post = "AND 1=1"; } $where[] = "{$wpdb->posts}.post_type = '{$type}' {$where_post}"; $where[] = "{$wpdb->posts}.post_type = 'attachment' AND parent.post_type = '{$type}' " . str_replace("{$wpdb->posts}.", "parent.", $where_post); } $where = agp_implode(' ) OR ( ', $where, ' ( ', ' ) '); if (!strpos($query, "JOIN {$wpdb->posts}")) { $query = str_replace("WHERE ", "INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID {$join} WHERE ( {$where} ) AND ", $query); } else { $query = str_replace("WHERE ", "{$join} WHERE {$where} AND ", $query); } } } } } return $query; }
function flt_comments_clauses($clauses, &$qry_obj) { global $wpdb; if (is_admin() && defined('SCOPER_NO_COMMENT_FILTERING') && empty($GLOBALS['current_user']->allcaps['moderate_comments'])) { return $clauses; } if (empty($clauses['join'])) { $clauses['join'] = "JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID"; } // for WP 3.1 and any manual 3rd-party join construction (subsequent filter will expand to additional statuses as appropriate) $clauses['where'] = preg_replace("/ post_status\\s*=\\s*[']?publish[']?/", " {$wpdb->posts}.post_status = 'publish'", $clauses['where']); // performance enhancement: simplify comments query if there are no attachment comments to filter (TODO: cache this result) $qry_any_attachment_comments = "SELECT ID FROM {$wpdb->posts} AS p INNER JOIN {$wpdb->comments} AS c ON p.ID = c.comment_post_ID WHERE p.post_type = 'attachment' LIMIT 1"; $post_type_arg = isset($qry_obj->query_vars['post_type']) ? $qry_obj->query_vars['post_type'] : ''; $post_id = !empty($qry_obj->query_vars['post_id']) ? $qry_obj->query_vars['post_id'] : 0; $attachment_query = 'attachment' == $post_type_arg || $post_id && 'attachment' == get_post_field('post_type', $post_id); $args = array('skip_teaser' => true); if (is_admin()) { require_once 'admin/comments-interceptor-admin_rs.php'; $args['force_reqd_caps'] = CommentsInterceptorAdmin_RS::get_reqd_caps(); } // $attachment_query: current query is for attachment post type, or for a specific post which is an attachment // $post_id: current query is for a specific post // NOTE: even if not $attachment_query, attachment comments are included by default along with comments on other post types (i.e. for Recent Comments sidebar) if (defined('SCOPER_NO_ATTACHMENT_COMMENTS') || !$attachment_query && ($post_id || !defined('SCOPER_ATTACHMENT_COMMENTS') && !scoper_get_var($qry_any_attachment_comments))) { $clauses['where'] = " AND " . $clauses['where']; $clauses['where'] = "1=1" . apply_filters('objects_where_rs', $clauses['where'], 'post', $post_type_arg, $args); } else { if (false === strpos($clauses['fields'], 'DISTINCT ')) { $clauses['fields'] = 'DISTINCT ' . $clauses['fields']; } if ($post_type_arg) { $post_types = (array) $post_type_arg; } else { $post_types = array_diff(get_post_types(array('public' => true)), array('attachment')); } $post_type_in = "'" . implode("','", $post_types) . "'"; $clauses['join'] .= " LEFT JOIN {$wpdb->posts} as parent ON parent.ID = {$wpdb->posts}.post_parent AND parent.post_type IN ({$post_type_in}) AND {$wpdb->posts}.post_type = 'attachment'"; $use_post_types = scoper_get_option('use_post_types'); $where = array(); foreach ($post_types as $type) { if (!empty($use_post_types[$type])) { $where_post = apply_filters('objects_where_rs', '', 'post', $type, $args); } else { $where_post = "AND 1=1"; } $where[] = "{$wpdb->posts}.post_type = '{$type}' {$where_post}"; $where[] = "{$wpdb->posts}.post_type = 'attachment' AND parent.post_type = '{$type}' " . str_replace("{$wpdb->posts}.", "parent.", $where_post); } $clauses['where'] = preg_replace("/\\s*AND\\s*{$wpdb->posts}.post_status\\s*=\\s*[']?publish[']?/", "", $clauses['where']); $clauses['where'] .= ' AND ( ' . agp_implode(' ) OR ( ', $where, ' ( ', ' ) ') . ' )'; } return $clauses; }
function act_attachment_access() { if (is_admin() || defined('DISABLE_QUERYFILTERS_RS') || is_content_administrator_rs() || !scoper_get_option('file_filtering')) { return; } // if ( is_attachment() ) { as of WP 2.6, is_attachment() returns false for custom permalink attachment URL if (is_attachment_rs()) { //rs_errlog( 'IS an attachment:' ); require_once dirname(__FILE__) . '/attachment-template_rs.php'; AttachmentTemplate_RS::attachment_access(); } }
function _validate_assigner_roles($scope, $src_or_tx_name, $item_id, $roles) { if (!$item_id && !is_user_administrator_rs()) { return false; } $user_has_role = array(); if (TERM_SCOPE_RS == $scope) { foreach (array_keys($roles) as $role_handle) { $role_attributes = $this->scoper->role_defs->get_role_attributes($role_handle); $args = array('src_name' => $role_attributes->src_name, 'object_type' => $role_attributes->object_type); $user_has_role[$role_handle] = $this->user_has_role_in_term($role_handle, $src_or_tx_name, $item_id, $args); } } else { if ($require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only')) { global $current_user; $is_user_administrator = is_user_administrator_rs(); $is_content_administrator = is_content_administrator_rs(); } foreach (array_keys($roles) as $role_handle) { // a user must have a blog-wide edit cap to modify editing role assignments (even if they have Editor role assigned for some current object) if ($require_blogwide_editor) { if (!$is_user_administrator && 'admin' == $require_blogwide_editor) { $user_has_role[$role_handle] = false; continue; } if (!$is_content_administrator && 'admin_content' == $require_blogwide_editor) { $user_has_role[$role_handle] = false; continue; } $src_name = $this->scoper->role_defs->member_property($role_handle, 'src_name'); $object_type = $this->scoper->role_defs->member_property($role_handle, 'object_type'); static $can_edit_blogwide; if (!isset($can_edit_blogwide)) { $can_edit_blogwide = array(); } if (!isset($can_edit_blogwide[$src_name][$object_type])) { $can_edit_blogwide[$src_name][$object_type] = $this->scoper->user_can_edit_blogwide($src_name, $object_type, array('require_others_cap' => true)); } if (!$can_edit_blogwide[$src_name][$object_type]) { $user_has_role[$role_handle] = false; continue; } } if (!empty($this->scoper->role_defs->role_caps[$role_handle])) { $user_has_role[$role_handle] = cr_user_can(array_keys($this->scoper->role_defs->role_caps[$role_handle]), $item_id); } } } return $user_has_role; }
function available_menu_items_parse_query(&$query) { if (scoper_get_option('admin_nav_menu_filter_items')) { $query->query_vars['include'] = ''; $query->query_vars['post__in'] = ''; $query->query_vars_hash = ''; $query->query_vars_changed = true; $query->query['include'] = ''; $query->query['post__in'] = ''; $query->query_vars['suppress_filters'] = false; $query->query_vars['post_status'] = ''; $query->query['suppress_filters'] = false; $query->query['post_status'] = ''; } }
function organize_assigned_roles($scope, $src_or_tx_name, $obj_or_term_id, $role_handles = '', $role_basis = ROLE_BASIS_USER, $get_defaults = false) { $assignments = array(); if ($get_defaults) { $obj_or_term_id = intval($obj_or_term_id); } $args = array('role_handles' => $role_handles); $args['id'] = $obj_or_term_id || $get_defaults ? $obj_or_term_id : false; $roles = ScoperRoleAssignments::get_assigned_roles($scope, $role_basis, $src_or_tx_name, $args); $role_duration_enabled = scoper_get_option('role_duration_limits'); $content_date_limits_enabled = scoper_get_option('content_date_limits'); if (!isset($roles[$obj_or_term_id])) { return array(); } foreach ($roles[$obj_or_term_id] as $role_handle => $agents) { foreach ($agents as $ug_id => $ass) { $ass_id = $ass['assignment_id']; $assign_for = $ass['assign_for']; $assignments[$role_handle]['assigned'][$ug_id]['inherited_from'] = $ass['inherited_from']; $assignments[$role_handle]['assigned'][$ug_id]['assign_for'] = $assign_for; $assignments[$role_handle]['assigned'][$ug_id]['assignment_id'] = $ass_id; if ($role_duration_enabled && $ass['date_limited']) { $assignments[$role_handle]['assigned'][$ug_id]['date_limited'] = $ass['date_limited']; $assignments[$role_handle]['assigned'][$ug_id]['start_date_gmt'] = $ass['start_date_gmt']; $assignments[$role_handle]['assigned'][$ug_id]['end_date_gmt'] = $ass['end_date_gmt']; } if ($content_date_limits_enabled && $ass['content_date_limited']) { $assignments[$role_handle]['assigned'][$ug_id]['content_date_limited'] = $ass['content_date_limited']; $assignments[$role_handle]['assigned'][$ug_id]['content_min_date_gmt'] = $ass['content_min_date_gmt']; $assignments[$role_handle]['assigned'][$ug_id]['content_max_date_gmt'] = $ass['content_max_date_gmt']; } // also save the calling function some work by returning each flavor of assignment as an array keyed by user/group id if ('children' == $assign_for || 'both' == $assign_for) { $assignments[$role_handle]['children'][$ug_id] = $ass_id; } if ('entity' == $assign_for || 'both' == $assign_for) { $assignments[$role_handle]['entity'][$ug_id] = $ass_id; } if ($ass['inherited_from']) { $assignments[$role_handle]['propagated'][$ass['inherited_from']] = $ass_id; } } } return $assignments; }
function TemplateInterceptor_RS() { $this->scoper =& $GLOBALS['scoper']; if (scoper_get_option('strip_private_caption')) { add_filter('the_title', array(&$this, 'flt_title'), 10, 3); if (defined('WPLANG') && WPLANG) { add_filter('gettext', array(&$this, 'flt_gettext'), 10, 3); } } if (defined('SCOPER_FILTER_COMMENT_COUNT')) { add_filter('get_comments_number', array(&$this, 'flt_get_comments_number')); } // this filter should pass post_id as 2nd arg, but does not as of WP 2.7 if (awp_is_plugin_active('events-calendar')) { add_filter('query', array(&$this, 'ec_getDaysEvents')); } if (awp_is_plugin_active('eventcalendar3')) { add_filter('query', array(&$this, 'ec3_query')); } }
function scoper_mu_users_menu() { if (!defined('DEFINE_GROUPS_RS') || !scoper_get_site_option('mu_sitewide_groups')) { return; } $cap_req = is_user_administrator_rs() || current_user_can('recommend_group_membership') ? 'read' : 'manage_groups'; $groups_caption = defined('GROUPS_CAPTION_RS') ? GROUPS_CAPTION_RS : __('Role Groups', 'scoper'); global $scoper_admin; $menu_name = awp_ver('3.1') ? 'users.php' : 'ms-admin.php'; add_submenu_page($menu_name, $groups_caption, $groups_caption, $cap_req, 'rs-groups', array(&$scoper_admin, 'menu_handler')); if (scoper_get_option('mu_sitewide_groups')) { global $plugin_page_cr; // satisfy WordPress' demand that all admin links be properly defined in menu if ('rs-default_groups' == $plugin_page_cr) { add_submenu_page($menu_name, __('User Groups', 'scoper'), __('Default Groups', 'scoper'), $cap_req, 'rs-default_groups', array(&$scoper_admin, 'menu_handler')); } if ('rs-group_members' == $plugin_page_cr) { add_submenu_page($menu_name, __('User Groups', 'scoper'), __('Group Members', 'scoper'), $cap_req, 'rs-group_members', array(&$scoper_admin, 'menu_handler')); } } }
function flt_manage_posts_columns($defaults) { global $current_user, $scoper, $scoper_role_usage; $object_type = cr_find_post_type(); if ($blogwide_role_requirement = scoper_get_option('role_admin_blogwide_editor_only')) { if ('admin' == $blogwide_role_requirement && !is_user_administrator_rs()) { return $defaults; } elseif ('content_admin' == $blogwide_role_requirement && !is_content_administrator_rs()) { return $defaults; } elseif ($blogwide_role_requirement) { if (!$scoper->user_can_edit_blogwide('post', $object_type, array('require_others_cap' => true))) { return $defaults; } } } $use_object_roles = scoper_get_otype_option('use_object_roles', 'post', $object_type); $use_term_roles = scoper_get_otype_option('use_term_roles', 'post', $object_type); if ($use_term_roles && !empty($scoper_role_usage->any_restricted_terms) || $use_object_roles && !empty($scoper_role_usage->any_restricted_objects)) { if (scoper_get_otype_option('restrictions_column', 'post', $object_type)) { $defaults['restricted'] = __('Restrict', 'scoper'); } } if (!empty($scoper_role_usage->have_termrole_ids['post'])) { if (scoper_get_otype_option('term_roles_column', 'post', $object_type)) { $defaults['termroles'] = __('Term Roles', 'scoper'); } } if ($use_object_roles && !empty($scoper_role_usage->have_objrole_ids['post'])) { if (scoper_get_otype_option('object_roles_column', 'post', $object_type)) { $otype_display_name = $scoper->data_sources->member_property('post', 'object_types', $object_type, 'display_name'); //$defaults['objroles'] = sprintf( _ x('%s Roles', 'Post or Page', 'scoper'), $otype_display_name); $defaults['objroles'] = sprintf(__('%s Roles', 'scoper'), $otype_display_name); } } return $defaults; }
/** * function UsersInterceptor_RS::users_who_can * * Get all users with required capabilities, applying scoped roles where pertinent. * * reqd_caps: array of capability names, or string value containing single capability name * cols: enumeration COLS_ALL_RS, COL_ID_RS, COLS_ID_NAME_RS or COLS_ID_DISPLAYNAME_RS. Determines return array dimensions. * object_src_name: object data source name as defined in $scoper->data_sources ( 'post' for posts OR pages ) * object_id: array(reqd_cap => object_id), or string value containing single object_id * * Any WP-defined or RS-defined cap may be included to filter users on blog-wide capabilities. * * In addition, object-specific calls filter users for RS-defined caps based on * Taxonomy/Object role assignment and role scoping requirements. * Any reqd_caps lacking a Role Scoper definition are still tested for blog-wide users roles. * * returns query results: 1D array of user_ids for $cols = COL_ID_RS, otherwise 2D array with all user columns */ function users_who_can($reqd_caps, $cols = COLS_ALL_RS, $object_src_name = '', $object_id = 0, $args = array()) { global $wpdb; $defaults = array('where' => '', 'orderby' => '', 'disable_memcache' => false, 'group_ids' => '', 'force_refresh' => false, 'force_all_users' => false); $args = array_merge($defaults, (array) $args); extract($args); if (!$orderby) { if (COLS_ALL_RS == $cols || COLS_ID_DISPLAYNAME_RS == $cols) { $orderby = " ORDER BY display_name"; } elseif (COLS_ID_NAME_RS == $cols) { $orderby = " ORDER BY user_login AS display_name"; } // calling code assumes display_name property for user or group object } if ('id' == $cols) { $cols = COL_ID_RS; } if (COL_ID_RS == $cols) { if ($force_all_users) { $qry = "SELECT ID FROM {$wpdb->users}"; } else { $qry = "SELECT DISTINCT uro.user_id AS ID FROM {$wpdb->user2role2object_rs} AS uro"; } } else { if (COLS_ID_DISPLAYNAME_RS == $cols) { $qcols = "{$wpdb->users}.ID, {$wpdb->users}.display_name"; } elseif (COLS_ID_NAME_RS == $cols) { $qcols = "{$wpdb->users}.ID, {$wpdb->users}.user_login AS display_name"; } elseif (COLS_ALL_RS == $cols) { $qcols = "{$wpdb->users}.*"; } else { $qcols = $cols; } $qry = "SELECT DISTINCT {$qcols} FROM {$wpdb->users}"; $where = ''; } if ($reqd_caps || !$force_all_users) { if (COL_ID_RS != $cols) { $qry .= " INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.user_id = {$wpdb->users}.ID"; } if (!is_array($args)) { $args = array(); } if (isset($args['ignore_user_roles'])) { unset($args['ignore_user_roles']); } $do_groups = empty($args['ignore_group_roles']); $args['ignore_group_roles'] = 1; $args['enforce_duration_limits'] = scoper_get_option('role_duration_limits'); $args['enforce_content_date_limits'] = scoper_get_option('role_content_date_limits'); //log_mem_usage_rs( 'before flt_users_where' ); $where = $this->flt_users_where($where, $reqd_caps, $object_src_name, $object_id, $args); //log_mem_usage_rs( 'flt_users_where' ); } $id_clause = $force_all_users ? '' : 'AND uro.user_id > 0'; $qry = "{$qry} WHERE 1=1 {$id_clause} {$where} {$orderby}"; $qry_key = $qry . serialize($args); // if we've already run this query before, return the result if (empty($disable_memcache) && isset($this->user_cache[$qry_key])) { return $this->user_cache[$qry_key]; } if (COL_ID_RS == $cols) { $users = scoper_get_col($qry); } else { $users = scoper_get_results($qry); } //log_mem_usage_rs( 'users query' ); if (!empty($do_groups)) { if (!empty($args['preserve_or_clause']) && strpos($args['preserve_or_clause'], 'uro.')) { unset($args['preserve_or_clause']); } if (!empty($args['orderby'])) { unset($args['orderby']); } if (empty($group_ids)) { $group_ids = $this->groups_who_can($reqd_caps, COL_ID_RS, $object_src_name, $object_id, $args); } if (!empty($group_ids)) { if (!defined('DISABLE_PERSISTENT_CACHE')) { // if persistent cache is enabled, use cached members list for each group instead of querying for all groups foreach ($group_ids as $group_id) { if ($group_members = ScoperAdminLib::get_group_members($group_id, $cols, true)) { $users = array_merge($users, $group_members); } } } else { // avoid separate query for each group if persistent cache is not enabled if ($group_members = ScoperAdminLib::get_group_members($group_ids, $cols, true)) { $users = array_merge($users, $group_members); } } } if (COL_ID_RS == $cols) { $users = array_unique($users); } else { $users = agp_array_unique_md($users); } } $this->user_cache[$qry_key] = $users; //log_mem_usage_rs( 'end UsersInt::users_who_can' ); return $users; }
function scoper_display_rs_roledefs($args = array()) { global $scoper; echo "<div id='rs-roledefs' style='clear:both;margin:0;' class='rs-options agp_js_hide {$args['bgcolor_class']}'>"; if (scoper_get_option('display_hints')) { echo '<div class="rs-optionhint">'; echo '<p style="margin-top:0">'; _e('These roles are defined by Role Scoper (and possibly other plugins) for your use in designating content-specific access or supplemental site-wide access. Although the default capabilities are ideal for most installations, you may modify them at your discretion.', 'scoper'); echo '</p>'; echo '<p>'; _e('Since Role Scoper role definitions pertain to a particular object type, available capabilities are defined by the provider of that object type. WordPress core or plugins can add or revise default role definitions based on available capabilities.', 'scoper'); echo '</p>'; echo '<p>'; if (awp_ver('3.0-dev')) { _e('WordPress Role assignments function as a default which may be supplemented or overriden by site-wide or content-specific assignment of these RS Roles.', 'scoper'); } else { _e('WordPress Role assignments function as a default which may be supplemented or overriden by blog-wide or content-specific assignment of these RS Roles.', 'scoper'); } echo '</p>'; echo '</div>'; } echo "<input type='hidden' name='rs_role_defs' value='1' />"; if (empty($args['customize_defaults'])) { $rs_role_defs = $scoper->role_defs; } else { global $scoper_role_types; $rs_role_defs = new CR_Roles(); //$this->load_role_caps(); $rs_role_defs->role_caps = apply_filters('define_role_caps_rs', cr_role_caps()); if ($user_role_caps = scoper_get_option('user_role_caps', -1, true)) { $rs_role_defs->add_role_caps($user_role_caps); } if ($disabled_role_caps = scoper_get_option('disabled_role_caps', -1, true)) { $rs_role_defs->remove_role_caps($disabled_role_caps); } $rs_role_defs->add_member_objects(cr_role_defs()); $rs_role_defs = apply_filters('define_roles_rs', $rs_role_defs); $rs_role_defs->remove_invalid(); // currently don't allow additional custom-defined post, page or link roles // To support merging in of WP role assignments, always note actual WP-defined roles // regardless of which role type we are scoping with. $scoper->log_wp_roles($rs_role_defs); $rs_role_defs->lock(); // prevent inadvertant improper API usage } // object_type association of roles needs to be based on default role_caps, otherwise roles with all caps disabled will be excluded from UI // This also allows the default bolding to be based on custom default settings when role defs are defined per-blog in wp-mu global $scoper_role_types; $rs_default_role_defs = new CR_Roles(); $rs_default_role_defs->role_caps = apply_filters('define_role_caps_rs', cr_role_caps()); $rs_default_role_defs->add_member_objects(cr_role_defs()); $rs_default_cap_defs = new CR_Capabilities(); $rs_default_cap_defs->add_member_objects(cr_cap_defs()); $rs_default_cap_defs = apply_filters('define_capabilities_rs', $rs_default_cap_defs); $scoper->log_cap_usage($rs_default_role_defs, $rs_default_cap_defs); if (IS_MU_RS && !$args['customize_defaults'] && !$args['sitewide']) { if ($user_role_caps = scoper_get_option('user_role_caps', -1, true)) { $rs_default_role_defs->add_role_caps($user_role_caps); } if ($disabled_role_caps = scoper_get_option('disabled_role_caps', -1, true)) { $rs_default_role_defs->remove_role_caps($disabled_role_caps); } } $rs_default_role_defs = apply_filters('define_roles_rs', $rs_default_role_defs); $rs_default_role_defs->remove_invalid(); if (has_filter('define_roles_rs')) { require_once SCOPER_ABSPATH . '/extension-helper_rs.php'; scoper_adjust_legacy_extension_cfg($rs_default_role_defs, $rs_default_cap_defs); } $reviewed_roles = array(); foreach ($scoper->data_sources->get_all() as $src_name => $src) { $object_types = $src->object_types; if ('post' == $src_name) { global $wp_taxonomies; foreach ($wp_taxonomies as $tx) { if ($_tx = $scoper->taxonomies->get($tx->name)) { // use RS taxonomy object so we can pull plural_name property $object_types[$tx->name] = $_tx; } } $use_post_types = scoper_get_option('use_post_types'); $use_taxonomies = scoper_get_option('use_taxonomies'); } foreach ($object_types as $object_type => $otype) { if ('post' == $src_name && empty($use_post_types[$object_type]) && empty($use_taxonomies[$object_type])) { continue; } $otype_roles = array(); $otype_display_names = array(); if ($obj_roles = $rs_default_role_defs->get_matching('rs', $src_name, $object_type)) { $otype_roles[$object_type] = $obj_roles; } if (!empty($otype->labels->name)) { $otype_display_names[$object_type] = $otype->labels->singular_name; } else { $otype_display_names[$object_type] = $otype->display_name; } if (!$otype_roles) { continue; } if ('post' == $src_name) { $plural_name = plural_name_from_cap_rs(get_post_type_object($object_type)); } else { $plural_name = ''; } foreach ($otype_roles as $object_type => $roles) { //display each role which has capabilities for this object type echo '<br />'; echo '<h3>' . sprintf(__('%s Roles'), $otype_display_names[$object_type]) . '</h3>'; ?> <table class='widefat rs-backwhite'> <thead> <tr class="thead"> <th width="15%"><?php echo __awp('Role'); ?> </th> <th><?php _e('Capabilities (abbreviated, defaults are bolded)', 'scoper'); ?> </th> </tr> </thead> <tbody> <?php $wp_role_sync = array('rs_post_contributor' => 'contributor', 'rs_post_revisor' => 'revisor', 'rs_post_author' => 'author', 'rs_post_editor' => 'editor', 'rs_page_editor' => 'editor'); if (defined('RVY_VERSION')) { $wp_role_sync['rs_page_revisor'] = 'revisor'; } global $wp_roles; $style = ''; foreach ($roles as $rs_role_handle => $role_def) { $reviewed_roles[] = $rs_role_handle; $style = ' class="alternate"' == $style ? '' : ' class="alternate"'; echo "\n\t" . "<tr{$style}><td><strong>" . $rs_role_defs->get_display_name($rs_role_handle) . '</strong>'; if (isset($wp_role_sync[$rs_role_handle])) { if (isset($wp_roles->role_objects[$wp_role_sync[$rs_role_handle]])) { $wp_role_handle = "wp_" . $wp_role_sync[$rs_role_handle]; $wp_display_name = $wp_roles->role_names[$wp_role_sync[$rs_role_handle]]; $contained_roles = $rs_role_defs->get_contained_roles($wp_role_handle); if (!isset($contained_roles[$rs_role_handle])) { echo '<br /><br /><span class="rs-warning">'; printf(__('Warning: Since the WP %1$s role def lacks some caps selected here, it will be treated as a lesser role if Restrictions are applied.', 'scoper'), $wp_display_name); echo '</span>'; $missing_caps = true; } else { $missing_caps = false; } // only display "sync WP role" checkbox if the WP role has missing caps or extra caps $otype_caps = $scoper->cap_defs->get_matching($src_name, $object_type, '', STATUS_ANY_RS); $wp_defined_caps = array_intersect_key($wp_roles->role_objects[$wp_role_sync[$rs_role_handle]]->capabilities, $otype_caps); $wp_extra_caps = array_diff_key($wp_defined_caps, $rs_role_defs->role_caps[$rs_role_handle]); /* if ( $wp_extra_caps ) $sync_caption = sprintf( _ x( 'sync WP %1$s <br />to these selections (currently includes %2$s)', 'role name', 'scoper' ), $wp_display_name, implode( ", ", array_keys($wp_extra_caps) ) ); else $sync_caption = sprintf( _ x( 'sync WP %s <br />to these selections', 'role name', 'scoper' ), $wp_display_name); */ if ($wp_extra_caps) { $sync_caption = sprintf(__('sync WP %1$s <br />to these selections (currently includes %2$s)', 'scoper'), $wp_display_name, implode(", ", array_keys($wp_extra_caps))); } else { $sync_caption = sprintf(__('sync WP %s <br />to these selections', 'scoper'), $wp_display_name); } echo '<br /><br />'; $title = __('note: only the capabilities listed here will be affected', 'scoper'); echo "<input type='checkbox' name='sync_wp_roles[]' id='sync_wp_role_{$rs_role_handle}' value='{$rs_role_handle}:{$wp_role_handle}' title='{$title}' />" . "<label for='sync_wp_role_{$rs_role_handle}' title='{$title}'>" . $sync_caption . '</label>'; } } echo "</td><td><ul class='rs-cap_list'>"; $active_cap_names = array_keys($rs_role_defs->role_caps[$rs_role_handle]); if (!empty($role_def->anon_user_blogrole) || !empty($role_def->no_custom_caps)) { $disabled_role = 'disabled="disabled"'; $available_cap_names = $active_cap_names; } else { $disabled_role = ''; $available_caps = $rs_default_cap_defs->get_matching($src_name, $object_type, '', STATUS_ANY_RS); $available_cap_names = array_keys($available_caps); sort($available_cap_names); $available_cap_names = array_merge($available_cap_names, $active_cap_names); } // abbreviate type caps and reorder display $show_cap_names = array(); foreach ($available_cap_names as $cap_name) { if ($plural_name && strpos($cap_name, "_{$plural_name}")) { $display = str_replace("_{$plural_name}", '', $cap_name); $display = sprintf(__('%s...', 'scoper'), $display); } else { $display = $cap_name; } $show_cap_names[$display] = $cap_name; } ksort($show_cap_names); foreach ($show_cap_names as $display => $cap_name) { $checked = in_array($cap_name, $active_cap_names) ? 'checked="checked"' : ''; $is_default = !empty($rs_default_role_defs->role_caps[$rs_role_handle][$cap_name]); $disabled_cap = $disabled_role || $is_default && !empty($available_caps[$cap_name]->no_custom_remove) || !$is_default && !empty($available_caps[$cap_name]->no_custom_add); $disabled = $disabled_cap ? 'disabled="disabled"' : ''; $style = $is_default ? "style='font-weight: bold'" : ''; $cap_safename = str_replace(' ', '_', $cap_name); echo "<li><input type='checkbox' name='{$rs_role_handle}_caps[]' id='{$rs_role_handle}_{$cap_safename}' value='{$cap_name}' {$checked} {$disabled} />" . "<label for='{$rs_role_handle}_{$cap_safename}' title='{$cap_name}' {$style}>" . str_replace(' ', ' ', ucwords(str_replace('_', ' ', $display))) . '</label></li>'; } echo '</ul></td></tr>'; } echo '</tbody></table>'; echo '<br /><br />'; } // foreach otype_role (distinguish object roles from term roles) } // end foreach object_type } // end foreach data source $reviewed_roles = implode(',', array_unique($reviewed_roles)); echo "<input type='hidden' name='reviewed_roles' value='{$reviewed_roles}' />"; echo '<span class="alignright">'; echo '<label for="rs_role_resync"><input name="rs_role_resync" type="checkbox" id="rs_role_resync" value="1" />'; echo ' '; _e('Re-sync with WordPress roles on next Update', 'scoper'); echo '</label></span>'; echo '<br />'; ?> </div> <?php }
function scoper_object_roles_list($viewing_user, $args = array()) { $html = ''; if (!USER_ROLES_RS && !GROUP_ROLES_RS) { wp_die(__awp('Cheatin’ uh?')); } $defaults = array('enforce_duration_limits' => true, 'is_user_profile' => false, 'echo' => true); $args = array_merge($defaults, (array) $args); extract($args); global $scoper, $wpdb, $current_user; if ($viewing_user) { if (!is_object($viewing_user)) { global $current_rs_user; if ($viewing_user == $current_rs_user->ID) { $viewing_user = $current_rs_user; } else { $viewing_user = new WP_Scoped_User($viewing_user); } } } $all_roles = array(); $role_display = array(); foreach ($scoper->role_defs->get_all_keys() as $role_handle) { if ($viewing_user) { $role_display[$role_handle] = $scoper->role_defs->get_display_name($role_handle, OBJECT_UI_RS); } else { $role_display[$role_handle] = $scoper->role_defs->get_abbrev($role_handle, OBJECT_UI_RS); } } if (!$is_user_profile) { $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only'); if ('admin' === $require_blogwide_editor && !is_user_administrator_rs()) { return false; } if ('admin_content' === $require_blogwide_editor && !is_content_administrator_rs()) { return false; } } else { $require_blogwide_editor = false; } foreach ($scoper->data_sources->get_all() as $src_name => $src) { $otype_count = 0; if (!empty($src->taxonomy_only) || $src_name == 'group' && !$viewing_user) { continue; } $strict_objects = $scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name); foreach ($src->object_types as $object_type => $otype) { $otype_count++; $disable_role_admin = false; if ($require_blogwide_editor) { if (!$scoper->user_can_edit_blogwide('post', $object_type, array('require_others_cap' => true))) { $disable_role_admin = true; } } if (!empty($src->cols->type) && !empty($otype->name)) { $col_type = $src->cols->type; $otype_clause = "AND {$src->table}.{$col_type} = '{$otype->name}'"; } elseif ($otype_count < 2) { $otype_clause = ''; } else { continue; } $col_id = $src->cols->id; $col_name = $src->cols->name; $ug_clause_for_user_being_viewed = $viewing_user ? $viewing_user->get_user_clause('uro') : ''; // TODO: replace join with uro subselect $qry = "SELECT DISTINCT {$src->table}.{$col_name}, {$src->table}.{$col_id}, uro.role_name, uro.date_limited, uro.start_date_gmt, uro.end_date_gmt" . " FROM {$src->table} "; $join = " INNER JOIN {$wpdb->user2role2object_rs} AS uro" . " ON uro.obj_or_term_id = {$src->table}.{$col_id}" . " AND uro.src_or_tx_name = '{$src_name}'" . " AND uro.scope = 'object' AND uro.role_type = 'rs'"; $duration_clause = $enforce_duration_limits ? scoper_get_duration_clause("{$src->table}.{$src->cols->date}") : ''; $status_clause = 'post' == $src_name ? "AND post_status != 'auto-draft'" : ''; // TODO: version update script to delete post roles on auto-drafts (stored via default roles) $where = " WHERE 1=1 {$status_clause} {$otype_clause} {$duration_clause} {$ug_clause_for_user_being_viewed}"; $orderby = " ORDER BY {$src->table}.{$col_name} ASC, uro.role_name ASC"; $qry .= $join . $where . $orderby; $results = scoper_get_results($qry); if (!is_user_administrator_rs()) { // no need to filter admins - just query the assignments // only list role assignments which the logged-in user can administer $args['required_operation'] = OP_EDIT_RS; // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities /* if ( cr_get_reqd_caps( $src_name, OP_ADMIN_RS, $object_type ) { $args['required_operation'] = OP_ADMIN_RS; } else { $reqd_caps = array(); foreach (array_keys($src->statuses) as $status_name) { $admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_ADMIN_RS, $status_name); $delete_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_DELETE_RS, $status_name); $reqd_caps[$object_type][$status_name] = array_merge(array_keys($admin_caps), array_keys($delete_caps)); } $args['force_reqd_caps'] = $reqd_caps; } */ $qry = "SELECT {$src->table}.{$col_id} FROM {$src->table} WHERE 1=1"; $args['require_full_object_role'] = true; $qry_flt = apply_filters('objects_request_rs', $qry, $src_name, $object_type, $args); $cu_admin_results = scoper_get_col($qry_flt); if (empty($viewing_user) || $current_user->ID != $viewing_user->ID) { foreach ($results as $key => $row) { if (!in_array($row->{$col_id}, $cu_admin_results)) { unset($results[$key]); } } } else { // for current user's view of their own user profile, just de-link unadminable objects $link_roles = array(); $link_objects = array(); if (!$disable_role_admin) { foreach ($results as $key => $row) { if (in_array($row->{$col_id}, $cu_admin_results)) { $link_roles[$row->{$col_id}] = true; } } $args['required_operation'] = OP_EDIT_RS; $args['require_full_object_role'] = false; if (isset($args['force_reqd_caps'])) { unset($args['force_reqd_caps']); } $qry_flt = apply_filters('objects_request_rs', $qry, $src_name, $object_type, $args); $cu_edit_results = scoper_get_col($qry_flt); foreach ($results as $key => $row) { if (in_array($row->{$col_id}, $cu_edit_results)) { $link_objects[$row->{$col_id}] = true; } } } } } $object_roles = array(); $objnames = array(); if ($results) { $got_object_roles = true; foreach ($results as $row) { if (!isset($objnames[$row->{$col_id}])) { if ('post' == $src->name) { $objnames[$row->{$col_id}] = apply_filters('the_title', $row->{$col_name}, $row->{$col_id}); } else { $objnames[$row->{$col_id}] = $row->{$col_name}; } } $role_handle = 'rs_' . $row->role_name; if ($row->date_limited) { $duration_key = serialize(array('start_date_gmt' => $row->start_date_gmt, 'end_date_gmt' => $row->end_date_gmt)); } else { $duration_key = ''; } $object_roles[$duration_key][$row->{$col_id}][$role_handle] = true; } } else { continue; } ?> <?php $title_roles = __('edit roles', 'scoper'); foreach (array_keys($object_roles) as $duration_key) { $date_caption = ''; $limit_class = ''; $limit_style = ''; $link_class = ''; if ($duration_key) { $html .= "<h3 style='margin-bottom:0'>{$date_caption}</h3>"; $duration_limits = unserialize($duration_key); $duration_limits['date_limited'] = true; ScoperAdminUI::set_agent_formatting($duration_limits, $date_caption, $limit_class, $link_class, $limit_style); $title = "title='{$date_caption}'"; $date_caption = '<span class="rs-gray"> ' . trim($date_caption) . '</span>'; } else { $title = "title='{$title_roles}'"; } if (!$disable_role_admin && (is_user_administrator_rs() || $cu_admin_results)) { //if ( ( $src_name != $object_type ) && ( 'post' != $object_type ) ) { // menu links currently assume unique object type names // $roles_page = "rs-roles-{$object_type}_{$src_name}"; //} else { $roles_page = "rs-{$object_type}-roles"; //} $url = "admin.php?page={$roles_page}"; $html .= "<h4><a name='{$object_type}' href='{$url}'><strong>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $otype->labels->singular_name, '</strong></a><span style="font-weight:normal">' . $date_caption) . "</span></h4>"; } else { $html .= "<h4><strong>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $otype->labels->singular_name, $date_caption) . "</strong></h4>"; } $html .= "<ul class='rs-termlist'><li>" . "<table class='widefat'>" . "<thead>" . "<tr class='thead'>" . "\t<th class='rs-tightcol'>" . __('ID') . "</th>" . "\t<th>" . __awp('Name') . "</th>" . "\t<th>" . __('Role Assignments', 'scoper') . "</th>" . "</tr>" . "</thead>"; $id_clause = isset($role_codes[$role_handle]) ? "id='roles-{$role_codes[$role_handle]}'" : ''; $html .= "<tbody {$id_clause}>"; $style = ' class="rs-backwhite"'; $title_item = sprintf(__('edit %s', 'scoper'), agp_strtolower($otype->labels->singular_name)); foreach ($object_roles[$duration_key] as $obj_id => $roles) { $object_name = esc_attr($objnames[$obj_id]); $html .= "\n\t<tr{$style}>"; $link_this_object = !isset($link_objects) || isset($link_objects[$obj_id]); // link from object ID to the object type's default editor, if defined if ($link_this_object && !empty($src->edit_url)) { $src_edit_url = sprintf($src->edit_url, $obj_id); $html .= "<td><a href='{$src_edit_url}' class='edit' title='{$title_item}'>{$obj_id}</a></td>"; } else { $html .= "<td>{$obj_id}</td>"; } $name = !empty($objnames[$obj_id]) ? $objnames[$obj_id] : __('(untitled)', 'scoper'); // link from object name to our "Edit Object Role Assignment" interface $link_this_role = !isset($link_roles) || isset($link_roles[$obj_id]); if ($link_this_role) { if ('group' == $object_type) { $rs_edit_url = sprintf($src->edit_url, $obj_id); } else { $rs_edit_url = "admin.php?page=rs-object_role_edit&src_name={$src_name}&object_type={$object_type}&object_id={$obj_id}&object_name={$object_name}"; } $html .= "\n\t<td><a {$title}{$limit_style}class='{$link_class}{$limit_class}' href='{$rs_edit_url}'>{$name}</a></td>"; } else { $html .= "\n\t<td>{$name}</td>"; } $html .= "<td>"; $role_list = array(); foreach (array_keys($roles) as $role_handle) { // roles which require object assignment are asterisked (bolding would contradict the notation of term roles list, where propogating roles are bolded) if (isset($strict_objects['restrictions'][$role_handle][$obj_id]) || isset($strict_objects['unrestrictions'][$role_handle]) && is_array($strict_objects['unrestrictions'][$role_handle]) && !isset($strict_objects['unrestrictions'][$role_handle][$obj_id])) { $role_list[] = "<span class='rs-backylw'>" . $role_display[$role_handle] . '</span>'; } else { $role_list[] = $role_display[$role_handle]; } } $html .= implode(', ', $role_list); $html .= '</td></tr>'; $style = ' class="alternate"' == $style ? ' class="rs-backwhite"' : ' class="alternate"'; } // end foreach object_roles $html .= '</tbody></table>'; $html .= '</li></ul><br />'; } // end foreach role date range } // end foreach object_types } // end foreach data source if ($echo) { echo $html; } else { return $html; } }
function flt_get_pages($results, $args = array()) { $results = (array) $results; global $wpdb; // === BEGIN Role Scoper ADDITION: global var; various special case exemption checks === // global $scoper, $current_rs_user; // need to skip cache retrieval if QTranslate is filtering get_pages with a priority of 1 or less $no_cache = !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate'); // buffer titles in case they were filtered previously $titles = scoper_get_property_array($results, 'ID', 'post_title'); // depth is not really a get_pages arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1 if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) { if (0 !== strpos($args['exclude'], ',')) { // work around wp_list_pages() bug of attaching leading comma if a plugin uses wp_list_pages_excludes filter $args['exclude_tree'] = $args['exclude']; } } // // === END Role Scoper ADDITION === // ================================= $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', 'depth' => 0, 'suppress_filters' => 0, 'remap_parents' => -1, 'enforce_actual_depth' => -1, 'remap_thru_excluded_parent' => -1); // Role Scoper arguments added above // === BEGIN Role Scoper ADDITION: support front-end optimization $post_type = isset($args['post_type']) ? $args['post_type'] : $defaults['post_type']; $use_post_types = (array) scoper_get_option('use_post_types'); if (empty($use_post_types[$post_type])) { return $results; } if ($scoper->is_front()) { if ('page' == $post_type && defined('SCOPER_GET_PAGES_LEAN')) { // custom types are likely to have custom fields $defaults['fields'] = "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_parent, {$wpdb->posts}.post_date, {$wpdb->posts}.post_date_gmt, {$wpdb->posts}.post_status, {$wpdb->posts}.post_name, {$wpdb->posts}.post_modified, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.guid, {$wpdb->posts}.menu_order, {$wpdb->posts}.comment_count"; } else { $defaults['fields'] = "{$wpdb->posts}.*"; if (!defined('SCOPER_FORCE_PAGES_CACHE')) { $no_cache = true; } // serialization / unserialization of post_content for all pages is too memory-intensive for sites with a lot of pages } } else { // required for xmlrpc getpagelist method $defaults['fields'] = "{$wpdb->posts}.*"; if (!defined('SCOPER_FORCE_PAGES_CACHE')) { $no_cache = true; } } // === END Role Scoper MODIFICATION === $r = wp_parse_args($args, $defaults); extract($r, EXTR_SKIP); $number = (int) $number; $offset = (int) $offset; $child_of = (int) $child_of; // Role Scoper modification: null value will confuse children array check // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types(array('public' => true, 'hierarchical' => true)); if (!in_array($post_type, $hierarchical_post_types)) { return $results; } // Make sure we have a valid post status if (!in_array($post_status, get_post_stati())) { return $results; } // for the page parent dropdown, return no available selections for a published main page if the logged user isn't allowed to de-associate it from Main if (!empty($name) && 'parent_id' == $name) { global $post; if (!$post->post_parent && !$GLOBALS['scoper_admin_filters']->user_can_associate_main($post_type)) { $status_obj = get_post_status_object($post->post_status); if ($status_obj->public || $status_obj->private) { return array(); } } if (!empty($post) && $post_type == $post->post_type) { if ($post->post_parent) { $append_page = get_post($post->post_parent); } $exclude_tree = $post->ID; } } //$scoper->last_get_pages_args = $r; // don't copy entire args array unless it proves necessary $scoper->last_get_pages_depth = $depth; $scoper->last_get_pages_suppress_filters = $suppress_filters; if ($suppress_filters) { return $results; } // === BEGIN Role Scoper MODIFICATION: wp-cache key and flag specific to access type and user/groups // if (!scoper_get_otype_option('use_object_roles', 'post', $post_type)) { return $results; } $key = md5(serialize(compact(array_keys($defaults)))); $ckey = md5($key . CURRENT_ACCESS_NAME_RS); $cache_flag = 'rs_get_pages'; $cache = $current_rs_user->cache_get($cache_flag); if (false !== $cache) { if (!is_array($cache)) { $cache = array(); } if (!$no_cache && isset($cache[$ckey])) { // alternate filter name (WP core already applied get_pages filter) return apply_filters('get_pages_rs', $cache[$ckey], $r); } } // // === END Role Scoper MODIFICATION === // ==================================== $inclusions = ''; if (!empty($include)) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = wp_parse_id_list($include); if (!empty($incpages)) { foreach ($incpages as $incpage) { if (empty($inclusions)) { $inclusions = ' AND ( ID = ' . intval($incpage) . ' '; } else { $inclusions .= ' OR ID = ' . intval($incpage) . ' '; } } } } if (!empty($inclusions)) { $inclusions .= ')'; } $exclusions = ''; if (!empty($exclude)) { $expages = wp_parse_id_list($exclude); if (!empty($expages)) { foreach ($expages as $expage) { if (empty($exclusions)) { $exclusions = ' AND ( ID <> ' . intval($expage) . ' '; } else { $exclusions .= ' AND ID <> ' . intval($expage) . ' '; } } } } if (!empty($exclusions)) { $exclusions .= ')'; } $author_query = ''; if (!empty($authors)) { $post_authors = wp_parse_id_list($authors); if (!empty($post_authors)) { foreach ($post_authors as $post_author) { //Do we have an author id or an author login? if (0 == intval($post_author)) { $post_author = get_userdatabylogin($post_author); if (empty($post_author)) { continue; } if (empty($post_author->ID)) { continue; } $post_author = $post_author->ID; } if ('' == $author_query) { $author_query = ' post_author = ' . intval($post_author) . ' '; } else { $author_query .= ' OR post_author = ' . intval($post_author) . ' '; } } if ('' != $author_query) { $author_query = " AND ({$author_query})"; } } } $join = ''; $where = "{$exclusions} {$inclusions} "; if (!empty($meta_key) || !empty($meta_value)) { $join = " INNER JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id"; // Role Scoper modification: was LEFT JOIN in WP 3.0 core (TODO: would that botch uro join results? // meta_key and meta_value might be slashed $meta_key = stripslashes($meta_key); $meta_value = stripslashes($meta_value); if (!empty($meta_key)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_key = %s", $meta_key); } if (!empty($meta_value)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_value = %s", $meta_value); } } if ($parent >= 0) { $where .= $wpdb->prepare(' AND post_parent = %d ', $parent); } // === BEGIN Role Scoper MODIFICATION: // allow pages of multiple statuses to be displayed (requires default status=publish to be ignored) // $where_post_type = $wpdb->prepare("post_type = '%s'", $post_type); $where_status = ''; $is_front = $scoper->is_front(); $is_teaser_active = $scoper->is_front() && scoper_get_otype_option('do_teaser', 'post') && scoper_get_otype_option('use_teaser', 'post', $post_type); $private_teaser = $is_teaser_active && scoper_get_otype_option('use_teaser', 'post', $post_type) && !scoper_get_otype_option('teaser_hide_private', 'post', $post_type); if ($is_front && (!empty($current_rs_user->ID) || $private_teaser)) { $frontend_list_private = scoper_get_otype_option('private_items_listable', 'post', 'page'); } else { $frontend_list_private = false; } // WP core does not include private pages in query. Include private statuses in anticipation of user-specific filtering if ($post_status && ('publish' != $post_status || $is_front && !$frontend_list_private)) { $where_status = $wpdb->prepare("post_status = '%s'", $post_status); } else { // since we will be applying status clauses based on content-specific roles and restrictions, only a sanity check safeguard is needed when post_status is unspecified or defaulted to "publish" $safeguard_statuses = array(); foreach (get_post_stati(array('internal' => false), 'object') as $status_name => $status_obj) { if (!$is_front || $status_obj->private || $status_obj->public) { $safeguard_statuses[] = $status_name; } } $where_status = "post_status IN ('" . implode("','", $safeguard_statuses) . "')"; } $query = "SELECT {$fields} FROM {$wpdb->posts} {$join} WHERE 1=1 AND {$where_post_type} AND ( {$where_status} {$where} {$author_query} ) ORDER BY {$sort_column} {$sort_order}"; if (!empty($number)) { $query .= ' LIMIT ' . $offset . ',' . $number; } if ($is_teaser_active && !defined('SCOPER_TEASER_HIDE_PAGE_LISTING')) { // We are in the front end and the teaser is enabled for pages $query = apply_filters('objects_request_rs', $query, 'post', $post_type, array('force_teaser' => true)); $pages = scoper_get_results($query); // execute unfiltered query // Pass results of unfiltered query through the teaser filter. // If listing private pages is disabled, they will be omitted completely, but restricted published pages // will still be teased. This is a slight design compromise to satisfy potentially conflicting user goals without yet another option $pages = apply_filters('objects_results_rs', $pages, 'post', (array) $post_type, array('request' => $query, 'force_teaser' => true, 'object_type' => $post_type)); // restore buffered titles in case they were filtered previously scoper_restore_property_array($pages, $titles, 'ID', 'post_title'); $pages = apply_filters('objects_teaser_rs', $pages, 'post', $post_type, array('request' => $query, 'force_teaser' => true)); if ($frontend_list_private) { if (!scoper_get_otype_option('teaser_hide_private', 'post', $post_type)) { $tease_all = true; } } } else { $_args = array('skip_teaser' => true); if (in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'))) { if ($post_type_obj = get_post_type_object($post_type)) { $plural_name = plural_name_from_cap_rs($post_type_obj); $_args['alternate_reqd_caps'][0] = array("create_child_{$plural_name}"); } } // Pass query through the request filter $query = apply_filters('objects_request_rs', $query, 'post', $post_type, $_args); // Execute the filtered query $pages = scoper_get_results($query); // restore buffered titles in case they were filtered previously scoper_restore_property_array($pages, $titles, 'ID', 'post_title'); } if (empty($pages)) { // alternate hook name (WP core already applied get_pages filter) return apply_filters('get_pages_rs', array(), $r); } // // === END Role Scoper MODIFICATION === // ==================================== // Role Scoper note: WP core get_pages has already updated wp_cache and pagecache with unfiltered results. update_page_cache($pages); // === BEGIN Role Scoper MODIFICATION: Support a disjointed pages tree with some parents hidden ======== if ($child_of || empty($tease_all)) { // if we're including all pages with teaser, no need to continue thru tree remapping $ancestors = ScoperAncestry::get_page_ancestors(); // array of all ancestor IDs for keyed page_id, with direct parent first $orderby = $sort_column; if ($parent > 0 || !$hierarchical) { $remap_parents = false; } else { // if these settings were passed into this get_pages call, use them if (-1 === $remap_parents) { $remap_parents = scoper_get_option('remap_page_parents'); } if ($remap_parents) { if (-1 === $enforce_actual_depth) { $enforce_actual_depth = scoper_get_option('enforce_actual_page_depth'); } if (-1 === $remap_thru_excluded_parent) { $remap_thru_excluded_parent = scoper_get_option('remap_thru_excluded_page_parent'); } } } $remap_args = compact('child_of', 'parent', 'exclude', 'depth', 'orderby', 'remap_parents', 'enforce_actual_depth', 'remap_thru_excluded_parent'); // one or more of these args may have been modified after extraction ScoperHardway::remap_tree($pages, $ancestors, 'ID', 'post_parent', $remap_args); } // === END Role Scoper MODIFICATION === // ==================================== if (!empty($exclude_tree)) { $exclude = array(); $exclude = (int) $exclude_tree; $children = get_page_children($exclude, $pages); // RS note: okay to use unfiltered function here since it's only used for excluding $excludes = array(); foreach ($children as $child) { $excludes[] = $child->ID; } $excludes[] = $exclude; $total = count($pages); for ($i = 0; $i < $total; $i++) { if (in_array($pages[$i]->ID, $excludes)) { unset($pages[$i]); } } } if (!empty($append_page) && !empty($pages)) { $found = false; foreach (array_keys($pages) as $key) { if ($post->post_parent == $pages[$key]->ID) { $found = true; break; } } if (empty($found)) { $pages[] = $append_page; } } // re-index the array, just in case anyone cares $pages = array_values($pages); // === BEGIN Role Scoper MODIFICATION: cache key and flag specific to access type and user/groups // if (!$no_cache) { $cache[$ckey] = $pages; $current_rs_user->cache_set($cache, $cache_flag); } // alternate hook name (WP core already applied get_pages filter) $pages = apply_filters('get_pages_rs', $pages, $r); // // === END Role Scoper MODIFICATION === // ==================================== return $pages; }
} else { _e('Group Administrators', 'scoper'); } ?> </h3> <?php UserGroups_tp::group_members_checklist($group_id, 'manager', $all_users); ?> </div> <?php } ?> <?php if (scoper_get_option('group_ajax')) { ?> <div style="clear:both;"></div> <div class="rs-group_admins"> <h3><?php if ($sitewide_groups) { printf(__('Group Moderators %1$s(via login to %2$s)%3$s', 'scoper'), '<span style="font-weight: normal">', rtrim($blog_path, '/'), '</span>'); } else { _e('Group Moderators', 'scoper'); } ?> </h3> <?php UserGroups_tp::group_members_checklist($group_id, 'moderator', $all_users); ?> </div>
function ui_user_roles() { if (!is_user_administrator_rs() && !scoper_get_option('display_user_profile_roles')) { return; } global $profileuser, $current_rs_user; $profile_user_rs = $profileuser->ID == $current_rs_user->ID ? $current_rs_user : new WP_Scoped_User($profileuser->ID); include_once dirname(__FILE__) . '/profile_ui_rs.php'; ScoperProfileUI::display_ui_user_roles($profile_user_rs); }
function force_distinct_taxonomy_caps() { global $wp_taxonomies; $use_taxonomies = scoper_get_option('use_taxonomies'); // note: we are allowing the 'assign_terms' property to retain its default value of 'edit_posts'. The RS user_has_cap filter will convert it to the corresponding type-specific cap as needed. $tx_specific_caps = array('edit_terms' => 'manage_terms', 'manage_terms' => 'manage_terms', 'delete_terms' => 'manage_terms'); $used_values = array(); $customized = array(); // currently, disallow category and post_tag cap use by custom taxonomies, but don't require category and post_tag to have different caps $core_taxonomies = array('category'); foreach ($core_taxonomies as $taxonomy) { foreach (array_keys($tx_specific_caps) as $cap_property) { $used_values[] = $wp_taxonomies[$taxonomy]->cap->{$cap_property}; } } $used_values = array_unique($used_values); $use_taxonomies['nav_menu'] = true; foreach (array_keys($wp_taxonomies) as $taxonomy) { if ('post_tag' == $taxonomy) { // complication due to default use of "manage_categories" cap for both categories and tags continue; } if ('yes' == $wp_taxonomies[$taxonomy]->public) { // clean up a GD Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true) $wp_taxonomies[$taxonomy]->public = true; } elseif ('' === $wp_taxonomies[$taxonomy]->public && !empty($wp_taxonomies[$taxonomy]->query_var_bool)) { // clean up a More Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true) $wp_taxonomies[$taxonomy]->public = true; } if (empty($use_taxonomies[$taxonomy]) || in_array($taxonomy, $core_taxonomies)) { continue; } $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap; $plural_name = $taxonomy . 's'; // as of WP 3.1, no basis for determinining this unless type-specific caps are set // don't allow any capability defined for this taxonomy to match any capability defined for category or post tag (unless this IS category or post tag) foreach ($tx_specific_caps as $cap_property => $replacement_cap_format) { if (!empty($tx_caps[$cap_property]) && in_array($tx_caps[$cap_property], $used_values)) { $wp_taxonomies[$taxonomy]->cap->{$cap_property} = str_replace('terms', $plural_name, $replacement_cap_format); if ('nav_menu' != $taxonomy) { $customized[$taxonomy] = true; } // WP default is for nav menus editable only by administrator, so no need for notice } $used_values[] = $tx_caps[$cap_property]; } } // One-time message alerting Administrators that custom taxonomies were auto-enabled for RS filtering if ($customized) { $logged = !empty($_POST['rs_defaults']) ? array() : (array) scoper_get_option('log_customized_taxonomies'); if ($new_customized = array_diff_key($customized, $logged)) { $labels = array(); foreach (array_keys($new_customized) as $taxonomy) { $tx_obj = get_taxonomy($taxonomy); $labels[$taxonomy] = !empty($tx_obj->labels->name) ? $tx_obj->labels->name : $taxonomy; $label_str = implode(', ', $labels); } $msg_format = __('The following Custom Taxonomies are enabled for RS filtering: <strong>%1$s</strong>. Non-administrators will be unable to manage them until you either disable filtering (<strong>Roles > Options > Realm > Taxonomy Usage</strong>) or assign taxonomy-specific Roles (<strong>Roles > General</strong>). Disregard this message if you have already done so.', 'scoper'); $message = sprintf($msg_format, $label_str); add_action('admin_notices', create_function('', 'echo \'<div id="message" class="error fade" style="color: black">' . $message . '</div>\';')); update_option('scoper_log_customized_taxonomies', array_merge($customized, $new_customized)); } } }
echo '</a> | '; // Show All $tr_display = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false ? 'block' : 'table-row'; $js_call = "\r\r\nagp_display_marked_elements('li','role-li','block');\r\r\nagp_setcss('.no-role','display','{$tr_display}');\r\r\nagp_setcss('.user-csv','display','inline');\r\r\nagp_setcss('.groups-csv','display','inline');\r\r\n"; echo "<a href='javascript:void(0);' onclick=\"{$js_call}\">"; _e('show all', 'scoper'); echo '</a>'; $all_roles = array(); $otype_source = array(); foreach ($scoper->data_sources->get_all() as $src_name => $src) { if (!empty($src->taxonomy_only)) { continue; } $object_types = $src->object_types; if ('post' == $src_name) { $use_post_types = scoper_get_option('use_post_types'); $use_post_types['nav_menu_item'] = true; // currently no RS Options switch for this $object_types['nav_menu_item'] = (object) array('labels' => (object) array('name' => __('Nav Menu Manager', 'scoper'))); } $include_taxonomy_otypes = true; foreach ($object_types as $object_type => $otype) { if ('post' == $src_name && empty($use_post_types[$object_type])) { continue; } $otype_roles = array(); $otype_roles[$object_type] = $scoper->role_defs->get_matching('rs', $src_name, $object_type); $otype_source[$object_type] = $src_name; $uses_taxonomies = scoper_get_taxonomy_usage($src_name, $object_type); if ($include_taxonomy_otypes) { foreach ($uses_taxonomies as $taxonomy) {
function scoper_get_taxonomy_usage($src_name, $object_types = '') { $taxonomies = array(); $object_types = (array) $object_types; foreach ($object_types as $object_type) { if (taxonomy_exists($object_type)) { $use_taxonomies = array($object_type => 1); } else { $use_taxonomies = scoper_get_otype_option('use_term_roles', $src_name, $object_type); } $taxonomies = array_merge($taxonomies, array_intersect((array) $use_taxonomies, array(1))); // array cast prevents PHP warning on first-time execution following update to RS 1.2 } if ($taxonomies) { // make sure we indicate non-usage of term roles for taxonomies that are completely disabled for RS if ('post' == $src_name) { $use_taxonomies = scoper_get_option('use_taxonomies'); $taxonomies = array_intersect_key($taxonomies, array_intersect($use_taxonomies, array(1))); } return array_keys($taxonomies); } else { return array(); } }
function users_who_can($reqd_caps, $cols = COLS_ALL_RS, $object_src_name = '', $object_id = 0, $args = array()) { // if there are not capability requirements, no need to load Users_Interceptor filtering class if (!$reqd_caps) { if (COL_ID_RS == $cols) { $qcols = 'ID'; } elseif (COLS_ID_NAME_RS == $cols) { $qcols = "ID, user_login AS display_name"; } elseif (COLS_ID_DISPLAYNAME_RS == $cols) { $qcols = "ID, display_name"; } elseif (COLS_ALL_RS == $cols) { $qcols = "*"; } else { $qcols = $cols; } global $wpdb; $orderby = $cols == COL_ID_RS ? '' : 'ORDER BY display_name'; if (IS_MU_RS && !scoper_get_option('mu_sitewide_groups') && !defined('FORCE_ALL_SITE_USERS_RS')) { $qry = "SELECT {$qcols} FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} AS um ON {$wpdb->users}.ID = um.user_id AND um.meta_key = '{$wpdb->prefix}capabilities' {$orderby}"; } else { $qry = "SELECT {$qcols} FROM {$wpdb->users} {$orderby}"; } if (COL_ID_RS == $cols) { return scoper_get_col($qry); } else { return scoper_get_results($qry); } } else { $defaults = array('where' => '', 'orderby' => '', 'disable_memcache' => false, 'group_ids' => '', 'force_refresh' => false, 'force_all_users' => false); $args = array_merge($defaults, (array) $args); extract($args); $cache_flag = "rs_users_who_can"; $cache_id = md5(serialize($reqd_caps) . $cols . 'src' . $object_src_name . 'id' . $object_id . serialize($args)); if (!$force_refresh) { // if we already have the results cached, no need to load Users_Interceptor filtering class $users = wpp_cache_get($cache_id, $cache_flag); if (is_array($users)) { return $users; } } $this->init_users_interceptor(); $users = $GLOBALS['users_interceptor']->users_who_can($reqd_caps, $cols, $object_src_name, $object_id, $args); wpp_cache_set($cache_id, $users, $cache_flag); return $users; } }
function role_submission($scope, $mode, $role_bases, $src_or_tx_name, $role_codes, $agent_caption_plural, $nonce_id) { global $scoper; $role_assigner = init_role_assigner(); $err = 0; $role_count = 0; check_admin_referer($nonce_id); $set_roles = array(); $selected_roles = isset($_POST['roles']) ? $_POST['roles'] : array(); if (OBJECT_SCOPE_RS == $scope) { $src = $scoper->data_sources->get($src_or_tx_name); $date_col_defined = !empty($src->cols->date); } elseif (TERM_SCOPE_RS == $scope) { $tx = $scoper->taxonomies->get($src_or_tx_name); $date_col_defined = $scoper->data_sources->member_property($tx->object_source, 'cols', 'date'); } else { $date_col_defined = true; } switch ($mode) { case ROLE_ASSIGNMENT_RS: $assign_for = $_POST['assign_for']; $selected_agents = array(); foreach ($role_bases as $role_basis) { if (!empty($_POST[$role_basis])) { $selected_agents[$role_basis] = $_POST[$role_basis]; } else { $csv_id = "{$role_basis}_csv"; if (!empty($_POST[$csv_id])) { $selected_agents[$role_basis] = ScoperAdminLib::agent_ids_from_csv($csv_id, $role_basis); } else { $role_bases = array_diff($role_bases, array($role_basis)); } } } $agents_msg = array(); $valid_role_selection = !empty($selected_roles); $duration_limits_enabled = $date_col_defined && scoper_get_option('role_duration_limits'); $content_date_limits_enabled = $date_col_defined && scoper_get_option('role_content_date_limits'); break; case ROLE_RESTRICTION_RS: $role_bases = array('n/a'); $default_restrictions = isset($_POST['default_restrictions']) ? $_POST['default_restrictions'] : array(); $max_scope = $_POST['max_scope']; $require_for = $_POST['require_for']; $selected_agents = array('n/a' => array(0)); $valid_role_selection = !empty($selected_roles) || !empty($default_restrictions); $modcount = 0; $duration_limits_enabled = $content_date_limits_enabled = false; break; } if (!$selected_agents) { $_POST['scoper_error'] = 1; echo '<div id="message" class="error"><p><strong>'; printf(__('Error: no %s were selected!', 'scoper'), $agent_caption_plural); echo '</strong></p></div>'; $err = 1; } elseif (!$valid_role_selection) { $_POST['scoper_error'] = 1; echo '<div id="message" class="error"><p><strong>'; _e('Error: no roles were selected!', 'scoper'); echo '</strong></p></div>'; $err = 2; } else { if (ROLE_ASSIGNMENT_RS == $mode) { if (!empty($_POST['set_role_duration']) || !empty($_POST['set_content_date_limits'])) { $date_entries_gmt = ScoperAdminBulkLib::process_role_date_entries(); } } foreach ($role_bases as $role_basis) { foreach ($selected_agents[$role_basis] as $agent_id) { // must set default restrictions first if (!empty($default_restrictions)) { $def_roles = array(); foreach ($default_restrictions as $role) { $keys = explode('-', $role); //keys[0]=role_code, 1=term_id or obj_id if (count($keys) < 2) { continue; } if (!($role_handle = array_search($keys[0], $role_codes))) { continue; } $def_roles[$keys[1]][$role_handle] = array('max_scope' => $max_scope, 'for_item' => false, 'for_children' => true); $modcount++; } $role_assigner->restrict_roles($scope, $src_or_tx_name, 0, $def_roles[0], array('force_flush' => true)); } if (!empty($selected_roles)) { foreach ($selected_roles as $role) { $keys = explode('-', $role); //keys[0]=role_code, 1=term_id or obj_id, 2=group_id or user_id if (count($keys) < 2) { continue; } if (!($role_handle = array_search($keys[0], $role_codes))) { continue; } switch ($mode) { case ROLE_ASSIGNMENT_RS: $set_roles[$role_basis][$keys[1]][$role_handle][$agent_id] = $keys[1] || !$assign_for ? $assign_for : ASSIGN_FOR_CHILDREN_RS; // always assign default category assignments as for_children break; case ROLE_RESTRICTION_RS: $for_item = ASSIGN_FOR_ENTITY_RS == $require_for || ASSIGN_FOR_BOTH_RS == $require_for; $for_children = ASSIGN_FOR_CHILDREN_RS == $require_for || ASSIGN_FOR_BOTH_RS == $require_for; $set_roles[$keys[1]][$role_handle] = array('max_scope' => $max_scope, 'for_item' => $for_item, 'for_children' => $for_children); $modcount++; break; } } } } // end foreach selected agents if (ROLE_ASSIGNMENT_RS == $mode) { $args = array('force_flush' => true, 'set_role_duration' => '', 'set_content_date_limits' => ''); if ($duration_limits_enabled && !empty($_POST['set_role_duration'])) { $is_limited = $date_entries_gmt->start_date_gmt || $date_entries_gmt->end_date_gmt != SCOPER_MAX_DATE_STRING || !empty($_POST['start_date_gmt_keep-timestamp']) || !empty($_POST['end_date_gmt_keep-timestamp']); $args['set_role_duration'] = (object) array('date_limited' => $is_limited, 'start_date_gmt' => $date_entries_gmt->start_date_gmt, 'end_date_gmt' => $date_entries_gmt->end_date_gmt); } if ($content_date_limits_enabled && !empty($_POST['set_content_date_limits'])) { $is_limited = $date_entries_gmt->content_min_date_gmt || $date_entries_gmt->content_max_date_gmt != SCOPER_MAX_DATE_STRING || !empty($_POST['content_min_date_gmt_keep-timestamp']) || !empty($_POST['content_max_date_gmt_keep-timestamp']); $args['set_content_date_limits'] = (object) array('content_date_limited' => $is_limited, 'content_min_date_gmt' => $date_entries_gmt->content_min_date_gmt, 'content_max_date_gmt' => $date_entries_gmt->content_max_date_gmt); } if (isset($set_roles[$role_basis])) { foreach ($set_roles[$role_basis] as $id => $item_roles) { $role_assigner->assign_roles($scope, $src_or_tx_name, $id, $item_roles, $role_basis, $args); } } } else { foreach ($set_roles as $id => $item_roles) { $role_assigner->restrict_roles($scope, $src_or_tx_name, $id, $item_roles, array('force_flush' => true)); } } if (!empty($selected_agents[$role_basis])) { if (ROLE_BASIS_USER == $role_basis) { $agents_msg[] = sprintf(_n("%d user", "%d users", count($selected_agents[$role_basis]), 'scoper'), count($selected_agents[$role_basis])); } else { $agents_msg[] = sprintf(_n("%d group", "%d groups", count($selected_agents[$role_basis]), 'scoper'), count($selected_agents[$role_basis])); } } } // end foreach role basis echo '<div id="message" class="updated fade"><p>'; switch ($mode) { case ROLE_ASSIGNMENT_RS: $roles_msg = sprintf(_n("%d role selection", "%d role selections", count($selected_roles), 'scoper'), count($selected_roles)); $agents_msg = implode(", ", $agents_msg); //printf( _ x('Role Assignments Updated: %1$s for %2$s', 'n role selections for x users, y groups', 'scoper'), $roles_msg, $agents_msg ); printf(__('Role Assignments Updated: %1$s for %2$s', 'scoper'), $roles_msg, $agents_msg); break; case ROLE_RESTRICTION_RS: printf(_n("Role Restrictions Updated: %d setting", "Role Restrictions Updated: %d settings", $modcount, 'scoper'), $modcount); break; } echo '</p></div>'; // allow the DB server a little time to refresh before querying what we just put in global $wpdb; $junk = scoper_get_col("SELECT assignment_id FROM {$wpdb->user2role2object_rs} LIMIT 10"); } //endif no input error return $err; }
function group_members_checklist($group_id, $user_class = 'member', $all_users = '') { global $scoper; if (!$all_users) { $all_users = $scoper->users_who_can('', COLS_ID_NAME_RS); } if ($group_id) { $group = ScoperAdminLib::get_group($group_id); } if ('member' == $user_class) { $current_ids = $group_id ? array_flip(ScoperAdminLib::get_group_members($group_id, COL_ID_RS)) : array(); if (!empty($group) && in_array($group->meta_id, array('rv_pending_rev_notice_ed_nr_', 'rv_scheduled_rev_notice_ed_nr_'))) { $args = array('any_object' => true); $eligible_ids = array(); foreach (get_post_types(array('public' => true), 'object') as $_type => $_type_obj) { $args['object_type'] = $_type; $type_eligible_ids = $scoper->users_who_can(array($_type_obj->cap->edit_published_posts, $_type_obj->cap->edit_others_posts), COL_ID_RS, 'post', 0, $args); $eligible_ids = array_merge($eligible_ids, $type_eligible_ids); } $eligible_ids = array_unique($eligible_ids); } else { // force_all_users arg is a temporary measure to ensure that any user can be viewed / added to a sitewide MU group regardless of what blog backend it's edited through $_args = IS_MU_RS && scoper_get_option('mu_sitewide_groups', true) ? array('force_all_users' => true) : array(); $eligible_ids = $scoper->users_who_can('', COL_ID_RS, '', '', $_args); } $admin_ids = array(); } else { $group_role_defs = 'moderator' == $user_class ? array('rs_group_moderator') : array('rs_group_manager'); if ($group_id) { require_once dirname(__FILE__) . '/role_assignment_lib_rs.php'; $current_roles = ScoperRoleAssignments::organize_assigned_roles(OBJECT_SCOPE_RS, 'group', $group_id, $group_role_defs, ROLE_BASIS_USER); $current_roles = agp_array_flatten($current_roles, false); $current_ids = isset($current_roles['assigned']) ? $current_roles['assigned'] : array(); } else { $current_ids = array(); } $cap_name = defined('SCOPER_USER_ADMIN_CAP') ? constant('SCOPER_USER_ADMIN_CAP') : 'edit_users'; $admin_ids = $scoper->users_who_can($cap_name, COL_ID_RS); // optionally, limit available group managers according to role_admin_blogwide_editor_only option if ('manager' == $user_class) { $require_blogwide_editor = false; if (!empty($group)) { if (!strpos($group->meta_id, '_nr_')) { // don't limit manager selection for groups that don't have role assignments $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only'); } } if ('admin' == $require_blogwide_editor) { $eligible_ids = $admin_ids; } elseif ('admin_content' == $require_blogwide_editor) { $cap_name = defined('SCOPER_CONTENT_ADMIN_CAP') ? constant('SCOPER_CONTENT_ADMIN_CAP') : 'activate_plugins'; $eligible_ids = array_unique(array_merge($admin_ids, $scoper->users_who_can($cap_name, COL_ID_RS))); } elseif ($require_blogwide_editor) { $post_editors = $scoper->users_who_can('edit_others_posts', COL_ID_RS); $page_editors = $scoper->users_who_can('edit_others_pages', COL_ID_RS); $eligible_ids = array_unique(array_merge($post_editors, $page_editors, $admin_ids)); } else { $eligible_ids = ''; } } else { $eligible_ids = ''; } } // endif user class is not "member" $css_id = $user_class; $args = array('eligible_ids' => $eligible_ids, 'via_other_scope_ids' => $admin_ids, 'suppress_extra_prefix' => true); require_once dirname(__FILE__) . '/agents_checklist_rs.php'; ScoperAgentsChecklist::agents_checklist(ROLE_BASIS_USER, $all_users, $css_id, $current_ids, $args); }
function add_meta_boxes() { /* // optional hack to prevent role assignment boxes for non-Editors // // This is now handled as a Role Scoper Option. // On the Advanced tab, Hidden Editing Elements section: select "Role administration requires a blog-wide Editor role" // // end optional hack */ // ========= register WP-rendered metaboxes ============ $src_name = 'post'; // TODO: different handling for edit-tags.php $object_type = cr_find_post_type(); $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only'); if ('admin' == $require_blogwide_editor && !is_user_administrator_rs()) { return; } if ('admin_content' == $require_blogwide_editor && !is_content_administrator_rs()) { return; } if (!scoper_get_otype_option('use_object_roles', $src_name, $object_type)) { return; } if ($require_blogwide_editor) { if (!$this->scoper->user_can_edit_blogwide($src_name, $object_type, array('require_others_cap' => true))) { return; } } $role_defs = $this->scoper->role_defs->get_matching('rs', $src_name, $object_type); foreach ($role_defs as $role_handle => $role_def) { if (!isset($role_def->valid_scopes[OBJECT_SCOPE_RS])) { continue; } $box_id = $role_handle; add_meta_box($box_id, $this->scoper->role_defs->get_abbrev($role_handle, OBJECT_UI_RS), array(&$this, 'draw_object_roles_content'), $object_type); $this->meta_box_ids[$role_handle] = $box_id; } }
function scoper_admin_section_restrictions($taxonomy) { global $scoper, $scoper_admin; $tx = $scoper->taxonomies->get($taxonomy); if (empty($tx) || empty($tx->requires_term)) { wp_die(__('Invalid taxonomy', 'scoper')); } $is_administrator = is_administrator_rs($tx, 'user'); if (!$scoper_admin->user_can_admin_terms($taxonomy)) { wp_die(__awp('Cheatin’ uh?')); } require_once dirname(__FILE__) . '/admin-bulk_rs.php'; $role_assigner = init_role_assigner(); $nonce_id = 'scoper-assign-roles'; $role_codes = ScoperAdminBulk::get_role_codes(); echo '<a name="scoper_top"></a>'; // retrieve all terms to track hierarchical relationship, even though some may not be adminable by current user $val = ORDERBY_HIERARCHY_RS; $args = array('order_by' => $val); $all_terms = $scoper->get_terms($taxonomy, UNFILTERED_RS, COLS_ALL_RS, 0, $args); // =========================== Submission Handling ========================= if (isset($_POST['rs_submit'])) { $err = ScoperAdminBulk::role_submission(TERM_SCOPE_RS, ROLE_RESTRICTION_RS, '', $taxonomy, $role_codes, '', $nonce_id); if (scoper_get_option('file_filtering')) { scoper_flush_file_rules(); } } else { $err = 0; } // =========================== Prepare Data =============================== $tx_src = $scoper->data_sources->get($tx->source); if ($col_id = $tx_src->cols->id) { // determine which terms current user can admin if ($admin_terms = $scoper->get_terms($taxonomy, ADMIN_TERMS_FILTER_RS, COL_ID_RS)) { $admin_terms = array_fill_keys($admin_terms, true); } } else { $admin_terms = array(); } // =========================== Display UI =============================== ?> <div class="wrap agp-width97"> <?php $tx_label = $tx->labels->singular_name; $src_label = $scoper->data_sources->member_property($tx->object_source, 'labels', 'singular_name'); echo '<h2>' . sprintf(__('%s Restrictions', 'scoper'), $tx_label); echo ' <span style="font-size: 0.6em; font-style: normal">(<a href="#scoper_notes">' . __('see notes', 'scoper') . '</a>)</span></h2>'; if (scoper_get_option('display_hints')) { echo '<div class="rs-hint">'; if ('category' == $taxonomy && scoper_get_otype_option('use_object_roles', 'post', 'post')) { printf(__('Reduce access by requiring some role(s) to be %1$s%2$s-assigned%3$s (or %4$s-assigned). Corresponding General Roles (whether assigned by WordPress or Role Scoper) are ignored.', 'scoper'), "<a href='admin.php?page=rs-{$taxonomy}-roles_t'>", $tx_label, '</a>', $src_label); } else { printf(__('Reduce access by requiring some role(s) to be %1$s%2$s-assigned%3$s. Corresponding General Role assignments are ignored.', 'scoper'), "<a href='admin.php?page=rs-{$taxonomy}-roles_t'>", $tx_label, '</a>'); } echo '</div>'; } if (!($role_defs_by_otype = $scoper->role_defs->get_for_taxonomy($tx->object_source, $taxonomy))) { echo '<br />' . sprintf(__('Role definition error (taxonomy: %s).', 'scoper'), $taxonomy); echo '</div>'; return; } if (empty($admin_terms)) { echo '<br />' . sprintf(__('Either you do not have permission to administer any %s, or none exist.', 'scoper'), $tx->labels->name); echo '</div>'; return; } ?> <form action="" method="post" name="role_scope" id="role_assign"> <?php wp_nonce_field($nonce_id); echo '<br /><div id="rs-term-scroll-links">'; echo ScoperAdminBulkLib::taxonomy_scroll_links($tx, $all_terms, $admin_terms); echo '</div><hr />'; // ============ Assignment Mode Selection Display ================ // TODO: is Link Category label handled without workaround now? $tx_label = agp_strtolower($tx->labels->name); $tx_label_singular = agp_strtolower($tx->labels->singular_name); $parent_col = $tx_src->cols->parent; if (!$parent_col || !empty($tx->uses_standard_schema) && empty($tx->hierarchical)) { $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => sprintf(__('for selected %s', 'scoper'), $tx_label)); } else { $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => sprintf(__('for selected %s', 'scoper'), $tx_label), ASSIGN_FOR_CHILDREN_RS => sprintf(__('for sub-%s of selected', 'scoper'), $tx_label), ASSIGN_FOR_BOTH_RS => sprintf(__('for selected and sub-%s', 'scoper'), $tx_label)); } $max_scopes = array('term' => __('Restrict selected roles', 'scoper'), 'blog' => __('Unrestrict selected roles', 'scoper')); $args = array('max_scopes' => $max_scopes, 'scope' => TERM_SCOPE_RS); ScoperAdminBulk::display_inputs(ROLE_RESTRICTION_RS, $assignment_modes, $args); ScoperAdminBulk::item_tree_jslinks(ROLE_RESTRICTION_RS); // IE (6 at least) won't obey link color directive in a.classname CSS $ie_link_style = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false ? ' style="color:white;"' : ''; $args = array('include_child_restrictions' => true, 'return_array' => true, 'role_type' => 'rs', 'force_refresh' => true); $strict_terms = $scoper->get_restrictions(TERM_SCOPE_RS, $taxonomy, $args); //strict_terms[taxonomy][role name][term_id] = array: terms which require Role Scoper assignment for specified role (user blog roles ignored, required caps may be supplied by scoper term role or object-specific assignment) // (for other terms, Role Scoper role assignment is optional (term role assignments will supplement blog caps) $editable_roles = array(); foreach ($all_terms as $term) { $id = $term->{$col_id}; foreach ($role_defs_by_otype as $object_type => $role_defs) { foreach (array_keys($role_defs) as $role_handle) { if ($role_assigner->user_has_role_in_term($role_handle, $taxonomy, $id, '', array('src_name' => $tx->object_source, 'object_type' => $object_type))) { $editable_roles[$id][$role_handle] = true; } } } } $default_restrictions = $scoper->get_default_restrictions(TERM_SCOPE_RS); $default_strict_roles = !empty($default_restrictions[$taxonomy]) ? array_flip(array_keys($default_restrictions[$taxonomy])) : array(); $table_captions = ScoperAdminUI::restriction_captions(TERM_SCOPE_RS, $tx, $tx_label_singular, $tx_label); $args = array('admin_items' => $admin_terms, 'editable_roles' => $editable_roles, 'default_strict_roles' => $default_strict_roles, 'ul_class' => 'rs-termlist', 'ie_link_style' => $ie_link_style, 'err' => $err, 'table_captions' => $table_captions); ScoperAdminBulk::item_tree(TERM_SCOPE_RS, ROLE_RESTRICTION_RS, $tx_src, $tx, $all_terms, '', $strict_terms, $role_defs_by_otype, $role_codes, $args); echo '<a href="#scoper_top">' . __('top', 'scoper') . '</a>'; echo '<hr />'; echo '<h4 style="margin-bottom:0.1em"><a name="scoper_notes"></a>' . __("Notes", 'scoper') . ':</h4><ul class="rs-notes">'; $osrc = $scoper->data_sources->get($tx->object_source); if (empty($osrc->no_object_roles)) { echo '<li>'; printf(__('Any %1$s Restriction causes the specified role to be granted only via %1$s Role assignment, regardless of these %2$s settings.', 'scoper'), $osrc->labels->singular_name, $tx->labels->singular_name); echo '</li></ul>'; } ?> </form> </div> <?php }
function _flt_last_resort_query($query) { global $wpdb, $pagenow, $scoper; $posts = $wpdb->posts; $comments = $wpdb->comments; $links = $wpdb->links; $term_taxonomy = $wpdb->term_taxonomy; // WP 3.0: SELECT * FROM wp_comments c LEFT JOIN wp_posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' AND ( c.comment_approved = '0' OR c.comment_approved = '1' ) ORDER BY c.comment_date_gmt // if (strpos($query, "ELECT ") && preg_match("/FROM\\s*{$GLOBALS['wpdb']->comments}/", $query) && (!strpos($query, "ELECT COUNT") || empty($_POST)) && !strpos($_SERVER['SCRIPT_FILENAME'], 'p-admin/upload.php')) { //define( 'SCOPER_NO_COMMENT_FILTERING', true ); if (defined('SCOPER_NO_COMMENT_FILTERING') && empty($GLOBALS['current_user']->allcaps['moderate_comments'])) { return $query; } // cache the filtered results for pending comment count query, which (as of WP 3.0.1) is executed once per-post in the edit listing $post_id = 0; if ($doing_pending_comment_count = strpos($query, 'COUNT(comment_ID)') && strpos($query, 'comment_post_ID') && strpos($query, "comment_approved = '0'")) { if ('index.php' != $pagenow) { // there's too much happening on the dashboard (and too much low-level query filtering) to buffer listed IDs reliably. if (preg_match("/comment_post_ID IN \\( '([0-9]+)' \\)/", $query, $matches)) { if ($matches[1]) { $post_id = $matches[1]; } } } if ($post_id) { static $cache_pending_comment_count; if (!isset($cache_pending_comment_count)) { $cache_pending_comment_count = array(); } elseif (isset($cache_pending_comment_count[$post_id])) { return "SELECT {$post_id} AS comment_post_ID, {$cache_pending_comment_count[$post_id]} AS num_comments"; } } } $comment_alias = strpos($query, "{$comments} c") || strpos($query, "{$comments} AS c") ? 'c' : $comments; // apply DISTINCT clause so JOINs don't cause redundant comment count $query = str_replace("SELECT *", "SELECT DISTINCT {$comment_alias}.*", $query); $query = str_replace("SELECT SQL_CALC_FOUND_ROWS *", "SELECT SQL_CALC_FOUND_ROWS DISTINCT {$comment_alias}.*", $query); if (!strpos($query, ' DISTINCT ')) { $query = str_replace("SELECT ", "SELECT DISTINCT ", $query); } //$query = str_replace( "COUNT(*)", " COUNT(DISTINCT $comments.comment_ID)", $query); // TODO: confirm preg_replace works and str_replace is not needed //$query = str_replace( "COUNT(comment_ID)", " COUNT(DISTINCT $comments.comment_ID)", $query); $query = preg_replace("/COUNT(\\s*\\*\\s*)/", " COUNT(DISTINCT {$comments}.comment_ID)", $query); $query = preg_replace("/COUNT(\\s*comment_ID\\s*)/", " COUNT(DISTINCT {$comments}.comment_ID)", $query); $query = str_replace(" user_id ", " {$comment_alias}.user_id ", $query); if (!strpos($query, "JOIN {$posts}")) { if (strpos($query, "{$comments} c")) { $query = preg_replace("/FROM\\s*{$comments} c\\s*WHERE /", "FROM {$comments} c INNER JOIN {$posts} ON {$posts}.ID = {$comment_alias}.comment_post_ID WHERE ", $query); } else { $query = preg_replace("/FROM\\s*{$comments}\\s*WHERE /", "FROM {$comments} INNER JOIN {$posts} ON {$posts}.ID = {$comment_alias}.comment_post_ID WHERE ", $query); } if (strpos($query, "GROUP BY")) { $query = preg_replace("/FROM\\s*{$comments}\\s*GROUP BY /", "FROM {$comments} INNER JOIN {$posts} ON {$posts}.ID = {$comment_alias}.comment_post_ID GROUP BY ", $query); } } $generic_uri = in_array($pagenow, array('index.php', 'comments.php')); if (!$generic_uri && ($_post_type = cr_find_post_type('', false))) { // arg: don't return 'post' as default if detection fails $post_types = array($_post_type => get_post_type_object($_post_type)); } else { $post_types = array_diff_key(get_post_types(array('public' => true), 'object'), array('attachment' => true)); } $post_statuses = get_post_stati(array('internal' => null), 'object'); $reqd_caps = array(); $use_post_types = scoper_get_option('use_post_types'); foreach ($post_types as $_post_type => $type_obj) { if (empty($use_post_types[$_post_type])) { continue; } foreach ($post_statuses as $status => $status_obj) { $reqd_caps[$_post_type][$status] = array($type_obj->cap->edit_others_posts, 'moderate_comments'); if ($status_obj->private) { $reqd_caps[$_post_type][$status][] = $type_obj->cap->edit_private_posts; } $status_name = 'publish' == $status || 'future' == $status ? 'published' : $status; $property = "edit_{$status_name}_posts"; if (!empty($type_obj->cap->{$property}) && !in_array($type_obj->cap->{$property}, $reqd_caps[$_post_type][$status])) { $reqd_caps[$_post_type][$status][] = $type_obj->cap->{$property}; } } } $args = array('force_reqd_caps' => $reqd_caps); if (strpos($query, "{$posts} p") || strpos($query, "{$posts} AS p")) { $args['source_alias'] = 'p'; } $object_type = 'edit.php' == $pagenow ? cr_find_post_type() : ''; $query = apply_filters('objects_request_rs', $query, 'post', $object_type, $args); // pre-execute the comments listing query and buffer the listed IDs for more efficient user_has_cap calls if (strpos($query, "* FROM {$comments}") && empty($scoper->listed_ids['post'])) { if ($results = scoper_get_results($query)) { $scoper->listed_ids['post'] = array(); foreach ($results as $row) { if (!empty($row->comment_post_ID)) { $scoper->listed_ids['post'][$row->comment_post_ID] = true; } } } } elseif ($doing_pending_comment_count && $post_id) { if (isset($scoper->listed_ids['post'])) { $listed_ids = array_keys($scoper->listed_ids['post']); } elseif (!empty($GLOBALS['wp_object_cache']->cache['posts']) && is_array($GLOBALS['wp_object_cache']->cache['posts'])) { $listed_ids = array_keys($GLOBALS['wp_object_cache']->cache['posts']); } else { $listed_ids = array(); } // make sure our current post_id is in the list $listed_ids[] = $post_id; if (count($listed_ids) > 1) { // cache the pending comment count for all listed posts $query = str_replace("comment_post_ID IN ( '{$post_id}' )", "comment_post_ID IN ( '" . implode("','", $listed_ids) . "' )", $query); $results = scoper_get_results($query); $cache_pending_comment_count = array_fill_keys($listed_ids, 0); foreach ($results as $row) { $cache_pending_comment_count[$row->comment_post_ID] = $row->comment_count; } } } //d_echo( "<br />replaced: $query<br />" ); //rs_errlog ("<br /><br />replaced with $query<br /><br />"); } // endif matched query substring // num cats: "SELECT COUNT(*) FROM wp_term_taxonomy" // SELECT DISTINCT COUNT(tt.term_id) FROM wp_term_taxonomy AS tt WHERE 1=1 AND tt.taxonomy = 'category' // SELECT DISTINCT tt.term_id FROM wp_term_taxonomy AS tt WHERE if (!in_array($pagenow, array('post.php', 'post-new.php')) && !defined('XMLRPC_REQUEST')) { if (strpos($query, " FROM {$term_taxonomy}") || strpos($query, " FROM {$wpdb->terms}")) { //rs_errlog ("<br />caught $query <br />"); // don't mess with parent category selection/availability for single term edit $is_term_admin = in_array($pagenow, array('edit-tags.php', 'edit-link-categories.php')); if ($is_term_admin) { if (!empty($_REQUEST['tag_ID'])) { return $query; } } $matches = array(); if ($return = preg_match("/taxonomy IN \\('(.*)'/", $query, $matches)) { $taxonomy = explode("','", str_replace(' ', '', $matches[1])); } elseif ($return = preg_match("/taxonomy\\s*=\\s*'(.*)'/", $query, $matches)) { $taxonomy = $matches[1]; } if (!empty($taxonomy)) { if ('profile.php' == $pagenow) { return $query; } else { $query = apply_filters('terms_request_rs', $query, $taxonomy, array('is_term_admin' => $is_term_admin)); } } //rs_errlog ("<br /><br /> returning $query <br />"); return $query; } } // get_users_drafts() and get_others_unpublished_posts() // // Recent posts: SELECT ID, post_title FROM wp_posts WHERE post_type = 'post' AND (post_status = 'publish' OR post_status = 'private') AND post_date_gmt < '2008-04-30 05:04:04' ORDER BY post_date DESC LIMIT 5 // Scheduled entries: SELECT ID, post_title, post_date_gmt FROM wp_posts WHERE post_type = 'post' AND post_status = 'future' ORDER BY post_date ASC" if (strpos($query, "post_date_gmt <") && strpos($query, "ELECT ID, post_title") && strpos($query, " FROM {$posts} WHERE ") || strpos($query, "ELECT ID, post_title, post_date_gmt") && strpos($query, " FROM {$posts} WHERE ")) { if ($_post_type = cr_find_post_type()) { $query = apply_filters('objects_request_rs', $query, 'post', $_post_type, ''); } } // links //SELECT * , IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated FROM wp_links WHERE 1=1 ORDER BY link_name ASC if ((strpos($query, "FROM {$links} WHERE") || strpos($query, "FROM {$links} WHERE")) && strpos($query, "ELECT ")) { $query = apply_filters('objects_request_rs', $query, 'link', 'link'); return $query; } return $query; }